add Showdown calculator
This commit is contained in:
		
							
								
								
									
										145
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										145
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -11,3 +11,148 @@ htmlcov | |||||||
| *.db | *.db | ||||||
| cache/ | cache/ | ||||||
| token | token | ||||||
|  |  | ||||||
|  | # Created by https://www.toptal.com/developers/gitignore/api/node | ||||||
|  | # Edit at https://www.toptal.com/developers/gitignore?templates=node | ||||||
|  |  | ||||||
|  | ### Node ### | ||||||
|  | # Logs | ||||||
|  | logs | ||||||
|  | *.log | ||||||
|  | npm-debug.log* | ||||||
|  | yarn-debug.log* | ||||||
|  | yarn-error.log* | ||||||
|  | lerna-debug.log* | ||||||
|  | .pnpm-debug.log* | ||||||
|  |  | ||||||
|  | # Diagnostic reports (https://nodejs.org/api/report.html) | ||||||
|  | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||||||
|  |  | ||||||
|  | # Runtime data | ||||||
|  | pids | ||||||
|  | *.pid | ||||||
|  | *.seed | ||||||
|  | *.pid.lock | ||||||
|  |  | ||||||
|  | # Directory for instrumented libs generated by jscoverage/JSCover | ||||||
|  | lib-cov | ||||||
|  |  | ||||||
|  | # Coverage directory used by tools like istanbul | ||||||
|  | coverage | ||||||
|  | *.lcov | ||||||
|  |  | ||||||
|  | # nyc test coverage | ||||||
|  | .nyc_output | ||||||
|  |  | ||||||
|  | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||||||
|  | .grunt | ||||||
|  |  | ||||||
|  | # Bower dependency directory (https://bower.io/) | ||||||
|  | bower_components | ||||||
|  |  | ||||||
|  | # node-waf configuration | ||||||
|  | .lock-wscript | ||||||
|  |  | ||||||
|  | # Compiled binary addons (https://nodejs.org/api/addons.html) | ||||||
|  | build/Release | ||||||
|  |  | ||||||
|  | # Dependency directories | ||||||
|  | node_modules/ | ||||||
|  | jspm_packages/ | ||||||
|  |  | ||||||
|  | # Snowpack dependency directory (https://snowpack.dev/) | ||||||
|  | web_modules/ | ||||||
|  |  | ||||||
|  | # TypeScript cache | ||||||
|  | *.tsbuildinfo | ||||||
|  |  | ||||||
|  | # Optional npm cache directory | ||||||
|  | .npm | ||||||
|  |  | ||||||
|  | # Optional eslint cache | ||||||
|  | .eslintcache | ||||||
|  |  | ||||||
|  | # Optional stylelint cache | ||||||
|  | .stylelintcache | ||||||
|  |  | ||||||
|  | # Microbundle cache | ||||||
|  | .rpt2_cache/ | ||||||
|  | .rts2_cache_cjs/ | ||||||
|  | .rts2_cache_es/ | ||||||
|  | .rts2_cache_umd/ | ||||||
|  |  | ||||||
|  | # Optional REPL history | ||||||
|  | .node_repl_history | ||||||
|  |  | ||||||
|  | # Output of 'npm pack' | ||||||
|  | *.tgz | ||||||
|  |  | ||||||
|  | # Yarn Integrity file | ||||||
|  | .yarn-integrity | ||||||
|  |  | ||||||
|  | # dotenv environment variable files | ||||||
|  | .env | ||||||
|  | .env.development.local | ||||||
|  | .env.test.local | ||||||
|  | .env.production.local | ||||||
|  | .env.local | ||||||
|  |  | ||||||
|  | # parcel-bundler cache (https://parceljs.org/) | ||||||
|  | .cache | ||||||
|  | .parcel-cache | ||||||
|  |  | ||||||
|  | # Next.js build output | ||||||
|  | .next | ||||||
|  | out | ||||||
|  |  | ||||||
|  | # Nuxt.js build / generate output | ||||||
|  | .nuxt | ||||||
|  | dist | ||||||
|  |  | ||||||
|  | # Gatsby files | ||||||
|  | .cache/ | ||||||
|  | # Comment in the public line in if your project uses Gatsby and not Next.js | ||||||
|  | # https://nextjs.org/blog/next-9-1#public-directory-support | ||||||
|  | # public | ||||||
|  |  | ||||||
|  | # vuepress build output | ||||||
|  | .vuepress/dist | ||||||
|  |  | ||||||
|  | # vuepress v2.x temp and cache directory | ||||||
|  | .temp | ||||||
|  |  | ||||||
|  | # Docusaurus cache and generated files | ||||||
|  | .docusaurus | ||||||
|  |  | ||||||
|  | # Serverless directories | ||||||
|  | .serverless/ | ||||||
|  |  | ||||||
|  | # FuseBox cache | ||||||
|  | .fusebox/ | ||||||
|  |  | ||||||
|  | # DynamoDB Local files | ||||||
|  | .dynamodb/ | ||||||
|  |  | ||||||
|  | # TernJS port file | ||||||
|  | .tern-port | ||||||
|  |  | ||||||
|  | # Stores VSCode versions used for testing VSCode extensions | ||||||
|  | .vscode-test | ||||||
|  |  | ||||||
|  | # yarn v2 | ||||||
|  | .yarn/cache | ||||||
|  | .yarn/unplugged | ||||||
|  | .yarn/build-state.yml | ||||||
|  | .yarn/install-state.gz | ||||||
|  | .pnp.* | ||||||
|  |  | ||||||
|  | ### Node Patch ### | ||||||
|  | # Serverless Webpack directories | ||||||
|  | .webpack/ | ||||||
|  |  | ||||||
|  | # Optional stylelint cache | ||||||
|  |  | ||||||
|  | # SvelteKit build / generate output | ||||||
|  | .svelte-kit | ||||||
|  |  | ||||||
|  | # End of https://www.toptal.com/developers/gitignore/api/node | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								bot.py
									
									
									
									
									
								
							| @@ -61,11 +61,30 @@ class BotClient(discord.Client): | |||||||
