├── .env.example ├── .eslintrc ├── .gitignore ├── .prettierrc ├── Procfile ├── README.md ├── env.d.ts ├── package.json ├── src ├── assert-env-vars.ts ├── commands.ts ├── commands │ ├── context │ │ └── report.ts │ ├── create-mentionable-slash-command.ts │ └── slash │ │ ├── jobs.ts │ │ ├── ping.ts │ │ └── promotion.ts ├── features │ ├── antispam.ts │ ├── countdown.ts │ ├── rules.ts │ └── welcomeQuestions.ts ├── index.ts ├── register-commands.ts ├── types.ts └── utils.ts ├── tsconfig.json └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | # Required vars 2 | DISCORD_BOT_TOKEN= 3 | DISCORD_CLIENT_ID= 4 | MOD_LOG_CHANNEL_ID= 5 | 6 | # If you plan to register new commands in dev 7 | # DEV_GUILD_ID= 8 | 9 | # These are not required, you can set them to override the default channels IDs on dev 10 | # RULES_CHANNEL_ID= 11 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["@typescript-eslint"], 5 | "extends": [ 6 | "eslint:recommended", 7 | "plugin:@typescript-eslint/recommended", 8 | "prettier" 9 | ], 10 | "env": { 11 | "node": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "singleQuote": true, 4 | "trailingComma": "es5", 5 | "arrowParens": "always" 6 | } 7 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: node dist/index.js 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js Discord Bot 2 | 3 | The source code of the Discord bot for the official [Next.js Discord](https://nextjs.org/discord). 4 | 5 | ## Features 6 | 7 | - Adding users to certain channels based on message reactions 8 | - Anti-spam protection through a whitelist 9 | - Monitoring for certain emojis and words 10 | - Helping log messages that mods flag 11 | - Keeping rules up to date 12 | - Alert reactions 13 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | namespace NodeJS { 3 | interface ProcessEnv { 4 | // Required env variables 5 | DISCORD_BOT_TOKEN: string; 6 | DISCORD_CLIENT_ID: string; 7 | MOD_LOG_CHANNEL_ID: string; 8 | } 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-bot", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "author": "Rafael Almeida", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "node dist/index.js", 9 | "dev": "ts-node-dev src/index.ts", 10 | "dev:register-commands": "DEV=true ts-node ./src/register-commands.ts", 11 | "register-commands": "ts-node ./src/register-commands.ts", 12 | "build": "tsc", 13 | "lint": "eslint src" 14 | }, 15 | "dependencies": { 16 | "discord.js": "^14.7.1", 17 | "dotenv": "^16.0.3" 18 | }, 19 | "devDependencies": { 20 | "@types/node": "^18.11.10", 21 | "@typescript-eslint/eslint-plugin": "^5.45.0", 22 | "@typescript-eslint/parser": "^5.45.0", 23 | "eslint": "^8.29.0", 24 | "eslint-config-prettier": "^8.5.0", 25 | "eslint-plugin-prettier": "^4.2.1", 26 | "prettier": "^2.8.0", 27 | "ts-node": "^10.9.1", 28 | "ts-node-dev": "^2.0.0", 29 | "typescript": "^4.9.3" 30 | }, 31 | "engines": { 32 | "node": ">=16.6" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/assert-env-vars.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | import dotenv from 'dotenv'; 3 | 4 | dotenv.config(); 5 | 6 | const required = (name: string, val: string | undefined) => 7 | assert(val, `${name} is not defined`); 8 | 9 | const optional = (name: string, val: string | undefined) => { 10 | if (!val) { 11 | console.warn(`Warning: ${name} is not defined, some features may not work`); 12 | } 13 | }; 14 | 15 | required('DISCORD_BOT_TOKEN', process.env.DISCORD_BOT_TOKEN); 16 | required('DISCORD_CLIENT_ID', process.env.DISCORD_CLIENT_ID); 17 | required('MOD_LOG_CHANNEL_ID', process.env.MOD_LOG_CHANNEL_ID); 18 | optional('MODERATOR_ROLE_ID', process.env.MODERATOR_ROLE_ID); 19 | -------------------------------------------------------------------------------- /src/commands.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs'; 3 | import { SlashCommandFile, ContextMenuCommandFile } from './types'; 4 | import { isJsOrTsFile } from './utils'; 5 | 6 | export const slashCommands = fs 7 | .readdirSync(path.resolve(__dirname, './commands/slash')) 8 | .filter(isJsOrTsFile) 9 | .map((file) => { 10 | const { command } = 11 | // eslint-disable-next-line @typescript-eslint/no-var-requires 12 | require(`./commands/slash/${file}`) as SlashCommandFile; 13 | return command; 14 | }); 15 | 16 | export const contextMenuCommands = fs 17 | .readdirSync(path.resolve(__dirname, './commands/context')) 18 | .filter(isJsOrTsFile) 19 | .map((file) => { 20 | const { command } = 21 | // eslint-disable-next-line @typescript-eslint/no-var-requires 22 | require(`./commands/context/${file}`) as ContextMenuCommandFile; 23 | return command; 24 | }); 25 | 26 | export const allCommands = () => { 27 | return [...slashCommands, ...contextMenuCommands]; 28 | }; 29 | -------------------------------------------------------------------------------- /src/commands/context/report.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApplicationCommandType, 3 | ContextMenuCommandBuilder, 4 | PermissionFlagsBits, 5 | } from 'discord.js'; 6 | import { ContextMenuCommand } from '../../types'; 7 | import { isStaff } from '../../utils'; 8 | 9 | /** 10 | * Report message command 11 | * --- 12 | * Logs a message in the mod log channel. If a normal user uses the command it will ping the mods 13 | */ 14 | 15 | // We will keep a memory cache of warned messages to avoid showing multiple warnings 16 | const warnedMessageIds: string[] = []; 17 | 18 | export const command: ContextMenuCommand = { 19 | data: new ContextMenuCommandBuilder() 20 | .setName('Report') 21 | .setDMPermission(false) 22 | .setDefaultMemberPermissions(PermissionFlagsBits.SendMessages) 23 | .setType(ApplicationCommandType.Message), 24 | 25 | async execute(interaction) { 26 | const { client, guild, user, targetMessage } = interaction; 27 | 28 | if (!guild) return; 29 | 30 | const sendSuccessMessage = () => { 31 | interaction.reply({ 32 | content: 33 | 'Thanks, the message has been reported and the moderators have been notified', 34 | ephemeral: true, 35 | }); 36 | }; 37 | 38 | if (warnedMessageIds.includes(targetMessage.id)) { 39 | // Send the success message anyway so they know the mods have been notified 40 | sendSuccessMessage(); 41 | return; 42 | } 43 | 44 | const channel = client.channels.cache.get(process.env.MOD_LOG_CHANNEL_ID); 45 | 46 | if (!channel || !channel.isTextBased()) { 47 | console.error( 48 | `No mod-log channel found (using the ID ${process.env.MOD_LOG_CHANNEL_ID})!` 49 | ); 50 | 51 | interaction.reply({ 52 | content: 'Something went wrong, please try again later', 53 | ephemeral: true, 54 | }); 55 | 56 | return; 57 | } 58 | 59 | const author = await guild.members.fetch(targetMessage.author.id); 60 | const userGuildMember = await guild.members.fetch(user.id); 61 | const isUserStaff = isStaff(userGuildMember); 62 | 63 | channel.send({ 64 | content: !isUserStaff 65 | ? `<@&${process.env.MODERATOR_ROLE_ID}>` 66 | : undefined, 67 | embeds: [ 68 | { 69 | title: '⚠️ Message Reported', 70 | description: '```' + targetMessage.content + '```', 71 | color: 16098851, 72 | author: { 73 | name: author?.displayName ?? 'Unknown user', 74 | icon_url: author?.displayAvatarURL(), 75 | }, 76 | fields: [ 77 | { 78 | name: 'Author', 79 | value: `<@${targetMessage.author.id}>`, 80 | inline: true, 81 | }, 82 | { 83 | name: 'Channel', 84 | value: `<#${targetMessage.channelId}>`, 85 | inline: true, 86 | }, 87 | { 88 | name: 'Jump to message', 89 | value: `[Click here](${targetMessage.url})`, 90 | inline: true, 91 | }, 92 | ], 93 | footer: { 94 | icon_url: userGuildMember.displayAvatarURL(), 95 | text: `Reported by ${userGuildMember.displayName}`, 96 | }, 97 | }, 98 | ], 99 | }); 100 | 101 | if (isUserStaff) { 102 | interaction.reply({ 103 | content: 'Message logged in the mod channel', 104 | ephemeral: true, 105 | }); 106 | } else { 107 | sendSuccessMessage(); 108 | } 109 | 110 | warnedMessageIds.push(targetMessage.id); 111 | }, 112 | }; 113 | -------------------------------------------------------------------------------- /src/commands/create-mentionable-slash-command.ts: -------------------------------------------------------------------------------- 1 | import { SlashCommandBuilder, GuildMember } from 'discord.js'; 2 | import { SlashCommand } from '../types'; 3 | 4 | type Options = { 5 | name: string; 6 | description: string; 7 | reply: { 8 | title: string; 9 | content: string; 10 | }; 11 | }; 12 | 13 | export const createMentionableSlashCommand = ({ 14 | name, 15 | description, 16 | reply, 17 | }: Options) => { 18 | const command: SlashCommand = { 19 | data: new SlashCommandBuilder() 20 | .setName(name) 21 | .setDescription(description) 22 | .addUserOption((option) => 23 | option 24 | .setName('member') 25 | .setDescription('The member to send this message') 26 | ), 27 | 28 | async execute(interaction) { 29 | const { options } = interaction; 30 | 31 | const target = options.getMember('member'); 32 | const targetId = target instanceof GuildMember ? target.id : null; 33 | 34 | interaction.reply({ 35 | content: targetId ? `<@${targetId}>` : undefined, 36 | embeds: [ 37 | { 38 | title: reply.title, 39 | description: reply.content, 40 | }, 41 | ], 42 | }); 43 | }, 44 | }; 45 | 46 | return command; 47 | }; 48 | -------------------------------------------------------------------------------- /src/commands/slash/jobs.ts: -------------------------------------------------------------------------------- 1 | import { createMentionableSlashCommand } from '../create-mentionable-slash-command'; 2 | 3 | export const command = createMentionableSlashCommand({ 4 | name: 'jobs', 5 | description: 'Replies with directions for job posts', 6 | reply: { 7 | title: 'Job posts are not allowed in the server', 8 | content: 9 | "We currently do not allow job posts in this server, unless it's in the context of a discussion. If you're looking to get hired or to advertise a job vacancy see <#910564441119150100>", 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /src/commands/slash/ping.ts: -------------------------------------------------------------------------------- 1 | import { createMentionableSlashCommand } from '../create-mentionable-slash-command'; 2 | 3 | export const command = createMentionableSlashCommand({ 4 | name: 'ping', 5 | description: 'Explains why we disencourage pinging other members', 6 | reply: { 7 | title: "Don't ping or DM other devs you aren't actively talking to", 8 | content: 9 | "Do not ping other people in order to get attention to your question unless they are actively involved in the discussion. If you're looking to get help, it is a lot better to post your question in a public channel so other people can help or learn from the questions", 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /src/commands/slash/promotion.ts: -------------------------------------------------------------------------------- 1 | import { createMentionableSlashCommand } from '../create-mentionable-slash-command'; 2 | 3 | export const command = createMentionableSlashCommand({ 4 | name: 'promotion', 5 | description: 'Replies with the server rules for promotion', 6 | reply: { 7 | title: 'Promotion is not allowed outside the respective channels', 8 | content: 9 | "We have a few channels that allow for self-promotion (<#771729272074534922>, <#1024406585012924486>). Sharing promotional links such as referral links, giveaways/contests or anything that would be a plain advertisement is discouraged and may be removed.\n\nIf what you want to share doesn't fit the promotion channels, contact a moderator to know if the post is valid before posting it.", 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /src/features/antispam.ts: -------------------------------------------------------------------------------- 1 | import { OnMessageHandler } from '../types'; 2 | import { isStaff, logAndDelete } from '../utils'; 3 | 4 | /** 5 | * Anti spam 6 | * --- 7 | * If a message has too many emojis or contains certain keywords, the bot will log the message and delete it 8 | */ 9 | 10 | const MAX_EMOJI_COUNT = 16; // Flags are two symbols so 16 max emojis = max of 8 flags 11 | const ROLES_WHITELIST = ['partner']; // Allow partners to go above the emojis limit 12 | const INTRODUCTIONS_CHANNEL_ID = '766393115044216854'; 13 | 14 | const emojiRegex = /\p{Emoji_Presentation}/gu; 15 | const spamKeywords = ['discord', 'nitro', 'steam', 'free', 'gift']; 16 | 17 | const dmMessage = 18 | 'Hello there! Our automated systems detected your message as a spam message and it has been deleted. If this is an error on our side, please feel free to contact one of the moderators.'; 19 | 20 | export const onMessage: OnMessageHandler = async (client, message) => { 21 | const messageAuthor = await message.guild?.members.fetch(message.author.id); 22 | 23 | if ( 24 | !messageAuthor || 25 | isStaff(messageAuthor) || 26 | messageAuthor.roles.cache.some((role) => 27 | ROLES_WHITELIST.includes(role.name.toLowerCase()) 28 | ) 29 | ) 30 | return; 31 | 32 | const emojisCount = message.content.match(emojiRegex)?.length ?? 0; 33 | 34 | if ( 35 | emojisCount > 36 | (message.channelId === INTRODUCTIONS_CHANNEL_ID 37 | ? MAX_EMOJI_COUNT * 5 38 | : MAX_EMOJI_COUNT) 39 | ) { 40 | await message.author.send(dmMessage); 41 | await logAndDelete(client, message, 'Too many emojis'); 42 | return; 43 | } 44 | 45 | const messageHasPingKeywords = ['@everyone', '@here'].some((pingKeyword) => 46 | message.content.includes(pingKeyword) 47 | ); 48 | const messageHasSpamKeywords = message.content 49 | .split(' ') 50 | .some((word) => spamKeywords.includes(word.toLowerCase())); 51 | 52 | if (messageHasPingKeywords && messageHasSpamKeywords) { 53 | await message.author.send(dmMessage); 54 | await logAndDelete(client, message, 'Spam keywords'); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /src/features/countdown.ts: -------------------------------------------------------------------------------- 1 | import { VoiceChannel } from 'discord.js'; 2 | import { OnStartupHandler } from '../types'; 3 | import { remainingTime } from '../utils'; 4 | 5 | /** 6 | * Countdown module 7 | * --- 8 | * The bot will keep track of a countdown, updating a voice channel name so all the members can see it 9 | */ 10 | 11 | const TITLE_VOICE_CHANNEL_ID = '902455952048029696'; 12 | const COUNTDOWN_VOICE_CHANNEL_ID = '902456113298022420'; 13 | const TARGET_TIME = '26 Oct 2021 09:00:00 GMT-0700'; 14 | 15 | let enabled = false; 16 | 17 | export const onStartup: OnStartupHandler = async (client) => { 18 | if (!enabled) return; 19 | 20 | const voiceChannel = client.channels.cache.get( 21 | COUNTDOWN_VOICE_CHANNEL_ID 22 | ) as VoiceChannel; 23 | 24 | if (!voiceChannel) { 25 | console.warn( 26 | `No countdown voice channel found (using the ID ${COUNTDOWN_VOICE_CHANNEL_ID}), skipping the countdown module!` 27 | ); 28 | return; 29 | } 30 | 31 | const targetDate = new Date(TARGET_TIME); 32 | 33 | const updateChannelName = () => { 34 | if (!enabled) return false; 35 | 36 | const timeDiff = targetDate.getTime() - Date.now(); 37 | 38 | if (timeDiff <= 0) { 39 | const channelName = `Next.js Conf started!`; 40 | voiceChannel.setName(channelName); 41 | 42 | const titleVoiceChannel = client.channels.cache.get( 43 | TITLE_VOICE_CHANNEL_ID 44 | ); 45 | titleVoiceChannel?.delete(); 46 | 47 | enabled = false; 48 | return; 49 | } 50 | 51 | const { days, hours, minutes } = remainingTime( 52 | Date.now(), 53 | targetDate.getTime() 54 | ); 55 | 56 | const channelName = `${days} Days ${hours} Hours ${minutes} Mins`; 57 | voiceChannel.setName(channelName); 58 | }; 59 | 60 | // We can only update it every 5 minutes (Discord rate limiting) 61 | const interval = 5 * 1000 * 60; 62 | setInterval(updateChannelName, interval); 63 | updateChannelName(); 64 | }; 65 | -------------------------------------------------------------------------------- /src/features/rules.ts: -------------------------------------------------------------------------------- 1 | import { TextChannel } from 'discord.js'; 2 | import { OnStartupHandler } from '../types'; 3 | /** 4 | * Rules module 5 | * --- 6 | * When the bot starts, it will post the rules defined below into the configured channel. 7 | * To avoid spamming the channel everytime it is started, the messages existing in the channel 8 | * are going to be "recycled". This means that if we edit something in the rules, we will try to edit 9 | * the existing messages to avoid creating pings in the channel. 10 | */ 11 | 12 | const RULES_CHANNEL_ID = process.env.RULES_CHANNEL_ID ?? '752553802359505020'; 13 | const INTRO_CHANNEL_ID = '766393115044216854'; 14 | // const HELP_CHANNEL_ID = '752668543891276009'; 15 | // const OFFTOPIC_CHANNEL_ID = '766433464055496744'; 16 | // const SHOWCASE_CHANNEL_ID = '771729272074534922'; 17 | // const KUDOS_CHANNEL_ID = '911305422307225682'; 18 | // const GENERAL_CHANNEL_ID = '752647196419031042'; 19 | 20 | // 'https://i.imgur.com/Zqc3Nc6.png', 21 | // ` 22 | // Welcome to the official Next.js Discord server! 23 | 24 | // This is the place to chat about Next.js, ask questions, show off your projects, and collaborate with other developers. 25 | 26 | // **Here's a quick breakdown of our channels:** 27 | // <#${GENERAL_CHANNEL_ID}>:: General chat about Next.js 28 | // <#${HELP_CHANNEL_ID}>: Ask for help with Next.js 29 | // <#${OFFTOPIC_CHANNEL_ID}>: Anything else you want to talk about 30 | // <#${SHOWCASE_CHANNEL_ID}>: Show off your Next.js projects 31 | // <#${KUDOS_CHANNEL_ID}>: Shout out people who helped you out 32 | 33 | // We abide by our Code of Conduct. Please read it: 34 | // `, 35 | 36 | const RULES_MESSAGES = [ 37 | `**To unlock the rest of the server, make sure to introduce yourself in the <#${INTRO_CHANNEL_ID}> channel!** Use this template: 38 | 39 | 🌎 I'm from: Italy 40 | 🏢 I work at: Amazon 41 | 💻 I work with this tech: Next.js, Typescript, Tailwind, and Prisma 42 | 🍎 I snack on: ☕ 43 | 44 | Also, tell us what tools you use so we can automatically add you to the relevant channels! 45 | 46 | <:javascript:770004227366846494> : JavaScript 47 | 48 | <:typescript:770004243545325580> : TypeScript 49 | 50 | <:tailwind:913088128468787210> : Tailwind 51 | 52 | <:rust:913088096692748349> : Rust 53 | 54 | <:swr:770004547422650388> : SWR 55 | 56 | <:mdx:935667057121439805> : MDX 57 | `, 58 | ]; 59 | 60 | export const onStartup: OnStartupHandler = async (client) => { 61 | const channel = client.channels.cache.get(RULES_CHANNEL_ID) as TextChannel; 62 | 63 | if (!channel) { 64 | console.warn( 65 | `No rules channel found (using the ID ${RULES_CHANNEL_ID}), skipping the rules module!` 66 | ); 67 | return; 68 | } 69 | 70 | const channelMessages = await channel.messages.fetch({ limit: 100 }); 71 | 72 | // Filter only the messages from the bot 73 | const channelMessagesFromBot = channelMessages.filter( 74 | (m) => m.author.id === client.user?.id 75 | ); 76 | 77 | // Sort the messages from oldest to newest (so they match the same order of the rules) 78 | const channelMessagesReversed = [ 79 | ...channelMessagesFromBot.values(), 80 | ].reverse(); 81 | 82 | // For each message sent in the channel... 83 | for (let i = 0; i < channelMessagesReversed.length; i++) { 84 | const message = channelMessagesReversed[i]; 85 | 86 | // We first check if there is no rule message matching this position, 87 | // this means that we have more messages in the channel than in our rules, so 88 | // we need to delete this message (and this is going to be true to all the next messages) 89 | if (!RULES_MESSAGES[i]) { 90 | await message.delete(); 91 | continue; 92 | } 93 | 94 | // If the content of the message doesn't match the respective message in the rules, edit it 95 | if (message.content !== RULES_MESSAGES[i]) { 96 | await message.edit(RULES_MESSAGES[i]); 97 | } 98 | } 99 | 100 | // And in the end, check if there are more messages in the rules than in the channel, 101 | // this means that we didn't have enough messages to edit so we need to create more 102 | const messagesLeftToCreate = 103 | RULES_MESSAGES.length - channelMessagesReversed.length; 104 | 105 | if (messagesLeftToCreate > 0) { 106 | // Grab the last n messages from the rules... 107 | const remainingMessages = RULES_MESSAGES.slice( 108 | Math.max(RULES_MESSAGES.length - messagesLeftToCreate, 0) 109 | ); 110 | 111 | // And create them! 112 | await Promise.all( 113 | remainingMessages.map((message) => channel.send(message)) 114 | ); 115 | } 116 | }; 117 | -------------------------------------------------------------------------------- /src/features/welcomeQuestions.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-non-null-assertion */ 2 | import { OnReactionHandler } from '../types'; 3 | 4 | /** 5 | * Welcome Questions Module 6 | * --- 7 | * The bot will keep track of the reactions to a message to assign users certain roles which then adds them to the relevant channels 8 | */ 9 | 10 | type LanguageObject = { 11 | [key: string]: string; 12 | }; 13 | 14 | const LANGUAGES: LanguageObject = { 15 | javascript: '913086422351769610', 16 | typescript: '913086489229918238', 17 | tailwind: '913086567042674719', 18 | rust: '913086533387567165', 19 | swr: '915643752406720592', 20 | mdx: '935666082100957234', 21 | }; 22 | 23 | // Make sure to update this message ID when bot generates a new one 24 | const LANGUAGES_MESSAGE_ID = '913092687924695071'; 25 | 26 | export const onReactionAdd: OnReactionHandler = async ( 27 | client, 28 | reaction, 29 | user 30 | ) => { 31 | const { message } = reaction; 32 | 33 | // if message isn't the welcome message, exit 34 | if (message.id !== LANGUAGES_MESSAGE_ID) { 35 | console.log('msg is NOT in the welcome channel'); 36 | return; 37 | } else { 38 | console.log('msg is in the welcome channel'); 39 | } 40 | 41 | // If reaction isn't one of the ones provided above, exit 42 | if (!Object.keys(LANGUAGES).includes(reaction.emoji.name!)) { 43 | console.log('emoji is NOT in there'); 44 | return; 45 | } else { 46 | console.log('emoji is in there'); 47 | } 48 | 49 | // Now we've certified a valid emoji and message ID, assign role to user 50 | const member = await message 51 | .guild!.members.fetch(user.id) 52 | .catch((err) => console.log(err.message)); 53 | if (!member) return; 54 | 55 | const language = LANGUAGES[reaction.emoji.toString().split(':')[1]]; 56 | member.roles.add(language).catch((err) => console.log(err.message)); 57 | }; 58 | 59 | export const onReactionRemove: OnReactionHandler = async ( 60 | client, 61 | reaction, 62 | user 63 | ) => { 64 | const { message } = reaction; 65 | // if message isn't the welcome message, exit 66 | if (message.id !== LANGUAGES_MESSAGE_ID) { 67 | console.log('msg is NOT in the welcome channel'); 68 | return; 69 | } else { 70 | console.log('msg is in the welcome channel'); 71 | } 72 | 73 | // If reaction isn't one of the ones provided above, exit 74 | if (!Object.keys(LANGUAGES).includes(reaction.emoji.name!)) { 75 | console.log('emoji is NOT in there'); 76 | return; 77 | } else { 78 | console.log('emoji is in there'); 79 | } 80 | 81 | // Now we've certified a valid emoji and message ID, assign role to user 82 | const member = await message 83 | .guild!.members.fetch(user.id) 84 | .catch((err) => console.log(err.message)); 85 | if (!member) return; 86 | 87 | const language = LANGUAGES[reaction.emoji.toString().split(':')[1]]; 88 | member.roles.remove(language).catch((err) => console.log(err.message)); 89 | }; 90 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import path from 'node:path'; 3 | import discord, { Events, GatewayIntentBits, Partials, User } from 'discord.js'; 4 | import './assert-env-vars'; 5 | 6 | import { FeatureFile } from './types'; 7 | import { isJsOrTsFile } from './utils'; 8 | import { slashCommands, contextMenuCommands } from './commands'; 9 | 10 | const INTRO_CHANNEL_ID = '766393115044216854'; 11 | const VERIFIED_ROLE = '930202099264938084'; 12 | 13 | if (!process.env.DISCORD_BOT_TOKEN) { 14 | throw new Error('No bot token found!'); 15 | } 16 | 17 | const client = new discord.Client({ 18 | intents: [ 19 | GatewayIntentBits.Guilds, 20 | GatewayIntentBits.GuildMessages, 21 | GatewayIntentBits.GuildMessageReactions, 22 | ], 23 | partials: [Partials.Message, Partials.Channel, Partials.Reaction], 24 | }); 25 | 26 | const features: FeatureFile[] = []; 27 | const featureFiles = fs 28 | .readdirSync(path.resolve(__dirname, './features')) 29 | // Look for files as TS (dev) or JS (built files) 30 | .filter(isJsOrTsFile); 31 | 32 | for (const featureFile of featureFiles) { 33 | // eslint-disable-next-line @typescript-eslint/no-var-requires 34 | const feature = require(`./features/${featureFile}`) as FeatureFile; 35 | features.push(feature); 36 | } 37 | 38 | client.on('ready', () => { 39 | console.log(`Logged in as ${client.user?.tag}!`); 40 | features.forEach((f) => f.onStartup?.(client)); 41 | }); 42 | 43 | client.on(Events.InteractionCreate, async (interaction) => { 44 | if (interaction.isChatInputCommand()) { 45 | slashCommands 46 | .find((c) => c.data.name === interaction.commandName) 47 | ?.execute(interaction); 48 | } 49 | 50 | if (interaction.isMessageContextMenuCommand()) { 51 | contextMenuCommands 52 | .find((c) => c.data.name === interaction.commandName) 53 | ?.execute(interaction); 54 | } 55 | }); 56 | 57 | client.on('messageCreate', (message) => { 58 | if (message.author.bot) return; 59 | 60 | // if user types into the intros channel, give them the verified role 61 | if (message.channel.id == INTRO_CHANNEL_ID) { 62 | message.member?.roles 63 | .add(VERIFIED_ROLE) 64 | .catch((err) => console.log(err.message, 'Verify')); 65 | } 66 | 67 | features.forEach((f) => f.onMessage?.(client, message)); 68 | }); 69 | 70 | client.on('messageReactionAdd', async (reaction, user) => { 71 | if (user.partial) { 72 | try { 73 | await user.fetch(); 74 | } catch (error) { 75 | console.log('Error while trying to fetch an user', error); 76 | } 77 | } 78 | 79 | if (reaction.message.partial) { 80 | try { 81 | await reaction.message.fetch(); 82 | } catch (error) { 83 | console.log('Error while trying to fetch a reaction message', error); 84 | } 85 | } 86 | 87 | if (reaction.partial) { 88 | try { 89 | const fetchedReaction = await reaction.fetch(); 90 | features.forEach((f) => 91 | f.onReactionAdd?.(client, fetchedReaction, user as User) 92 | ); 93 | } catch (error) { 94 | console.log('Error while trying to fetch a reaction', error); 95 | } 96 | } else { 97 | features.forEach((f) => f.onReactionAdd?.(client, reaction, user as User)); 98 | } 99 | }); 100 | 101 | client.on('messageReactionRemove', async (reaction, user) => { 102 | if (user.partial) { 103 | try { 104 | await user.fetch(); 105 | } catch (error) { 106 | console.log('Error while trying to fetch an user', error); 107 | } 108 | } 109 | 110 | if (reaction.message.partial) { 111 | try { 112 | await reaction.message.fetch(); 113 | } catch (error) { 114 | console.log('Error while trying to fetch a reaction message', error); 115 | } 116 | } 117 | 118 | if (reaction.partial) { 119 | try { 120 | const fetchedReaction = await reaction.fetch(); 121 | features.forEach((f) => 122 | f.onReactionRemove?.(client, fetchedReaction, user as User) 123 | ); 124 | } catch (error) { 125 | console.log('Error while trying to fetch a reaction', error); 126 | } 127 | } else { 128 | features.forEach((f) => 129 | f.onReactionRemove?.(client, reaction, user as User) 130 | ); 131 | } 132 | }); 133 | 134 | // Wake up 🤖 135 | client.login(process.env.DISCORD_BOT_TOKEN); 136 | -------------------------------------------------------------------------------- /src/register-commands.ts: -------------------------------------------------------------------------------- 1 | import { REST, Routes } from 'discord.js'; 2 | import './assert-env-vars'; 3 | 4 | import { allCommands } from './commands'; 5 | 6 | (async () => { 7 | const isDevRegister = process.env.DEV === 'true'; 8 | const guildId = process.env.DEV_GUILD_ID; 9 | 10 | if (isDevRegister && !guildId) { 11 | throw new Error( 12 | 'The DEV_GUILD_ID env variable should be set to register commands in dev' 13 | ); 14 | } 15 | 16 | const commands = allCommands().map((file) => file.data.toJSON()); 17 | 18 | const rest = new REST({ version: '10' }).setToken( 19 | process.env.DISCORD_BOT_TOKEN 20 | ); 21 | 22 | console.log(`Started refreshing ${commands.length} application commands.`); 23 | 24 | const data = (await rest.put( 25 | isDevRegister 26 | ? Routes.applicationGuildCommands( 27 | process.env.DISCORD_CLIENT_ID, 28 | guildId ?? '' 29 | ) 30 | : Routes.applicationCommands(process.env.DISCORD_CLIENT_ID), 31 | { body: commands } 32 | )) as unknown[]; 33 | 34 | console.log(`Successfully reloaded ${data.length} application commands.`); 35 | })(); 36 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChatInputCommandInteraction, 3 | Client, 4 | ContextMenuCommandBuilder, 5 | Message, 6 | MessageContextMenuCommandInteraction, 7 | MessageReaction, 8 | SlashCommandBuilder, 9 | User, 10 | } from 'discord.js'; 11 | 12 | /* -------------------- 13 | * Feature handlers 14 | */ 15 | 16 | export type OnStartupHandler = (client: Client) => Promise; 17 | 18 | export type OnMessageHandler = ( 19 | client: Client, 20 | message: Message 21 | ) => Promise; 22 | 23 | export type OnReactionHandler = ( 24 | client: Client, 25 | reaction: MessageReaction, 26 | user: User 27 | ) => Promise; 28 | 29 | /* -------------------------------------------------- */ 30 | 31 | export type FeatureFile = { 32 | onStartup?: OnStartupHandler; 33 | onMessage?: OnMessageHandler; 34 | onReactionAdd?: OnReactionHandler; 35 | onReactionRemove?: OnReactionHandler; 36 | }; 37 | 38 | export type SlashCommand = { 39 | data: Omit; 40 | execute: (interaction: ChatInputCommandInteraction) => void | Promise; 41 | }; 42 | 43 | export type SlashCommandFile = { 44 | command: SlashCommand; 45 | }; 46 | 47 | export type ContextMenuCommand = { 48 | data: ContextMenuCommandBuilder; 49 | execute: ( 50 | interaction: MessageContextMenuCommandInteraction 51 | ) => void | Promise; 52 | }; 53 | 54 | export type ContextMenuCommandFile = { 55 | command: ContextMenuCommand; 56 | }; 57 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { Client, GuildMember, Message, TextChannel } from 'discord.js'; 2 | 3 | const MOD_LOG_CHANNEL_ID = 4 | process.env.MOD_LOG_CHANNEL_ID ?? '763149438951882792'; 5 | 6 | const staffRoles = ['next.js', 'moderator', 'vercel']; 7 | 8 | export const isStaff = (member: GuildMember | null | undefined): boolean => { 9 | if (!member) return false; 10 | 11 | return member.roles.cache.some((role) => 12 | staffRoles.includes(role.name.toLowerCase()) 13 | ); 14 | }; 15 | 16 | export const isJsOrTsFile = (file: string) => 17 | file.endsWith('.ts') || file.endsWith('.js'); 18 | 19 | export const logAndDelete = async ( 20 | client: Client, 21 | message: Message, 22 | reason: string 23 | ) => { 24 | const modLogChannel = client.channels.cache.get( 25 | MOD_LOG_CHANNEL_ID 26 | ) as TextChannel; 27 | 28 | await modLogChannel.send({ 29 | embeds: [ 30 | { 31 | title: 'Message automatically deleted', 32 | description: '```' + message.content + '```', 33 | color: 16098851, 34 | fields: [ 35 | { 36 | name: 'Author profile', 37 | value: `<@${message.author.id}>`, 38 | inline: true, 39 | }, 40 | { 41 | name: 'Reason', 42 | value: reason, 43 | inline: true, 44 | }, 45 | { 46 | name: 'Channel', 47 | value: `<#${message.channel.id}>`, 48 | inline: true, 49 | }, 50 | ], 51 | }, 52 | ], 53 | }); 54 | 55 | message.delete(); 56 | }; 57 | 58 | type RemainingTime = { 59 | days: number; 60 | hours: number; 61 | minutes: number; 62 | seconds: number; 63 | }; 64 | 65 | export const remainingTime = ( 66 | startTime: number, 67 | endTime: number 68 | ): RemainingTime => { 69 | // https://stackoverflow.com/a/13904120 70 | // get total seconds between the times 71 | let delta = Math.abs(endTime - startTime) / 1000; 72 | 73 | // calculate (and subtract) whole days 74 | const days = Math.floor(delta / 86400); 75 | delta -= days * 86400; 76 | 77 | // calculate (and subtract) whole hours 78 | const hours = Math.floor(delta / 3600) % 24; 79 | delta -= hours * 3600; 80 | 81 | // calculate (and subtract) whole minutes 82 | const minutes = Math.floor(delta / 60) % 60; 83 | delta -= minutes * 60; 84 | 85 | // what's left is seconds 86 | const seconds = delta % 60; // in theory the modulus is not required 87 | 88 | return { days, hours, minutes, seconds }; 89 | }; 90 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "outDir": "dist", 7 | "strict": true, 8 | "allowJs": false, 9 | "moduleResolution": "node", 10 | "esModuleInterop": true, 11 | "skipLibCheck": true, 12 | "forceConsistentCasingInFileNames": true 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["node_modules"], 16 | "files": ["env.d.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@cspotcode/source-map-support@^0.8.0": 6 | version "0.8.1" 7 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 8 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 9 | dependencies: 10 | "@jridgewell/trace-mapping" "0.3.9" 11 | 12 | "@discordjs/builders@^1.4.0": 13 | version "1.4.0" 14 | resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.4.0.tgz#b951b5e6ce4e459cd06174ce50dbd51c254c1d47" 15 | integrity sha512-nEeTCheTTDw5kO93faM1j8ZJPonAX86qpq/QVoznnSa8WWcCgJpjlu6GylfINTDW6o7zZY0my2SYdxx2mfNwGA== 16 | dependencies: 17 | "@discordjs/util" "^0.1.0" 18 | "@sapphire/shapeshift" "^3.7.1" 19 | discord-api-types "^0.37.20" 20 | fast-deep-equal "^3.1.3" 21 | ts-mixer "^6.0.2" 22 | tslib "^2.4.1" 23 | 24 | "@discordjs/collection@^1.3.0": 25 | version "1.3.0" 26 | resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.3.0.tgz#65bf9674db72f38c25212be562bb28fa0dba6aa3" 27 | integrity sha512-ylt2NyZ77bJbRij4h9u/wVy7qYw/aDqQLWnadjvDqW/WoWCxrsX6M3CIw9GVP5xcGCDxsrKj5e0r5evuFYwrKg== 28 | 29 | "@discordjs/rest@^1.4.0": 30 | version "1.4.0" 31 | resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-1.4.0.tgz#ceaff2a63680c5a0d8c43b85c8a2b023413d4080" 32 | integrity sha512-k3Ip7ffFSAfp7Mu4H/3BEXFvFz+JsbXRrRtpeBMnSp1LefhtlZWJE6xdXzNlblktKNQltnRwY+z0NZrGQdxAMw== 33 | dependencies: 34 | "@discordjs/collection" "^1.3.0" 35 | "@discordjs/util" "^0.1.0" 36 | "@sapphire/async-queue" "^1.5.0" 37 | "@sapphire/snowflake" "^3.2.2" 38 | discord-api-types "^0.37.20" 39 | file-type "^18.0.0" 40 | tslib "^2.4.1" 41 | undici "^5.13.0" 42 | 43 | "@discordjs/util@^0.1.0": 44 | version "0.1.0" 45 | resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-0.1.0.tgz#e42ca1bf407bc6d9adf252877d1b206e32ba369a" 46 | integrity sha512-e7d+PaTLVQav6rOc2tojh2y6FE8S7REkqLldq1XF4soCx74XB/DIjbVbVLtBemf0nLW77ntz0v+o5DytKwFNLQ== 47 | 48 | "@eslint/eslintrc@^1.3.3": 49 | version "1.3.3" 50 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" 51 | integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== 52 | dependencies: 53 | ajv "^6.12.4" 54 | debug "^4.3.2" 55 | espree "^9.4.0" 56 | globals "^13.15.0" 57 | ignore "^5.2.0" 58 | import-fresh "^3.2.1" 59 | js-yaml "^4.1.0" 60 | minimatch "^3.1.2" 61 | strip-json-comments "^3.1.1" 62 | 63 | "@humanwhocodes/config-array@^0.11.6": 64 | version "0.11.7" 65 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" 66 | integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== 67 | dependencies: 68 | "@humanwhocodes/object-schema" "^1.2.1" 69 | debug "^4.1.1" 70 | minimatch "^3.0.5" 71 | 72 | "@humanwhocodes/module-importer@^1.0.1": 73 | version "1.0.1" 74 | resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" 75 | integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== 76 | 77 | "@humanwhocodes/object-schema@^1.2.1": 78 | version "1.2.1" 79 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" 80 | integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== 81 | 82 | "@jridgewell/resolve-uri@^3.0.3": 83 | version "3.1.0" 84 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" 85 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== 86 | 87 | "@jridgewell/sourcemap-codec@^1.4.10": 88 | version "1.4.14" 89 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" 90 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== 91 | 92 | "@jridgewell/trace-mapping@0.3.9": 93 | version "0.3.9" 94 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 95 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 96 | dependencies: 97 | "@jridgewell/resolve-uri" "^3.0.3" 98 | "@jridgewell/sourcemap-codec" "^1.4.10" 99 | 100 | "@nodelib/fs.scandir@2.1.5": 101 | version "2.1.5" 102 | resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" 103 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 104 | dependencies: 105 | "@nodelib/fs.stat" "2.0.5" 106 | run-parallel "^1.1.9" 107 | 108 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 109 | version "2.0.5" 110 | resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" 111 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 112 | 113 | "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": 114 | version "1.2.8" 115 | resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" 116 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 117 | dependencies: 118 | "@nodelib/fs.scandir" "2.1.5" 119 | fastq "^1.6.0" 120 | 121 | "@sapphire/async-queue@^1.5.0": 122 | version "1.5.0" 123 | resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.0.tgz#2f255a3f186635c4fb5a2381e375d3dfbc5312d8" 124 | integrity sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA== 125 | 126 | "@sapphire/shapeshift@^3.7.1": 127 | version "3.7.1" 128 | resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.7.1.tgz#11f6b7bedc5bc980a1de57bd98ea2566d679d39f" 129 | integrity sha512-JmYN/0GW49Vl8Hi4PwrsDBNjcuCylH78vWYolVys74LRIzilAAMINxx4RHQOdvYoz+ceJKVp4+zBbQ5kuIFOLw== 130 | dependencies: 131 | fast-deep-equal "^3.1.3" 132 | lodash.uniqwith "^4.5.0" 133 | 134 | "@sapphire/snowflake@^3.2.2": 135 | version "3.3.0" 136 | resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.3.0.tgz#247413e4d7924a9f508c6a5c8d427e4105ac0fe6" 137 | integrity sha512-Hec5N6zEkZuZFLybVKyLFLlcSgYmR6C1/+9NkIhxPwOf6tgX52ndJCSz8ADejmbrNE0VuNCNkpzhRZzenEC9vA== 138 | 139 | "@tokenizer/token@^0.3.0": 140 | version "0.3.0" 141 | resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" 142 | integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== 143 | 144 | "@tsconfig/node10@^1.0.7": 145 | version "1.0.9" 146 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" 147 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== 148 | 149 | "@tsconfig/node12@^1.0.7": 150 | version "1.0.11" 151 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 152 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 153 | 154 | "@tsconfig/node14@^1.0.0": 155 | version "1.0.3" 156 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 157 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 158 | 159 | "@tsconfig/node16@^1.0.2": 160 | version "1.0.3" 161 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" 162 | integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== 163 | 164 | "@types/json-schema@^7.0.9": 165 | version "7.0.9" 166 | resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz" 167 | integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== 168 | 169 | "@types/node@*": 170 | version "16.11.1" 171 | resolved "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz" 172 | integrity sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA== 173 | 174 | "@types/node@^18.11.10": 175 | version "18.11.10" 176 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.10.tgz#4c64759f3c2343b7e6c4b9caf761c7a3a05cee34" 177 | integrity sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ== 178 | 179 | "@types/semver@^7.3.12": 180 | version "7.3.13" 181 | resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" 182 | integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== 183 | 184 | "@types/strip-bom@^3.0.0": 185 | version "3.0.0" 186 | resolved "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz" 187 | integrity sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I= 188 | 189 | "@types/strip-json-comments@0.0.30": 190 | version "0.0.30" 191 | resolved "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz" 192 | integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== 193 | 194 | "@types/ws@^8.5.3": 195 | version "8.5.3" 196 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" 197 | integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== 198 | dependencies: 199 | "@types/node" "*" 200 | 201 | "@typescript-eslint/eslint-plugin@^5.45.0": 202 | version "5.45.0" 203 | resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz#ffa505cf961d4844d38cfa19dcec4973a6039e41" 204 | integrity sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA== 205 | dependencies: 206 | "@typescript-eslint/scope-manager" "5.45.0" 207 | "@typescript-eslint/type-utils" "5.45.0" 208 | "@typescript-eslint/utils" "5.45.0" 209 | debug "^4.3.4" 210 | ignore "^5.2.0" 211 | natural-compare-lite "^1.4.0" 212 | regexpp "^3.2.0" 213 | semver "^7.3.7" 214 | tsutils "^3.21.0" 215 | 216 | "@typescript-eslint/parser@^5.45.0": 217 | version "5.45.0" 218 | resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.45.0.tgz#b18a5f6b3cf1c2b3e399e9d2df4be40d6b0ddd0e" 219 | integrity sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ== 220 | dependencies: 221 | "@typescript-eslint/scope-manager" "5.45.0" 222 | "@typescript-eslint/types" "5.45.0" 223 | "@typescript-eslint/typescript-estree" "5.45.0" 224 | debug "^4.3.4" 225 | 226 | "@typescript-eslint/scope-manager@5.45.0": 227 | version "5.45.0" 228 | resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz#7a4ac1bfa9544bff3f620ab85947945938319a96" 229 | integrity sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw== 230 | dependencies: 231 | "@typescript-eslint/types" "5.45.0" 232 | "@typescript-eslint/visitor-keys" "5.45.0" 233 | 234 | "@typescript-eslint/type-utils@5.45.0": 235 | version "5.45.0" 236 | resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz#aefbc954c40878fcebeabfb77d20d84a3da3a8b2" 237 | integrity sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q== 238 | dependencies: 239 | "@typescript-eslint/typescript-estree" "5.45.0" 240 | "@typescript-eslint/utils" "5.45.0" 241 | debug "^4.3.4" 242 | tsutils "^3.21.0" 243 | 244 | "@typescript-eslint/types@5.45.0": 245 | version "5.45.0" 246 | resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.45.0.tgz#794760b9037ee4154c09549ef5a96599621109c5" 247 | integrity sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA== 248 | 249 | "@typescript-eslint/typescript-estree@5.45.0": 250 | version "5.45.0" 251 | resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz#f70a0d646d7f38c0dfd6936a5e171a77f1e5291d" 252 | integrity sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ== 253 | dependencies: 254 | "@typescript-eslint/types" "5.45.0" 255 | "@typescript-eslint/visitor-keys" "5.45.0" 256 | debug "^4.3.4" 257 | globby "^11.1.0" 258 | is-glob "^4.0.3" 259 | semver "^7.3.7" 260 | tsutils "^3.21.0" 261 | 262 | "@typescript-eslint/utils@5.45.0": 263 | version "5.45.0" 264 | resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.45.0.tgz#9cca2996eee1b8615485a6918a5c763629c7acf5" 265 | integrity sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA== 266 | dependencies: 267 | "@types/json-schema" "^7.0.9" 268 | "@types/semver" "^7.3.12" 269 | "@typescript-eslint/scope-manager" "5.45.0" 270 | "@typescript-eslint/types" "5.45.0" 271 | "@typescript-eslint/typescript-estree" "5.45.0" 272 | eslint-scope "^5.1.1" 273 | eslint-utils "^3.0.0" 274 | semver "^7.3.7" 275 | 276 | "@typescript-eslint/visitor-keys@5.45.0": 277 | version "5.45.0" 278 | resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz#e0d160e9e7fdb7f8da697a5b78e7a14a22a70528" 279 | integrity sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg== 280 | dependencies: 281 | "@typescript-eslint/types" "5.45.0" 282 | eslint-visitor-keys "^3.3.0" 283 | 284 | acorn-jsx@^5.3.2: 285 | version "5.3.2" 286 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 287 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 288 | 289 | acorn-walk@^8.1.1: 290 | version "8.2.0" 291 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" 292 | integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== 293 | 294 | acorn@^8.4.1, acorn@^8.8.0: 295 | version "8.8.1" 296 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" 297 | integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== 298 | 299 | ajv@^6.10.0, ajv@^6.12.4: 300 | version "6.12.6" 301 | resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" 302 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 303 | dependencies: 304 | fast-deep-equal "^3.1.1" 305 | fast-json-stable-stringify "^2.0.0" 306 | json-schema-traverse "^0.4.1" 307 | uri-js "^4.2.2" 308 | 309 | ansi-regex@^5.0.1: 310 | version "5.0.1" 311 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" 312 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 313 | 314 | ansi-styles@^4.1.0: 315 | version "4.3.0" 316 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" 317 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 318 | dependencies: 319 | color-convert "^2.0.1" 320 | 321 | anymatch@~3.1.2: 322 | version "3.1.2" 323 | resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" 324 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 325 | dependencies: 326 | normalize-path "^3.0.0" 327 | picomatch "^2.0.4" 328 | 329 | arg@^4.1.0: 330 | version "4.1.3" 331 | resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" 332 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 333 | 334 | argparse@^2.0.1: 335 | version "2.0.1" 336 | resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" 337 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 338 | 339 | array-union@^2.1.0: 340 | version "2.1.0" 341 | resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" 342 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 343 | 344 | balanced-match@^1.0.0: 345 | version "1.0.2" 346 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 347 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 348 | 349 | binary-extensions@^2.0.0: 350 | version "2.2.0" 351 | resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" 352 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 353 | 354 | brace-expansion@^1.1.7: 355 | version "1.1.11" 356 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 357 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 358 | dependencies: 359 | balanced-match "^1.0.0" 360 | concat-map "0.0.1" 361 | 362 | braces@^3.0.1, braces@~3.0.2: 363 | version "3.0.2" 364 | resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" 365 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 366 | dependencies: 367 | fill-range "^7.0.1" 368 | 369 | buffer-from@^1.0.0: 370 | version "1.1.2" 371 | resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" 372 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 373 | 374 | busboy@^1.6.0: 375 | version "1.6.0" 376 | resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" 377 | integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== 378 | dependencies: 379 | streamsearch "^1.1.0" 380 | 381 | callsites@^3.0.0: 382 | version "3.1.0" 383 | resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" 384 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 385 | 386 | chalk@^4.0.0: 387 | version "4.1.2" 388 | resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" 389 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 390 | dependencies: 391 | ansi-styles "^4.1.0" 392 | supports-color "^7.1.0" 393 | 394 | chokidar@^3.5.1: 395 | version "3.5.2" 396 | resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz" 397 | integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== 398 | dependencies: 399 | anymatch "~3.1.2" 400 | braces "~3.0.2" 401 | glob-parent "~5.1.2" 402 | is-binary-path "~2.1.0" 403 | is-glob "~4.0.1" 404 | normalize-path "~3.0.0" 405 | readdirp "~3.6.0" 406 | optionalDependencies: 407 | fsevents "~2.3.2" 408 | 409 | color-convert@^2.0.1: 410 | version "2.0.1" 411 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" 412 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 413 | dependencies: 414 | color-name "~1.1.4" 415 | 416 | color-name@~1.1.4: 417 | version "1.1.4" 418 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 419 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 420 | 421 | concat-map@0.0.1: 422 | version "0.0.1" 423 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 424 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 425 | 426 | create-require@^1.1.0: 427 | version "1.1.1" 428 | resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" 429 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 430 | 431 | cross-spawn@^7.0.2: 432 | version "7.0.3" 433 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" 434 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 435 | dependencies: 436 | path-key "^3.1.0" 437 | shebang-command "^2.0.0" 438 | which "^2.0.1" 439 | 440 | debug@^4.1.1, debug@^4.3.2: 441 | version "4.3.2" 442 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz" 443 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 444 | dependencies: 445 | ms "2.1.2" 446 | 447 | debug@^4.3.4: 448 | version "4.3.4" 449 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 450 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 451 | dependencies: 452 | ms "2.1.2" 453 | 454 | deep-is@^0.1.3: 455 | version "0.1.4" 456 | resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" 457 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 458 | 459 | diff@^4.0.1: 460 | version "4.0.2" 461 | resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" 462 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 463 | 464 | dir-glob@^3.0.1: 465 | version "3.0.1" 466 | resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" 467 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 468 | dependencies: 469 | path-type "^4.0.0" 470 | 471 | discord-api-types@^0.37.20: 472 | version "0.37.20" 473 | resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.20.tgz#f23894e3e6b894abb5431ff6c4aa52471360377c" 474 | integrity sha512-uAO+55E11rMkYR36/paE1vKN8c2bZa1mgrIaiQIBgIZRKZTDIGOZB+8I5eMRPFJcGxrg16riUu+0aTu2JQEPew== 475 | 476 | discord.js@^14.7.1: 477 | version "14.7.1" 478 | resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.7.1.tgz#26079d0ff4d27daf02480a403c456121f0682bd9" 479 | integrity sha512-1FECvqJJjjeYcjSm0IGMnPxLqja/pmG1B0W2l3lUY2Gi4KXiyTeQmU1IxWcbXHn2k+ytP587mMWqva2IA87EbA== 480 | dependencies: 481 | "@discordjs/builders" "^1.4.0" 482 | "@discordjs/collection" "^1.3.0" 483 | "@discordjs/rest" "^1.4.0" 484 | "@discordjs/util" "^0.1.0" 485 | "@sapphire/snowflake" "^3.2.2" 486 | "@types/ws" "^8.5.3" 487 | discord-api-types "^0.37.20" 488 | fast-deep-equal "^3.1.3" 489 | lodash.snakecase "^4.1.1" 490 | tslib "^2.4.1" 491 | undici "^5.13.0" 492 | ws "^8.11.0" 493 | 494 | doctrine@^3.0.0: 495 | version "3.0.0" 496 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" 497 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 498 | dependencies: 499 | esutils "^2.0.2" 500 | 501 | dotenv@^16.0.3: 502 | version "16.0.3" 503 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" 504 | integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== 505 | 506 | dynamic-dedupe@^0.3.0: 507 | version "0.3.0" 508 | resolved "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz" 509 | integrity sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE= 510 | dependencies: 511 | xtend "^4.0.0" 512 | 513 | escape-string-regexp@^4.0.0: 514 | version "4.0.0" 515 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" 516 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 517 | 518 | eslint-config-prettier@^8.5.0: 519 | version "8.5.0" 520 | resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" 521 | integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== 522 | 523 | eslint-plugin-prettier@^4.2.1: 524 | version "4.2.1" 525 | resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" 526 | integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== 527 | dependencies: 528 | prettier-linter-helpers "^1.0.0" 529 | 530 | eslint-scope@^5.1.1: 531 | version "5.1.1" 532 | resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" 533 | integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== 534 | dependencies: 535 | esrecurse "^4.3.0" 536 | estraverse "^4.1.1" 537 | 538 | eslint-scope@^7.1.1: 539 | version "7.1.1" 540 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" 541 | integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== 542 | dependencies: 543 | esrecurse "^4.3.0" 544 | estraverse "^5.2.0" 545 | 546 | eslint-utils@^3.0.0: 547 | version "3.0.0" 548 | resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" 549 | integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== 550 | dependencies: 551 | eslint-visitor-keys "^2.0.0" 552 | 553 | eslint-visitor-keys@^2.0.0: 554 | version "2.1.0" 555 | resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" 556 | integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 557 | 558 | eslint-visitor-keys@^3.3.0: 559 | version "3.3.0" 560 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" 561 | integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== 562 | 563 | eslint@^8.29.0: 564 | version "8.29.0" 565 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.29.0.tgz#d74a88a20fb44d59c51851625bc4ee8d0ec43f87" 566 | integrity sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg== 567 | dependencies: 568 | "@eslint/eslintrc" "^1.3.3" 569 | "@humanwhocodes/config-array" "^0.11.6" 570 | "@humanwhocodes/module-importer" "^1.0.1" 571 | "@nodelib/fs.walk" "^1.2.8" 572 | ajv "^6.10.0" 573 | chalk "^4.0.0" 574 | cross-spawn "^7.0.2" 575 | debug "^4.3.2" 576 | doctrine "^3.0.0" 577 | escape-string-regexp "^4.0.0" 578 | eslint-scope "^7.1.1" 579 | eslint-utils "^3.0.0" 580 | eslint-visitor-keys "^3.3.0" 581 | espree "^9.4.0" 582 | esquery "^1.4.0" 583 | esutils "^2.0.2" 584 | fast-deep-equal "^3.1.3" 585 | file-entry-cache "^6.0.1" 586 | find-up "^5.0.0" 587 | glob-parent "^6.0.2" 588 | globals "^13.15.0" 589 | grapheme-splitter "^1.0.4" 590 | ignore "^5.2.0" 591 | import-fresh "^3.0.0" 592 | imurmurhash "^0.1.4" 593 | is-glob "^4.0.0" 594 | is-path-inside "^3.0.3" 595 | js-sdsl "^4.1.4" 596 | js-yaml "^4.1.0" 597 | json-stable-stringify-without-jsonify "^1.0.1" 598 | levn "^0.4.1" 599 | lodash.merge "^4.6.2" 600 | minimatch "^3.1.2" 601 | natural-compare "^1.4.0" 602 | optionator "^0.9.1" 603 | regexpp "^3.2.0" 604 | strip-ansi "^6.0.1" 605 | strip-json-comments "^3.1.0" 606 | text-table "^0.2.0" 607 | 608 | espree@^9.4.0: 609 | version "9.4.1" 610 | resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" 611 | integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== 612 | dependencies: 613 | acorn "^8.8.0" 614 | acorn-jsx "^5.3.2" 615 | eslint-visitor-keys "^3.3.0" 616 | 617 | esquery@^1.4.0: 618 | version "1.4.0" 619 | resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" 620 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 621 | dependencies: 622 | estraverse "^5.1.0" 623 | 624 | esrecurse@^4.3.0: 625 | version "4.3.0" 626 | resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" 627 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 628 | dependencies: 629 | estraverse "^5.2.0" 630 | 631 | estraverse@^4.1.1: 632 | version "4.3.0" 633 | resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" 634 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 635 | 636 | estraverse@^5.1.0, estraverse@^5.2.0: 637 | version "5.2.0" 638 | resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" 639 | integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== 640 | 641 | esutils@^2.0.2: 642 | version "2.0.3" 643 | resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" 644 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 645 | 646 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 647 | version "3.1.3" 648 | resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" 649 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 650 | 651 | fast-diff@^1.1.2: 652 | version "1.2.0" 653 | resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz" 654 | integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== 655 | 656 | fast-glob@^3.2.9: 657 | version "3.2.12" 658 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" 659 | integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== 660 | dependencies: 661 | "@nodelib/fs.stat" "^2.0.2" 662 | "@nodelib/fs.walk" "^1.2.3" 663 | glob-parent "^5.1.2" 664 | merge2 "^1.3.0" 665 | micromatch "^4.0.4" 666 | 667 | fast-json-stable-stringify@^2.0.0: 668 | version "2.1.0" 669 | resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" 670 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 671 | 672 | fast-levenshtein@^2.0.6: 673 | version "2.0.6" 674 | resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" 675 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 676 | 677 | fastq@^1.6.0: 678 | version "1.13.0" 679 | resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz" 680 | integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== 681 | dependencies: 682 | reusify "^1.0.4" 683 | 684 | file-entry-cache@^6.0.1: 685 | version "6.0.1" 686 | resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" 687 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 688 | dependencies: 689 | flat-cache "^3.0.4" 690 | 691 | file-type@^18.0.0: 692 | version "18.0.0" 693 | resolved "https://registry.yarnpkg.com/file-type/-/file-type-18.0.0.tgz#7a39378f8657ddc02807a0c62cb77cb4dc318197" 694 | integrity sha512-jjMwFpnW8PKofLE/4ohlhqwDk5k0NC6iy0UHAJFKoY1fQeGMN0GDdLgHQrvCbSpMwbqzoCZhRI5dETCZna5qVA== 695 | dependencies: 696 | readable-web-to-node-stream "^3.0.2" 697 | strtok3 "^7.0.0" 698 | token-types "^5.0.1" 699 | 700 | fill-range@^7.0.1: 701 | version "7.0.1" 702 | resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" 703 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 704 | dependencies: 705 | to-regex-range "^5.0.1" 706 | 707 | find-up@^5.0.0: 708 | version "5.0.0" 709 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 710 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 711 | dependencies: 712 | locate-path "^6.0.0" 713 | path-exists "^4.0.0" 714 | 715 | flat-cache@^3.0.4: 716 | version "3.0.4" 717 | resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" 718 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 719 | dependencies: 720 | flatted "^3.1.0" 721 | rimraf "^3.0.2" 722 | 723 | flatted@^3.1.0: 724 | version "3.2.2" 725 | resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz" 726 | integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== 727 | 728 | fs.realpath@^1.0.0: 729 | version "1.0.0" 730 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 731 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 732 | 733 | fsevents@~2.3.2: 734 | version "2.3.2" 735 | resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" 736 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 737 | 738 | function-bind@^1.1.1: 739 | version "1.1.1" 740 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" 741 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 742 | 743 | glob-parent@^5.1.2, glob-parent@~5.1.2: 744 | version "5.1.2" 745 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" 746 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 747 | dependencies: 748 | is-glob "^4.0.1" 749 | 750 | glob-parent@^6.0.2: 751 | version "6.0.2" 752 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" 753 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 754 | dependencies: 755 | is-glob "^4.0.3" 756 | 757 | glob@^7.1.3: 758 | version "7.2.0" 759 | resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" 760 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 761 | dependencies: 762 | fs.realpath "^1.0.0" 763 | inflight "^1.0.4" 764 | inherits "2" 765 | minimatch "^3.0.4" 766 | once "^1.3.0" 767 | path-is-absolute "^1.0.0" 768 | 769 | globals@^13.15.0: 770 | version "13.18.0" 771 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.18.0.tgz#fb224daeeb2bb7d254cd2c640f003528b8d0c1dc" 772 | integrity sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A== 773 | dependencies: 774 | type-fest "^0.20.2" 775 | 776 | globby@^11.1.0: 777 | version "11.1.0" 778 | resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" 779 | integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== 780 | dependencies: 781 | array-union "^2.1.0" 782 | dir-glob "^3.0.1" 783 | fast-glob "^3.2.9" 784 | ignore "^5.2.0" 785 | merge2 "^1.4.1" 786 | slash "^3.0.0" 787 | 788 | grapheme-splitter@^1.0.4: 789 | version "1.0.4" 790 | resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" 791 | integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== 792 | 793 | has-flag@^4.0.0: 794 | version "4.0.0" 795 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" 796 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 797 | 798 | has@^1.0.3: 799 | version "1.0.3" 800 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" 801 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 802 | dependencies: 803 | function-bind "^1.1.1" 804 | 805 | ieee754@^1.2.1: 806 | version "1.2.1" 807 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 808 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 809 | 810 | ignore@^5.2.0: 811 | version "5.2.1" 812 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.1.tgz#c2b1f76cb999ede1502f3a226a9310fdfe88d46c" 813 | integrity sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA== 814 | 815 | import-fresh@^3.0.0, import-fresh@^3.2.1: 816 | version "3.3.0" 817 | resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" 818 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 819 | dependencies: 820 | parent-module "^1.0.0" 821 | resolve-from "^4.0.0" 822 | 823 | imurmurhash@^0.1.4: 824 | version "0.1.4" 825 | resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" 826 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 827 | 828 | inflight@^1.0.4: 829 | version "1.0.6" 830 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 831 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 832 | dependencies: 833 | once "^1.3.0" 834 | wrappy "1" 835 | 836 | inherits@2, inherits@^2.0.3: 837 | version "2.0.4" 838 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 839 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 840 | 841 | is-binary-path@~2.1.0: 842 | version "2.1.0" 843 | resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" 844 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 845 | dependencies: 846 | binary-extensions "^2.0.0" 847 | 848 | is-core-module@^2.2.0: 849 | version "2.8.0" 850 | resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz" 851 | integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== 852 | dependencies: 853 | has "^1.0.3" 854 | 855 | is-extglob@^2.1.1: 856 | version "2.1.1" 857 | resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" 858 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 859 | 860 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: 861 | version "4.0.3" 862 | resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" 863 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 864 | dependencies: 865 | is-extglob "^2.1.1" 866 | 867 | is-number@^7.0.0: 868 | version "7.0.0" 869 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 870 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 871 | 872 | is-path-inside@^3.0.3: 873 | version "3.0.3" 874 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" 875 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== 876 | 877 | isexe@^2.0.0: 878 | version "2.0.0" 879 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" 880 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 881 | 882 | js-sdsl@^4.1.4: 883 | version "4.2.0" 884 | resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" 885 | integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== 886 | 887 | js-yaml@^4.1.0: 888 | version "4.1.0" 889 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" 890 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 891 | dependencies: 892 | argparse "^2.0.1" 893 | 894 | json-schema-traverse@^0.4.1: 895 | version "0.4.1" 896 | resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" 897 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 898 | 899 | json-stable-stringify-without-jsonify@^1.0.1: 900 | version "1.0.1" 901 | resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" 902 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 903 | 904 | levn@^0.4.1: 905 | version "0.4.1" 906 | resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" 907 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 908 | dependencies: 909 | prelude-ls "^1.2.1" 910 | type-check "~0.4.0" 911 | 912 | locate-path@^6.0.0: 913 | version "6.0.0" 914 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 915 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 916 | dependencies: 917 | p-locate "^5.0.0" 918 | 919 | lodash.merge@^4.6.2: 920 | version "4.6.2" 921 | resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" 922 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 923 | 924 | lodash.snakecase@^4.1.1: 925 | version "4.1.1" 926 | resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" 927 | integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== 928 | 929 | lodash.uniqwith@^4.5.0: 930 | version "4.5.0" 931 | resolved "https://registry.yarnpkg.com/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz#7a0cbf65f43b5928625a9d4d0dc54b18cadc7ef3" 932 | integrity sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q== 933 | 934 | lru-cache@^6.0.0: 935 | version "6.0.0" 936 | resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" 937 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 938 | dependencies: 939 | yallist "^4.0.0" 940 | 941 | make-error@^1.1.1: 942 | version "1.3.6" 943 | resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" 944 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 945 | 946 | merge2@^1.3.0, merge2@^1.4.1: 947 | version "1.4.1" 948 | resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" 949 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 950 | 951 | micromatch@^4.0.4: 952 | version "4.0.4" 953 | resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz" 954 | integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== 955 | dependencies: 956 | braces "^3.0.1" 957 | picomatch "^2.2.3" 958 | 959 | minimatch@^3.0.4: 960 | version "3.0.4" 961 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" 962 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 963 | dependencies: 964 | brace-expansion "^1.1.7" 965 | 966 | minimatch@^3.0.5, minimatch@^3.1.2: 967 | version "3.1.2" 968 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 969 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 970 | dependencies: 971 | brace-expansion "^1.1.7" 972 | 973 | minimist@^1.2.6: 974 | version "1.2.7" 975 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" 976 | integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== 977 | 978 | mkdirp@^1.0.4: 979 | version "1.0.4" 980 | resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" 981 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 982 | 983 | ms@2.1.2: 984 | version "2.1.2" 985 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" 986 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 987 | 988 | natural-compare-lite@^1.4.0: 989 | version "1.4.0" 990 | resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" 991 | integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== 992 | 993 | natural-compare@^1.4.0: 994 | version "1.4.0" 995 | resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" 996 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 997 | 998 | normalize-path@^3.0.0, normalize-path@~3.0.0: 999 | version "3.0.0" 1000 | resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" 1001 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1002 | 1003 | once@^1.3.0: 1004 | version "1.4.0" 1005 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 1006 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1007 | dependencies: 1008 | wrappy "1" 1009 | 1010 | optionator@^0.9.1: 1011 | version "0.9.1" 1012 | resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" 1013 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 1014 | dependencies: 1015 | deep-is "^0.1.3" 1016 | fast-levenshtein "^2.0.6" 1017 | levn "^0.4.1" 1018 | prelude-ls "^1.2.1" 1019 | type-check "^0.4.0" 1020 | word-wrap "^1.2.3" 1021 | 1022 | p-limit@^3.0.2: 1023 | version "3.1.0" 1024 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 1025 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 1026 | dependencies: 1027 | yocto-queue "^0.1.0" 1028 | 1029 | p-locate@^5.0.0: 1030 | version "5.0.0" 1031 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 1032 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 1033 | dependencies: 1034 | p-limit "^3.0.2" 1035 | 1036 | parent-module@^1.0.0: 1037 | version "1.0.1" 1038 | resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" 1039 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 1040 | dependencies: 1041 | callsites "^3.0.0" 1042 | 1043 | path-exists@^4.0.0: 1044 | version "4.0.0" 1045 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 1046 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1047 | 1048 | path-is-absolute@^1.0.0: 1049 | version "1.0.1" 1050 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 1051 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1052 | 1053 | path-key@^3.1.0: 1054 | version "3.1.1" 1055 | resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" 1056 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1057 | 1058 | path-parse@^1.0.6: 1059 | version "1.0.7" 1060 | resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" 1061 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 1062 | 1063 | path-type@^4.0.0: 1064 | version "4.0.0" 1065 | resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" 1066 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 1067 | 1068 | peek-readable@^5.0.0: 1069 | version "5.0.0" 1070 | resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0.tgz#7ead2aff25dc40458c60347ea76cfdfd63efdfec" 1071 | integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A== 1072 | 1073 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: 1074 | version "2.3.0" 1075 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz" 1076 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== 1077 | 1078 | prelude-ls@^1.2.1: 1079 | version "1.2.1" 1080 | resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" 1081 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 1082 | 1083 | prettier-linter-helpers@^1.0.0: 1084 | version "1.0.0" 1085 | resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz" 1086 | integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== 1087 | dependencies: 1088 | fast-diff "^1.1.2" 1089 | 1090 | prettier@^2.8.0: 1091 | version "2.8.0" 1092 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.0.tgz#c7df58393c9ba77d6fba3921ae01faf994fb9dc9" 1093 | integrity sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA== 1094 | 1095 | punycode@^2.1.0: 1096 | version "2.1.1" 1097 | resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" 1098 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1099 | 1100 | queue-microtask@^1.2.2: 1101 | version "1.2.3" 1102 | resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" 1103 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 1104 | 1105 | readable-stream@^3.6.0: 1106 | version "3.6.0" 1107 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 1108 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 1109 | dependencies: 1110 | inherits "^2.0.3" 1111 | string_decoder "^1.1.1" 1112 | util-deprecate "^1.0.1" 1113 | 1114 | readable-web-to-node-stream@^3.0.2: 1115 | version "3.0.2" 1116 | resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" 1117 | integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== 1118 | dependencies: 1119 | readable-stream "^3.6.0" 1120 | 1121 | readdirp@~3.6.0: 1122 | version "3.6.0" 1123 | resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" 1124 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1125 | dependencies: 1126 | picomatch "^2.2.1" 1127 | 1128 | regexpp@^3.2.0: 1129 | version "3.2.0" 1130 | resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" 1131 | integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== 1132 | 1133 | resolve-from@^4.0.0: 1134 | version "4.0.0" 1135 | resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" 1136 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1137 | 1138 | resolve@^1.0.0: 1139 | version "1.20.0" 1140 | resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz" 1141 | integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== 1142 | dependencies: 1143 | is-core-module "^2.2.0" 1144 | path-parse "^1.0.6" 1145 | 1146 | reusify@^1.0.4: 1147 | version "1.0.4" 1148 | resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" 1149 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 1150 | 1151 | rimraf@^2.6.1: 1152 | version "2.7.1" 1153 | resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" 1154 | integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== 1155 | dependencies: 1156 | glob "^7.1.3" 1157 | 1158 | rimraf@^3.0.2: 1159 | version "3.0.2" 1160 | resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" 1161 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1162 | dependencies: 1163 | glob "^7.1.3" 1164 | 1165 | run-parallel@^1.1.9: 1166 | version "1.2.0" 1167 | resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" 1168 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1169 | dependencies: 1170 | queue-microtask "^1.2.2" 1171 | 1172 | safe-buffer@~5.2.0: 1173 | version "5.2.1" 1174 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1175 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1176 | 1177 | semver@^7.3.7: 1178 | version "7.3.8" 1179 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" 1180 | integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== 1181 | dependencies: 1182 | lru-cache "^6.0.0" 1183 | 1184 | shebang-command@^2.0.0: 1185 | version "2.0.0" 1186 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" 1187 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1188 | dependencies: 1189 | shebang-regex "^3.0.0" 1190 | 1191 | shebang-regex@^3.0.0: 1192 | version "3.0.0" 1193 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" 1194 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1195 | 1196 | slash@^3.0.0: 1197 | version "3.0.0" 1198 | resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" 1199 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 1200 | 1201 | source-map-support@^0.5.12: 1202 | version "0.5.20" 1203 | resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz" 1204 | integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== 1205 | dependencies: 1206 | buffer-from "^1.0.0" 1207 | source-map "^0.6.0" 1208 | 1209 | source-map@^0.6.0: 1210 | version "0.6.1" 1211 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" 1212 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1213 | 1214 | streamsearch@^1.1.0: 1215 | version "1.1.0" 1216 | resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" 1217 | integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== 1218 | 1219 | string_decoder@^1.1.1: 1220 | version "1.3.0" 1221 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1222 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1223 | dependencies: 1224 | safe-buffer "~5.2.0" 1225 | 1226 | strip-ansi@^6.0.1: 1227 | version "6.0.1" 1228 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1229 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1230 | dependencies: 1231 | ansi-regex "^5.0.1" 1232 | 1233 | strip-bom@^3.0.0: 1234 | version "3.0.0" 1235 | resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" 1236 | integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= 1237 | 1238 | strip-json-comments@^2.0.0: 1239 | version "2.0.1" 1240 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" 1241 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 1242 | 1243 | strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: 1244 | version "3.1.1" 1245 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" 1246 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1247 | 1248 | strtok3@^7.0.0: 1249 | version "7.0.0" 1250 | resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0.tgz#868c428b4ade64a8fd8fee7364256001c1a4cbe5" 1251 | integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ== 1252 | dependencies: 1253 | "@tokenizer/token" "^0.3.0" 1254 | peek-readable "^5.0.0" 1255 | 1256 | supports-color@^7.1.0: 1257 | version "7.2.0" 1258 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" 1259 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1260 | dependencies: 1261 | has-flag "^4.0.0" 1262 | 1263 | text-table@^0.2.0: 1264 | version "0.2.0" 1265 | resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" 1266 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 1267 | 1268 | to-regex-range@^5.0.1: 1269 | version "5.0.1" 1270 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 1271 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1272 | dependencies: 1273 | is-number "^7.0.0" 1274 | 1275 | token-types@^5.0.1: 1276 | version "5.0.1" 1277 | resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.1.tgz#aa9d9e6b23c420a675e55413b180635b86a093b4" 1278 | integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg== 1279 | dependencies: 1280 | "@tokenizer/token" "^0.3.0" 1281 | ieee754 "^1.2.1" 1282 | 1283 | tree-kill@^1.2.2: 1284 | version "1.2.2" 1285 | resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" 1286 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 1287 | 1288 | ts-mixer@^6.0.2: 1289 | version "6.0.2" 1290 | resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.2.tgz#3e4e4bb8daffb24435f6980b15204cb5b287e016" 1291 | integrity sha512-zvHx3VM83m2WYCE8XL99uaM7mFwYSkjR2OZti98fabHrwkjsCvgwChda5xctein3xGOyaQhtTeDq/1H/GNvF3A== 1292 | 1293 | ts-node-dev@^2.0.0: 1294 | version "2.0.0" 1295 | resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-2.0.0.tgz#bdd53e17ab3b5d822ef519928dc6b4a7e0f13065" 1296 | integrity sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w== 1297 | dependencies: 1298 | chokidar "^3.5.1" 1299 | dynamic-dedupe "^0.3.0" 1300 | minimist "^1.2.6" 1301 | mkdirp "^1.0.4" 1302 | resolve "^1.0.0" 1303 | rimraf "^2.6.1" 1304 | source-map-support "^0.5.12" 1305 | tree-kill "^1.2.2" 1306 | ts-node "^10.4.0" 1307 | tsconfig "^7.0.0" 1308 | 1309 | ts-node@^10.4.0, ts-node@^10.9.1: 1310 | version "10.9.1" 1311 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" 1312 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== 1313 | dependencies: 1314 | "@cspotcode/source-map-support" "^0.8.0" 1315 | "@tsconfig/node10" "^1.0.7" 1316 | "@tsconfig/node12" "^1.0.7" 1317 | "@tsconfig/node14" "^1.0.0" 1318 | "@tsconfig/node16" "^1.0.2" 1319 | acorn "^8.4.1" 1320 | acorn-walk "^8.1.1" 1321 | arg "^4.1.0" 1322 | create-require "^1.1.0" 1323 | diff "^4.0.1" 1324 | make-error "^1.1.1" 1325 | v8-compile-cache-lib "^3.0.1" 1326 | yn "3.1.1" 1327 | 1328 | tsconfig@^7.0.0: 1329 | version "7.0.0" 1330 | resolved "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz" 1331 | integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== 1332 | dependencies: 1333 | "@types/strip-bom" "^3.0.0" 1334 | "@types/strip-json-comments" "0.0.30" 1335 | strip-bom "^3.0.0" 1336 | strip-json-comments "^2.0.0" 1337 | 1338 | tslib@^1.8.1: 1339 | version "1.14.1" 1340 | resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" 1341 | integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== 1342 | 1343 | tslib@^2.4.1: 1344 | version "2.4.1" 1345 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" 1346 | integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== 1347 | 1348 | tsutils@^3.21.0: 1349 | version "3.21.0" 1350 | resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" 1351 | integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== 1352 | dependencies: 1353 | tslib "^1.8.1" 1354 | 1355 | type-check@^0.4.0, type-check@~0.4.0: 1356 | version "0.4.0" 1357 | resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" 1358 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1359 | dependencies: 1360 | prelude-ls "^1.2.1" 1361 | 1362 | type-fest@^0.20.2: 1363 | version "0.20.2" 1364 | resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" 1365 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1366 | 1367 | typescript@^4.9.3: 1368 | version "4.9.3" 1369 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" 1370 | integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== 1371 | 1372 | undici@^5.13.0: 1373 | version "5.13.0" 1374 | resolved "https://registry.yarnpkg.com/undici/-/undici-5.13.0.tgz#56772fba89d8b25e39bddc8c26a438bd73ea69bb" 1375 | integrity sha512-UDZKtwb2k7KRsK4SdXWG7ErXiL7yTGgLWvk2AXO1JMjgjh404nFo6tWSCM2xMpJwMPx3J8i/vfqEh1zOqvj82Q== 1376 | dependencies: 1377 | busboy "^1.6.0" 1378 | 1379 | uri-js@^4.2.2: 1380 | version "4.4.1" 1381 | resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" 1382 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1383 | dependencies: 1384 | punycode "^2.1.0" 1385 | 1386 | util-deprecate@^1.0.1: 1387 | version "1.0.2" 1388 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1389 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1390 | 1391 | v8-compile-cache-lib@^3.0.1: 1392 | version "3.0.1" 1393 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 1394 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 1395 | 1396 | which@^2.0.1: 1397 | version "2.0.2" 1398 | resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" 1399 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1400 | dependencies: 1401 | isexe "^2.0.0" 1402 | 1403 | word-wrap@^1.2.3: 1404 | version "1.2.3" 1405 | resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" 1406 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1407 | 1408 | wrappy@1: 1409 | version "1.0.2" 1410 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 1411 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1412 | 1413 | ws@^8.11.0: 1414 | version "8.11.0" 1415 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" 1416 | integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== 1417 | 1418 | xtend@^4.0.0: 1419 | version "4.0.2" 1420 | resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" 1421 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 1422 | 1423 | yallist@^4.0.0: 1424 | version "4.0.0" 1425 | resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" 1426 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1427 | 1428 | yn@3.1.1: 1429 | version "3.1.1" 1430 | resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" 1431 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 1432 | 1433 | yocto-queue@^0.1.0: 1434 | version "0.1.0" 1435 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1436 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1437 | --------------------------------------------------------------------------------