├── .eslintrc.json ├── public ├── logo.png ├── favicon.ico ├── assets │ ├── demo-preview.mp4 │ └── slackanimation.gif ├── logo.svg └── vercel.svg ├── styles ├── globals.css ├── Inter-Regular.ttf └── Inter-SemiBold.ttf ├── postcss.config.js ├── vercel.json ├── .env.example ├── next-env.d.ts ├── pages ├── _document.tsx ├── _app.tsx ├── api │ ├── event.ts │ ├── cron │ │ ├── index.ts │ │ └── test.ts │ ├── cmd │ │ └── configure.ts │ ├── auth.ts │ ├── og.tsx │ └── response.ts ├── success │ └── [[...teamId]].tsx └── index.tsx ├── components ├── loading-dots.tsx ├── loading-dots.module.css ├── layout │ ├── meta.tsx │ └── index.tsx ├── modal.tsx ├── slack-button.tsx └── video-modal.tsx ├── .gitignore ├── tsconfig.json ├── tailwind.config.js ├── next.config.js ├── package.json ├── lib ├── hn.ts ├── cron.ts ├── helpers.ts ├── upstash.ts └── slack.ts ├── manifest.ts ├── README.md └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vercel-labs/slacker/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vercel-labs/slacker/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /styles/Inter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vercel-labs/slacker/HEAD/styles/Inter-Regular.ttf -------------------------------------------------------------------------------- /styles/Inter-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vercel-labs/slacker/HEAD/styles/Inter-SemiBold.ttf -------------------------------------------------------------------------------- /public/assets/demo-preview.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vercel-labs/slacker/HEAD/public/assets/demo-preview.mp4 -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/slackanimation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vercel-labs/slacker/HEAD/public/assets/slackanimation.gif -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "crons": [ 3 | { 4 | "path": "/api/cron", 5 | "schedule": "* * * * *" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | UPSTASH_REDIS_REST_URL= 2 | UPSTASH_REDIS_REST_TOKEN= 3 | SLACK_SIGNING_SECRET= 4 | SLACK_VERIFICATION_TOKEN= 5 | NEXT_PUBLIC_SLACK_CLIENT_ID= -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from "next/document"; 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /components/loading-dots.tsx: -------------------------------------------------------------------------------- 1 | import styles from "./loading-dots.module.css"; 2 | 3 | const LoadingDots = ({ color = "#000" }: { color: string }) => { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | ); 11 | }; 12 | 13 | export default LoadingDots; 14 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import "@/styles/globals.css"; 2 | import type { AppProps } from "next/app"; 3 | import { Inter } from "@next/font/google"; 4 | import { Analytics } from "@vercel/analytics/react"; 5 | 6 | const inter = Inter({ 7 | variable: "--font-inter", 8 | subsets: ["latin"], 9 | }); 10 | 11 | function MyApp({ Component, pageProps }: AppProps) { 12 | return ( 13 |
14 | 15 | 16 |
17 | ); 18 | } 19 | 20 | export default MyApp; 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | .env 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | -------------------------------------------------------------------------------- /pages/api/event.ts: -------------------------------------------------------------------------------- 1 | import { handleUninstall, handleUnfurl } from "@/lib/slack"; 2 | import type { NextApiRequest, NextApiResponse } from "next"; 3 | 4 | export default async function handler( 5 | req: NextApiRequest, 6 | res: NextApiResponse 7 | ) { 8 | if (req.body.challenge) return res.status(200).json(req.body); // unique case for Slack challenge 9 | 10 | if (req.body.event.type === "app_uninstalled") { 11 | return handleUninstall(req, res); 12 | } 13 | 14 | if (req.body.event.type === "link_shared") { 15 | return handleUnfurl(req, res); 16 | } 17 | 18 | return res.status(404).json({ message: "Unknown event type" }); 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "baseUrl": ".", 8 | "paths": { 9 | "@/lib/*": ["lib/*"], 10 | "@/components/*": ["components/*"], 11 | "@/styles/*": ["styles/*"] 12 | }, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noEmit": true, 16 | "esModuleInterop": true, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "jsx": "preserve", 22 | "incremental": true 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /components/loading-dots.module.css: -------------------------------------------------------------------------------- 1 | .loading { 2 | display: inline-flex; 3 | align-items: center; 4 | } 5 | 6 | .loading .spacer { 7 | margin-right: 2px; 8 | } 9 | 10 | .loading span { 11 | animation-name: blink; 12 | animation-duration: 1.4s; 13 | animation-iteration-count: infinite; 14 | animation-fill-mode: both; 15 | width: 5px; 16 | height: 5px; 17 | border-radius: 50%; 18 | display: inline-block; 19 | margin: 0 1px; 20 | } 21 | 22 | .loading span:nth-of-type(2) { 23 | animation-delay: 0.2s; 24 | } 25 | 26 | .loading span:nth-of-type(3) { 27 | animation-delay: 0.4s; 28 | } 29 | 30 | @keyframes blink { 31 | 0% { 32 | opacity: 0.2; 33 | } 34 | 20% { 35 | opacity: 1; 36 | } 37 | 100% { 38 | opacity: 0.2; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: [ 3 | "./pages/**/*.{js,ts,jsx,tsx}", 4 | "./components/**/*.{js,ts,jsx,tsx}", 5 | ], 6 | theme: { 7 | extend: { 8 | backgroundImage: { 9 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", 10 | "gradient-conic": "conic-gradient(var(--tw-gradient-stops))", 11 | }, 12 | fontFamily: { 13 | default: ["var(--font-inter)", "system-ui", "sans-serif"], 14 | }, 15 | keyframes: { 16 | disco: { 17 | "0%": { transform: "translateY(-50%) rotate(0deg)" }, 18 | "100%": { transform: "translateY(-50%) rotate(360deg)" }, 19 | }, 20 | }, 21 | animation: { 22 | disco: "disco 1.5s linear infinite", 23 | }, 24 | }, 25 | }, 26 | plugins: [require("@tailwindcss/forms")], 27 | }; 28 | -------------------------------------------------------------------------------- /pages/api/cron/index.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next"; 2 | import { cron } from "@/lib/cron"; 3 | import { log } from "@/lib/slack"; 4 | import { isDuplicateCron } from "@/lib/upstash"; 5 | 6 | export default async function handler( 7 | _req: NextApiRequest, 8 | res: NextApiResponse 9 | ) { 10 | if (await isDuplicateCron()) { 11 | // check if this is a duplicate cron job (threshold of 55s) 12 | return res.status(500).json({ message: "Duplicate cron job" }); 13 | } 14 | try { 15 | const response = await cron(); 16 | console.log("Cron job successful!"); 17 | res.status(200).json({ message: "Cron job successful!" }); 18 | } catch (err) { 19 | console.log("Cron job error:", err); 20 | await log("Cron job error: \n" + "```" + JSON.stringify(err) + "```"); 21 | res.status(500).json({ statusCode: 500, message: err }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | swcMinify: true, 5 | images: { 6 | domains: ["cdn.loom.com"], 7 | }, 8 | async rewrites() { 9 | return [ 10 | { 11 | source: "/assets/demo.mp4", 12 | destination: 13 | "https://assets.vercel.com/video/upload/v1677175120/random/slacker.mp4", 14 | }, 15 | ]; 16 | }, 17 | async redirects() { 18 | return [ 19 | { 20 | source: "/github", 21 | destination: "https://github.com/vercel-labs/slacker", 22 | permanent: true, 23 | }, 24 | { 25 | source: "/support", 26 | destination: "mailto:stey@vercel.com", 27 | permanent: true, 28 | }, 29 | { 30 | source: "/privacy", 31 | destination: "https://vercel.com/privacy", 32 | permanent: true, 33 | }, 34 | ]; 35 | }, 36 | }; 37 | 38 | module.exports = nextConfig; 39 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /pages/api/cron/test.ts: -------------------------------------------------------------------------------- 1 | import { testCron } from "@/lib/cron"; 2 | import type { NextApiRequest, NextApiResponse } from "next"; 3 | 4 | const postsToTest = [ 5 | 32273228, // target word directly next to a bracket, e.g. Vercel(Api) 6 | 32257847, // target word inside a code block, e.g. ```blah blah blah...Vercel...blah blah blah``` 7 | 32179305, // target word in an inline-link e.g. 8 | 32276017, // target word in title URL e.g. https://chronotrains-eu.vercel.app/ 9 | ]; 10 | 11 | const fakeTeamsAndKeywords = { 12 | VERCEL: ["next.js", "vercel", "javascript"], 13 | SUPABASE: ["supabase", "typescript"], 14 | }; 15 | 16 | const fakeInterestedTeams = { 17 | 32273228: ["VERCEL", "SUPABASE"], 18 | 32257847: ["VERCEL", "SUPABASE"], 19 | 32179305: ["VERCEL"], 20 | 32276017: ["VERCEL"], 21 | }; 22 | 23 | export default async function handler( 24 | _req: NextApiRequest, 25 | res: NextApiResponse 26 | ) { 27 | const response = await testCron( 28 | postsToTest, 29 | fakeTeamsAndKeywords, 30 | fakeInterestedTeams 31 | ); 32 | res.status(200).json(response); 33 | } 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slacker", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@next/font": "^13.1.6", 13 | "@tailwindcss/forms": "^0.5.2", 14 | "@upstash/redis": "^1.10.2", 15 | "@vercel/analytics": "^0.1.9-beta.6", 16 | "@vercel/og": "^0.1.0", 17 | "escape-string-regexp": "5.0.0", 18 | "framer-motion": "^9.0.7", 19 | "html-entities": "^2.3.3", 20 | "html-to-mrkdwn": "^3.0.0", 21 | "lucide-react": "^0.115.0", 22 | "next": "^13.1.6", 23 | "p-retry": "^5.1.1", 24 | "react": "18.2.0", 25 | "react-dom": "18.2.0", 26 | "react-wrap-balancer": "^0.4.0", 27 | "swr": "^1.3.0" 28 | }, 29 | "devDependencies": { 30 | "@types/node": "18.0.6", 31 | "@types/react": "18.0.15", 32 | "@types/react-dom": "18.0.6", 33 | "@types/turndown": "^5.0.1", 34 | "autoprefixer": "^10.4.7", 35 | "eslint": "8.20.0", 36 | "eslint-config-next": "12.2.2", 37 | "postcss": "^8.4.14", 38 | "tailwindcss": "^3.1.6", 39 | "typescript": "4.7.4" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pages/api/cmd/configure.ts: -------------------------------------------------------------------------------- 1 | import { getTeamConfigAndStats } from "@/lib/upstash"; 2 | import { verifyRequest, configureBlocks } from "@/lib/slack"; 3 | import { NextApiRequest, NextApiResponse } from "next"; 4 | 5 | export default async function handler( 6 | req: NextApiRequest, 7 | res: NextApiResponse 8 | ) { 9 | const verification = verifyRequest(req); 10 | if (!verification.status) 11 | // verify that the request is coming from the correct Slack team 12 | return res.status(200).json({ 13 | response_type: "ephemeral", 14 | text: verification.message, 15 | }); 16 | 17 | const { team_id, command } = req.body; 18 | 19 | if (command === "/configure") { 20 | const { keywords, channel, unfurls, notifications } = 21 | await getTeamConfigAndStats(team_id); 22 | 23 | return res.status(200).json({ 24 | response_type: "ephemeral", 25 | text: "Configure your bot", 26 | unfurl_links: false, // do not unfurl links & media for bot configuration message 27 | unfurl_media: false, 28 | blocks: configureBlocks(keywords, channel, unfurls, notifications), 29 | }); 30 | } else { 31 | return res.status(200).json({ 32 | // account for old commands that are now deprecated 33 | response_type: "ephemeral", 34 | text: 35 | "The command `" + 36 | command + 37 | "` is deprecated. Please use `/configure` instead.", 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/hn.ts: -------------------------------------------------------------------------------- 1 | import pRetry from "p-retry"; 2 | 3 | export async function getLatestPost() { 4 | /* get latest post id from hacker news */ 5 | const res = await fetch( 6 | `https://hacker-news.firebaseio.com/v0/maxitem.json?print=pretty` 7 | ); 8 | const json = await res.json(); 9 | return json as number; 10 | } 11 | 12 | export async function getPost(id: number) { 13 | /* get post data using its id from hacker news */ 14 | const run = async () => { 15 | console.log("fetching post", id); 16 | const res = await fetch( 17 | `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty` 18 | ); 19 | const json = await res.json(); 20 | if (res.status === 404 || json === null) { 21 | throw new Error(res.statusText); 22 | } 23 | return json; 24 | }; 25 | try { 26 | return await pRetry(run, { 27 | retries: 5, 28 | minTimeout: 50, 29 | }); 30 | } catch (e) { 31 | return null; 32 | } 33 | } 34 | 35 | export async function getParent(post: any): Promise { 36 | /* recursively get parent of post */ 37 | if (!post.parent) { 38 | return post; 39 | } else { 40 | const parent = await getPost(post.parent); 41 | if (parent) { 42 | return getParent(parent); 43 | } 44 | console.log(`Hacker News post not found. Post number: ${post.id}`); // by the off chance that the post fails to fetch/doesn't exist, log it 45 | return post; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /components/layout/meta.tsx: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | 3 | const DOMAIN = "https://slacker.run"; 4 | 5 | export default function Meta({ 6 | title = "Slacker - Stay on top of your Hacker News mentions", 7 | description = "Slacer is a bot that notifies you on Slack whenever your company/product is mentioned on Hacker News.", 8 | image = `${DOMAIN}/api/og`, 9 | }: { 10 | title?: string; 11 | description?: string; 12 | image?: string; 13 | }) { 14 | return ( 15 | 16 | {title} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /pages/api/auth.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from "next"; 2 | import { setAccessToken } from "@/lib/upstash"; 3 | import { log } from "@/lib/slack"; 4 | 5 | export default async function handler( 6 | req: NextApiRequest, 7 | res: NextApiResponse 8 | ) { 9 | const { code } = req.query; // get code from request posted to redirect_uri from Slack 10 | try { 11 | const response = await fetch( 12 | `https://slack.com/api/oauth.v2.access?client_id=${process.env.NEXT_PUBLIC_SLACK_CLIENT_ID}&client_secret=${process.env.SLACK_CLIENT_SECRET}&code=${code}` 13 | ); 14 | const json = await response.json(); 15 | const { access_token, team } = json; 16 | if (access_token && team.id) { 17 | const upstashRepsonse = await setAccessToken(access_token, team.id); 18 | if (upstashRepsonse[0] === "OK") { 19 | await log( 20 | "Team *`" + 21 | team.name + 22 | "`* (*`" + 23 | team.id + 24 | "`*) just installed the bot :tada:" 25 | ); 26 | res.redirect(`/success/${team.id}`); 27 | } else { 28 | // failed to store access token in redis for some reason 29 | res.status(500).json(upstashRepsonse); 30 | } 31 | } else { 32 | // no access token or team id in json response from slack oauth API 33 | res.status(500).json({ 34 | message: 35 | "No access token or team id found in response from Slack's /oauth.v2.access API.", 36 | }); 37 | } 38 | } catch (err) { 39 | // failed to fetch from slack oauth API 40 | res 41 | .status(500) 42 | .json({ statusCode: 500, message: "An unknown error occured." }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /manifest.ts: -------------------------------------------------------------------------------- 1 | export const commonWords = [ 2 | "the", 3 | "be", 4 | "to", 5 | "of", 6 | "and", 7 | "a", 8 | "in", 9 | "that", 10 | "have", 11 | "I", 12 | "it", 13 | "for", 14 | "not", 15 | "on", 16 | "with", 17 | "he", 18 | "as", 19 | "you", 20 | "do", 21 | "at", 22 | "this", 23 | "but", 24 | "his", 25 | "by", 26 | "from", 27 | "they", 28 | "we", 29 | "say", 30 | "her", 31 | "she", 32 | "or", 33 | "an", 34 | "will", 35 | "my", 36 | "one", 37 | "all", 38 | "would", 39 | "there", 40 | "their", 41 | "what", 42 | "so", 43 | "up", 44 | "out", 45 | "if", 46 | "about", 47 | "who", 48 | "get", 49 | "which", 50 | "go", 51 | "me", 52 | "when", 53 | "make", 54 | "can", 55 | "like", 56 | "time", 57 | "no", 58 | "just", 59 | "him", 60 | "know", 61 | "take", 62 | "people", 63 | "into", 64 | "year", 65 | "your", 66 | "good", 67 | "some", 68 | "could", 69 | "them", 70 | "see", 71 | "other", 72 | "than", 73 | "then", 74 | "now", 75 | "look", 76 | "only", 77 | "come", 78 | "its", 79 | "over", 80 | "think", 81 | "also", 82 | "back", 83 | "after", 84 | "use", 85 | "two", 86 | "how", 87 | "our", 88 | "work", 89 | "first", 90 | "well", 91 | "way", 92 | "even", 93 | "new", 94 | "want", 95 | "because", 96 | "any", 97 | "these", 98 | "give", 99 | "day", 100 | "most", 101 | "us", 102 | "each", 103 | "water", 104 | "been", 105 | "call", 106 | "oil", 107 | "has", 108 | "word", 109 | "more", 110 | "long", 111 | "write", 112 | "down", 113 | "were", 114 | "did", 115 | "many", 116 | "number", 117 | "may", 118 | "i", 119 | "said", 120 | "part", 121 | "is", 122 | ]; 123 | -------------------------------------------------------------------------------- /components/modal.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Dispatch, 3 | SetStateAction, 4 | useCallback, 5 | useEffect, 6 | useRef, 7 | } from "react"; 8 | import { AnimatePresence, motion } from "framer-motion"; 9 | 10 | export default function Modal({ 11 | children, 12 | showModal, 13 | setShowModal, 14 | }: { 15 | children: React.ReactNode; 16 | showModal: boolean; 17 | setShowModal: Dispatch>; 18 | }) { 19 | const modalRef = useRef(null); 20 | 21 | const onKeyDown = useCallback( 22 | (e: KeyboardEvent) => { 23 | if (e.key === "Escape") { 24 | setShowModal(false); 25 | } 26 | }, 27 | [setShowModal] 28 | ); 29 | 30 | useEffect(() => { 31 | document.addEventListener("keydown", onKeyDown); 32 | return () => document.removeEventListener("keydown", onKeyDown); 33 | }, [onKeyDown]); 34 | 35 | return ( 36 | 37 | {showModal && ( 38 | <> 39 | { 47 | if (modalRef.current === e.target) { 48 | setShowModal(false); 49 | } 50 | }} 51 | > 52 | {children} 53 | 54 | setShowModal(false)} 61 | /> 62 | 63 | )} 64 | 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /components/slack-button.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | import slackGif from "../public/assets/slackanimation.gif"; 3 | 4 | export default function SlackButton({ 5 | text, 6 | url, 7 | onClick, 8 | }: { 9 | text: string; 10 | url: string; 11 | onClick?: () => void; 12 | }) { 13 | return ( 14 | 24 |
25 | Slack logo animated 31 |
32 | 60 | {text} 61 |
62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /components/layout/index.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | import Link from "next/link"; 3 | import { ReactNode } from "react"; 4 | import Meta from "./meta"; 5 | 6 | export default function Layout({ 7 | meta, 8 | children, 9 | }: { 10 | meta?: { 11 | title?: string; 12 | description?: string; 13 | image?: string; 14 | }; 15 | children: ReactNode; 16 | }) { 17 | return ( 18 | <> 19 | 20 |
21 |
22 | 23 | Precedent logo 29 |

30 | Slacker 31 |

32 | 33 | 40 | 41 | View the code 42 | 43 | 47 | 48 |
49 |
50 |
51 | {children} 52 |
53 |
54 | 58 | Support 59 | 60 | 66 | Privacy Policy 67 | 68 |
69 | 70 | ); 71 | } 72 | -------------------------------------------------------------------------------- /pages/api/og.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | import { ImageResponse } from "@vercel/og"; 3 | import { NextRequest } from "next/server"; 4 | 5 | export const config = { 6 | runtime: "experimental-edge", 7 | }; 8 | 9 | export const interBold = fetch( 10 | new URL("../../styles/Inter-SemiBold.ttf", import.meta.url) 11 | ).then((res) => res.arrayBuffer()); 12 | 13 | export const interRegular = fetch( 14 | new URL("../../styles/Inter-Regular.ttf", import.meta.url) 15 | ).then((res) => res.arrayBuffer()); 16 | 17 | export default async function handler(req: NextRequest) { 18 | const [interBoldData, interRegularData] = await Promise.all([ 19 | interBold, 20 | interRegular, 21 | ]); 22 | 23 | const { searchParams } = req.nextUrl; 24 | const title = searchParams.get("title") || "Slacker"; 25 | 26 | return new ImageResponse( 27 | ( 28 |
40 | 52 | 58 | 59 |

71 | {title} 72 |

73 |
74 | ), 75 | { 76 | width: 1200, 77 | height: 630, 78 | fonts: [ 79 | { 80 | name: "Inter Bold", 81 | data: interBoldData, 82 | }, 83 | { 84 | name: "Inter Regular", 85 | data: interRegularData, 86 | }, 87 | ], 88 | } 89 | ); 90 | } 91 | -------------------------------------------------------------------------------- /pages/success/[[...teamId]].tsx: -------------------------------------------------------------------------------- 1 | import { ParsedUrlQuery } from "querystring"; 2 | import { GetStaticProps } from "next"; 3 | import SlackButton from "@/components/slack-button"; 4 | import Layout from "@/components/layout"; 5 | import { Play } from "lucide-react"; 6 | import { useVideoModal } from "@/components/video-modal"; 7 | import va from "@vercel/analytics"; 8 | import { useEffect } from "react"; 9 | 10 | export default function SuccessTeam(props: { teamId: string }) { 11 | const { setShowVideoModal, VideoModal } = useVideoModal(); 12 | useEffect(() => { 13 | va.track("Install Success", { teamId: props.teamId }); 14 | // eslint-disable-next-line react-hooks/exhaustive-deps 15 | }, []); 16 | 17 | return ( 18 | 19 | 20 |
21 |

22 | Installation Successful 23 |

24 |

25 | You can now create a channel to receive notifications in and start 26 | configuring the bot with the{" "} 27 | /configure command. 28 |

29 |
30 | 31 |
32 | 43 |
51 |
52 | 60 |
61 |
62 | ); 63 | } 64 | 65 | export const getStaticPaths = async () => { 66 | return { 67 | paths: [], 68 | fallback: "blocking", 69 | }; 70 | }; 71 | 72 | interface Params extends ParsedUrlQuery { 73 | teamId: string; 74 | } 75 | 76 | export const getStaticProps: GetStaticProps = async (context) => { 77 | const { teamId } = context.params as Params; 78 | return { 79 | props: { teamId: teamId ? teamId[0] : null }, 80 | }; 81 | }; 82 | -------------------------------------------------------------------------------- /components/video-modal.tsx: -------------------------------------------------------------------------------- 1 | import Modal from "./modal"; 2 | import { 3 | useRef, 4 | useEffect, 5 | useState, 6 | Dispatch, 7 | SetStateAction, 8 | useCallback, 9 | useMemo, 10 | } from "react"; 11 | 12 | const VideoModal = ({ 13 | showVideoModal, 14 | setShowVideoModal, 15 | }: { 16 | showVideoModal: boolean; 17 | setShowVideoModal: Dispatch>; 18 | }) => { 19 | const videoRef = useRef(null); 20 | useEffect(() => { 21 | if (showVideoModal) videoRef.current?.focus(); 22 | }, [showVideoModal]); 23 | 24 | return ( 25 | 26 | 37 | ); 38 | }; 39 | 40 | export function useVideoModal() { 41 | const [showVideoModal, setShowVideoModal] = useState(false); 42 | 43 | const VideoModalCallback = useCallback(() => { 44 | return ( 45 | 49 | ); 50 | }, [showVideoModal, setShowVideoModal]); 51 | 52 | return useMemo( 53 | () => ({ setShowVideoModal, VideoModal: VideoModalCallback }), 54 | [setShowVideoModal, VideoModalCallback] 55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import SlackButton from "@/components/slack-button"; 2 | import Layout from "@/components/layout"; 3 | import { Play } from "lucide-react"; 4 | import { useVideoModal } from "@/components/video-modal"; 5 | import va from "@vercel/analytics"; 6 | import Balancer from "react-wrap-balancer"; 7 | 8 | export default function Home() { 9 | const { setShowVideoModal, VideoModal } = useVideoModal(); 10 | return ( 11 | 12 | 13 |
14 |

15 | Stay on top of your HN mentions 16 |

17 |

18 | Slacker notifies you on Slack whenever your company is mentioned on 19 | Hacker News. Built with{" "} 20 | 26 | Vercel Cron Jobs 27 | 28 | . 29 |

30 |
31 | 32 |
33 | 44 |
54 |
55 | va.track("Install Clicked")} 57 | text="Add to Slack" 58 | url={`https://slack.com/oauth/v2/authorize?scope=chat:write,chat:write.public,links:read,links:write,commands,team:read&client_id=${process.env.NEXT_PUBLIC_SLACK_CLIENT_ID}`} 59 | /> 60 | 66 | Looking to self-host instead? 67 | 68 |
69 |
70 | ); 71 | } 72 | -------------------------------------------------------------------------------- /lib/cron.ts: -------------------------------------------------------------------------------- 1 | import { getLatestPost, getPost } from "./hn"; 2 | import { 3 | getLastCheckedId, 4 | setLastCheckedId, 5 | checkIfPostWasChecked, 6 | getTeamsAndKeywords, 7 | } from "./upstash"; 8 | import { equalsIgnoreOrder, postScanner } from "./helpers"; 9 | import { sendSlackMessage } from "./slack"; 10 | 11 | export async function cron() { 12 | // last checked post id from redis, latest post id from hacker news 13 | const [lastCheckedId, latestPostId] = await Promise.all([ 14 | getLastCheckedId(), 15 | getLatestPost(), 16 | ]); 17 | 18 | if (latestPostId === lastCheckedId) { 19 | // if latest post id is the same as last checked id, do nothing 20 | return { results: "No new posts" }; 21 | } 22 | 23 | const teamsAndKeywords = await getTeamsAndKeywords(); // get all team keys from redis 24 | const scanner = postScanner(teamsAndKeywords); // create a post scanner that contains all teams and their keywords in a constructed regex 25 | 26 | let results: { 27 | [postId: string]: string[]; // for each post, store the teams that it was sent to 28 | } = {}; 29 | let errors: any[] = []; 30 | 31 | for (let i = lastCheckedId + 1; i <= latestPostId; i++) { 32 | if (await checkIfPostWasChecked(i)) continue; // avoid double checking posts 33 | 34 | const post = await getPost(i); // get post from hacker news 35 | if (!post) { 36 | console.log(`Hacker News post not found. Post number: ${i}`); // by the off chance that the post fails to fetch/doesn't exist, log it 37 | continue; 38 | } 39 | if (post.deleted) { 40 | continue; // if post is deleted, skip it 41 | } 42 | console.log("checking for keywords in post", i); 43 | const interestedTeams = Array.from(scanner(post)); // get teams that are interested in this post 44 | if (interestedTeams.length > 0) { 45 | results[i] = interestedTeams; // add post id and interested teams to results 46 | await Promise.all( 47 | interestedTeams.map(async (teamId) => { 48 | console.log("sending post to team", teamId); 49 | try { 50 | await sendSlackMessage(i, teamId); // send post to team 51 | } catch (e) { 52 | console.log( 53 | `Error sending post ${i} to team ${teamId}. Cause of error: ${e}` 54 | ); 55 | errors.push({ 56 | error: e, 57 | postId: i, 58 | teamId: teamId, 59 | }); // if there's an error, add it to errors 60 | } 61 | }) 62 | ); 63 | } 64 | } 65 | 66 | await setLastCheckedId(latestPostId); // set last checked post id in redis 67 | return { 68 | summary: `Processed post ${lastCheckedId} to post ${latestPostId} (${ 69 | latestPostId - lastCheckedId 70 | } posts)`, 71 | results, 72 | errors, 73 | }; 74 | } 75 | 76 | export async function testCron( 77 | postsToTest: number[], 78 | fakeTeamsAndKeywords: { [teamId: string]: string[] }, 79 | fakeInterestedTeams: { [postId: number]: string[] } 80 | ) { 81 | const scanner = postScanner(fakeTeamsAndKeywords); 82 | let results: { [postId: number]: string } = {}; 83 | for (const id of postsToTest) { 84 | console.log(`checking for post ${id}`); 85 | const post = await getPost(id); // get post from hacker news 86 | if (!post) { 87 | results[id] = `Hacker News post not found.`; 88 | continue; 89 | } 90 | if (post.deleted) { 91 | continue; // if post is deleted, skip it 92 | } 93 | const interestedTeams = Array.from(scanner(post)); // get teams that are interested in this post 94 | if (!equalsIgnoreOrder(fakeInterestedTeams[id], interestedTeams)) { 95 | results[ 96 | id 97 | ] = `Interested teams don't match. Expected: ${fakeInterestedTeams[id]}, Actual: ${interestedTeams}`; 98 | } 99 | } 100 | return { 101 | message: 102 | Object.keys(results).length > 0 103 | ? "Some tests failing" 104 | : "All tests passed", 105 | results, 106 | }; 107 | } 108 | -------------------------------------------------------------------------------- /pages/api/response.ts: -------------------------------------------------------------------------------- 1 | import { NextApiRequest, NextApiResponse } from "next"; 2 | import { 3 | addKeyword, 4 | removeKeyword, 5 | setChannel, 6 | countKeywords, 7 | } from "@/lib/upstash"; 8 | import { verifyRequest, log, respondToSlack } from "@/lib/slack"; 9 | import { commonWords } from "manifest"; 10 | 11 | export default async function handler( 12 | req: NextApiRequest, 13 | res: NextApiResponse 14 | ) { 15 | if (req.method !== "POST") { 16 | return res.status(405).json({ 17 | response_type: "ephemeral", 18 | text: "This endpoint only accepts POST requests", 19 | }); 20 | } 21 | 22 | const verification = verifyRequest(req); 23 | if (!verification.status) { 24 | // verify that the request is coming from the correct Slack team 25 | return res.status(403).json({ 26 | response_type: "ephemeral", 27 | text: "Nice try buddy. Slack signature mismatch.", 28 | }); 29 | } 30 | 31 | const payload = JSON.parse(req.body.payload); 32 | const { response_url, message, actions, team } = payload; 33 | 34 | // get the action type and the action value 35 | const { action_id, ...data } = actions[0]; 36 | 37 | /* ----------------- 38 | * ADDING A KEYWORD 39 | * ----------------- 40 | * Here, we're adding a keyword to the list of keywords that are 41 | * monitored by the team. 42 | * 43 | * We first process the keyword by converting it to lowercase and 44 | * removing any leading or trailing whitespace and quotes. 45 | * 46 | * For the hosted service (https://slacker.run), 47 | * we'll also define some abuse prevention measures for the added keyword. 48 | * 49 | * We also handle the case where Upstash fails to add the keyword. 50 | * 51 | * In all error cases, we respond to Slack with the same inputs as before 52 | * but with the addition of an error message. 53 | */ 54 | if (action_id === "add_keyword") { 55 | const rawKeyword = data.value; 56 | if (!rawKeyword) { 57 | return respondToSlack(res, response_url, team.id, { 58 | keyword: 59 | ":warning: Please enter a keyword that is at least 3 characters long.", 60 | }); 61 | } 62 | 63 | const keyword = rawKeyword 64 | .toLowerCase() 65 | .trim() 66 | .replace(/[‘’“”'"]+/g, ""); 67 | 68 | const hostedService = !process.env.SLACK_OAUTH_TOKEN; 69 | 70 | if (hostedService) { 71 | const keywordsCount = await countKeywords(team.id); 72 | 73 | // if the keyword too common, we'll reject it 74 | if (commonWords.includes(keyword)) { 75 | return respondToSlack(res, response_url, team.id, { 76 | keyword: 77 | ":warning: The keyword `" + 78 | keyword + 79 | "` is too common. Try a different one.", 80 | }); 81 | } else if (keywordsCount >= 15) { 82 | // if the team has too many keywords, we'll reject it 83 | return respondToSlack(res, response_url, team.id, { 84 | keyword: 85 | ":warning: You have too many keywords. Try removing some before adding more.", 86 | }); 87 | } 88 | } 89 | 90 | const response = await addKeyword(team.id, keyword); 91 | if (response === 1) { 92 | await log("Team *`" + team.id + "`* is now tracking *`" + keyword + "`*"); 93 | return respondToSlack(res, response_url, team.id); 94 | } else { 95 | return respondToSlack(res, response_url, team.id, { 96 | keyword: `:warning: Failed to add keyword. Cause: ${ 97 | response === 0 ? "Keyword already exists" : response 98 | }`, 99 | }); 100 | } 101 | 102 | /* ----------------- 103 | * REMOVING A KEYWORD 104 | * ----------------- 105 | * Here, we're remove a keyword to the list of keywords that are 106 | * monitored by the team. 107 | * This is rather straightforward, with the same error handling 108 | * measures as adding a keyword. 109 | */ 110 | } else if (action_id === "remove_keyword") { 111 | const wordToRemove = data.value; 112 | 113 | const response = await removeKeyword(team.id, wordToRemove); 114 | if (response === 1) { 115 | await log( 116 | "Team *`" + team.id + "`* stopped tracking *`" + wordToRemove + "`*" 117 | ); 118 | return respondToSlack(res, response_url, team.id); 119 | } else { 120 | return respondToSlack(res, response_url, team.id, { 121 | keyword: `:warning: Failed to remove keyword. Cause: ${ 122 | response === 0 ? "Keyword not found" : response 123 | }`, 124 | }); 125 | } 126 | 127 | /* ----------------- 128 | * SETTING A CHANNEL 129 | * ----------------- 130 | * Here, we're setting the channel that the bot will post notifications to. 131 | * This is rather straightforward, with the same error handling 132 | * measures as adding a keyword. 133 | */ 134 | } else if (action_id === "set_channel") { 135 | const channelId = data.selected_conversation; 136 | const response = await setChannel(team.id, channelId); 137 | if (response === "OK") { 138 | return respondToSlack(res, response_url, team.id, { 139 | channel: `:white_check_mark: Successfully set channel to <#${channelId}>`, 140 | }); 141 | } else { 142 | return respondToSlack(res, response_url, team.id, { 143 | channel: `:warning: Failed to set channel. Cause: ${response}`, 144 | }); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /lib/helpers.ts: -------------------------------------------------------------------------------- 1 | import { decode } from "html-entities"; 2 | // @ts-ignore - no type info for this module 3 | import mrkdwn from "html-to-mrkdwn"; 4 | import regexEscape from "escape-string-regexp"; 5 | import { TeamAndKeywords } from "@/lib/upstash"; 6 | 7 | export function combineText(post: any) { 8 | /* combine text from post's title, text, and url */ 9 | let text = ""; 10 | if (post.url) { 11 | text += `${post.url}\n`; 12 | } 13 | if (post.title) { 14 | text += `${post.title}\n`; 15 | } 16 | if (post.text) { 17 | text += `${post.text}\n`; 18 | } 19 | return text; 20 | } 21 | 22 | export function postScanner(teamsAndKeywords: TeamAndKeywords) { 23 | const keywordMapping = new Map() as Map; 24 | const keywords = new Set(); 25 | 26 | for (const teamId of Object.keys(teamsAndKeywords)) { 27 | for (const keyword of teamsAndKeywords[teamId]) { 28 | keywords.add(keyword); 29 | 30 | let teams = keywordMapping.get(keyword); 31 | if (teams === undefined) { 32 | teams = []; 33 | keywordMapping.set(keyword, teams); 34 | } 35 | teams.push(teamId); 36 | } 37 | } 38 | 39 | const keywordArray = Array.from(keywords) as string[]; 40 | const boundaries = keywordArray.map( 41 | (keyword) => `\\b${regexEscape(keyword)}\\b` 42 | ); 43 | 44 | const scanner = new RegExp(`(${boundaries.join(")|(")})`, "gi"); // create a regex that matches all keywords 45 | 46 | return (post: any): Set => { 47 | const text = combineText(post); // combine text from post's title, text, and url 48 | const teamsInterestedInThisPost = new Set() as Set; // set of team IDs that are interested in this post 49 | 50 | text.replace(scanner, (_, ...terms) => { 51 | for (let i = 0; i < keywordArray.length; i++) { 52 | if (terms[i] !== undefined) { 53 | // if the keyword is found in the text 54 | const teamsSubscribedToThisKeyword = keywordMapping.get( 55 | keywordArray[i] 56 | ); 57 | teamsSubscribedToThisKeyword!.forEach((teamId) => { 58 | // using ! here because we know teamsSubscribedToThisKeyword is always defined 59 | teamsInterestedInThisPost.add(teamId); // add team ID to set of teams that are interested in this post (if not already in set) 60 | }); 61 | break; 62 | } 63 | } 64 | return ""; // replace all instances of keywords with empty string (just for the replace function, we're not actually interested in the text here) 65 | }); 66 | 67 | return teamsInterestedInThisPost; // return set of team IDs that are interested in this post 68 | }; 69 | } 70 | 71 | export function truncateString(str: string, num: number) { 72 | if (!str) return ""; 73 | if (str.length > num) { 74 | return str.slice(0, num) + "..."; 75 | } else { 76 | return str; 77 | } 78 | } 79 | 80 | export function regexOperations(post: any, keywords: string[]) { 81 | const mentionedTerms = new Set(); 82 | 83 | // This transforms each keyword into the string to explicitly match the 84 | // keyword in a dynamically constructed regex. Eg, 85 | // ["Vercel", "NextJS"] -> ["\bVercel\b", "\bNextJS"\b"] 86 | const keywordWordBoundary = keywords.map( 87 | (keyword) => `\\b${regexEscape(keyword)}\\b` 88 | ); 89 | 90 | // This regex will be of the form: 91 | // const termsRegex = /(\bVercel\b)|(\bNextJS\b))\b/gi 92 | const termsRegex = new RegExp(`(${keywordWordBoundary.join(")|(")})`, "gi"); 93 | 94 | const marked: string = mrkdwn(decode(post?.text || "")) 95 | ? mrkdwn(decode(post?.text || "")).text 96 | : ""; 97 | 98 | // We use String.replace here so that we can know which capture group is 99 | // actually matched, so that we can extract the appropriate keyword. 100 | combineText(post).replace(termsRegex, (_, ...terms: string[]) => { 101 | // In order to preserve the case-sensitivity of the keywords, we do a bit of meta-programming. 102 | // We generated N regex capture groups, and we want to see if any of them matched. The index 103 | // of the capture group matches the index of the keyword, so we can then decorate the actual 104 | // text in the post, and know which keyword matched. 105 | for (let i = 0; i < keywords.length; i++) { 106 | if (terms[i] !== undefined) { 107 | mentionedTerms.add(keywords[i]); 108 | } 109 | } 110 | 111 | // We don't actually care about the replaced text, we're just using this 112 | // for the side-effects. 113 | return ""; 114 | }); 115 | 116 | // This regex searches for our keywords, while also matching a few extra 117 | // patterns that we want to prevent a keyword match during. Eg, "Vercel" may 118 | // appear in the link href (eg, " is awesome!"), 119 | // and we only want to decorate the link's text. We match: 120 | // - the ````` ```text``` ````` code blocks, so that we may ignore it when decorating. 121 | // - the `]*|(\bVercel\b|\bNextJS\b)/gi 127 | const decorateRegex = new RegExp( 128 | [ 129 | "```(?:(?!```)[^])*", // code blocks, using a negative lookahead and an an "anything" `[^]` negative char class. 130 | `]*`, // An auto-generated link without explicit text 132 | `(${keywordWordBoundary.join("|")})`, // Our keywords to decorate 133 | ].join("|"), 134 | "gi" 135 | ); 136 | 137 | const processedPost = marked.replace(decorateRegex, (match, term) => { 138 | // If we have a term, then it's something like "Vercel" and we can decorate it. 139 | if (term) { 140 | return "*`" + term + "`*"; 141 | } 142 | 143 | // Else, we matched a link's href and we do not want to decorate. 144 | return match; 145 | }); 146 | 147 | return { 148 | processedPost, 149 | mentionedTerms, 150 | }; 151 | } 152 | 153 | export const equalsIgnoreOrder = (a: string[], b: string[]) => { 154 | if (a.length !== b.length) return false; 155 | return a.sort().join(",") === b.sort().join(","); 156 | }; 157 | -------------------------------------------------------------------------------- /lib/upstash.ts: -------------------------------------------------------------------------------- 1 | import { Redis } from "@upstash/redis"; 2 | import { getLatestPost } from "./hn"; 3 | 4 | export const redis = new Redis({ 5 | url: process.env.UPSTASH_REDIS_REST_URL || "", 6 | token: process.env.UPSTASH_REDIS_REST_TOKEN || "", 7 | }); 8 | 9 | export async function isDuplicateCron() { 10 | /* Function to check for duplicate cron jobs: 11 | * nx tells it to only set the key if it does not exist yet, otherwise an error is returned 12 | * ex sets the TTL on the key to 55 seconds 13 | * This function should return string OK if the key did not exists and was set correctly 14 | * or null if the key already existed 15 | */ 16 | const response = await redis.set("dedupIndex", "set", { nx: true, ex: 55 }); 17 | return response === null; 18 | } 19 | 20 | export async function getAccessToken(teamId: string) { 21 | // If you are self hosting this app & have set a SLACK_OAUTH_TOKEN env var, you can just return it here. 22 | if (process.env.SLACK_OAUTH_TOKEN) return process.env.SLACK_OAUTH_TOKEN; 23 | 24 | /* Get the access token for a Slack team in redis */ 25 | return await redis.get(`${teamId}_token`); 26 | } 27 | 28 | export async function setAccessToken(accessToken: string, teamId: string) { 29 | /* Set the access token for a Slack team in redis */ 30 | const slack = await fetch("https://slack.com/api/team.info", { 31 | headers: { 32 | Authorization: `Bearer ${accessToken}`, 33 | }, 34 | }) 35 | .then((res) => res.json()) 36 | .catch((err) => { 37 | console.log(err); 38 | return { ok: false, message: "Failed to fetch team info" }; 39 | }); 40 | 41 | const pipeline = redis.pipeline(); 42 | pipeline.set(`${teamId}_token`, accessToken); 43 | pipeline.hset("metadata", { 44 | [teamId]: { joined: Date.now(), slack: slack.ok ? slack.team : null }, 45 | }); 46 | return await pipeline.exec(); 47 | } 48 | 49 | export async function getKeywords(teamId: string): Promise { 50 | /* Get list of keywords for a given team from redis */ 51 | return (await redis.hget("keywords", teamId)) || []; 52 | } 53 | 54 | export async function addKeyword(teamId: string, keyword: string) { 55 | /* Add a keyword for a team in redis */ 56 | const keywords = await getKeywords(teamId); // get list of keywords for team 57 | 58 | if (!keywords.includes(keyword)) { 59 | // if keyword is not already in list, add it 60 | keywords.push(keyword); 61 | await redis.hset("keywords", { [teamId]: keywords }); 62 | return 1; // return 1 to indicate keyword was added (hset returns 0 if key already exists) 63 | } else { 64 | // if keyword is already in list 65 | return 0; // return 0 to indicate keyword already exists and was not added 66 | } 67 | } 68 | 69 | export async function removeKeyword(teamId: string, keyword: string) { 70 | /* Remove a keyword for a team in redis */ 71 | const keywords = await getKeywords(teamId); // get list of keywords for team 72 | 73 | if (keywords.includes(keyword)) { 74 | // if keyword is in list, remove it 75 | keywords.splice(keywords.indexOf(keyword), 1); 76 | await redis.hset("keywords", { [teamId]: keywords }); 77 | return 1; // return 1 to indicate keyword was removed (hset returns 0 if key already exists) 78 | } else { 79 | // if keyword is not in list 80 | return 0; // return 0 to indicate keyword was not in the list and was not removed 81 | } 82 | } 83 | 84 | export async function countKeywords(teamId: string) { 85 | /* Count the list of keywords from redis */ 86 | return (await getKeywords(teamId)).length; 87 | } 88 | 89 | export async function getChannel(teamId: string) { 90 | /* Get the channel ID to send notifications in for a Slack team in redis */ 91 | return await redis.get(`${teamId}_channel`); 92 | } 93 | 94 | export async function setChannel(teamId: string, channel: string) { 95 | /* Set the channel ID to send notifications in for a Slack team in redis */ 96 | return await redis.set(`${teamId}_channel`, channel); 97 | } 98 | 99 | export async function getLastCheckedId(): Promise { 100 | /* Get the last checked post ID from redis */ 101 | const lastCheckedId = (await redis.get("lastCheckedId")) as number; 102 | if (!lastCheckedId) { 103 | // if lastCheckedId is not set (first time running), return the latest post ID on HN instead 104 | const latestPostId = await getLatestPost(); 105 | return latestPostId; 106 | } 107 | return lastCheckedId; 108 | } 109 | 110 | export async function setLastCheckedId(id: number) { 111 | /* Set the last checked post ID in redis */ 112 | return await redis.set("lastCheckedId", id); 113 | } 114 | 115 | export async function checkIfPostWasChecked(id: number) { 116 | /* Check if a post has been checked in redis –  117 | if setting the key for the post returns null, it means it's already been set 118 | Here, we're setting the keys to expire in 24 hours 119 | */ 120 | return ( 121 | (await redis.set(`post_${id}`, true, { nx: true, ex: 24 * 60 * 60 })) === 122 | null 123 | ); 124 | } 125 | 126 | export interface TeamAndKeywords { 127 | [teamId: string]: string[]; 128 | } 129 | 130 | export async function getTeamsAndKeywords(): Promise { 131 | /* Get all teams and their respective keywords */ 132 | return (await redis.hgetall("keywords")) || {}; 133 | } 134 | 135 | export async function clearDataForTeam(teamId: string) { 136 | /* Clear all data for a team */ 137 | const metadata = (await redis.hget("metadata", teamId)) as { 138 | joined: string; 139 | slack: any; 140 | }; 141 | const keywords = await redis.hget("keywords", teamId); 142 | const pipeline = redis.pipeline(); 143 | pipeline.del(`${teamId}_token`); 144 | pipeline.del(`${teamId}_channel`); 145 | pipeline.hdel("keywords", teamId); 146 | pipeline.hset("metadata", { [teamId]: { ...metadata, keywords } }); 147 | return await pipeline.exec(); 148 | } 149 | 150 | export async function trackUnfurls(teamId: string) { 151 | /* Track unfurls for a team */ 152 | return await redis.incr(`${teamId}_unfurls`); 153 | } 154 | 155 | export async function trackBotUsage(teamId: string) { 156 | /* Track unfurls for a team */ 157 | return await redis.incr(`${teamId}_notifications`); 158 | } 159 | 160 | export interface TeamConfigAndStats { 161 | teamId: string; 162 | keywords: string[]; 163 | channel: string; 164 | unfurls: number; 165 | notifications: number; 166 | } 167 | 168 | export async function getTeamConfigAndStats( 169 | teamId: string 170 | ): Promise { 171 | /* Pipeline function to retrieve the team's keywords, channel and usage stats (unfurls, notifications) */ 172 | const pipeline = redis.pipeline(); 173 | pipeline.hget("keywords", teamId); 174 | pipeline.mget( 175 | `${teamId}_channel`, 176 | `${teamId}_unfurls`, 177 | `${teamId}_notifications` 178 | ); 179 | const json = await pipeline.exec<[string[], [string, number, number]]>(); 180 | return { 181 | teamId, 182 | keywords: json[0] || [], 183 | channel: json[1][0], 184 | unfurls: json[1][1] || 0, 185 | notifications: json[1][2] || 0, 186 | }; 187 | } 188 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | Slacker OG Image 3 |

Slacker

4 |

A bot that notifies you on Slack whenever your company/product is mentioned on Hacker News.

5 | 6 | 7 | 8 | Demo 9 | 10 |
11 | 12 |
13 | Add to Slack 14 |
15 | 16 |

17 | or deploy your own 18 |

19 |
20 | 21 | ## Built With 22 | 23 | 1. [Vercel Functions](https://vercel.com/docs/concepts/functions) for [cron processes](https://github.com/vercel-labs/slacker/blob/main/pages/api/cron/index.ts) & [event subscriptions via webhooks](https://github.com/vercel-labs/slacker/blob/main/pages/api/event.ts) 24 | 2. [Vercel Cron Jobs](https://vercel.com/docs/cron-jobs) for triggering cron processes. 25 | 3. [Hacker News API](https://github.com/HackerNews/API) for [pulling data](https://github.com/vercel-labs/slacker/blob/main/lib/hn.ts) 26 | 4. [Slack API](https://api.slack.com/docs) for [sending](https://github.com/vercel-labs/slacker/blob/main/lib/slack.ts#L47) and [unfurling](https://github.com/vercel-labs/slacker/blob/main/lib/slack.ts#L73) messages 27 | 5. [Upstash](https://upstash.com) for key-value storage ([Redis](https://upstash.com/redis)). 28 | 29 |
30 | 31 | ## How It Works 32 | 33 | 1. Set up a [Vercel cron job](https://vercel.com/docs/cron-jobs) that pings our [`/api/cron` endpoint](https://github.com/vercel-labs/slacker/blob/main/pages/api/cron/index.ts) once every 60 seconds. 34 | 2. Get the last checked HN post ID ([`lastCheckedId`](https://github.com/vercel-labs/slacker/blob/main/lib/cron.ts#L11)) and the list of `keywords` to check against from Upstash. 35 | 3. Get the `latestPostId` using HN API's [`maxitem`](https://github.com/HackerNews/API#max-item-id) endpoint. Then, perform checks against each post between `lastCheckedId` and `latestPostId` to see if they contain any of the delineated `keywords`. 36 | 4. For each positive post, send its link to Slack using the [`chat.postMessage` method](https://api.slack.com/methods/chat.postMessage). 37 | 5. Listen to the [`link_shared` event](https://api.slack.com/events/link_shared) at our `/api/event` endpoint. Once an event occurs, send a POST request to Slack to unfurl the link using the [chat.unfurl method](https://api.slack.com/methods/chat.unfurl). 38 | 39 | 40 | 41 | 42 | Slacker Overview 43 | 44 | 45 | ## One-Click Install 46 | 47 | > Here's a [60s video](https://user-images.githubusercontent.com/28986134/221060512-df024fa3-594e-4e09-9d1e-656fae85f5c3.mp4) that walks you through the installation process, step-by-step. 48 | 49 | You can click the button below to install the bot directly into your desired Slack workspace: 50 | 51 | Add to Slack 52 | 53 | Once it's installed, create a channel to receive notifications in and start configuring the bot with the `/configure` command. 54 | 55 |
56 | 57 | ## Deploy Your Own 58 | 59 | You can also deploy your own version of this bot using Vercel and Upstash. Note that while this is in early-access, some of these processes might change. 60 | 61 | > Prefer a video tutorial instead? Watch this [video](https://youtu.be/_F4VuVKJn0Q). 62 | 63 | ### Step 1: Create Slack App + Secure Env Vars 64 | 65 | 1. Navigate to [api.slack.com/apps](https://api.slack.com/apps) and click on "Create New App". 66 | 2. Select "From scratch" and input `Hacker News Bot` as the name of your app. 67 | 3. Voilà! You've just created your Slack app. Here, you'll receive 3 values that will be used for your Vercel deployment in the next step: 68 | - **Client ID**: This is your App's unique public-facing ID that will be the value for the `NEXT_PUBLIC_SLACK_CLIENT_ID` env var. 69 | - **Signing Secret**: This is the signing secret used to validate that requests are genuinely coming from Slack. It will be the value for the `SLACK_SIGNING_SECRET` env var. 70 | - **Verification Token**: This is the verification token used to validate that requests are genuinely coming from Slack. It will be the value for the `SLACK_VERIFICATION_TOKEN` env var. 71 | 72 | ![CleanShot 2022-07-25 at 02 16 31](https://user-images.githubusercontent.com/28986134/180720201-816f985d-774b-41fe-8cf5-b87f730d77d2.png) 73 | 74 | ### Step 2: Create Upstash Account 75 | 76 | Go to [console.upstash.com](https://console.upstash.com/login) and create an account. You'll need it for the next step. 77 | 78 | ### Step 3: Deploy to Vercel 79 | 80 | You can deploy your bot to Vercel with one-click: 81 | 82 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel-labs%2Fslacker&project-name=slacker&repository-name=slacker&env=NEXT_PUBLIC_SLACK_CLIENT_ID,SLACK_SIGNING_SECRET,SLACK_VERIFICATION_TOKEN&envDescription=Read%20more%20about%20the%20required%20env%20vars%20here%3A&envLink=https%3A%2F%2Fgithub.com%2F%2Fslacker%23deploy-your-own&demo-title=Hacker%20News%20Slack%20Bot&demo-description=A%20bot%20that%20monitors%20Hacker%20News%20for%20mentions%20of%20certain%20keywords%20and%20sends%20it%20to%20a%20Slack%20channel.&demo-url=https%3A%2F%2Fhn-slack-bot.vercel.app%2F&demo-image=https%3A%2F%2Fhn-slack-bot.vercel.app%2Fthumbnail.png&integration-ids=oac_V3R1GIpkoJorr6fqyiwdhl17) 83 | 84 | Be sure to include all 5 of the env vars above in your deployment. 85 | 86 | When the project finishes deploying, get your project's domain (e.g. `https://slacker-eight.vercel.app/`). You'll need it for the next step. 87 | 88 | ### Step 4: Configuring Slack app 89 | 90 | For your Slack app to be able to send/unfurl messages in your Slack workspace, we will need to configure a few things: 91 | 92 | #### Step 4A: Configuring OAuth Scopes 93 | 94 | 1. From your Slack app home screen, select "OAuth & Permissions" from the sidebar (under "Features"). 95 | 2. Scroll down to "Scopes", and add the following scopes under "Bot Token Scopes": 96 | 97 | - `chat:write` 98 | - `chat:write.public` 99 | - `links:read` 100 | - `links:write` 101 | 102 | ![CleanShot 2022-07-25 at 13 49 18](https://user-images.githubusercontent.com/28986134/180852042-653ed883-1cb6-45fd-bb6b-1969fb3ea705.png) 103 | 104 | #### Step 4B: Configuring Event Subscriptions 105 | 106 | 1. Now, select "Event Subscriptions" from the sidebar (under "Features"). 107 | 2. Toggle "Enable Events" to "ON". 108 | 3. For the "Request URL" field, input your Vercel project's domain and append `/api/event` to it. The final URL should look something like `https://slacker-eight.vercel.app/api/event`. 109 | 4. Scroll down to "Subscribe to bot events". Add the `link_shared` bot user event. 110 | 5. Do the same for `Subscribe to events on behalf of users". 111 | ![Slack app configurations (1)](https://user-images.githubusercontent.com/28986134/180888217-911be4f9-be58-4f1c-a0bf-db915bbcb006.png) 112 | 6. Under "App unfurl domains", add `news.ycombinator.com`. 113 | ![Slack app configurations](https://user-images.githubusercontent.com/28986134/180942661-8c3821c5-d841-4d0c-b6a9-3e88e11baed7.png) 114 | 7. Click on "Save Changes". 115 | 116 | #### Step 4C: Configure Slash Commands 117 | 118 | Select "Slash Commands" from the sidebar (under "Features"). Create the following commmand with its respective Request URLs (based on your Vercel project's domain): 119 | 120 | - Command: `/configure` 121 | - Request URL: `https://[YOUR_VERCEL_PROJECT_DOMAIN]/api/cmd/configure` 122 | - Short Description: Configure your HN Slack Bot 123 | 124 | #### Step 4D: Enable Interactivity 125 | 126 | 1. Now, select "Interactivity & Shortcuts" from the sidebar (under "Features"). 127 | 2. Toggle "Interactivity" to "ON". 128 | 3. For the "Request URL" field, input your Vercel project's domain and append `/api/response` to it. The final URL should look something like `https://slacker-eight.vercel.app/api/response`. 129 | 4. Click on "Save Changes". 130 | 131 | #### Step 4E: Install App to Slack Workspace + Get OAuth token 132 | 133 | 1. Go to "Basic Information" (under "Settings"). 134 | 2. Under "Install your app", click on "Install to Workspace". 135 | 3. You should receive a notification that your app has been installed in your Slack workspace. 136 | 4. Go back to "OAuth & Permissions". Copy the value of "Bot User OAuth Token". 137 | ![CleanShot 2022-07-25 at 18 28 46](https://user-images.githubusercontent.com/28986134/180891662-32c45dd7-18a1-4dd1-a729-e652bbdd42d6.png) 138 | 5. Set it as the `SLACK_OAUTH_TOKEN` env var in your Vercel project. Here's a [guide](https://vercel.com/docs/concepts/projects/environment-variables) on how to do that. 139 | 140 | 141 | 142 | Add env var 143 | 144 | 6. Redeploy your Vercel project for the changes to take effect. 145 | 7. To verify that this worked, go to any channel on your Slack workspace and send a Hacker News link. The link should now unfurl and show a nice preview (like the one above). 146 | 147 |
148 | 149 | ## Authors 150 | 151 | This project was originally created by [Steven Tey](https://twitter.com/steventey) at [Vercel](https://vercel.com/), with contributions/feedback from: 152 | 153 | - Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) – [Vercel](https://vercel.com) 154 | - Justin Ridgewell ([@jridgewell](https://github.com/jridgewell)) – [Vercel](https://vercel.com) 155 | - Andrew Healey ([@healeycodes](https://github.com/healeycodes)) – [Vercel](https://vercel.com) 156 | - Drew Bredvick ([@dbredvick](https://twitter.com/dbredvick)) – [Vercel](https://vercel.com) 157 | - Lee Robinson ([@leeerob](https://twitter.com/leeerob)) – [Vercel](https://vercel.com) 158 | - Andreas Thomas ([@chronarkdotdev](https://twitter.com/chronarkdotdev)) – [Upstash](https://upstash.com) 159 | 160 |
161 | 162 | ## License 163 | 164 | The MIT License. 165 | 166 |
167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /lib/slack.ts: -------------------------------------------------------------------------------- 1 | import { NextApiRequest, NextApiResponse } from "next"; 2 | import crypto from "crypto"; 3 | import { truncateString, regexOperations } from "./helpers"; 4 | import { 5 | clearDataForTeam, 6 | getAccessToken, 7 | getChannel, 8 | getKeywords, 9 | trackBotUsage, 10 | trackUnfurls, 11 | getTeamConfigAndStats, 12 | } from "./upstash"; 13 | import { getPost, getParent } from "@/lib/hn"; 14 | 15 | export function verifyRequest(req: NextApiRequest) { 16 | /* Verify that requests are genuinely coming from Slack and not a forgery */ 17 | const { 18 | "x-slack-signature": slack_signature, 19 | "x-slack-request-timestamp": timestamp, 20 | } = req.headers as { [key: string]: string }; 21 | 22 | if (!slack_signature || !timestamp) { 23 | return { 24 | status: false, 25 | message: "No slack signature or timestamp found in request headers.", 26 | }; 27 | } 28 | if (process.env.SLACK_SIGNING_SECRET === undefined) { 29 | return { 30 | status: false, 31 | message: "`SLACK_SIGNING_SECRET` env var is not defined.", 32 | }; 33 | } 34 | if ( 35 | Math.abs(Math.floor(new Date().getTime() / 1000) - parseInt(timestamp)) > 36 | 60 * 5 37 | ) { 38 | return { 39 | status: false, 40 | message: "Nice try buddy. Slack signature mismatch.", 41 | }; 42 | } 43 | const req_body = new URLSearchParams(req.body).toString(); // convert body to URL search params 44 | const sig_basestring = "v0:" + timestamp + ":" + req_body; // create base string 45 | const my_signature = // create signature 46 | "v0=" + 47 | crypto 48 | .createHmac("sha256", process.env.SLACK_SIGNING_SECRET as string) 49 | .update(sig_basestring) 50 | .digest("hex"); 51 | 52 | if ( 53 | crypto.timingSafeEqual( 54 | Buffer.from(slack_signature), 55 | Buffer.from(my_signature) 56 | ) 57 | ) { 58 | return { 59 | status: true, 60 | message: "Verified Request.", 61 | }; 62 | } else { 63 | return { 64 | status: false, 65 | message: "Nice try buddy. Slack signature mismatch.", 66 | }; 67 | } 68 | } 69 | 70 | export async function sendSlackMessage(postId: number, teamId: string) { 71 | /* Send a message containing the link to the hacker news post to Slack */ 72 | const [accessToken, channelId] = await Promise.all([ 73 | getAccessToken(teamId), 74 | getChannel(teamId), 75 | ]); 76 | console.log( 77 | `Sending message to team ${teamId} in channel ${channelId} for post ${postId}` 78 | ); 79 | const response = await fetch("https://slack.com/api/chat.postMessage", { 80 | method: "POST", 81 | headers: { 82 | "Content-Type": "application/json", 83 | Authorization: `Bearer ${accessToken}`, 84 | }, 85 | body: JSON.stringify({ 86 | text: `https://news.ycombinator.com/item?id=${postId}`, 87 | channel: channelId, 88 | unfurl_links: true, 89 | }), 90 | }); 91 | const trackResponse = await trackBotUsage(teamId); // track bot usage for a team 92 | return { 93 | response, 94 | trackResponse, 95 | }; 96 | } 97 | 98 | export async function handleUnfurl(req: NextApiRequest, res: NextApiResponse) { 99 | /* Unfurl a hacker news post to Slack using Slack's Attachments API: https://api.slack.com/messaging/composing/layouts#attachments */ 100 | 101 | const { team_id } = req.body; 102 | if (!team_id) { 103 | return res.status(400).json({ message: "No team_id found" }); 104 | } 105 | const channel = req.body.event.channel; // channel the message was sent in 106 | const ts = req.body.event.message_ts; // message timestamp 107 | const url = req.body.event.links[0].url; // url that was shared 108 | const newUrl = new URL(url); 109 | const id = newUrl.searchParams.get("id"); // get hacker news post id 110 | if (!id) { 111 | return res.status(400).json({ message: "No id found" }); 112 | } 113 | 114 | const [post, accessToken, keywords] = await Promise.all([ 115 | getPost(parseInt(id)), // get post data from hacker news API 116 | getAccessToken(team_id), // get access token from upstash 117 | getKeywords(team_id), // get keywords from upstash 118 | ]); 119 | 120 | const { processedPost, mentionedTerms } = regexOperations(post, keywords); // get post data with keywords highlighted 121 | 122 | const originalPost = post.parent ? await getParent(post) : null; // if post is a comment, get title of original post 123 | 124 | const response = await fetch("https://slack.com/api/chat.unfurl", { 125 | // unfurl the hacker news post using the Slack API 126 | method: "POST", 127 | headers: { 128 | "Content-Type": "application/json", 129 | Authorization: `Bearer ${accessToken}`, 130 | }, 131 | body: JSON.stringify({ 132 | channel, 133 | ts, 134 | unfurls: { 135 | [url]: { 136 | mrkdwn_in: ["author_name", "text", "footer"], 137 | fallback: `https://news.ycombinator.com/item?id=${post.id}`, 138 | author_name: `New ${post.type} from ${post.by}`, 139 | author_link: `https://news.ycombinator.com/item?id=${post.id}`, 140 | author_icon: `https://ui-avatars.com/api/?name=${post.by}&background=random`, 141 | ...(post.title && { 142 | title: post.title, 143 | title_link: `https://news.ycombinator.com/item?id=${post.id}`, 144 | }), 145 | text: processedPost, 146 | ...(mentionedTerms.size > 0 && { 147 | fields: [ 148 | { 149 | title: "Mentioned Terms", 150 | value: Array.from(mentionedTerms).join(", "), 151 | short: false, 152 | }, 153 | ], 154 | }), 155 | footer: ` | `, 164 | footer_icon: 165 | "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Y_Combinator_logo.svg/1024px-Y_Combinator_logo.svg.png", 166 | }, 167 | }, 168 | }), 169 | }); 170 | const trackResponse = await trackUnfurls(team_id); // track unfurl usage for a team 171 | 172 | return res.status(200).json({ 173 | response, 174 | trackResponse, 175 | }); 176 | } 177 | 178 | export function verifyRequestWithToken(req: NextApiRequest) { 179 | const { token } = req.body; 180 | return token === process.env.SLACK_VERIFICATION_TOKEN; 181 | } 182 | 183 | export async function handleUninstall( 184 | req: NextApiRequest, 185 | res: NextApiResponse 186 | ) { 187 | if (!verifyRequestWithToken(req)) 188 | // verify that the request is coming from the correct Slack team 189 | // here we use the verification token because for some reason signing secret doesn't work 190 | return res.status(403).json({ 191 | message: "Nice try buddy. Slack signature mismatch.", 192 | }); 193 | const { team_id } = req.body; 194 | const response = await clearDataForTeam(team_id); 195 | const logResponse = await log( 196 | "Team *`" + team_id + "`* just uninstalled the bot :cry:" 197 | ); 198 | return res.status(200).json({ 199 | response, 200 | logResponse, 201 | }); 202 | } 203 | 204 | export async function log(message: string) { 205 | /* Log a message to the console */ 206 | console.log(message); 207 | if (!process.env.VERCEL_SLACK_HOOK) return; 208 | try { 209 | return await fetch(process.env.VERCEL_SLACK_HOOK, { 210 | method: "POST", 211 | headers: { 212 | "Content-Type": "application/json", 213 | }, 214 | body: JSON.stringify({ 215 | blocks: [ 216 | { 217 | type: "section", 218 | text: { 219 | type: "mrkdwn", 220 | text: message, 221 | }, 222 | }, 223 | ], 224 | }), 225 | }); 226 | } catch (e) { 227 | console.log(`Failed to log to Vercel Slack. Error: ${e}`); 228 | } 229 | } 230 | 231 | export const configureBlocks = ( 232 | keywords: string[], 233 | channel: string, 234 | unfurls: number, 235 | notifications: number, 236 | feedback?: { 237 | keyword?: string; 238 | channel?: string; 239 | } 240 | ) => [ 241 | { 242 | type: "header", 243 | text: { 244 | type: "plain_text", 245 | text: ":hammer_and_wrench: Bot Configuration :hammer_and_wrench:", 246 | }, 247 | }, 248 | { 249 | type: "context", 250 | block_id: "stats", 251 | elements: [ 252 | { 253 | type: "mrkdwn", 254 | text: `Current Usage: ${unfurls} link previews shown, ${notifications} notifications sent | `, 255 | }, 256 | ], 257 | }, 258 | { 259 | type: "divider", 260 | }, 261 | { 262 | type: "section", 263 | text: { 264 | type: "mrkdwn", 265 | text: ":bulb: KEYWORDS :bulb:", 266 | }, 267 | }, 268 | { 269 | type: "section", 270 | text: { 271 | type: "mrkdwn", 272 | text: 273 | keywords.length > 0 274 | ? "Here's the list of keywords that you're currently tracking:" 275 | : "_No keywords configured yet._", 276 | }, 277 | }, 278 | ...(keywords.length > 0 279 | ? keywords.map((keyword: any) => ({ 280 | type: "section", 281 | block_id: `keyword_${keyword}`, 282 | text: { 283 | type: "mrkdwn", 284 | text: "`" + keyword + "`", 285 | }, 286 | accessory: { 287 | action_id: "remove_keyword", 288 | type: "button", 289 | text: { 290 | type: "plain_text", 291 | text: "Remove", 292 | }, 293 | value: keyword, 294 | }, 295 | })) 296 | : []), 297 | { 298 | type: "input", 299 | dispatch_action: true, 300 | element: { 301 | type: "plain_text_input", 302 | action_id: "add_keyword", 303 | placeholder: { 304 | type: "plain_text", 305 | text: "Add a keyword (must be between 3 and 30 characters)", 306 | }, 307 | dispatch_action_config: { 308 | trigger_actions_on: ["on_enter_pressed"], 309 | }, 310 | min_length: 3, 311 | max_length: 30, 312 | focus_on_load: true, 313 | }, 314 | label: { 315 | type: "plain_text", 316 | text: " ", 317 | }, 318 | }, 319 | ...(feedback?.keyword 320 | ? [ 321 | { 322 | type: "context", 323 | elements: [ 324 | { 325 | type: "mrkdwn", 326 | text: feedback.keyword, 327 | }, 328 | ], 329 | }, 330 | ] 331 | : []), 332 | { 333 | type: "divider", 334 | }, 335 | { 336 | type: "section", 337 | text: { 338 | type: "mrkdwn", 339 | text: ":hash: CHANNEL :hash:", 340 | }, 341 | }, 342 | { 343 | type: "section", 344 | text: { 345 | type: "mrkdwn", 346 | text: "Select a public channel to receive notifications in:", 347 | }, 348 | accessory: { 349 | action_id: "set_channel", 350 | type: "conversations_select", 351 | placeholder: { 352 | type: "plain_text", 353 | text: "Select a channel...", 354 | emoji: true, 355 | }, 356 | ...(channel ? { initial_conversation: channel } : {}), 357 | }, 358 | }, 359 | ...(feedback?.channel 360 | ? [ 361 | { 362 | type: "context", 363 | elements: [ 364 | { 365 | type: "mrkdwn", 366 | text: feedback.channel, 367 | }, 368 | ], 369 | }, 370 | ] 371 | : []), 372 | { 373 | type: "divider", 374 | }, 375 | { 376 | type: "context", 377 | elements: [ 378 | { 379 | type: "mrkdwn", 380 | text: "Made and with :black_heart: by ", 381 | }, 382 | ], 383 | }, 384 | ]; 385 | 386 | export async function respondToSlack( 387 | res: NextApiResponse, 388 | response_url: string, 389 | teamId: string, 390 | feedback?: { 391 | keyword?: string; 392 | channel?: string; 393 | } 394 | ) { 395 | const { keywords, channel, unfurls, notifications } = 396 | await getTeamConfigAndStats(teamId); // get the latest state of the bot configurations to make sure it's up to date 397 | 398 | // respond to Slack with the new state of the bot 399 | const response = await fetch(response_url, { 400 | method: "POST", 401 | headers: { 402 | "Content-Type": "application/json", 403 | }, 404 | body: JSON.stringify({ 405 | blocks: configureBlocks( 406 | keywords, 407 | channel, 408 | unfurls, 409 | notifications, 410 | feedback 411 | ), 412 | }), 413 | }); 414 | return res.status(200).json(response); 415 | } 416 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime-corejs3@^7.10.2": 6 | version "7.18.9" 7 | resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.18.9.tgz" 8 | integrity sha512-qZEWeccZCrHA2Au4/X05QW5CMdm4VjUDCrGq5gf1ZDcM4hRqreKrtwAn7yci9zfgAS9apvnsFXiGBHBAxZdK9A== 9 | dependencies: 10 | core-js-pure "^3.20.2" 11 | regenerator-runtime "^0.13.4" 12 | 13 | "@babel/runtime@^7.10.2", "@babel/runtime@^7.18.3": 14 | version "7.18.9" 15 | resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz" 16 | integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== 17 | dependencies: 18 | regenerator-runtime "^0.13.4" 19 | 20 | "@emotion/is-prop-valid@^0.8.2": 21 | version "0.8.8" 22 | resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" 23 | integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== 24 | dependencies: 25 | "@emotion/memoize" "0.7.4" 26 | 27 | "@emotion/memoize@0.7.4": 28 | version "0.7.4" 29 | resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" 30 | integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== 31 | 32 | "@eslint/eslintrc@^1.3.0": 33 | version "1.3.0" 34 | resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz" 35 | integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== 36 | dependencies: 37 | ajv "^6.12.4" 38 | debug "^4.3.2" 39 | espree "^9.3.2" 40 | globals "^13.15.0" 41 | ignore "^5.2.0" 42 | import-fresh "^3.2.1" 43 | js-yaml "^4.1.0" 44 | minimatch "^3.1.2" 45 | strip-json-comments "^3.1.1" 46 | 47 | "@humanwhocodes/config-array@^0.9.2": 48 | version "0.9.5" 49 | resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz" 50 | integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== 51 | dependencies: 52 | "@humanwhocodes/object-schema" "^1.2.1" 53 | debug "^4.1.1" 54 | minimatch "^3.0.4" 55 | 56 | "@humanwhocodes/object-schema@^1.2.1": 57 | version "1.2.1" 58 | resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" 59 | integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== 60 | 61 | "@motionone/animation@^10.15.1": 62 | version "10.15.1" 63 | resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.15.1.tgz#4a85596c31cbc5100ae8eb8b34c459fb0ccf6807" 64 | integrity sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ== 65 | dependencies: 66 | "@motionone/easing" "^10.15.1" 67 | "@motionone/types" "^10.15.1" 68 | "@motionone/utils" "^10.15.1" 69 | tslib "^2.3.1" 70 | 71 | "@motionone/dom@^10.15.3": 72 | version "10.15.5" 73 | resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.15.5.tgz#4af18f8136d85c2fc997cac98121c969f6731802" 74 | integrity sha512-Xc5avlgyh3xukU9tydh9+8mB8+2zAq+WlLsC3eEIp7Ax7DnXgY7Bj/iv0a4X2R9z9ZFZiaXK3BO0xMYHKbAAdA== 75 | dependencies: 76 | "@motionone/animation" "^10.15.1" 77 | "@motionone/generators" "^10.15.1" 78 | "@motionone/types" "^10.15.1" 79 | "@motionone/utils" "^10.15.1" 80 | hey-listen "^1.0.8" 81 | tslib "^2.3.1" 82 | 83 | "@motionone/easing@^10.15.1": 84 | version "10.15.1" 85 | resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.15.1.tgz#95cf3adaef34da6deebb83940d8143ede3deb693" 86 | integrity sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw== 87 | dependencies: 88 | "@motionone/utils" "^10.15.1" 89 | tslib "^2.3.1" 90 | 91 | "@motionone/generators@^10.15.1": 92 | version "10.15.1" 93 | resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.15.1.tgz#dc6abb11139d1bafe758a41c134d4c753a9b871c" 94 | integrity sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ== 95 | dependencies: 96 | "@motionone/types" "^10.15.1" 97 | "@motionone/utils" "^10.15.1" 98 | tslib "^2.3.1" 99 | 100 | "@motionone/types@^10.15.1": 101 | version "10.15.1" 102 | resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.15.1.tgz#89441b54285012795cbba8612cbaa0fa420db3eb" 103 | integrity sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA== 104 | 105 | "@motionone/utils@^10.15.1": 106 | version "10.15.1" 107 | resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.15.1.tgz#6b5f51bde75be88b5411e084310299050368a438" 108 | integrity sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw== 109 | dependencies: 110 | "@motionone/types" "^10.15.1" 111 | hey-listen "^1.0.8" 112 | tslib "^2.3.1" 113 | 114 | "@next/env@13.1.6": 115 | version "13.1.6" 116 | resolved "https://registry.yarnpkg.com/@next/env/-/env-13.1.6.tgz#c4925609f16142ded1a5cb833359ab17359b7a93" 117 | integrity sha512-s+W9Fdqh5MFk6ECrbnVmmAOwxKQuhGMT7xXHrkYIBMBcTiOqNWhv5KbJIboKR5STXxNXl32hllnvKaffzFaWQg== 118 | 119 | "@next/eslint-plugin-next@12.2.2": 120 | version "12.2.2" 121 | resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-12.2.2.tgz" 122 | integrity sha512-XOi0WzJhGH3Lk51SkSu9eZxF+IY1ZZhWcJTIGBycAbWU877IQa6+6KxMATWCOs7c+bmp6Sd8KywXJaDRxzu0JA== 123 | dependencies: 124 | glob "7.1.7" 125 | 126 | "@next/font@^13.1.6": 127 | version "13.1.6" 128 | resolved "https://registry.yarnpkg.com/@next/font/-/font-13.1.6.tgz#2bf99e3321ec9b4d65781c0d0ebff072e8752e1a" 129 | integrity sha512-AITjmeb1RgX1HKMCiA39ztx2mxeAyxl4ljv2UoSBUGAbFFMg8MO7YAvjHCgFhD39hL7YTbFjol04e/BPBH5RzQ== 130 | 131 | "@next/swc-android-arm-eabi@13.1.6": 132 | version "13.1.6" 133 | resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.1.6.tgz#d766dfc10e27814d947b20f052067c239913dbcc" 134 | integrity sha512-F3/6Z8LH/pGlPzR1AcjPFxx35mPqjE5xZcf+IL+KgbW9tMkp7CYi1y7qKrEWU7W4AumxX/8OINnDQWLiwLasLQ== 135 | 136 | "@next/swc-android-arm64@13.1.6": 137 | version "13.1.6" 138 | resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-13.1.6.tgz#f37a98d5f18927d8c9970d750d516ac779465176" 139 | integrity sha512-cMwQjnB8vrYkWyK/H0Rf2c2pKIH4RGjpKUDvbjVAit6SbwPDpmaijLio0LWFV3/tOnY6kvzbL62lndVA0mkYpw== 140 | 141 | "@next/swc-darwin-arm64@13.1.6": 142 | version "13.1.6" 143 | resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.1.6.tgz#ec1b90fd9bf809d8b81004c5182e254dced4ad96" 144 | integrity sha512-KKRQH4DDE4kONXCvFMNBZGDb499Hs+xcFAwvj+rfSUssIDrZOlyfJNy55rH5t2Qxed1e4K80KEJgsxKQN1/fyw== 145 | 146 | "@next/swc-darwin-x64@13.1.6": 147 | version "13.1.6" 148 | resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.1.6.tgz#e869ac75d16995eee733a7d1550322d9051c1eb4" 149 | integrity sha512-/uOky5PaZDoaU99ohjtNcDTJ6ks/gZ5ykTQDvNZDjIoCxFe3+t06bxsTPY6tAO6uEAw5f6vVFX5H5KLwhrkZCA== 150 | 151 | "@next/swc-freebsd-x64@13.1.6": 152 | version "13.1.6" 153 | resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.1.6.tgz#84a7b2e423a2904afc2edca21c2f1ba6b53fa4c1" 154 | integrity sha512-qaEALZeV7to6weSXk3Br80wtFQ7cFTpos/q+m9XVRFggu+8Ib895XhMWdJBzew6aaOcMvYR6KQ6JmHA2/eMzWw== 155 | 156 | "@next/swc-linux-arm-gnueabihf@13.1.6": 157 | version "13.1.6" 158 | resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.1.6.tgz#980eed1f655ff8a72187d8a6ef9e73ac39d20d23" 159 | integrity sha512-OybkbC58A1wJ+JrJSOjGDvZzrVEQA4sprJejGqMwiZyLqhr9Eo8FXF0y6HL+m1CPCpPhXEHz/2xKoYsl16kNqw== 160 | 161 | "@next/swc-linux-arm64-gnu@13.1.6": 162 | version "13.1.6" 163 | resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.1.6.tgz#87a71db21cded3f7c63d1d19079845c59813c53d" 164 | integrity sha512-yCH+yDr7/4FDuWv6+GiYrPI9kcTAO3y48UmaIbrKy8ZJpi7RehJe3vIBRUmLrLaNDH3rY1rwoHi471NvR5J5NQ== 165 | 166 | "@next/swc-linux-arm64-musl@13.1.6": 167 | version "13.1.6" 168 | resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.1.6.tgz#c5aac8619331b9fd030603bbe2b36052011e11de" 169 | integrity sha512-ECagB8LGX25P9Mrmlc7Q/TQBb9rGScxHbv/kLqqIWs2fIXy6Y/EiBBiM72NTwuXUFCNrWR4sjUPSooVBJJ3ESQ== 170 | 171 | "@next/swc-linux-x64-gnu@13.1.6": 172 | version "13.1.6" 173 | resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.1.6.tgz#9513d36d540bbfea575576746736054c31aacdea" 174 | integrity sha512-GT5w2mruk90V/I5g6ScuueE7fqj/d8Bui2qxdw6lFxmuTgMeol5rnzAv4uAoVQgClOUO/MULilzlODg9Ib3Y4Q== 175 | 176 | "@next/swc-linux-x64-musl@13.1.6": 177 | version "13.1.6" 178 | resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.1.6.tgz#d61fc6884899f5957251f4ce3f522e34a2c479b7" 179 | integrity sha512-keFD6KvwOPzmat4TCnlnuxJCQepPN+8j3Nw876FtULxo8005Y9Ghcl7ACcR8GoiKoddAq8gxNBrpjoxjQRHeAQ== 180 | 181 | "@next/swc-win32-arm64-msvc@13.1.6": 182 | version "13.1.6" 183 | resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.1.6.tgz#fac2077a8ae9768e31444c9ae90807e64117cda7" 184 | integrity sha512-OwertslIiGQluFvHyRDzBCIB07qJjqabAmINlXUYt7/sY7Q7QPE8xVi5beBxX/rxTGPIbtyIe3faBE6Z2KywhQ== 185 | 186 | "@next/swc-win32-ia32-msvc@13.1.6": 187 | version "13.1.6" 188 | resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.1.6.tgz#498bc11c91b4c482a625bf4b978f98ae91111e46" 189 | integrity sha512-g8zowiuP8FxUR9zslPmlju7qYbs2XBtTLVSxVikPtUDQedhcls39uKYLvOOd1JZg0ehyhopobRoH1q+MHlIN/w== 190 | 191 | "@next/swc-win32-x64-msvc@13.1.6": 192 | version "13.1.6" 193 | resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.1.6.tgz#17ed919c723426b7d0ce1cd73d40ce3dcd342089" 194 | integrity sha512-Ls2OL9hi3YlJKGNdKv8k3X/lLgc3VmLG3a/DeTkAd+lAituJp8ZHmRmm9f9SL84fT3CotlzcgbdaCDfFwFA6bA== 195 | 196 | "@nodelib/fs.scandir@2.1.5": 197 | version "2.1.5" 198 | resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" 199 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 200 | dependencies: 201 | "@nodelib/fs.stat" "2.0.5" 202 | run-parallel "^1.1.9" 203 | 204 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 205 | version "2.0.5" 206 | resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" 207 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 208 | 209 | "@nodelib/fs.walk@^1.2.3": 210 | version "1.2.8" 211 | resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" 212 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 213 | dependencies: 214 | "@nodelib/fs.scandir" "2.1.5" 215 | fastq "^1.6.0" 216 | 217 | "@resvg/resvg-wasm@2.0.0-alpha.4": 218 | version "2.0.0-alpha.4" 219 | resolved "https://registry.yarnpkg.com/@resvg/resvg-wasm/-/resvg-wasm-2.0.0-alpha.4.tgz#fc2f86186a9641df030d8f9f3f9d995899cd1ecb" 220 | integrity sha512-pWIG9a/x1ky8gXKRhPH1OPKpHFoMN1ISLbJ+O+gPXQHIAKhNd5I28RlWf7q576hAOQA9JZTlo3p/M2uyLzJmmw== 221 | 222 | "@rushstack/eslint-patch@^1.1.3": 223 | version "1.1.4" 224 | resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz" 225 | integrity sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA== 226 | 227 | "@shuding/opentype.js@1.4.0-beta.0": 228 | version "1.4.0-beta.0" 229 | resolved "https://registry.yarnpkg.com/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz#5d1e7e9e056f546aad41df1c5043f8f85d39e24b" 230 | integrity sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA== 231 | dependencies: 232 | fflate "^0.7.3" 233 | string.prototype.codepointat "^0.2.1" 234 | 235 | "@swc/helpers@0.4.14": 236 | version "0.4.14" 237 | resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74" 238 | integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== 239 | dependencies: 240 | tslib "^2.4.0" 241 | 242 | "@tailwindcss/forms@^0.5.2": 243 | version "0.5.2" 244 | resolved "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.2.tgz" 245 | integrity sha512-pSrFeJB6Bg1Mrg9CdQW3+hqZXAKsBrSG9MAfFLKy1pVA4Mb4W7C0k7mEhlmS2Dfo/otxrQOET7NJiJ9RrS563w== 246 | dependencies: 247 | mini-svg-data-uri "^1.2.3" 248 | 249 | "@types/json5@^0.0.29": 250 | version "0.0.29" 251 | resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" 252 | integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== 253 | 254 | "@types/node@18.0.6": 255 | version "18.0.6" 256 | resolved "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz" 257 | integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== 258 | 259 | "@types/prop-types@*": 260 | version "15.7.5" 261 | resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" 262 | integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== 263 | 264 | "@types/react-dom@18.0.6": 265 | version "18.0.6" 266 | resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.6.tgz" 267 | integrity sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA== 268 | dependencies: 269 | "@types/react" "*" 270 | 271 | "@types/react@*", "@types/react@18.0.15": 272 | version "18.0.15" 273 | resolved "https://registry.npmjs.org/@types/react/-/react-18.0.15.tgz" 274 | integrity sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow== 275 | dependencies: 276 | "@types/prop-types" "*" 277 | "@types/scheduler" "*" 278 | csstype "^3.0.2" 279 | 280 | "@types/retry@0.12.1": 281 | version "0.12.1" 282 | resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz" 283 | integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== 284 | 285 | "@types/scheduler@*": 286 | version "0.16.2" 287 | resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz" 288 | integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== 289 | 290 | "@types/turndown@^5.0.1": 291 | version "5.0.1" 292 | resolved "https://registry.npmjs.org/@types/turndown/-/turndown-5.0.1.tgz" 293 | integrity sha512-N8Ad4e3oJxh9n9BiZx9cbe/0M3kqDpOTm2wzj13wdDUxDPjfjloWIJaquZzWE1cYTAHpjOH3rcTnXQdpEfS/SQ== 294 | 295 | "@typescript-eslint/parser@^5.21.0": 296 | version "5.30.7" 297 | resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.7.tgz" 298 | integrity sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A== 299 | dependencies: 300 | "@typescript-eslint/scope-manager" "5.30.7" 301 | "@typescript-eslint/types" "5.30.7" 302 | "@typescript-eslint/typescript-estree" "5.30.7" 303 | debug "^4.3.4" 304 | 305 | "@typescript-eslint/scope-manager@5.30.7": 306 | version "5.30.7" 307 | resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.7.tgz" 308 | integrity sha512-7BM1bwvdF1UUvt+b9smhqdc/eniOnCKxQT/kj3oXtj3LqnTWCAM0qHRHfyzCzhEfWX0zrW7KqXXeE4DlchZBKw== 309 | dependencies: 310 | "@typescript-eslint/types" "5.30.7" 311 | "@typescript-eslint/visitor-keys" "5.30.7" 312 | 313 | "@typescript-eslint/types@5.30.7": 314 | version "5.30.7" 315 | resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.7.tgz" 316 | integrity sha512-ocVkETUs82+U+HowkovV6uxf1AnVRKCmDRNUBUUo46/5SQv1owC/EBFkiu4MOHeZqhKz2ktZ3kvJJ1uFqQ8QPg== 317 | 318 | "@typescript-eslint/typescript-estree@5.30.7": 319 | version "5.30.7" 320 | resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.7.tgz" 321 | integrity sha512-tNslqXI1ZdmXXrHER83TJ8OTYl4epUzJC0aj2i4DMDT4iU+UqLT3EJeGQvJ17BMbm31x5scSwo3hPM0nqQ1AEA== 322 | dependencies: 323 | "@typescript-eslint/types" "5.30.7" 324 | "@typescript-eslint/visitor-keys" "5.30.7" 325 | debug "^4.3.4" 326 | globby "^11.1.0" 327 | is-glob "^4.0.3" 328 | semver "^7.3.7" 329 | tsutils "^3.21.0" 330 | 331 | "@typescript-eslint/visitor-keys@5.30.7": 332 | version "5.30.7" 333 | resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.7.tgz" 334 | integrity sha512-KrRXf8nnjvcpxDFOKej4xkD7657+PClJs5cJVSG7NNoCNnjEdc46juNAQt7AyuWctuCgs6mVRc1xGctEqrjxWw== 335 | dependencies: 336 | "@typescript-eslint/types" "5.30.7" 337 | eslint-visitor-keys "^3.3.0" 338 | 339 | "@upstash/redis@^1.10.2": 340 | version "1.10.2" 341 | resolved "https://registry.npmjs.org/@upstash/redis/-/redis-1.10.2.tgz" 342 | integrity sha512-eQg9i6PUeBhsH7XddIcdBJXSlJlXhcad4aOg4QvvjshssyZhlmu6SW2dKkr50vgjZScln8pCsexZkEcpn8GMhQ== 343 | dependencies: 344 | isomorphic-fetch "^3.0.0" 345 | 346 | "@vercel/analytics@^0.1.9-beta.6": 347 | version "0.1.9-beta.6" 348 | resolved "https://registry.yarnpkg.com/@vercel/analytics/-/analytics-0.1.9-beta.6.tgz#8bba86eaa1e479523e79fc4c71f8955774b7e8cc" 349 | integrity sha512-83mHCRsx2BAWijgBd17BvVw2g9/FkRs+i1paGES3KRf5yB+aU8VadlxoEeP2wkiLCMxpZWxrzaGKdwkoKId0TQ== 350 | 351 | "@vercel/og@^0.1.0": 352 | version "0.1.0" 353 | resolved "https://registry.yarnpkg.com/@vercel/og/-/og-0.1.0.tgz#dd0574bca4acef7cf69576142d9b158fb74fda08" 354 | integrity sha512-0M7YT3TKd1bsJ/At46B5EMtxgZBixfTQV5VRnkdd8bTiKAGnzw/li+uORU4pvOyyPLoVQJpzuU0Xx+bbAKu2bQ== 355 | dependencies: 356 | "@resvg/resvg-wasm" "2.0.0-alpha.4" 357 | satori "0.2.2" 358 | yoga-wasm-web "0.3.0" 359 | 360 | abab@^2.0.0: 361 | version "2.0.6" 362 | resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" 363 | integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== 364 | 365 | acorn-globals@^4.1.0: 366 | version "4.3.4" 367 | resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz" 368 | integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== 369 | dependencies: 370 | acorn "^6.0.1" 371 | acorn-walk "^6.0.1" 372 | 373 | acorn-jsx@^5.3.2: 374 | version "5.3.2" 375 | resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" 376 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 377 | 378 | acorn-node@^1.8.2: 379 | version "1.8.2" 380 | resolved "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz" 381 | integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== 382 | dependencies: 383 | acorn "^7.0.0" 384 | acorn-walk "^7.0.0" 385 | xtend "^4.0.2" 386 | 387 | acorn-walk@^6.0.1: 388 | version "6.2.0" 389 | resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz" 390 | integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== 391 | 392 | acorn-walk@^7.0.0: 393 | version "7.2.0" 394 | resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" 395 | integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== 396 | 397 | acorn@^5.5.3: 398 | version "5.7.4" 399 | resolved "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz" 400 | integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== 401 | 402 | acorn@^6.0.1: 403 | version "6.4.2" 404 | resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" 405 | integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== 406 | 407 | acorn@^7.0.0: 408 | version "7.4.1" 409 | resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" 410 | integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== 411 | 412 | acorn@^8.7.1: 413 | version "8.7.1" 414 | resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz" 415 | integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== 416 | 417 | ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: 418 | version "6.12.6" 419 | resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" 420 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 421 | dependencies: 422 | fast-deep-equal "^3.1.1" 423 | fast-json-stable-stringify "^2.0.0" 424 | json-schema-traverse "^0.4.1" 425 | uri-js "^4.2.2" 426 | 427 | ansi-regex@^5.0.1: 428 | version "5.0.1" 429 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" 430 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 431 | 432 | ansi-styles@^4.1.0: 433 | version "4.3.0" 434 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" 435 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 436 | dependencies: 437 | color-convert "^2.0.1" 438 | 439 | anymatch@~3.1.2: 440 | version "3.1.2" 441 | resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" 442 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 443 | dependencies: 444 | normalize-path "^3.0.0" 445 | picomatch "^2.0.4" 446 | 447 | arg@^5.0.2: 448 | version "5.0.2" 449 | resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" 450 | integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== 451 | 452 | argparse@^2.0.1: 453 | version "2.0.1" 454 | resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" 455 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 456 | 457 | aria-query@^4.2.2: 458 | version "4.2.2" 459 | resolved "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz" 460 | integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== 461 | dependencies: 462 | "@babel/runtime" "^7.10.2" 463 | "@babel/runtime-corejs3" "^7.10.2" 464 | 465 | array-equal@^1.0.0: 466 | version "1.0.0" 467 | resolved "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz" 468 | integrity sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA== 469 | 470 | array-includes@^3.1.4, array-includes@^3.1.5: 471 | version "3.1.5" 472 | resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz" 473 | integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== 474 | dependencies: 475 | call-bind "^1.0.2" 476 | define-properties "^1.1.4" 477 | es-abstract "^1.19.5" 478 | get-intrinsic "^1.1.1" 479 | is-string "^1.0.7" 480 | 481 | array-union@^2.1.0: 482 | version "2.1.0" 483 | resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" 484 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 485 | 486 | array.prototype.flat@^1.2.5: 487 | version "1.3.0" 488 | resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz" 489 | integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== 490 | dependencies: 491 | call-bind "^1.0.2" 492 | define-properties "^1.1.3" 493 | es-abstract "^1.19.2" 494 | es-shim-unscopables "^1.0.0" 495 | 496 | array.prototype.flatmap@^1.3.0: 497 | version "1.3.0" 498 | resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz" 499 | integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg== 500 | dependencies: 501 | call-bind "^1.0.2" 502 | define-properties "^1.1.3" 503 | es-abstract "^1.19.2" 504 | es-shim-unscopables "^1.0.0" 505 | 506 | asn1@~0.2.3: 507 | version "0.2.6" 508 | resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" 509 | integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== 510 | dependencies: 511 | safer-buffer "~2.1.0" 512 | 513 | assert-plus@1.0.0, assert-plus@^1.0.0: 514 | version "1.0.0" 515 | resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" 516 | integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== 517 | 518 | ast-types-flow@^0.0.7: 519 | version "0.0.7" 520 | resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" 521 | integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== 522 | 523 | async-limiter@~1.0.0: 524 | version "1.0.1" 525 | resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" 526 | integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== 527 | 528 | asynckit@^0.4.0: 529 | version "0.4.0" 530 | resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" 531 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 532 | 533 | autoprefixer@^10.4.7: 534 | version "10.4.7" 535 | resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz" 536 | integrity sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA== 537 | dependencies: 538 | browserslist "^4.20.3" 539 | caniuse-lite "^1.0.30001335" 540 | fraction.js "^4.2.0" 541 | normalize-range "^0.1.2" 542 | picocolors "^1.0.0" 543 | postcss-value-parser "^4.2.0" 544 | 545 | aws-sign2@~0.7.0: 546 | version "0.7.0" 547 | resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" 548 | integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== 549 | 550 | aws4@^1.8.0: 551 | version "1.11.0" 552 | resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" 553 | integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== 554 | 555 | axe-core@^4.4.2: 556 | version "4.4.3" 557 | resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz" 558 | integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== 559 | 560 | axobject-query@^2.2.0: 561 | version "2.2.0" 562 | resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz" 563 | integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== 564 | 565 | balanced-match@^1.0.0: 566 | version "1.0.2" 567 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 568 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 569 | 570 | bcrypt-pbkdf@^1.0.0: 571 | version "1.0.2" 572 | resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" 573 | integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== 574 | dependencies: 575 | tweetnacl "^0.14.3" 576 | 577 | binary-extensions@^2.0.0: 578 | version "2.2.0" 579 | resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" 580 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 581 | 582 | brace-expansion@^1.1.7: 583 | version "1.1.11" 584 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 585 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 586 | dependencies: 587 | balanced-match "^1.0.0" 588 | concat-map "0.0.1" 589 | 590 | braces@^3.0.2, braces@~3.0.2: 591 | version "3.0.2" 592 | resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" 593 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 594 | dependencies: 595 | fill-range "^7.0.1" 596 | 597 | browser-process-hrtime@^1.0.0: 598 | version "1.0.0" 599 | resolved "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz" 600 | integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== 601 | 602 | browserslist@^4.20.3: 603 | version "4.21.2" 604 | resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz" 605 | integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== 606 | dependencies: 607 | caniuse-lite "^1.0.30001366" 608 | electron-to-chromium "^1.4.188" 609 | node-releases "^2.0.6" 610 | update-browserslist-db "^1.0.4" 611 | 612 | call-bind@^1.0.0, call-bind@^1.0.2: 613 | version "1.0.2" 614 | resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" 615 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== 616 | dependencies: 617 | function-bind "^1.1.1" 618 | get-intrinsic "^1.0.2" 619 | 620 | callsites@^3.0.0: 621 | version "3.1.0" 622 | resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" 623 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 624 | 625 | camelcase-css@^2.0.1: 626 | version "2.0.1" 627 | resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" 628 | integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== 629 | 630 | camelize@^1.0.0: 631 | version "1.0.1" 632 | resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" 633 | integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== 634 | 635 | caniuse-lite@^1.0.30001335, caniuse-lite@^1.0.30001366: 636 | version "1.0.30001367" 637 | resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz" 638 | integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== 639 | 640 | caniuse-lite@^1.0.30001406: 641 | version "1.0.30001457" 642 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301" 643 | integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA== 644 | 645 | caseless@~0.12.0: 646 | version "0.12.0" 647 | resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" 648 | integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== 649 | 650 | chalk@^4.0.0: 651 | version "4.1.2" 652 | resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" 653 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 654 | dependencies: 655 | ansi-styles "^4.1.0" 656 | supports-color "^7.1.0" 657 | 658 | chokidar@^3.5.3: 659 | version "3.5.3" 660 | resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" 661 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 662 | dependencies: 663 | anymatch "~3.1.2" 664 | braces "~3.0.2" 665 | glob-parent "~5.1.2" 666 | is-binary-path "~2.1.0" 667 | is-glob "~4.0.1" 668 | normalize-path "~3.0.0" 669 | readdirp "~3.6.0" 670 | optionalDependencies: 671 | fsevents "~2.3.2" 672 | 673 | client-only@0.0.1: 674 | version "0.0.1" 675 | resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" 676 | integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== 677 | 678 | color-convert@^2.0.1: 679 | version "2.0.1" 680 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" 681 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 682 | dependencies: 683 | color-name "~1.1.4" 684 | 685 | color-name@^1.1.4, color-name@~1.1.4: 686 | version "1.1.4" 687 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 688 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 689 | 690 | combined-stream@^1.0.6, combined-stream@~1.0.6: 691 | version "1.0.8" 692 | resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" 693 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 694 | dependencies: 695 | delayed-stream "~1.0.0" 696 | 697 | concat-map@0.0.1: 698 | version "0.0.1" 699 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 700 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 701 | 702 | core-js-pure@^3.20.2: 703 | version "3.23.5" 704 | resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.5.tgz" 705 | integrity sha512-8t78LdpKSuCq4pJYCYk8hl7XEkAX+BP16yRIwL3AanTksxuEf7CM83vRyctmiEL8NDZ3jpUcv56fk9/zG3aIuw== 706 | 707 | core-util-is@1.0.2: 708 | version "1.0.2" 709 | resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" 710 | integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== 711 | 712 | cross-spawn@^7.0.2: 713 | version "7.0.3" 714 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" 715 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 716 | dependencies: 717 | path-key "^3.1.0" 718 | shebang-command "^2.0.0" 719 | which "^2.0.1" 720 | 721 | css-background-parser@^0.1.0: 722 | version "0.1.0" 723 | resolved "https://registry.yarnpkg.com/css-background-parser/-/css-background-parser-0.1.0.tgz#48a17f7fe6d4d4f1bca3177ddf16c5617950741b" 724 | integrity sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA== 725 | 726 | css-box-shadow@1.0.0-3: 727 | version "1.0.0-3" 728 | resolved "https://registry.yarnpkg.com/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz#9eaeb7140947bf5d649fc49a19e4bbaa5f602713" 729 | integrity sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg== 730 | 731 | css-color-keywords@^1.0.0: 732 | version "1.0.0" 733 | resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" 734 | integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== 735 | 736 | css-to-react-native@^3.0.0: 737 | version "3.2.0" 738 | resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32" 739 | integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== 740 | dependencies: 741 | camelize "^1.0.0" 742 | css-color-keywords "^1.0.0" 743 | postcss-value-parser "^4.0.2" 744 | 745 | cssesc@^3.0.0: 746 | version "3.0.0" 747 | resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" 748 | integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== 749 | 750 | cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": 751 | version "0.3.8" 752 | resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz" 753 | integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== 754 | 755 | cssstyle@^1.0.0: 756 | version "1.4.0" 757 | resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz" 758 | integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== 759 | dependencies: 760 | cssom "0.3.x" 761 | 762 | csstype@^3.0.2: 763 | version "3.1.0" 764 | resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz" 765 | integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== 766 | 767 | damerau-levenshtein@^1.0.8: 768 | version "1.0.8" 769 | resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" 770 | integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== 771 | 772 | dashdash@^1.12.0: 773 | version "1.14.1" 774 | resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" 775 | integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== 776 | dependencies: 777 | assert-plus "^1.0.0" 778 | 779 | data-urls@^1.0.0: 780 | version "1.1.0" 781 | resolved "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz" 782 | integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== 783 | dependencies: 784 | abab "^2.0.0" 785 | whatwg-mimetype "^2.2.0" 786 | whatwg-url "^7.0.0" 787 | 788 | debug@^2.6.9: 789 | version "2.6.9" 790 | resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" 791 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 792 | dependencies: 793 | ms "2.0.0" 794 | 795 | debug@^3.2.7: 796 | version "3.2.7" 797 | resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" 798 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== 799 | dependencies: 800 | ms "^2.1.1" 801 | 802 | debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: 803 | version "4.3.4" 804 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" 805 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 806 | dependencies: 807 | ms "2.1.2" 808 | 809 | deep-is@^0.1.3, deep-is@~0.1.3: 810 | version "0.1.4" 811 | resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" 812 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 813 | 814 | define-properties@^1.1.3, define-properties@^1.1.4: 815 | version "1.1.4" 816 | resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" 817 | integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== 818 | dependencies: 819 | has-property-descriptors "^1.0.0" 820 | object-keys "^1.1.1" 821 | 822 | defined@^1.0.0: 823 | version "1.0.0" 824 | resolved "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz" 825 | integrity sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ== 826 | 827 | delayed-stream@~1.0.0: 828 | version "1.0.0" 829 | resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" 830 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 831 | 832 | detective@^5.2.1: 833 | version "5.2.1" 834 | resolved "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz" 835 | integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw== 836 | dependencies: 837 | acorn-node "^1.8.2" 838 | defined "^1.0.0" 839 | minimist "^1.2.6" 840 | 841 | didyoumean@^1.2.2: 842 | version "1.2.2" 843 | resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" 844 | integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== 845 | 846 | dir-glob@^3.0.1: 847 | version "3.0.1" 848 | resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" 849 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 850 | dependencies: 851 | path-type "^4.0.0" 852 | 853 | dlv@^1.1.3: 854 | version "1.1.3" 855 | resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" 856 | integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== 857 | 858 | doctrine@^2.1.0: 859 | version "2.1.0" 860 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" 861 | integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== 862 | dependencies: 863 | esutils "^2.0.2" 864 | 865 | doctrine@^3.0.0: 866 | version "3.0.0" 867 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" 868 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 869 | dependencies: 870 | esutils "^2.0.2" 871 | 872 | domexception@^1.0.1: 873 | version "1.0.1" 874 | resolved "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz" 875 | integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== 876 | dependencies: 877 | webidl-conversions "^4.0.2" 878 | 879 | ecc-jsbn@~0.1.1: 880 | version "0.1.2" 881 | resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" 882 | integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== 883 | dependencies: 884 | jsbn "~0.1.0" 885 | safer-buffer "^2.1.0" 886 | 887 | electron-to-chromium@^1.4.188: 888 | version "1.4.197" 889 | resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.197.tgz" 890 | integrity sha512-7EZCIDDraA2NUaHewLaAh6T63cZzgBmgDx/iiaeZ/pjSs36bOFEJ3hLIrn1TKCFhV0PEZZKu6qFPrxa/LGAzLg== 891 | 892 | emoji-regex@^10.2.1: 893 | version "10.2.1" 894 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.2.1.tgz#a41c330d957191efd3d9dfe6e1e8e1e9ab048b3f" 895 | integrity sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA== 896 | 897 | emoji-regex@^9.2.2: 898 | version "9.2.2" 899 | resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" 900 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 901 | 902 | es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: 903 | version "1.20.1" 904 | resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz" 905 | integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== 906 | dependencies: 907 | call-bind "^1.0.2" 908 | es-to-primitive "^1.2.1" 909 | function-bind "^1.1.1" 910 | function.prototype.name "^1.1.5" 911 | get-intrinsic "^1.1.1" 912 | get-symbol-description "^1.0.0" 913 | has "^1.0.3" 914 | has-property-descriptors "^1.0.0" 915 | has-symbols "^1.0.3" 916 | internal-slot "^1.0.3" 917 | is-callable "^1.2.4" 918 | is-negative-zero "^2.0.2" 919 | is-regex "^1.1.4" 920 | is-shared-array-buffer "^1.0.2" 921 | is-string "^1.0.7" 922 | is-weakref "^1.0.2" 923 | object-inspect "^1.12.0" 924 | object-keys "^1.1.1" 925 | object.assign "^4.1.2" 926 | regexp.prototype.flags "^1.4.3" 927 | string.prototype.trimend "^1.0.5" 928 | string.prototype.trimstart "^1.0.5" 929 | unbox-primitive "^1.0.2" 930 | 931 | es-shim-unscopables@^1.0.0: 932 | version "1.0.0" 933 | resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" 934 | integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== 935 | dependencies: 936 | has "^1.0.3" 937 | 938 | es-to-primitive@^1.2.1: 939 | version "1.2.1" 940 | resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" 941 | integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== 942 | dependencies: 943 | is-callable "^1.1.4" 944 | is-date-object "^1.0.1" 945 | is-symbol "^1.0.2" 946 | 947 | escalade@^3.1.1: 948 | version "3.1.1" 949 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" 950 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 951 | 952 | escape-string-regexp@5.0.0: 953 | version "5.0.0" 954 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" 955 | integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== 956 | 957 | escape-string-regexp@^4.0.0: 958 | version "4.0.0" 959 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" 960 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 961 | 962 | escodegen@^1.9.1: 963 | version "1.14.3" 964 | resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz" 965 | integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== 966 | dependencies: 967 | esprima "^4.0.1" 968 | estraverse "^4.2.0" 969 | esutils "^2.0.2" 970 | optionator "^0.8.1" 971 | optionalDependencies: 972 | source-map "~0.6.1" 973 | 974 | eslint-config-next@12.2.2: 975 | version "12.2.2" 976 | resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-12.2.2.tgz" 977 | integrity sha512-oJhWBLC4wDYYUFv/5APbjHUFd0QRFCojMdj/QnMoOEktmeTvwnnoA8F8uaXs0fQgsaTK0tbUxBRv9/Y4/rpxOA== 978 | dependencies: 979 | "@next/eslint-plugin-next" "12.2.2" 980 | "@rushstack/eslint-patch" "^1.1.3" 981 | "@typescript-eslint/parser" "^5.21.0" 982 | eslint-import-resolver-node "^0.3.6" 983 | eslint-import-resolver-typescript "^2.7.1" 984 | eslint-plugin-import "^2.26.0" 985 | eslint-plugin-jsx-a11y "^6.5.1" 986 | eslint-plugin-react "^7.29.4" 987 | eslint-plugin-react-hooks "^4.5.0" 988 | 989 | eslint-import-resolver-node@^0.3.6: 990 | version "0.3.6" 991 | resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz" 992 | integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== 993 | dependencies: 994 | debug "^3.2.7" 995 | resolve "^1.20.0" 996 | 997 | eslint-import-resolver-typescript@^2.7.1: 998 | version "2.7.1" 999 | resolved "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz" 1000 | integrity sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ== 1001 | dependencies: 1002 | debug "^4.3.4" 1003 | glob "^7.2.0" 1004 | is-glob "^4.0.3" 1005 | resolve "^1.22.0" 1006 | tsconfig-paths "^3.14.1" 1007 | 1008 | eslint-module-utils@^2.7.3: 1009 | version "2.7.3" 1010 | resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz" 1011 | integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== 1012 | dependencies: 1013 | debug "^3.2.7" 1014 | find-up "^2.1.0" 1015 | 1016 | eslint-plugin-import@^2.26.0: 1017 | version "2.26.0" 1018 | resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz" 1019 | integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== 1020 | dependencies: 1021 | array-includes "^3.1.4" 1022 | array.prototype.flat "^1.2.5" 1023 | debug "^2.6.9" 1024 | doctrine "^2.1.0" 1025 | eslint-import-resolver-node "^0.3.6" 1026 | eslint-module-utils "^2.7.3" 1027 | has "^1.0.3" 1028 | is-core-module "^2.8.1" 1029 | is-glob "^4.0.3" 1030 | minimatch "^3.1.2" 1031 | object.values "^1.1.5" 1032 | resolve "^1.22.0" 1033 | tsconfig-paths "^3.14.1" 1034 | 1035 | eslint-plugin-jsx-a11y@^6.5.1: 1036 | version "6.6.0" 1037 | resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.0.tgz" 1038 | integrity sha512-kTeLuIzpNhXL2CwLlc8AHI0aFRwWHcg483yepO9VQiHzM9bZwJdzTkzBszbuPrbgGmq2rlX/FaT2fJQsjUSHsw== 1039 | dependencies: 1040 | "@babel/runtime" "^7.18.3" 1041 | aria-query "^4.2.2" 1042 | array-includes "^3.1.5" 1043 | ast-types-flow "^0.0.7" 1044 | axe-core "^4.4.2" 1045 | axobject-query "^2.2.0" 1046 | damerau-levenshtein "^1.0.8" 1047 | emoji-regex "^9.2.2" 1048 | has "^1.0.3" 1049 | jsx-ast-utils "^3.3.1" 1050 | language-tags "^1.0.5" 1051 | minimatch "^3.1.2" 1052 | semver "^6.3.0" 1053 | 1054 | eslint-plugin-react-hooks@^4.5.0: 1055 | version "4.6.0" 1056 | resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz" 1057 | integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== 1058 | 1059 | eslint-plugin-react@^7.29.4: 1060 | version "7.30.1" 1061 | resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.30.1.tgz" 1062 | integrity sha512-NbEvI9jtqO46yJA3wcRF9Mo0lF9T/jhdHqhCHXiXtD+Zcb98812wvokjWpU7Q4QH5edo6dmqrukxVvWWXHlsUg== 1063 | dependencies: 1064 | array-includes "^3.1.5" 1065 | array.prototype.flatmap "^1.3.0" 1066 | doctrine "^2.1.0" 1067 | estraverse "^5.3.0" 1068 | jsx-ast-utils "^2.4.1 || ^3.0.0" 1069 | minimatch "^3.1.2" 1070 | object.entries "^1.1.5" 1071 | object.fromentries "^2.0.5" 1072 | object.hasown "^1.1.1" 1073 | object.values "^1.1.5" 1074 | prop-types "^15.8.1" 1075 | resolve "^2.0.0-next.3" 1076 | semver "^6.3.0" 1077 | string.prototype.matchall "^4.0.7" 1078 | 1079 | eslint-scope@^7.1.1: 1080 | version "7.1.1" 1081 | resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz" 1082 | integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== 1083 | dependencies: 1084 | esrecurse "^4.3.0" 1085 | estraverse "^5.2.0" 1086 | 1087 | eslint-utils@^3.0.0: 1088 | version "3.0.0" 1089 | resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" 1090 | integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== 1091 | dependencies: 1092 | eslint-visitor-keys "^2.0.0" 1093 | 1094 | eslint-visitor-keys@^2.0.0: 1095 | version "2.1.0" 1096 | resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" 1097 | integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 1098 | 1099 | eslint-visitor-keys@^3.3.0: 1100 | version "3.3.0" 1101 | resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" 1102 | integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== 1103 | 1104 | eslint@8.20.0: 1105 | version "8.20.0" 1106 | resolved "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz" 1107 | integrity sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA== 1108 | dependencies: 1109 | "@eslint/eslintrc" "^1.3.0" 1110 | "@humanwhocodes/config-array" "^0.9.2" 1111 | ajv "^6.10.0" 1112 | chalk "^4.0.0" 1113 | cross-spawn "^7.0.2" 1114 | debug "^4.3.2" 1115 | doctrine "^3.0.0" 1116 | escape-string-regexp "^4.0.0" 1117 | eslint-scope "^7.1.1" 1118 | eslint-utils "^3.0.0" 1119 | eslint-visitor-keys "^3.3.0" 1120 | espree "^9.3.2" 1121 | esquery "^1.4.0" 1122 | esutils "^2.0.2" 1123 | fast-deep-equal "^3.1.3" 1124 | file-entry-cache "^6.0.1" 1125 | functional-red-black-tree "^1.0.1" 1126 | glob-parent "^6.0.1" 1127 | globals "^13.15.0" 1128 | ignore "^5.2.0" 1129 | import-fresh "^3.0.0" 1130 | imurmurhash "^0.1.4" 1131 | is-glob "^4.0.0" 1132 | js-yaml "^4.1.0" 1133 | json-stable-stringify-without-jsonify "^1.0.1" 1134 | levn "^0.4.1" 1135 | lodash.merge "^4.6.2" 1136 | minimatch "^3.1.2" 1137 | natural-compare "^1.4.0" 1138 | optionator "^0.9.1" 1139 | regexpp "^3.2.0" 1140 | strip-ansi "^6.0.1" 1141 | strip-json-comments "^3.1.0" 1142 | text-table "^0.2.0" 1143 | v8-compile-cache "^2.0.3" 1144 | 1145 | espree@^9.3.2: 1146 | version "9.3.2" 1147 | resolved "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz" 1148 | integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== 1149 | dependencies: 1150 | acorn "^8.7.1" 1151 | acorn-jsx "^5.3.2" 1152 | eslint-visitor-keys "^3.3.0" 1153 | 1154 | esprima@^4.0.1: 1155 | version "4.0.1" 1156 | resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" 1157 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 1158 | 1159 | esquery@^1.4.0: 1160 | version "1.4.0" 1161 | resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" 1162 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 1163 | dependencies: 1164 | estraverse "^5.1.0" 1165 | 1166 | esrecurse@^4.3.0: 1167 | version "4.3.0" 1168 | resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" 1169 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 1170 | dependencies: 1171 | estraverse "^5.2.0" 1172 | 1173 | estraverse@^4.2.0: 1174 | version "4.3.0" 1175 | resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" 1176 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 1177 | 1178 | estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: 1179 | version "5.3.0" 1180 | resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" 1181 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== 1182 | 1183 | esutils@^2.0.2: 1184 | version "2.0.3" 1185 | resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" 1186 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 1187 | 1188 | extend@~3.0.2: 1189 | version "3.0.2" 1190 | resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" 1191 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== 1192 | 1193 | extsprintf@1.3.0, extsprintf@^1.2.0: 1194 | version "1.3.0" 1195 | resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" 1196 | integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== 1197 | 1198 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 1199 | version "3.1.3" 1200 | resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" 1201 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 1202 | 1203 | fast-glob@^3.2.11, fast-glob@^3.2.9: 1204 | version "3.2.11" 1205 | resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz" 1206 | integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== 1207 | dependencies: 1208 | "@nodelib/fs.stat" "^2.0.2" 1209 | "@nodelib/fs.walk" "^1.2.3" 1210 | glob-parent "^5.1.2" 1211 | merge2 "^1.3.0" 1212 | micromatch "^4.0.4" 1213 | 1214 | fast-json-stable-stringify@^2.0.0: 1215 | version "2.1.0" 1216 | resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" 1217 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 1218 | 1219 | fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: 1220 | version "2.0.6" 1221 | resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" 1222 | integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== 1223 | 1224 | fastq@^1.6.0: 1225 | version "1.13.0" 1226 | resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz" 1227 | integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== 1228 | dependencies: 1229 | reusify "^1.0.4" 1230 | 1231 | fflate@^0.7.3: 1232 | version "0.7.4" 1233 | resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.7.4.tgz#61587e5d958fdabb5a9368a302c25363f4f69f50" 1234 | integrity sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw== 1235 | 1236 | file-entry-cache@^6.0.1: 1237 | version "6.0.1" 1238 | resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" 1239 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 1240 | dependencies: 1241 | flat-cache "^3.0.4" 1242 | 1243 | fill-range@^7.0.1: 1244 | version "7.0.1" 1245 | resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" 1246 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 1247 | dependencies: 1248 | to-regex-range "^5.0.1" 1249 | 1250 | find-up@^2.1.0: 1251 | version "2.1.0" 1252 | resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" 1253 | integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== 1254 | dependencies: 1255 | locate-path "^2.0.0" 1256 | 1257 | flat-cache@^3.0.4: 1258 | version "3.0.4" 1259 | resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" 1260 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 1261 | dependencies: 1262 | flatted "^3.1.0" 1263 | rimraf "^3.0.2" 1264 | 1265 | flatted@^3.1.0: 1266 | version "3.2.6" 1267 | resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz" 1268 | integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== 1269 | 1270 | forever-agent@~0.6.1: 1271 | version "0.6.1" 1272 | resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" 1273 | integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== 1274 | 1275 | form-data@~2.3.2: 1276 | version "2.3.3" 1277 | resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" 1278 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== 1279 | dependencies: 1280 | asynckit "^0.4.0" 1281 | combined-stream "^1.0.6" 1282 | mime-types "^2.1.12" 1283 | 1284 | fraction.js@^4.2.0: 1285 | version "4.2.0" 1286 | resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" 1287 | integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== 1288 | 1289 | framer-motion@^9.0.7: 1290 | version "9.0.7" 1291 | resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-9.0.7.tgz#5fe5c1d43e01c458ed4838687901c6c520fe452c" 1292 | integrity sha512-2n4REUNiu/AsX2fZOp8Z/wnL8XXi2kXrqmCi9UfaydpXgGLnbwq61m9PjOuzECj6iedHNRCvqAMsDIeDzeLSdw== 1293 | dependencies: 1294 | "@motionone/dom" "^10.15.3" 1295 | hey-listen "^1.0.8" 1296 | tslib "^2.4.0" 1297 | optionalDependencies: 1298 | "@emotion/is-prop-valid" "^0.8.2" 1299 | 1300 | fs.realpath@^1.0.0: 1301 | version "1.0.0" 1302 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 1303 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 1304 | 1305 | fsevents@~2.3.2: 1306 | version "2.3.2" 1307 | resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" 1308 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 1309 | 1310 | function-bind@^1.1.1: 1311 | version "1.1.1" 1312 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" 1313 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 1314 | 1315 | function.prototype.name@^1.1.5: 1316 | version "1.1.5" 1317 | resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" 1318 | integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== 1319 | dependencies: 1320 | call-bind "^1.0.2" 1321 | define-properties "^1.1.3" 1322 | es-abstract "^1.19.0" 1323 | functions-have-names "^1.2.2" 1324 | 1325 | functional-red-black-tree@^1.0.1: 1326 | version "1.0.1" 1327 | resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" 1328 | integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== 1329 | 1330 | functions-have-names@^1.2.2: 1331 | version "1.2.3" 1332 | resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" 1333 | integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== 1334 | 1335 | get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: 1336 | version "1.1.2" 1337 | resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz" 1338 | integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== 1339 | dependencies: 1340 | function-bind "^1.1.1" 1341 | has "^1.0.3" 1342 | has-symbols "^1.0.3" 1343 | 1344 | get-symbol-description@^1.0.0: 1345 | version "1.0.0" 1346 | resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" 1347 | integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== 1348 | dependencies: 1349 | call-bind "^1.0.2" 1350 | get-intrinsic "^1.1.1" 1351 | 1352 | getpass@^0.1.1: 1353 | version "0.1.7" 1354 | resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" 1355 | integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== 1356 | dependencies: 1357 | assert-plus "^1.0.0" 1358 | 1359 | glob-parent@^5.1.2, glob-parent@~5.1.2: 1360 | version "5.1.2" 1361 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" 1362 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 1363 | dependencies: 1364 | is-glob "^4.0.1" 1365 | 1366 | glob-parent@^6.0.1, glob-parent@^6.0.2: 1367 | version "6.0.2" 1368 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" 1369 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 1370 | dependencies: 1371 | is-glob "^4.0.3" 1372 | 1373 | glob@7.1.7: 1374 | version "7.1.7" 1375 | resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" 1376 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== 1377 | dependencies: 1378 | fs.realpath "^1.0.0" 1379 | inflight "^1.0.4" 1380 | inherits "2" 1381 | minimatch "^3.0.4" 1382 | once "^1.3.0" 1383 | path-is-absolute "^1.0.0" 1384 | 1385 | glob@^7.1.3, glob@^7.2.0: 1386 | version "7.2.3" 1387 | resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" 1388 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 1389 | dependencies: 1390 | fs.realpath "^1.0.0" 1391 | inflight "^1.0.4" 1392 | inherits "2" 1393 | minimatch "^3.1.1" 1394 | once "^1.3.0" 1395 | path-is-absolute "^1.0.0" 1396 | 1397 | globals@^13.15.0: 1398 | version "13.16.0" 1399 | resolved "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz" 1400 | integrity sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q== 1401 | dependencies: 1402 | type-fest "^0.20.2" 1403 | 1404 | globby@^11.1.0: 1405 | version "11.1.0" 1406 | resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" 1407 | integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== 1408 | dependencies: 1409 | array-union "^2.1.0" 1410 | dir-glob "^3.0.1" 1411 | fast-glob "^3.2.9" 1412 | ignore "^5.2.0" 1413 | merge2 "^1.4.1" 1414 | slash "^3.0.0" 1415 | 1416 | har-schema@^2.0.0: 1417 | version "2.0.0" 1418 | resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" 1419 | integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== 1420 | 1421 | har-validator@~5.1.3: 1422 | version "5.1.5" 1423 | resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" 1424 | integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== 1425 | dependencies: 1426 | ajv "^6.12.3" 1427 | har-schema "^2.0.0" 1428 | 1429 | has-bigints@^1.0.1, has-bigints@^1.0.2: 1430 | version "1.0.2" 1431 | resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" 1432 | integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== 1433 | 1434 | has-flag@^4.0.0: 1435 | version "4.0.0" 1436 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" 1437 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 1438 | 1439 | has-property-descriptors@^1.0.0: 1440 | version "1.0.0" 1441 | resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" 1442 | integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== 1443 | dependencies: 1444 | get-intrinsic "^1.1.1" 1445 | 1446 | has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: 1447 | version "1.0.3" 1448 | resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" 1449 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 1450 | 1451 | has-tostringtag@^1.0.0: 1452 | version "1.0.0" 1453 | resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" 1454 | integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== 1455 | dependencies: 1456 | has-symbols "^1.0.2" 1457 | 1458 | has@^1.0.3: 1459 | version "1.0.3" 1460 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" 1461 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 1462 | dependencies: 1463 | function-bind "^1.1.1" 1464 | 1465 | hey-listen@^1.0.8: 1466 | version "1.0.8" 1467 | resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" 1468 | integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== 1469 | 1470 | html-encoding-sniffer@^1.0.2: 1471 | version "1.0.2" 1472 | resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz" 1473 | integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== 1474 | dependencies: 1475 | whatwg-encoding "^1.0.1" 1476 | 1477 | html-entities@^2.3.3: 1478 | version "2.3.3" 1479 | resolved "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz" 1480 | integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== 1481 | 1482 | html-to-mrkdwn@^3.0.0: 1483 | version "3.0.0" 1484 | resolved "https://registry.npmjs.org/html-to-mrkdwn/-/html-to-mrkdwn-3.0.0.tgz" 1485 | integrity sha512-UwbXoiKIb959O01POLuHs8kkv/xXbMKyAvB7+RaxN1bfScB6UkGfEdegb0Dfmbx8valRt2FCjOIbHJH14SOx9w== 1486 | dependencies: 1487 | jsdom "^11.6.2" 1488 | turndown "^4.0.0-rc.3" 1489 | turndown-plugin-gfm "1.0.1" 1490 | 1491 | http-signature@~1.2.0: 1492 | version "1.2.0" 1493 | resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" 1494 | integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== 1495 | dependencies: 1496 | assert-plus "^1.0.0" 1497 | jsprim "^1.2.2" 1498 | sshpk "^1.7.0" 1499 | 1500 | iconv-lite@0.4.24: 1501 | version "0.4.24" 1502 | resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" 1503 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 1504 | dependencies: 1505 | safer-buffer ">= 2.1.2 < 3" 1506 | 1507 | ignore@^5.2.0: 1508 | version "5.2.0" 1509 | resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" 1510 | integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== 1511 | 1512 | import-fresh@^3.0.0, import-fresh@^3.2.1: 1513 | version "3.3.0" 1514 | resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" 1515 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 1516 | dependencies: 1517 | parent-module "^1.0.0" 1518 | resolve-from "^4.0.0" 1519 | 1520 | imurmurhash@^0.1.4: 1521 | version "0.1.4" 1522 | resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" 1523 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 1524 | 1525 | inflight@^1.0.4: 1526 | version "1.0.6" 1527 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 1528 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 1529 | dependencies: 1530 | once "^1.3.0" 1531 | wrappy "1" 1532 | 1533 | inherits@2: 1534 | version "2.0.4" 1535 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 1536 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 1537 | 1538 | internal-slot@^1.0.3: 1539 | version "1.0.3" 1540 | resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" 1541 | integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== 1542 | dependencies: 1543 | get-intrinsic "^1.1.0" 1544 | has "^1.0.3" 1545 | side-channel "^1.0.4" 1546 | 1547 | is-bigint@^1.0.1: 1548 | version "1.0.4" 1549 | resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" 1550 | integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== 1551 | dependencies: 1552 | has-bigints "^1.0.1" 1553 | 1554 | is-binary-path@~2.1.0: 1555 | version "2.1.0" 1556 | resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" 1557 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 1558 | dependencies: 1559 | binary-extensions "^2.0.0" 1560 | 1561 | is-boolean-object@^1.1.0: 1562 | version "1.1.2" 1563 | resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" 1564 | integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== 1565 | dependencies: 1566 | call-bind "^1.0.2" 1567 | has-tostringtag "^1.0.0" 1568 | 1569 | is-callable@^1.1.4, is-callable@^1.2.4: 1570 | version "1.2.4" 1571 | resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz" 1572 | integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== 1573 | 1574 | is-core-module@^2.8.1, is-core-module@^2.9.0: 1575 | version "2.9.0" 1576 | resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz" 1577 | integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== 1578 | dependencies: 1579 | has "^1.0.3" 1580 | 1581 | is-date-object@^1.0.1: 1582 | version "1.0.5" 1583 | resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" 1584 | integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== 1585 | dependencies: 1586 | has-tostringtag "^1.0.0" 1587 | 1588 | is-extglob@^2.1.1: 1589 | version "2.1.1" 1590 | resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" 1591 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 1592 | 1593 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: 1594 | version "4.0.3" 1595 | resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" 1596 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 1597 | dependencies: 1598 | is-extglob "^2.1.1" 1599 | 1600 | is-negative-zero@^2.0.2: 1601 | version "2.0.2" 1602 | resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" 1603 | integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== 1604 | 1605 | is-number-object@^1.0.4: 1606 | version "1.0.7" 1607 | resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" 1608 | integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== 1609 | dependencies: 1610 | has-tostringtag "^1.0.0" 1611 | 1612 | is-number@^7.0.0: 1613 | version "7.0.0" 1614 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 1615 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 1616 | 1617 | is-regex@^1.1.4: 1618 | version "1.1.4" 1619 | resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" 1620 | integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== 1621 | dependencies: 1622 | call-bind "^1.0.2" 1623 | has-tostringtag "^1.0.0" 1624 | 1625 | is-shared-array-buffer@^1.0.2: 1626 | version "1.0.2" 1627 | resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" 1628 | integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== 1629 | dependencies: 1630 | call-bind "^1.0.2" 1631 | 1632 | is-string@^1.0.5, is-string@^1.0.7: 1633 | version "1.0.7" 1634 | resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" 1635 | integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== 1636 | dependencies: 1637 | has-tostringtag "^1.0.0" 1638 | 1639 | is-symbol@^1.0.2, is-symbol@^1.0.3: 1640 | version "1.0.4" 1641 | resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" 1642 | integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== 1643 | dependencies: 1644 | has-symbols "^1.0.2" 1645 | 1646 | is-typedarray@~1.0.0: 1647 | version "1.0.0" 1648 | resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" 1649 | integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== 1650 | 1651 | is-weakref@^1.0.2: 1652 | version "1.0.2" 1653 | resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" 1654 | integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== 1655 | dependencies: 1656 | call-bind "^1.0.2" 1657 | 1658 | isexe@^2.0.0: 1659 | version "2.0.0" 1660 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" 1661 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 1662 | 1663 | isomorphic-fetch@^3.0.0: 1664 | version "3.0.0" 1665 | resolved "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz" 1666 | integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== 1667 | dependencies: 1668 | node-fetch "^2.6.1" 1669 | whatwg-fetch "^3.4.1" 1670 | 1671 | isstream@~0.1.2: 1672 | version "0.1.2" 1673 | resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" 1674 | integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== 1675 | 1676 | "js-tokens@^3.0.0 || ^4.0.0": 1677 | version "4.0.0" 1678 | resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" 1679 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 1680 | 1681 | js-yaml@^4.1.0: 1682 | version "4.1.0" 1683 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" 1684 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 1685 | dependencies: 1686 | argparse "^2.0.1" 1687 | 1688 | jsbn@~0.1.0: 1689 | version "0.1.1" 1690 | resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" 1691 | integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== 1692 | 1693 | jsdom@^11.6.2, jsdom@^11.9.0: 1694 | version "11.12.0" 1695 | resolved "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz" 1696 | integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== 1697 | dependencies: 1698 | abab "^2.0.0" 1699 | acorn "^5.5.3" 1700 | acorn-globals "^4.1.0" 1701 | array-equal "^1.0.0" 1702 | cssom ">= 0.3.2 < 0.4.0" 1703 | cssstyle "^1.0.0" 1704 | data-urls "^1.0.0" 1705 | domexception "^1.0.1" 1706 | escodegen "^1.9.1" 1707 | html-encoding-sniffer "^1.0.2" 1708 | left-pad "^1.3.0" 1709 | nwsapi "^2.0.7" 1710 | parse5 "4.0.0" 1711 | pn "^1.1.0" 1712 | request "^2.87.0" 1713 | request-promise-native "^1.0.5" 1714 | sax "^1.2.4" 1715 | symbol-tree "^3.2.2" 1716 | tough-cookie "^2.3.4" 1717 | w3c-hr-time "^1.0.1" 1718 | webidl-conversions "^4.0.2" 1719 | whatwg-encoding "^1.0.3" 1720 | whatwg-mimetype "^2.1.0" 1721 | whatwg-url "^6.4.1" 1722 | ws "^5.2.0" 1723 | xml-name-validator "^3.0.0" 1724 | 1725 | json-schema-traverse@^0.4.1: 1726 | version "0.4.1" 1727 | resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" 1728 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 1729 | 1730 | json-schema@0.4.0: 1731 | version "0.4.0" 1732 | resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" 1733 | integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== 1734 | 1735 | json-stable-stringify-without-jsonify@^1.0.1: 1736 | version "1.0.1" 1737 | resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" 1738 | integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== 1739 | 1740 | json-stringify-safe@~5.0.1: 1741 | version "5.0.1" 1742 | resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" 1743 | integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== 1744 | 1745 | json5@^1.0.1: 1746 | version "1.0.1" 1747 | resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" 1748 | integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== 1749 | dependencies: 1750 | minimist "^1.2.0" 1751 | 1752 | jsprim@^1.2.2: 1753 | version "1.4.2" 1754 | resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" 1755 | integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== 1756 | dependencies: 1757 | assert-plus "1.0.0" 1758 | extsprintf "1.3.0" 1759 | json-schema "0.4.0" 1760 | verror "1.10.0" 1761 | 1762 | "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.1: 1763 | version "3.3.2" 1764 | resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.2.tgz" 1765 | integrity sha512-4ZCADZHRkno244xlNnn4AOG6sRQ7iBZ5BbgZ4vW4y5IZw7cVUD1PPeblm1xx/nfmMxPdt/LHsXZW8z/j58+l9Q== 1766 | dependencies: 1767 | array-includes "^3.1.5" 1768 | object.assign "^4.1.2" 1769 | 1770 | language-subtag-registry@~0.3.2: 1771 | version "0.3.22" 1772 | resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" 1773 | integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== 1774 | 1775 | language-tags@^1.0.5: 1776 | version "1.0.5" 1777 | resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz" 1778 | integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== 1779 | dependencies: 1780 | language-subtag-registry "~0.3.2" 1781 | 1782 | left-pad@^1.3.0: 1783 | version "1.3.0" 1784 | resolved "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz" 1785 | integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== 1786 | 1787 | levn@^0.4.1: 1788 | version "0.4.1" 1789 | resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" 1790 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 1791 | dependencies: 1792 | prelude-ls "^1.2.1" 1793 | type-check "~0.4.0" 1794 | 1795 | levn@~0.3.0: 1796 | version "0.3.0" 1797 | resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" 1798 | integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== 1799 | dependencies: 1800 | prelude-ls "~1.1.2" 1801 | type-check "~0.3.2" 1802 | 1803 | lilconfig@^2.0.5: 1804 | version "2.0.6" 1805 | resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz" 1806 | integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== 1807 | 1808 | locate-path@^2.0.0: 1809 | version "2.0.0" 1810 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" 1811 | integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== 1812 | dependencies: 1813 | p-locate "^2.0.0" 1814 | path-exists "^3.0.0" 1815 | 1816 | lodash.merge@^4.6.2: 1817 | version "4.6.2" 1818 | resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" 1819 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 1820 | 1821 | lodash.sortby@^4.7.0: 1822 | version "4.7.0" 1823 | resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz" 1824 | integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== 1825 | 1826 | lodash@^4.17.19: 1827 | version "4.17.21" 1828 | resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" 1829 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 1830 | 1831 | loose-envify@^1.1.0, loose-envify@^1.4.0: 1832 | version "1.4.0" 1833 | resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" 1834 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 1835 | dependencies: 1836 | js-tokens "^3.0.0 || ^4.0.0" 1837 | 1838 | lru-cache@^6.0.0: 1839 | version "6.0.0" 1840 | resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" 1841 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1842 | dependencies: 1843 | yallist "^4.0.0" 1844 | 1845 | lucide-react@^0.115.0: 1846 | version "0.115.0" 1847 | resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.115.0.tgz#793396ba54bcab6872c3e8933c3f2e0f6ff2ce9a" 1848 | integrity sha512-VGL7jBKN6pEXi6peXoyn9t9O7olvinaAonnoe+iFi/F2q7/yQzAFM5KR1OY15u9PlrB3scI9HvcTFoOrIjUaVQ== 1849 | 1850 | merge2@^1.3.0, merge2@^1.4.1: 1851 | version "1.4.1" 1852 | resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" 1853 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 1854 | 1855 | micromatch@^4.0.4: 1856 | version "4.0.5" 1857 | resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" 1858 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 1859 | dependencies: 1860 | braces "^3.0.2" 1861 | picomatch "^2.3.1" 1862 | 1863 | mime-db@1.52.0: 1864 | version "1.52.0" 1865 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" 1866 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 1867 | 1868 | mime-types@^2.1.12, mime-types@~2.1.19: 1869 | version "2.1.35" 1870 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" 1871 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 1872 | dependencies: 1873 | mime-db "1.52.0" 1874 | 1875 | mini-svg-data-uri@^1.2.3: 1876 | version "1.4.4" 1877 | resolved "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz" 1878 | integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg== 1879 | 1880 | minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: 1881 | version "3.1.2" 1882 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 1883 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1884 | dependencies: 1885 | brace-expansion "^1.1.7" 1886 | 1887 | minimist@^1.2.0, minimist@^1.2.6: 1888 | version "1.2.6" 1889 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" 1890 | integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== 1891 | 1892 | ms@2.0.0: 1893 | version "2.0.0" 1894 | resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" 1895 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== 1896 | 1897 | ms@2.1.2: 1898 | version "2.1.2" 1899 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" 1900 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1901 | 1902 | ms@^2.1.1: 1903 | version "2.1.3" 1904 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" 1905 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1906 | 1907 | nanoid@^3.3.4: 1908 | version "3.3.4" 1909 | resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz" 1910 | integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== 1911 | 1912 | natural-compare@^1.4.0: 1913 | version "1.4.0" 1914 | resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" 1915 | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== 1916 | 1917 | next@^13.1.6: 1918 | version "13.1.6" 1919 | resolved "https://registry.yarnpkg.com/next/-/next-13.1.6.tgz#054babe20b601f21f682f197063c9b0b32f1a27c" 1920 | integrity sha512-hHlbhKPj9pW+Cymvfzc15lvhaOZ54l+8sXDXJWm3OBNBzgrVj6hwGPmqqsXg40xO1Leq+kXpllzRPuncpC0Phw== 1921 | dependencies: 1922 | "@next/env" "13.1.6" 1923 | "@swc/helpers" "0.4.14" 1924 | caniuse-lite "^1.0.30001406" 1925 | postcss "8.4.14" 1926 | styled-jsx "5.1.1" 1927 | optionalDependencies: 1928 | "@next/swc-android-arm-eabi" "13.1.6" 1929 | "@next/swc-android-arm64" "13.1.6" 1930 | "@next/swc-darwin-arm64" "13.1.6" 1931 | "@next/swc-darwin-x64" "13.1.6" 1932 | "@next/swc-freebsd-x64" "13.1.6" 1933 | "@next/swc-linux-arm-gnueabihf" "13.1.6" 1934 | "@next/swc-linux-arm64-gnu" "13.1.6" 1935 | "@next/swc-linux-arm64-musl" "13.1.6" 1936 | "@next/swc-linux-x64-gnu" "13.1.6" 1937 | "@next/swc-linux-x64-musl" "13.1.6" 1938 | "@next/swc-win32-arm64-msvc" "13.1.6" 1939 | "@next/swc-win32-ia32-msvc" "13.1.6" 1940 | "@next/swc-win32-x64-msvc" "13.1.6" 1941 | 1942 | node-fetch@^2.6.1: 1943 | version "2.6.7" 1944 | resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" 1945 | integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== 1946 | dependencies: 1947 | whatwg-url "^5.0.0" 1948 | 1949 | node-releases@^2.0.6: 1950 | version "2.0.6" 1951 | resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz" 1952 | integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== 1953 | 1954 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1955 | version "3.0.0" 1956 | resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" 1957 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1958 | 1959 | normalize-range@^0.1.2: 1960 | version "0.1.2" 1961 | resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" 1962 | integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== 1963 | 1964 | nwsapi@^2.0.7: 1965 | version "2.2.1" 1966 | resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.1.tgz" 1967 | integrity sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg== 1968 | 1969 | oauth-sign@~0.9.0: 1970 | version "0.9.0" 1971 | resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" 1972 | integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== 1973 | 1974 | object-assign@^4.1.1: 1975 | version "4.1.1" 1976 | resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" 1977 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 1978 | 1979 | object-hash@^3.0.0: 1980 | version "3.0.0" 1981 | resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" 1982 | integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== 1983 | 1984 | object-inspect@^1.12.0, object-inspect@^1.9.0: 1985 | version "1.12.2" 1986 | resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" 1987 | integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== 1988 | 1989 | object-keys@^1.1.1: 1990 | version "1.1.1" 1991 | resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" 1992 | integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== 1993 | 1994 | object.assign@^4.1.2: 1995 | version "4.1.2" 1996 | resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz" 1997 | integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== 1998 | dependencies: 1999 | call-bind "^1.0.0" 2000 | define-properties "^1.1.3" 2001 | has-symbols "^1.0.1" 2002 | object-keys "^1.1.1" 2003 | 2004 | object.entries@^1.1.5: 2005 | version "1.1.5" 2006 | resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz" 2007 | integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== 2008 | dependencies: 2009 | call-bind "^1.0.2" 2010 | define-properties "^1.1.3" 2011 | es-abstract "^1.19.1" 2012 | 2013 | object.fromentries@^2.0.5: 2014 | version "2.0.5" 2015 | resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz" 2016 | integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== 2017 | dependencies: 2018 | call-bind "^1.0.2" 2019 | define-properties "^1.1.3" 2020 | es-abstract "^1.19.1" 2021 | 2022 | object.hasown@^1.1.1: 2023 | version "1.1.1" 2024 | resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz" 2025 | integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A== 2026 | dependencies: 2027 | define-properties "^1.1.4" 2028 | es-abstract "^1.19.5" 2029 | 2030 | object.values@^1.1.5: 2031 | version "1.1.5" 2032 | resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz" 2033 | integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== 2034 | dependencies: 2035 | call-bind "^1.0.2" 2036 | define-properties "^1.1.3" 2037 | es-abstract "^1.19.1" 2038 | 2039 | once@^1.3.0: 2040 | version "1.4.0" 2041 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 2042 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 2043 | dependencies: 2044 | wrappy "1" 2045 | 2046 | optionator@^0.8.1: 2047 | version "0.8.3" 2048 | resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" 2049 | integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== 2050 | dependencies: 2051 | deep-is "~0.1.3" 2052 | fast-levenshtein "~2.0.6" 2053 | levn "~0.3.0" 2054 | prelude-ls "~1.1.2" 2055 | type-check "~0.3.2" 2056 | word-wrap "~1.2.3" 2057 | 2058 | optionator@^0.9.1: 2059 | version "0.9.1" 2060 | resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" 2061 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 2062 | dependencies: 2063 | deep-is "^0.1.3" 2064 | fast-levenshtein "^2.0.6" 2065 | levn "^0.4.1" 2066 | prelude-ls "^1.2.1" 2067 | type-check "^0.4.0" 2068 | word-wrap "^1.2.3" 2069 | 2070 | p-limit@^1.1.0: 2071 | version "1.3.0" 2072 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" 2073 | integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== 2074 | dependencies: 2075 | p-try "^1.0.0" 2076 | 2077 | p-locate@^2.0.0: 2078 | version "2.0.0" 2079 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" 2080 | integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== 2081 | dependencies: 2082 | p-limit "^1.1.0" 2083 | 2084 | p-retry@^5.1.1: 2085 | version "5.1.1" 2086 | resolved "https://registry.npmjs.org/p-retry/-/p-retry-5.1.1.tgz" 2087 | integrity sha512-i69WkEU5ZAL8mrmdmVviWwU+DN+IUF8f4sSJThoJ3z5A7Nn5iuO5ROX3Boye0u+uYQLOSfgFl7SuFZCjlAVbQA== 2088 | dependencies: 2089 | "@types/retry" "0.12.1" 2090 | retry "^0.13.1" 2091 | 2092 | p-try@^1.0.0: 2093 | version "1.0.0" 2094 | resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" 2095 | integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== 2096 | 2097 | parent-module@^1.0.0: 2098 | version "1.0.1" 2099 | resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" 2100 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 2101 | dependencies: 2102 | callsites "^3.0.0" 2103 | 2104 | parse5@4.0.0: 2105 | version "4.0.0" 2106 | resolved "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz" 2107 | integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== 2108 | 2109 | path-exists@^3.0.0: 2110 | version "3.0.0" 2111 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" 2112 | integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== 2113 | 2114 | path-is-absolute@^1.0.0: 2115 | version "1.0.1" 2116 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 2117 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 2118 | 2119 | path-key@^3.1.0: 2120 | version "3.1.1" 2121 | resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" 2122 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 2123 | 2124 | path-parse@^1.0.7: 2125 | version "1.0.7" 2126 | resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" 2127 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 2128 | 2129 | path-type@^4.0.0: 2130 | version "4.0.0" 2131 | resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" 2132 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 2133 | 2134 | performance-now@^2.1.0: 2135 | version "2.1.0" 2136 | resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" 2137 | integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== 2138 | 2139 | picocolors@^1.0.0: 2140 | version "1.0.0" 2141 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 2142 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 2143 | 2144 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: 2145 | version "2.3.1" 2146 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" 2147 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 2148 | 2149 | pify@^2.3.0: 2150 | version "2.3.0" 2151 | resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" 2152 | integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== 2153 | 2154 | pn@^1.1.0: 2155 | version "1.1.0" 2156 | resolved "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz" 2157 | integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== 2158 | 2159 | postcss-import@^14.1.0: 2160 | version "14.1.0" 2161 | resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz" 2162 | integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== 2163 | dependencies: 2164 | postcss-value-parser "^4.0.0" 2165 | read-cache "^1.0.0" 2166 | resolve "^1.1.7" 2167 | 2168 | postcss-js@^4.0.0: 2169 | version "4.0.0" 2170 | resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz" 2171 | integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ== 2172 | dependencies: 2173 | camelcase-css "^2.0.1" 2174 | 2175 | postcss-load-config@^3.1.4: 2176 | version "3.1.4" 2177 | resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz" 2178 | integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== 2179 | dependencies: 2180 | lilconfig "^2.0.5" 2181 | yaml "^1.10.2" 2182 | 2183 | postcss-nested@5.0.6: 2184 | version "5.0.6" 2185 | resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz" 2186 | integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA== 2187 | dependencies: 2188 | postcss-selector-parser "^6.0.6" 2189 | 2190 | postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.6: 2191 | version "6.0.10" 2192 | resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz" 2193 | integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== 2194 | dependencies: 2195 | cssesc "^3.0.0" 2196 | util-deprecate "^1.0.2" 2197 | 2198 | postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0: 2199 | version "4.2.0" 2200 | resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" 2201 | integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== 2202 | 2203 | postcss@8.4.14, postcss@^8.4.14: 2204 | version "8.4.14" 2205 | resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz" 2206 | integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== 2207 | dependencies: 2208 | nanoid "^3.3.4" 2209 | picocolors "^1.0.0" 2210 | source-map-js "^1.0.2" 2211 | 2212 | prelude-ls@^1.2.1: 2213 | version "1.2.1" 2214 | resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" 2215 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 2216 | 2217 | prelude-ls@~1.1.2: 2218 | version "1.1.2" 2219 | resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" 2220 | integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== 2221 | 2222 | prop-types@^15.8.1: 2223 | version "15.8.1" 2224 | resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" 2225 | integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== 2226 | dependencies: 2227 | loose-envify "^1.4.0" 2228 | object-assign "^4.1.1" 2229 | react-is "^16.13.1" 2230 | 2231 | psl@^1.1.28: 2232 | version "1.9.0" 2233 | resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz" 2234 | integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== 2235 | 2236 | punycode@^2.1.0, punycode@^2.1.1: 2237 | version "2.1.1" 2238 | resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" 2239 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 2240 | 2241 | qs@~6.5.2: 2242 | version "6.5.3" 2243 | resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" 2244 | integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== 2245 | 2246 | queue-microtask@^1.2.2: 2247 | version "1.2.3" 2248 | resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" 2249 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 2250 | 2251 | quick-lru@^5.1.1: 2252 | version "5.1.1" 2253 | resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" 2254 | integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== 2255 | 2256 | react-dom@18.2.0: 2257 | version "18.2.0" 2258 | resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" 2259 | integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== 2260 | dependencies: 2261 | loose-envify "^1.1.0" 2262 | scheduler "^0.23.0" 2263 | 2264 | react-is@^16.13.1: 2265 | version "16.13.1" 2266 | resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" 2267 | integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== 2268 | 2269 | react-wrap-balancer@^0.4.0: 2270 | version "0.4.0" 2271 | resolved "https://registry.yarnpkg.com/react-wrap-balancer/-/react-wrap-balancer-0.4.0.tgz#1ee2bcee25e2c7524cf69297cb355b79cc5daf08" 2272 | integrity sha512-MUsROihHd7bFHCo9kCOifKDYBEZPgKTyGvfa8RcwRQKtT2cL7Um9Cc8A7GvuT8t3np7LAGsEkzdEyJdKrr5lVQ== 2273 | 2274 | react@18.2.0: 2275 | version "18.2.0" 2276 | resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" 2277 | integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== 2278 | dependencies: 2279 | loose-envify "^1.1.0" 2280 | 2281 | read-cache@^1.0.0: 2282 | version "1.0.0" 2283 | resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" 2284 | integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== 2285 | dependencies: 2286 | pify "^2.3.0" 2287 | 2288 | readdirp@~3.6.0: 2289 | version "3.6.0" 2290 | resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" 2291 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 2292 | dependencies: 2293 | picomatch "^2.2.1" 2294 | 2295 | regenerator-runtime@^0.13.4: 2296 | version "0.13.9" 2297 | resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" 2298 | integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== 2299 | 2300 | regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: 2301 | version "1.4.3" 2302 | resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" 2303 | integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== 2304 | dependencies: 2305 | call-bind "^1.0.2" 2306 | define-properties "^1.1.3" 2307 | functions-have-names "^1.2.2" 2308 | 2309 | regexpp@^3.2.0: 2310 | version "3.2.0" 2311 | resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" 2312 | integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== 2313 | 2314 | request-promise-core@1.1.4: 2315 | version "1.1.4" 2316 | resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz" 2317 | integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== 2318 | dependencies: 2319 | lodash "^4.17.19" 2320 | 2321 | request-promise-native@^1.0.5: 2322 | version "1.0.9" 2323 | resolved "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz" 2324 | integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== 2325 | dependencies: 2326 | request-promise-core "1.1.4" 2327 | stealthy-require "^1.1.1" 2328 | tough-cookie "^2.3.3" 2329 | 2330 | request@^2.87.0: 2331 | version "2.88.2" 2332 | resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" 2333 | integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== 2334 | dependencies: 2335 | aws-sign2 "~0.7.0" 2336 | aws4 "^1.8.0" 2337 | caseless "~0.12.0" 2338 | combined-stream "~1.0.6" 2339 | extend "~3.0.2" 2340 | forever-agent "~0.6.1" 2341 | form-data "~2.3.2" 2342 | har-validator "~5.1.3" 2343 | http-signature "~1.2.0" 2344 | is-typedarray "~1.0.0" 2345 | isstream "~0.1.2" 2346 | json-stringify-safe "~5.0.1" 2347 | mime-types "~2.1.19" 2348 | oauth-sign "~0.9.0" 2349 | performance-now "^2.1.0" 2350 | qs "~6.5.2" 2351 | safe-buffer "^5.1.2" 2352 | tough-cookie "~2.5.0" 2353 | tunnel-agent "^0.6.0" 2354 | uuid "^3.3.2" 2355 | 2356 | resolve-from@^4.0.0: 2357 | version "4.0.0" 2358 | resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" 2359 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 2360 | 2361 | resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1: 2362 | version "1.22.1" 2363 | resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" 2364 | integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== 2365 | dependencies: 2366 | is-core-module "^2.9.0" 2367 | path-parse "^1.0.7" 2368 | supports-preserve-symlinks-flag "^1.0.0" 2369 | 2370 | resolve@^2.0.0-next.3: 2371 | version "2.0.0-next.4" 2372 | resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz" 2373 | integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== 2374 | dependencies: 2375 | is-core-module "^2.9.0" 2376 | path-parse "^1.0.7" 2377 | supports-preserve-symlinks-flag "^1.0.0" 2378 | 2379 | retry@^0.13.1: 2380 | version "0.13.1" 2381 | resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" 2382 | integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== 2383 | 2384 | reusify@^1.0.4: 2385 | version "1.0.4" 2386 | resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" 2387 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 2388 | 2389 | rimraf@^3.0.2: 2390 | version "3.0.2" 2391 | resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" 2392 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 2393 | dependencies: 2394 | glob "^7.1.3" 2395 | 2396 | run-parallel@^1.1.9: 2397 | version "1.2.0" 2398 | resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" 2399 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 2400 | dependencies: 2401 | queue-microtask "^1.2.2" 2402 | 2403 | safe-buffer@^5.0.1, safe-buffer@^5.1.2: 2404 | version "5.2.1" 2405 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" 2406 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 2407 | 2408 | "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: 2409 | version "2.1.2" 2410 | resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" 2411 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 2412 | 2413 | satori@0.2.2: 2414 | version "0.2.2" 2415 | resolved "https://registry.yarnpkg.com/satori/-/satori-0.2.2.tgz#5a2661052a91aa75c55fdd4adbe686f0fe737877" 2416 | integrity sha512-/9A9cMdrkSqFPavObgQAn9737hMnBeKSgf/L5zWm2a6UzwMR2jl5xjrH4LURlJLEXdx/ijOjH0/Q6PUn2Fgpdg== 2417 | dependencies: 2418 | "@shuding/opentype.js" "1.4.0-beta.0" 2419 | css-background-parser "^0.1.0" 2420 | css-box-shadow "1.0.0-3" 2421 | css-to-react-native "^3.0.0" 2422 | emoji-regex "^10.2.1" 2423 | postcss-value-parser "^4.2.0" 2424 | yoga-wasm-web "^0.3.0" 2425 | 2426 | sax@^1.2.4: 2427 | version "1.2.4" 2428 | resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" 2429 | integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== 2430 | 2431 | scheduler@^0.23.0: 2432 | version "0.23.0" 2433 | resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" 2434 | integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== 2435 | dependencies: 2436 | loose-envify "^1.1.0" 2437 | 2438 | semver@^6.3.0: 2439 | version "6.3.0" 2440 | resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" 2441 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 2442 | 2443 | semver@^7.3.7: 2444 | version "7.3.7" 2445 | resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" 2446 | integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== 2447 | dependencies: 2448 | lru-cache "^6.0.0" 2449 | 2450 | shebang-command@^2.0.0: 2451 | version "2.0.0" 2452 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" 2453 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 2454 | dependencies: 2455 | shebang-regex "^3.0.0" 2456 | 2457 | shebang-regex@^3.0.0: 2458 | version "3.0.0" 2459 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" 2460 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 2461 | 2462 | side-channel@^1.0.4: 2463 | version "1.0.4" 2464 | resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" 2465 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== 2466 | dependencies: 2467 | call-bind "^1.0.0" 2468 | get-intrinsic "^1.0.2" 2469 | object-inspect "^1.9.0" 2470 | 2471 | slash@^3.0.0: 2472 | version "3.0.0" 2473 | resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" 2474 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 2475 | 2476 | source-map-js@^1.0.2: 2477 | version "1.0.2" 2478 | resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" 2479 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== 2480 | 2481 | source-map@~0.6.1: 2482 | version "0.6.1" 2483 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" 2484 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 2485 | 2486 | sshpk@^1.7.0: 2487 | version "1.17.0" 2488 | resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz" 2489 | integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== 2490 | dependencies: 2491 | asn1 "~0.2.3" 2492 | assert-plus "^1.0.0" 2493 | bcrypt-pbkdf "^1.0.0" 2494 | dashdash "^1.12.0" 2495 | ecc-jsbn "~0.1.1" 2496 | getpass "^0.1.1" 2497 | jsbn "~0.1.0" 2498 | safer-buffer "^2.0.2" 2499 | tweetnacl "~0.14.0" 2500 | 2501 | stealthy-require@^1.1.1: 2502 | version "1.1.1" 2503 | resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz" 2504 | integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== 2505 | 2506 | string.prototype.codepointat@^0.2.1: 2507 | version "0.2.1" 2508 | resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz#004ad44c8afc727527b108cd462b4d971cd469bc" 2509 | integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg== 2510 | 2511 | string.prototype.matchall@^4.0.7: 2512 | version "4.0.7" 2513 | resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz" 2514 | integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg== 2515 | dependencies: 2516 | call-bind "^1.0.2" 2517 | define-properties "^1.1.3" 2518 | es-abstract "^1.19.1" 2519 | get-intrinsic "^1.1.1" 2520 | has-symbols "^1.0.3" 2521 | internal-slot "^1.0.3" 2522 | regexp.prototype.flags "^1.4.1" 2523 | side-channel "^1.0.4" 2524 | 2525 | string.prototype.trimend@^1.0.5: 2526 | version "1.0.5" 2527 | resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz" 2528 | integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== 2529 | dependencies: 2530 | call-bind "^1.0.2" 2531 | define-properties "^1.1.4" 2532 | es-abstract "^1.19.5" 2533 | 2534 | string.prototype.trimstart@^1.0.5: 2535 | version "1.0.5" 2536 | resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz" 2537 | integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== 2538 | dependencies: 2539 | call-bind "^1.0.2" 2540 | define-properties "^1.1.4" 2541 | es-abstract "^1.19.5" 2542 | 2543 | strip-ansi@^6.0.1: 2544 | version "6.0.1" 2545 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" 2546 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 2547 | dependencies: 2548 | ansi-regex "^5.0.1" 2549 | 2550 | strip-bom@^3.0.0: 2551 | version "3.0.0" 2552 | resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" 2553 | integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== 2554 | 2555 | strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: 2556 | version "3.1.1" 2557 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" 2558 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 2559 | 2560 | styled-jsx@5.1.1: 2561 | version "5.1.1" 2562 | resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f" 2563 | integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== 2564 | dependencies: 2565 | client-only "0.0.1" 2566 | 2567 | supports-color@^7.1.0: 2568 | version "7.2.0" 2569 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" 2570 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 2571 | dependencies: 2572 | has-flag "^4.0.0" 2573 | 2574 | supports-preserve-symlinks-flag@^1.0.0: 2575 | version "1.0.0" 2576 | resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" 2577 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 2578 | 2579 | swr@^1.3.0: 2580 | version "1.3.0" 2581 | resolved "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz" 2582 | integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== 2583 | 2584 | symbol-tree@^3.2.2: 2585 | version "3.2.4" 2586 | resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" 2587 | integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== 2588 | 2589 | tailwindcss@^3.1.6: 2590 | version "3.1.6" 2591 | resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.6.tgz" 2592 | integrity sha512-7skAOY56erZAFQssT1xkpk+kWt2NrO45kORlxFPXUt3CiGsVPhH1smuH5XoDH6sGPXLyBv+zgCKA2HWBsgCytg== 2593 | dependencies: 2594 | arg "^5.0.2" 2595 | chokidar "^3.5.3" 2596 | color-name "^1.1.4" 2597 | detective "^5.2.1" 2598 | didyoumean "^1.2.2" 2599 | dlv "^1.1.3" 2600 | fast-glob "^3.2.11" 2601 | glob-parent "^6.0.2" 2602 | is-glob "^4.0.3" 2603 | lilconfig "^2.0.5" 2604 | normalize-path "^3.0.0" 2605 | object-hash "^3.0.0" 2606 | picocolors "^1.0.0" 2607 | postcss "^8.4.14" 2608 | postcss-import "^14.1.0" 2609 | postcss-js "^4.0.0" 2610 | postcss-load-config "^3.1.4" 2611 | postcss-nested "5.0.6" 2612 | postcss-selector-parser "^6.0.10" 2613 | postcss-value-parser "^4.2.0" 2614 | quick-lru "^5.1.1" 2615 | resolve "^1.22.1" 2616 | 2617 | text-table@^0.2.0: 2618 | version "0.2.0" 2619 | resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" 2620 | integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== 2621 | 2622 | to-regex-range@^5.0.1: 2623 | version "5.0.1" 2624 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 2625 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 2626 | dependencies: 2627 | is-number "^7.0.0" 2628 | 2629 | tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: 2630 | version "2.5.0" 2631 | resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" 2632 | integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== 2633 | dependencies: 2634 | psl "^1.1.28" 2635 | punycode "^2.1.1" 2636 | 2637 | tr46@^1.0.1: 2638 | version "1.0.1" 2639 | resolved "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz" 2640 | integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== 2641 | dependencies: 2642 | punycode "^2.1.0" 2643 | 2644 | tr46@~0.0.3: 2645 | version "0.0.3" 2646 | resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" 2647 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 2648 | 2649 | tsconfig-paths@^3.14.1: 2650 | version "3.14.1" 2651 | resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz" 2652 | integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== 2653 | dependencies: 2654 | "@types/json5" "^0.0.29" 2655 | json5 "^1.0.1" 2656 | minimist "^1.2.6" 2657 | strip-bom "^3.0.0" 2658 | 2659 | tslib@^1.8.1: 2660 | version "1.14.1" 2661 | resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" 2662 | integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== 2663 | 2664 | tslib@^2.3.1, tslib@^2.4.0: 2665 | version "2.5.0" 2666 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" 2667 | integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== 2668 | 2669 | tsutils@^3.21.0: 2670 | version "3.21.0" 2671 | resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" 2672 | integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== 2673 | dependencies: 2674 | tslib "^1.8.1" 2675 | 2676 | tunnel-agent@^0.6.0: 2677 | version "0.6.0" 2678 | resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" 2679 | integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== 2680 | dependencies: 2681 | safe-buffer "^5.0.1" 2682 | 2683 | turndown-plugin-gfm@1.0.1: 2684 | version "1.0.1" 2685 | resolved "https://registry.npmjs.org/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.1.tgz" 2686 | integrity sha512-7x+WNr8Ah/m6ytxGmONuH8VjP1kMxfThSwxrwjGojcuUfzhrLo1AJVSE8llIBZyo2Nu/OaNNWJeJUBvdJPJwKw== 2687 | 2688 | turndown@^4.0.0-rc.3: 2689 | version "4.0.2" 2690 | resolved "https://registry.npmjs.org/turndown/-/turndown-4.0.2.tgz" 2691 | integrity sha512-pqZ6WrHFGnxXC9q2xJ3Qa7EoLAwrojgFRajWZjxTKwbz9vnNnyi8lLjiD5h86UTPOcMlEyHjm6NMhjEDdlc25A== 2692 | dependencies: 2693 | jsdom "^11.9.0" 2694 | 2695 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 2696 | version "0.14.5" 2697 | resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" 2698 | integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== 2699 | 2700 | type-check@^0.4.0, type-check@~0.4.0: 2701 | version "0.4.0" 2702 | resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" 2703 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 2704 | dependencies: 2705 | prelude-ls "^1.2.1" 2706 | 2707 | type-check@~0.3.2: 2708 | version "0.3.2" 2709 | resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" 2710 | integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== 2711 | dependencies: 2712 | prelude-ls "~1.1.2" 2713 | 2714 | type-fest@^0.20.2: 2715 | version "0.20.2" 2716 | resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" 2717 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 2718 | 2719 | typescript@4.7.4: 2720 | version "4.7.4" 2721 | resolved "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz" 2722 | integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== 2723 | 2724 | unbox-primitive@^1.0.2: 2725 | version "1.0.2" 2726 | resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" 2727 | integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== 2728 | dependencies: 2729 | call-bind "^1.0.2" 2730 | has-bigints "^1.0.2" 2731 | has-symbols "^1.0.3" 2732 | which-boxed-primitive "^1.0.2" 2733 | 2734 | update-browserslist-db@^1.0.4: 2735 | version "1.0.5" 2736 | resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz" 2737 | integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== 2738 | dependencies: 2739 | escalade "^3.1.1" 2740 | picocolors "^1.0.0" 2741 | 2742 | uri-js@^4.2.2: 2743 | version "4.4.1" 2744 | resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" 2745 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 2746 | dependencies: 2747 | punycode "^2.1.0" 2748 | 2749 | util-deprecate@^1.0.2: 2750 | version "1.0.2" 2751 | resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" 2752 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 2753 | 2754 | uuid@^3.3.2: 2755 | version "3.4.0" 2756 | resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" 2757 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 2758 | 2759 | v8-compile-cache@^2.0.3: 2760 | version "2.3.0" 2761 | resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" 2762 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 2763 | 2764 | verror@1.10.0: 2765 | version "1.10.0" 2766 | resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" 2767 | integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== 2768 | dependencies: 2769 | assert-plus "^1.0.0" 2770 | core-util-is "1.0.2" 2771 | extsprintf "^1.2.0" 2772 | 2773 | w3c-hr-time@^1.0.1: 2774 | version "1.0.2" 2775 | resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz" 2776 | integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== 2777 | dependencies: 2778 | browser-process-hrtime "^1.0.0" 2779 | 2780 | webidl-conversions@^3.0.0: 2781 | version "3.0.1" 2782 | resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" 2783 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 2784 | 2785 | webidl-conversions@^4.0.2: 2786 | version "4.0.2" 2787 | resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz" 2788 | integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== 2789 | 2790 | whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: 2791 | version "1.0.5" 2792 | resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz" 2793 | integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== 2794 | dependencies: 2795 | iconv-lite "0.4.24" 2796 | 2797 | whatwg-fetch@^3.4.1: 2798 | version "3.6.2" 2799 | resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz" 2800 | integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== 2801 | 2802 | whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: 2803 | version "2.3.0" 2804 | resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz" 2805 | integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== 2806 | 2807 | whatwg-url@^5.0.0: 2808 | version "5.0.0" 2809 | resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" 2810 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 2811 | dependencies: 2812 | tr46 "~0.0.3" 2813 | webidl-conversions "^3.0.0" 2814 | 2815 | whatwg-url@^6.4.1: 2816 | version "6.5.0" 2817 | resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz" 2818 | integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== 2819 | dependencies: 2820 | lodash.sortby "^4.7.0" 2821 | tr46 "^1.0.1" 2822 | webidl-conversions "^4.0.2" 2823 | 2824 | whatwg-url@^7.0.0: 2825 | version "7.1.0" 2826 | resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz" 2827 | integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== 2828 | dependencies: 2829 | lodash.sortby "^4.7.0" 2830 | tr46 "^1.0.1" 2831 | webidl-conversions "^4.0.2" 2832 | 2833 | which-boxed-primitive@^1.0.2: 2834 | version "1.0.2" 2835 | resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" 2836 | integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== 2837 | dependencies: 2838 | is-bigint "^1.0.1" 2839 | is-boolean-object "^1.1.0" 2840 | is-number-object "^1.0.4" 2841 | is-string "^1.0.5" 2842 | is-symbol "^1.0.3" 2843 | 2844 | which@^2.0.1: 2845 | version "2.0.2" 2846 | resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" 2847 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 2848 | dependencies: 2849 | isexe "^2.0.0" 2850 | 2851 | word-wrap@^1.2.3, word-wrap@~1.2.3: 2852 | version "1.2.3" 2853 | resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" 2854 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 2855 | 2856 | wrappy@1: 2857 | version "1.0.2" 2858 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 2859 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 2860 | 2861 | ws@^5.2.0: 2862 | version "5.2.3" 2863 | resolved "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz" 2864 | integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== 2865 | dependencies: 2866 | async-limiter "~1.0.0" 2867 | 2868 | xml-name-validator@^3.0.0: 2869 | version "3.0.0" 2870 | resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz" 2871 | integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== 2872 | 2873 | xtend@^4.0.2: 2874 | version "4.0.2" 2875 | resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" 2876 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 2877 | 2878 | yallist@^4.0.0: 2879 | version "4.0.0" 2880 | resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" 2881 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 2882 | 2883 | yaml@^1.10.2: 2884 | version "1.10.2" 2885 | resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" 2886 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 2887 | 2888 | yoga-wasm-web@0.3.0: 2889 | version "0.3.0" 2890 | resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.3.0.tgz#b14493f35dccda41701524de80ff089fcda0b4ae" 2891 | integrity sha512-rD3L4jyMlO1m+RWU60lNwZQK5zmzglCV5fI1gTRikmpv3YzmNIZQbjyfE6cMNb9Xaly/C1SwemYGbsiOekMvnQ== 2892 | 2893 | yoga-wasm-web@^0.3.0: 2894 | version "0.3.1" 2895 | resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.3.1.tgz#f588ad0f1bc255ce1f89efeaf6b24f3d656e8987" 2896 | integrity sha512-J74OxJtRb5GLW/GH+ibYpb0/0zixk9qp0EOIuKKkavk0w0cMHIQ76YPkca4cRBUW+d+r+GFSM9Q3a+HXQd4b8g== 2897 | --------------------------------------------------------------------------------