|  |  | ||||||
|     async def on_message(self, message: discord.Message): |     async def on_message(self, message: discord.Message): | ||||||
|         content = message.content |         content = message.content | ||||||
|         if self.is_replay(message): |         if self.is_command(message): | ||||||
|  |             await self.on_command(message) | ||||||
|  |         elif self.is_replay(message): | ||||||
|             await self.on_replay(message) |             await self.on_replay(message) | ||||||
|         elif self.is_leaguefact(message): |         elif self.is_leaguefact(message): | ||||||
|             await self.on_leaguefact(message) |             await self.on_leaguefact(message) | ||||||
|  |  | ||||||
|  |     def is_command(self, message: discord.Message) -> bool: | ||||||
|  |         return message.content.startswith("%") | ||||||
|  |  | ||||||
|  |     async def on_command(self, message: discord.Message): | ||||||
|  |         command = discord.message.split(" ")[0] | ||||||
|  |         match command: | ||||||
|  |             case "%calc": | ||||||
|  |                 reply = await _calculate(command[1:]) | ||||||
|  |                 await message.reply(content=reply) | ||||||
|  |             case _: | ||||||
|  |                 _log.info(f"Unrecognised command {command}") | ||||||
|  |  | ||||||
|  |     async def _calculate(args: list[str]) -> str: | ||||||
|  |         proc = sp.run(["node", "calc_main.js", "--"] + args) | ||||||
|  |         msg = proc.stdout | ||||||
|  |         return msg.strip() | ||||||
|  |  | ||||||
|     def is_replay(self, message: discord.Message) -> bool: |     def is_replay(self, message: discord.Message) -> bool: | ||||||
|         if re.match("https://replay.pokemonshowdown.com/dl-.*", message.content): |         if re.match("https://replay.pokemonshowdown.com/dl-.*", message.content): | ||||||
|             return True |             return True | ||||||
|   | |||||||
							
								
								
									
										299
									
								
								calc.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								calc.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | |||||||
|  | import calc, { | ||||||
|  |   calculate, | ||||||
|  |   Generations, | ||||||
|  |   Field, | ||||||
|  |   Move, | ||||||
|  |   Pokemon, | ||||||
|  | } from "@smogon/calc"; | ||||||
|  | import assert from "assert"; | ||||||
|  | import chev, { Lexer } from "chevrotain"; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Creates a lexer. | ||||||
|  |  * | ||||||
|  |  * @returns {Lexer} | ||||||
|  |  */ | ||||||
|  | function buildLexer() { | ||||||
|  |   const Boost = chev.createToken({ name: "Boost", pattern: /[+-]\d+/ }); | ||||||
|  |   const EV = chev.createToken({ name: "EV", pattern: /\d+[+-]?/ }); | ||||||
|  |   const Stat = chev.createToken({ | ||||||
|  |     name: "Stat", | ||||||
|  |     pattern: /HP|Atk|Def|SpA|SpD|Spe/, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const Item = chev.createToken({ | ||||||
|  |     name: "Item", | ||||||
|  |     pattern: new RegExp(calc.ITEMS.flatMap((gen) => gen).join("|")), | ||||||
|  |   }); | ||||||
|  |   const Ability = chev.createToken({ | ||||||
|  |     name: "Ability", | ||||||
|  |     pattern: new RegExp(calc.ABILITIES.flatMap((gen) => gen).join("|")), | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const Pokemon = chev.createToken({ | ||||||
|  |     name: "Pokemon", | ||||||
|  |     pattern: new RegExp( | ||||||
|  |       calc.SPECIES.flatMap((gen) => Object.keys(gen)).join("|") | ||||||
|  |     ), | ||||||
|  |   }); | ||||||
|  |   const Move = chev.createToken({ | ||||||
|  |     name: "Move", | ||||||
|  |     pattern: new RegExp( | ||||||
|  |       calc.MOVES.flatMap((gen) => Object.keys(gen)).join("|") | ||||||
|  |     ), | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const whitespace = chev.createToken({ | ||||||
|  |     name: "Whitespace", | ||||||
|  |     pattern: /\s+/, | ||||||
|  |     group: Lexer.SKIPPED, | ||||||
|  |   }); | ||||||
|  |   const div = chev.createToken({ | ||||||
|  |     name: "div", | ||||||
|  |     pattern: "/", | ||||||
|  |     group: Lexer.SKIPPED, | ||||||
|  |   }); | ||||||
|  |   const vs = chev.createToken({ | ||||||
|  |     name: "vs", | ||||||
|  |     pattern: "vs.", | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const terrainEnter = chev.createToken({ | ||||||
|  |     name: "terrainEnter", | ||||||
|  |     pattern: "in", | ||||||
|  |     push_mode: "terrain_mode", | ||||||
|  |   }); | ||||||
|  |   const Weather = chev.createToken({ | ||||||
|  |     name: "Weather", | ||||||
|  |     pattern: /Sun|Rain|Sand|Snow/, | ||||||
|  |   }); | ||||||
|  |   const Terrain = chev.createToken({ | ||||||
|  |     name: "Terrain", | ||||||
|  |     pattern: /(Electric|Grassy|Misty|Psychic) Terrain/, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const screenEnter = chev.createToken({ | ||||||
|  |     name: "screenEnter", | ||||||
|  |     pattern: "through", | ||||||
|  |     push_mode: "screen_mode", | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   return new Lexer({ | ||||||
|  |     modes: { | ||||||
|  |       default_mode: [ | ||||||
|  |         whitespace, | ||||||
|  |         div, | ||||||
|  |         vs, | ||||||
|  |         Boost, | ||||||
|  |         EV, | ||||||
|  |         Stat, | ||||||
|  |         Item, | ||||||
|  |         Ability, | ||||||
|  |         Pokemon, | ||||||
|  |         Move, | ||||||
|  |         terrainEnter, | ||||||
|  |         screenEnter, | ||||||
|  |       ], | ||||||
|  |       terrain_mode: [whitespace, screenEnter, Weather, Terrain], | ||||||
|  |       screen_mode: [whitespace, Move], | ||||||
|  |     }, | ||||||
|  |     defaultMode: "default_mode", | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @generator | ||||||
|  |  * @template T item type | ||||||
|  |  * @param {T[]} arr | ||||||
|  |  * @yields {T} item | ||||||
|  |  */ | ||||||
|  | function* iterate(arr) { | ||||||
|  |   for (const a of arr) { | ||||||
|  |     yield a; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @param {string} type token type | ||||||
|  |  * @param {chev.IToken} token token | ||||||
|  |  * @return {string} matched token | ||||||
|  |  */ | ||||||
|  | function unwrapToken(type, token) { | ||||||
|  |   assert( | ||||||
|  |     token.tokenType.name == type, | ||||||
|  |     "expected token %s, got %s", | ||||||
|  |     type, | ||||||
|  |     token.tokenType.name | ||||||
|  |   ); | ||||||
|  |   return token.image; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const POS_NATURES = { | ||||||
|  |   atk: "Adamant", | ||||||
|  |   def: "Bold", | ||||||
|  |   spa: "Modest", | ||||||
|  |   spd: "Calm", | ||||||
|  |   spe: "Jolly", | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const NEG_NATURES = { | ||||||
|  |   atk: "Modest", | ||||||
|  |   def: "Lonely", | ||||||
|  |   spa: "Adamant", | ||||||
|  |   spd: "Rash", | ||||||
|  |   spe: "Brave", | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Parses a Smogon calculator output: | ||||||
|  |  * | ||||||
|  |  * -2 8 SpA Choice Specs Torkoal vs. | ||||||
|  |  * 252 HP / 4+ SpD Assault Vest Abomasnow | ||||||
|  |  * in Sun | ||||||
|  |  * through Light Screen | ||||||
|  |  * | ||||||
|  |  * @param {string} line textual line | ||||||
|  |  * @return {calc.Result} calculation result | ||||||
|  |  */ | ||||||
|  | function parseAndCalculate(line) { | ||||||
|  |   const lexer = buildLexer(); | ||||||
|  |   const result = lexer.tokenize(line); | ||||||
|  |   if (result.errors && result.errors.length > 0) { | ||||||
|  |     console.error("Unparsed tokens: %o", result.errors); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** @type {string} */ | ||||||
|  |   var attacker; | ||||||
|  |   /** @type {string} */ | ||||||
|  |   var defender; | ||||||
|  |  | ||||||
|  |   /** @type {calc.State.Pokemon} */ | ||||||
|  |   var attackerOpts = {}; | ||||||
|  |   /** @type {calc.State.Pokemon} */ | ||||||
|  |   var defenderOpts = {}; | ||||||
|  |  | ||||||
|  |   /** @type {string} */ | ||||||
|  |   var move; | ||||||
|  |   /** @type {calc.State.Field} */ | ||||||
|  |   var field = {}; | ||||||
|  |  | ||||||
|  |   // Tokenising state. | ||||||
|  |   var isAttacker = true; | ||||||
|  |   var it = iterate(result.tokens); | ||||||
|  |  | ||||||
|  |   const opts = () => (isAttacker ? attackerOpts : defenderOpts); | ||||||
|  |  | ||||||
|  |   while (true) { | ||||||
|  |     let item = it.next().value; | ||||||
|  |     if (!item) break; | ||||||
|  |     switch (item.tokenType.name) { | ||||||
|  |       case "Boost": | ||||||
|  |         { | ||||||
|  |           let boost = unwrapToken("Boost", item); | ||||||
|  |           let ev = unwrapToken("EV", it.next().value); | ||||||
|  |           let stat = unwrapToken("Stat", it.next().value).toLowerCase(); | ||||||
|  |           opts().boosts = { [stat]: parseInt(boost), ...opts().boosts }; | ||||||
|  |           opts().evs = { [stat]: parseInt(ev), ...opts().evs }; | ||||||
|  |           if (ev.endsWith("+")) { | ||||||
|  |             opts().nature = POS_NATURES[stat]; | ||||||
|  |           } else if (ev.endsWith("-")) { | ||||||
|  |             opts().nature = NEG_NATURES[stat]; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       case "EV": | ||||||
|  |         { | ||||||
|  |           let ev = unwrapToken("EV", item); | ||||||
|  |           let stat = unwrapToken("Stat", it.next().value).toLowerCase(); | ||||||
|  |           opts().evs = { [stat]: parseInt(ev), ...opts().evs }; | ||||||
|  |           if (ev.endsWith("+")) { | ||||||
|  |             opts().nature = POS_NATURES[stat]; | ||||||
|  |           } else if (ev.endsWith("-")) { | ||||||
|  |             opts().nature = NEG_NATURES[stat]; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       case "Stat": | ||||||
|  |         throw Error("Impossibel state: bare Stat"); | ||||||
|  |       case "Item": | ||||||
|  |         opts().item = unwrapToken("Item", item); | ||||||
|  |         break; | ||||||
|  |       case "Pokemon": | ||||||
|  |         { | ||||||
|  |           let name = unwrapToken("Pokemon", item); | ||||||
|  |           if (isAttacker) attacker = name; | ||||||
|  |           else defender = name; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       case "Move": | ||||||
|  |         move = unwrapToken("Move", item); | ||||||
|  |         break; | ||||||
|  |       case "terrainEnter": | ||||||
|  |         { | ||||||
|  |           let next = it.next().value; | ||||||
|  |           switch (next.tokenType.name) { | ||||||
|  |             case "Weather": | ||||||
|  |               field.weather = next.image; | ||||||
|  |               break; | ||||||
|  |             case "Terrain": | ||||||
|  |               field.terrain = next.image; | ||||||
|  |               break; | ||||||
|  |             default: | ||||||
|  |               throw Error( | ||||||
|  |                 "Unhandled terrain %s: %s", | ||||||
|  |                 next.tokenType.name, | ||||||
|  |                 next.image | ||||||
|  |               ); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       case "screenEnter": | ||||||
|  |         { | ||||||
|  |           let screen = unwrapToken("Move", it.next().value); | ||||||
|  |           field.defenderSide = field.defenderSide || {}; | ||||||
|  |           field.defenderSide.isLightScreen = screen === "Light Screen"; | ||||||
|  |           field.defenderSide.isReflect = screen === "Reflect"; | ||||||
|  |           field.defenderSide.isAuroraVeil = screen === "Aurora Veil"; | ||||||
|  |           field.defenderSide.is; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       case "vs": | ||||||
|  |         isAttacker = false; | ||||||
|  |         break; | ||||||
|  |       default: | ||||||
|  |         console.error("unmatched token type: %s", item.tokenType.name); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const gen = Generations.get(8); | ||||||
|  |   return calculate( | ||||||
|  |     gen, | ||||||
|  |     new Pokemon(gen, attacker, attackerOpts), | ||||||
|  |     new Pokemon(gen, defender, defenderOpts), | ||||||
|  |     new Move(gen, move), | ||||||
|  |     new Field(field) | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function test() { | ||||||
|  |   const text = | ||||||
|  |     "-2 8 SpA Choice Specs Torkoal Overheat vs. 252 HP / 4+ SpD Assault Vest Abomasnow in Sun through Light Screen"; | ||||||
|  |   const res = parseAndCalculate(text); | ||||||
|  |  | ||||||
|  |   assert(res.attacker.boosts.spa === -2, "should have -2 SpA"); | ||||||
|  |   assert(res.attacker.evs.spa === 8, "should have 8 SpA EVs"); | ||||||
|  |   assert(res.attacker.item === "Choice Specs", "should have Choice Specs"); | ||||||
|  |   assert(res.attacker.name === "Torkoal", "should be Torkoal"); | ||||||
|  |   assert(res.move.name === "Overheat", "should be Overheat"); | ||||||
|  |   assert(res.defender.evs.hp === 252, "should have 252 HP EVs"); | ||||||
|  |   assert(res.defender.evs.spd === 4, "should have 4 SpD EVs"); | ||||||
|  |   assert(res.field.weather === "Sun", "should be in sun"); | ||||||
|  |  | ||||||
|  |   assert( | ||||||
|  |     res.desc().replace(/:.*/, "") === text, | ||||||
|  |     "non-damage text should be equivalent to input" | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export { parseAndCalculate, test }; | ||||||
							
								
								
									
										8
									
								
								calc_main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								calc_main.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | import { parseAndCalculate } from "./calc.js"; | ||||||
|  |  | ||||||
|  | // FIXME: issue with using execArgv. | ||||||
|  | let args = process.argv.slice(2); | ||||||
|  | if (args[0] === "--") args = args.slice(1); | ||||||
|  | const line = args.join(" "); | ||||||
|  | const res = parseAndCalculate(line); | ||||||
|  | console.log(res.fullDesc()); | ||||||
| @@ -17,7 +17,11 @@ | |||||||
|                   ps.requests |                   ps.requests | ||||||
|                 ]); |                 ]); | ||||||
|               in |               in | ||||||
|               [ python pkgs.sqlite ]; |               [ | ||||||
|  |                 pkgs.nodejs | ||||||
|  |                 python | ||||||
|  |                 pkgs.sqlite | ||||||
|  |               ]; | ||||||
|           }; |           }; | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										431
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										431
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,431 @@ | |||||||
|  | { | ||||||
|  |   "name": "hhirls", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "lockfileVersion": 3, | ||||||
|  |   "requires": true, | ||||||
|  |   "packages": { | ||||||
|  |     "": { | ||||||
|  |       "name": "hhirls", | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "license": "WTFPL", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@smogon/calc": "^0.7.0", | ||||||
|  |         "chevrotain": "^10.5.0", | ||||||
|  |         "discord.js": "^14.9.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@chevrotain/cst-dts-gen": { | ||||||
|  |       "version": "10.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.5.0.tgz", | ||||||
|  |       "integrity": "sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@chevrotain/gast": "10.5.0", | ||||||
|  |         "@chevrotain/types": "10.5.0", | ||||||
|  |         "lodash": "4.17.21" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@chevrotain/gast": { | ||||||
|  |       "version": "10.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-10.5.0.tgz", | ||||||
|  |       "integrity": "sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@chevrotain/types": "10.5.0", | ||||||
|  |         "lodash": "4.17.21" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@chevrotain/types": { | ||||||
|  |       "version": "10.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-10.5.0.tgz", | ||||||
|  |       "integrity": "sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@chevrotain/utils": { | ||||||
|  |       "version": "10.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-10.5.0.tgz", | ||||||
|  |       "integrity": "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@discordjs/builders": { | ||||||
|  |       "version": "1.6.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.1.tgz", | ||||||
|  |       "integrity": "sha512-CCcLwn/8ANhlAbhlE18fcaN0hfXTen53/JiwZs1t9oE/Cqa9maA8ZRarkCIsXF4J7J/MYnd0J6IsxeKsq+f6mw==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@discordjs/formatters": "^0.3.0", | ||||||
|  |         "@discordjs/util": "^0.2.0", | ||||||
|  |         "@sapphire/shapeshift": "^3.8.1", | ||||||
|  |         "discord-api-types": "^0.37.37", | ||||||
|  |         "fast-deep-equal": "^3.1.3", | ||||||
|  |         "ts-mixer": "^6.0.3", | ||||||
|  |         "tslib": "^2.5.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=16.9.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@discordjs/collection": { | ||||||
|  |       "version": "1.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.0.tgz", | ||||||
|  |       "integrity": "sha512-suyVndkEAAWrGxyw/CPGdtXoRRU6AUNkibtnbJevQzpelkJh3Q1gQqWDpqf5i39CnAn5+LrN0YS+cULeEjq2Yw==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=16.9.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@discordjs/formatters": { | ||||||
|  |       "version": "0.3.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.0.tgz", | ||||||
|  |       "integrity": "sha512-Fc4MomalbP8HMKEMor3qUiboAKDtR7PSBoPjwm7WYghVRwgJlj5WYvUsriLsxeKk8+Qq2oy+HJlGTUkGvX0YnA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "discord-api-types": "^0.37.37" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=16.9.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@discordjs/rest": { | ||||||
|  |       "version": "1.7.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.0.tgz", | ||||||
|  |       "integrity": "sha512-r2HzmznRIo8IDGYBWqQfkEaGN1LrFfWQd3dSyC4tOpMU8nuVvFUEw6V/lwnG44jyOq+vgyDny2fxeUDMt9I4aQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@discordjs/collection": "^1.5.0", | ||||||
|  |         "@discordjs/util": "^0.2.0", | ||||||
|  |         "@sapphire/async-queue": "^1.5.0", | ||||||
|  |         "@sapphire/snowflake": "^3.4.0", | ||||||
|  |         "discord-api-types": "^0.37.37", | ||||||
|  |         "file-type": "^18.2.1", | ||||||
|  |         "tslib": "^2.5.0", | ||||||
|  |         "undici": "^5.21.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=16.9.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@discordjs/util": { | ||||||
|  |       "version": "0.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.2.0.tgz", | ||||||
|  |       "integrity": "sha512-/8qNbebFzLWKOOg+UV+RB8itp4SmU5jw0tBUD3ifElW6rYNOj1Ku5JaSW7lLl/WgjjxF01l/1uQPCzkwr110vg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=16.9.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@sapphire/async-queue": { | ||||||
|  |       "version": "1.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", | ||||||
|  |       "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=v14.0.0", | ||||||
|  |         "npm": ">=7.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@sapphire/shapeshift": { | ||||||
|  |       "version": "3.8.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.8.2.tgz", | ||||||
|  |       "integrity": "sha512-NXpnJAsxN3/h9TqQPntOeVWZrpIuucqXI3IWF6tj2fWCoRLCuVK5wx7Dtg7pRrtkYfsMUbDqgKoX26vrC5iYfA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "fast-deep-equal": "^3.1.3", | ||||||
|  |         "lodash": "^4.17.21" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=v14.0.0", | ||||||
|  |         "npm": ">=7.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@sapphire/snowflake": { | ||||||
|  |       "version": "3.4.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.4.2.tgz", | ||||||
|  |       "integrity": "sha512-KJwlv5gkGjs1uFV7/xx81n3tqgBwBJvH94n1xDyH3q+JSmtsMeSleJffarEBfG2yAFeJiFA4BnGOK6FFPHc19g==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=v14.0.0", | ||||||
|  |         "npm": ">=7.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@smogon/calc": { | ||||||
|  |       "version": "0.7.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@smogon/calc/-/calc-0.7.0.tgz", | ||||||
|  |       "integrity": "sha512-2+AGILYtqwRBceIIYkxH1dvtLwzSdyEwAAFWDfjYVwwNohmsNKjU5RVsDal8matpmNJptHF2FekSbHONNZTlUg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/node": "^18.11.9" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@tokenizer/token": { | ||||||
|  |       "version": "0.3.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", | ||||||
|  |       "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/node": { | ||||||
|  |       "version": "18.16.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz", | ||||||
|  |       "integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@types/ws": { | ||||||
|  |       "version": "8.5.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", | ||||||
|  |       "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@types/node": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/busboy": { | ||||||
|  |       "version": "1.6.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", | ||||||
|  |       "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "streamsearch": "^1.1.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10.16.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/chevrotain": { | ||||||
|  |       "version": "10.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-10.5.0.tgz", | ||||||
|  |       "integrity": "sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@chevrotain/cst-dts-gen": "10.5.0", | ||||||
|  |         "@chevrotain/gast": "10.5.0", | ||||||
|  |         "@chevrotain/types": "10.5.0", | ||||||
|  |         "@chevrotain/utils": "10.5.0", | ||||||
|  |         "lodash": "4.17.21", | ||||||
|  |         "regexp-to-ast": "0.5.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/discord-api-types": { | ||||||
|  |       "version": "0.37.40", | ||||||
|  |       "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.40.tgz", | ||||||
|  |       "integrity": "sha512-LMALvtO+p6ERK8rwWoaI490NfIE/egbqjR4/rfLL1z9gQE1gqLiTpIUUDIunfAtKYzeH6ucyXhaXXWpfZh/Q6g==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/discord.js": { | ||||||
|  |       "version": "14.9.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.9.0.tgz", | ||||||
|  |       "integrity": "sha512-ygGms5xP4hG+QrrY9k7d/OYCzMltSMtdl/2Snzq/nLCiZo+Sna91Ulv9l0+B5Jd/Czcq37B7wJAnmja7GOa+bg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@discordjs/builders": "^1.6.0", | ||||||
|  |         "@discordjs/collection": "^1.5.0", | ||||||
|  |         "@discordjs/formatters": "^0.3.0", | ||||||
|  |         "@discordjs/rest": "^1.7.0", | ||||||
|  |         "@discordjs/util": "^0.2.0", | ||||||
|  |         "@sapphire/snowflake": "^3.4.0", | ||||||
|  |         "@types/ws": "^8.5.4", | ||||||
|  |         "discord-api-types": "^0.37.37", | ||||||
|  |         "fast-deep-equal": "^3.1.3", | ||||||
|  |         "lodash.snakecase": "^4.1.1", | ||||||
|  |         "tslib": "^2.5.0", | ||||||
|  |         "undici": "^5.21.0", | ||||||
|  |         "ws": "^8.13.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=16.9.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/fast-deep-equal": { | ||||||
|  |       "version": "3.1.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", | ||||||
|  |       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/file-type": { | ||||||
|  |       "version": "18.3.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.3.0.tgz", | ||||||
|  |       "integrity": "sha512-pkPZ5OGIq0TYb37b8bHDLNeQSe1H2KlaQ2ySGpJkkr2KZdaWsO4QhPzHA0mQcsUW2cSqJk+4gM/UyLz/UFbXdQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "readable-web-to-node-stream": "^3.0.2", | ||||||
|  |         "strtok3": "^7.0.0", | ||||||
|  |         "token-types": "^5.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14.16" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/sindresorhus/file-type?sponsor=1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/ieee754": { | ||||||
|  |       "version": "1.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", | ||||||
|  |       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", | ||||||
|  |       "funding": [ | ||||||
|  |         { | ||||||
|  |           "type": "github", | ||||||
|  |           "url": "https://github.com/sponsors/feross" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "patreon", | ||||||
|  |           "url": "https://www.patreon.com/feross" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "consulting", | ||||||
|  |           "url": "https://feross.org/support" | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     "node_modules/inherits": { | ||||||
|  |       "version": "2.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", | ||||||
|  |       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/lodash": { | ||||||
|  |       "version": "4.17.21", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", | ||||||
|  |       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/lodash.snakecase": { | ||||||
|  |       "version": "4.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", | ||||||
|  |       "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/peek-readable": { | ||||||
|  |       "version": "5.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", | ||||||
|  |       "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14.16" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "github", | ||||||
|  |         "url": "https://github.com/sponsors/Borewit" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/readable-stream": { | ||||||
|  |       "version": "3.6.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", | ||||||
|  |       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "inherits": "^2.0.3", | ||||||
|  |         "string_decoder": "^1.1.1", | ||||||
|  |         "util-deprecate": "^1.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/readable-web-to-node-stream": { | ||||||
|  |       "version": "3.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", | ||||||
|  |       "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "readable-stream": "^3.6.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "github", | ||||||
|  |         "url": "https://github.com/sponsors/Borewit" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/regexp-to-ast": { | ||||||
|  |       "version": "0.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", | ||||||
|  |       "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/safe-buffer": { | ||||||
|  |       "version": "5.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", | ||||||
|  |       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", | ||||||
|  |       "funding": [ | ||||||
|  |         { | ||||||
|  |           "type": "github", | ||||||
|  |           "url": "https://github.com/sponsors/feross" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "patreon", | ||||||
|  |           "url": "https://www.patreon.com/feross" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "consulting", | ||||||
|  |           "url": "https://feross.org/support" | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     "node_modules/streamsearch": { | ||||||
|  |       "version": "1.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", | ||||||
|  |       "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/string_decoder": { | ||||||
|  |       "version": "1.3.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", | ||||||
|  |       "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "safe-buffer": "~5.2.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/strtok3": { | ||||||
|  |       "version": "7.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", | ||||||
|  |       "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@tokenizer/token": "^0.3.0", | ||||||
|  |         "peek-readable": "^5.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14.16" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "github", | ||||||
|  |         "url": "https://github.com/sponsors/Borewit" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/token-types": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", | ||||||
|  |       "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@tokenizer/token": "^0.3.0", | ||||||
|  |         "ieee754": "^1.2.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14.16" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "github", | ||||||
|  |         "url": "https://github.com/sponsors/Borewit" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/ts-mixer": { | ||||||
|  |       "version": "6.0.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", | ||||||
|  |       "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/tslib": { | ||||||
|  |       "version": "2.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", | ||||||
|  |       "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/undici": { | ||||||
|  |       "version": "5.22.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.0.tgz", | ||||||
|  |       "integrity": "sha512-fR9RXCc+6Dxav4P9VV/sp5w3eFiSdOjJYsbtWfd4s5L5C4ogyuVpdKIVHeW0vV1MloM65/f7W45nR9ZxwVdyiA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "busboy": "^1.6.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/util-deprecate": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", | ||||||
|  |       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/ws": { | ||||||
|  |       "version": "8.13.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", | ||||||
|  |       "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10.0.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "bufferutil": "^4.0.1", | ||||||
|  |         "utf-8-validate": ">=5.0.2" | ||||||
|  |       }, | ||||||
|  |       "peerDependenciesMeta": { | ||||||
|  |         "bufferutil": { | ||||||
|  |           "optional": true | ||||||
|  |         }, | ||||||
|  |         "utf-8-validate": { | ||||||
|  |           "optional": true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | { | ||||||
|  |   "name": "hhirls", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "description": "Pokemon Showdown data processing, mostly for HHIRLLL's Pokemon league. Ugly as fuck.", | ||||||
|  |   "main": "calc.js", | ||||||
|  |   "type": "module", | ||||||
|  |   "scripts": { | ||||||
|  |     "calc": "node calc_main.js", | ||||||
|  |     "test": "node -e 'import(\"./calc.js\").then(mod => mod.test())'" | ||||||
|  |   }, | ||||||
|  |   "author": "", | ||||||
|  |   "license": "WTFPL", | ||||||
|  |   "dependencies": { | ||||||
|  |     "@smogon/calc": "^0.7.0", | ||||||
|  |     "chevrotain": "^10.5.0", | ||||||
|  |     "discord.js": "^14.9.0" | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user