Compare commits

...
29 Commits
Author SHA1 Message Date
TrèsAbhi eab4266fd1 feat: logs 2026-02-21 22:27:48 -06:00
TrèsAbhi 86b4b63a7c feat: dead commands 2026-02-21 22:26:29 -06:00
TrèsAbhi 547614fa89 fix: react versouins 2026-02-18 19:11:58 -06:00
TrèsAbhi e803d96f20 feat: lgos 2026-02-18 19:06:49 -06:00
TrèsAbhi 009caeeaf1 fix: left align filters on small screens 2026-02-18 19:00:09 -06:00
TrèsAbhi bfa80cd549 fix: optional teritery shell 2026-02-18 18:57:17 -06:00
TrèsAbhi 987c798b7e feat: increase max zoom distance 2026-02-18 18:55:38 -06:00
TrèsAbhi 8dbe7cb155 fix: short hand compare toggles 2026-02-18 18:54:23 -06:00
TrèsAbhi 053f1e3ac8 fix: ricochet visualizer doesn't drag whole page 2026-02-18 18:53:29 -06:00
TrèsAbhi 588c0a809b fix: static armor updates on thickness change 2026-02-18 18:48:59 -06:00
TrèsAbhi dde059b1f9 fix: remove debug logs 2026-02-18 18:46:41 -06:00
TrèsAbhi 102072746a fix: static armor show on deselect 2026-02-18 18:45:39 -06:00
TrèsAbhi 10d7fe1e75 feat: auto crop image 2026-02-18 18:38:40 -06:00
TrèsAbhi 4cc4e664df fix: high end consumables gives 33% extra not 70% 2026-02-18 18:22:56 -06:00
TrèsAbhi d5269e763b fix: transparency checks and depth writing 2026-02-18 18:20:37 -06:00
TrèsAbhi bae7ca2720 fix: turret angles round back to \pm 180deg 2026-02-18 18:09:05 -06:00
TrèsAbhi a0b81bfb83 bruh 2026-02-18 16:52:47 -06:00
TrèsAbhi 629e9f814e bruh 2026-02-18 16:49:08 -06:00
TrèsAbhi f39d1bab4e wait wait wait no no no 2026-02-18 16:45:06 -06:00
TrèsAbhi bf61cb17de typo 2026-02-18 16:36:42 -06:00
TrèsAbhi c8ba6b1eca feat: 1.29.12 2026-02-18 16:36:12 -06:00
dependabot[bot] 1d8c823703 build(deps): bump bytes from 1.10.1 to 1.11.1 in /packages/app/src-tauri (#212)
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.10.1 to 1.11.1.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.10.1...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 09:57:06 -06:00
dependabot[bot] 3594c9a971 build(deps): bump time from 0.3.44 to 0.3.47 in /packages/app/src-tauri (#213)
Bumps [time](https://github.com/time-rs/time) from 0.3.44 to 0.3.47.
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.44...v0.3.47)

---
updated-dependencies:
- dependency-name: time
  dependency-version: 0.3.47
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 09:56:52 -06:00
TrèsAbhi f478a08bd9 New Crowdin updates (#211)
* New translations en.json (Polish)

* New translations en.json (Russian)

* New translations en.json (Russian)
2026-02-13 07:25:48 -06:00
TrèsAbhi 115fa5acad Remove locale redirection logic
Removed locale redirection logic from LocaleRedirector component.
2026-02-12 07:14:11 -06:00
TrèsAbhi c24a2989fa Fix locale redirection logic in LocaleRedirector.astro 2026-02-12 06:31:43 -06:00
TrèsAbhi a6cfb522b3 fix: remove cue4parse 2026-02-11 15:22:30 -06:00
TrèsAbhi 12e645f6e2 fix: legacy redirector ensure props 2026-02-11 15:20:09 -06:00
TrèsAbhi 9a3f64fcd6 Refactor locale redirection logic in LocaleRedirector 2026-02-11 09:31:48 -06:00
50 changed files with 1028 additions and 825 deletions

No files matched your search

+1
View File
@@ -17,6 +17,7 @@
"astrojs",
"astrolib",
"atgm",
"autocrop",
"Autoloader",
"Autoreloader",
"AYUV",
+316 -60
View File
@@ -1,11 +1,13 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "blitzkit",
"dependencies": {
"@prisma/client": "^6.18.0",
"prisma": "^6.18.0",
"sharp": "^0.34.5",
"typescript": "^5.9.3",
},
},
@@ -25,25 +27,26 @@
"@blitzkit/core": "workspace:*",
"@blitzkit/i18n": "workspace:*",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/themes": "^3.2.1",
"@radix-ui/themes": "^3.3.0",
"@resvg/resvg-js": "^2.6.2",
"@types/adm-zip": "^0.5.7",
"@types/bun": "^1.3.9",
"@types/lodash-es": "^4.17.12",
"@types/markdown-escape": "^1.1.3",
"@types/react": "^19.2.2",
"@types/react": "^19.2.14",
"adm-zip": "^0.5.16",
"bepaint": "^0.1.0-beta.3",
"discord.js": "^14.22.1",
"dotenv": "^17.2.2",
"discord.js": "^14.25.1",
"dotenv": "^17.3.1",
"fuzzysort": "^3.1.0",
"lodash-es": "^4.17.21",
"lodash-es": "^4.17.23",
"markdown-escape": "^2.0.0",
"pickleparser": "^0.2.1",
"prisma": "^6.17.1",
"prisma": "^6.19.2",
"protobufjs": "^7.5.4",
"react": "^19.2.0",
"satori": "^0.18.3",
"sharp": "^0.34.4",
"react": "^19.2.4",
"satori": "^0.18.4",
"sharp": "^0.34.5",
},
},
"packages/closed": {
@@ -161,12 +164,13 @@
"compare-versions": "^6.1.1",
"fuzzysort": "^3.1.0",
"immer": "^10.1.3",
"jimp": "^1.6.0",
"lodash-es": "^4.17.21",
"markdown-to-jsx": "^7.7.13",
"pwa-install-handler": "^2.6.3",
"quicklime": "^1.2.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-promise-suspense": "^0.3.4",
"three": "^0.180.0",
"three-stdlib": "^2.36.0",
@@ -410,15 +414,15 @@
"@dimforge/rapier3d-compat": ["@dimforge/[email protected]", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
"@discordjs/builders": ["@discordjs/[email protected]1.3", "", { "dependencies": { "@discordjs/formatters": "^0.6.1", "@discordjs/util": "^1.1.1", "@sapphire/shapeshift": "^4.0.0", "discord-api-types": "^0.38.16", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.4", "tslib": "^2.6.3" } }, "sha512-p3kf5eV49CJiRTfhtutUCeivSyQ/l2JlKodW1ZquRwwvlOWmG9+6jFShX6x8rUiYhnP6wKI96rgN/SXMy5e5aw=="],
"@discordjs/builders": ["@discordjs/[email protected]3.1", "", { "dependencies": { "@discordjs/formatters": "^0.6.2", "@discordjs/util": "^1.2.0", "@sapphire/shapeshift": "^4.0.0", "discord-api-types": "^0.38.33", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.4", "tslib": "^2.6.3" } }, "sha512-cOU0UDHc3lp/5nKByDxkmRiNZBpdp0kx55aarbiAfakfKJHlxv/yFW1zmIqCAmwH5CRlrH9iMFKJMpvW4DPB+w=="],
"@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ=="],
"@discordjs/formatters": ["@discordjs/[email protected].1", "", { "dependencies": { "discord-api-types": "^0.38.1" } }, "sha512-5cnX+tASiPCqCWtFcFslxBVUaCetB0thvM/JyavhbXInP1HJIEU+Qv/zMrnuwSsX3yWH2lVXNJZeDK3EiP4HHg=="],
"@discordjs/formatters": ["@discordjs/[email protected].2", "", { "dependencies": { "discord-api-types": "^0.38.33" } }, "sha512-y4UPwWhH6vChKRkGdMB4odasUbHOUwy7KL+OVwF86PvT6QVOwElx+TiI1/6kcmcEe+g5YRXJFiXSXUdabqZOvQ=="],
"@discordjs/rest": ["@discordjs/[email protected]", "", { "dependencies": { "@discordjs/collection": "^2.1.1", "@discordjs/util": "^1.1.1", "@sapphire/async-queue": "^1.5.3", "@sapphire/snowflake": "^3.5.3", "@vladfrangu/async_event_emitter": "^2.4.6", "discord-api-types": "^0.38.16", "magic-bytes.js": "^1.10.0", "tslib": "^2.6.3", "undici": "6.21.3" } }, "sha512-RDYrhmpB7mTvmCKcpj+pc5k7POKszS4E2O9TYc+U+Y4iaCP+r910QdO43qmpOja8LRr1RJ0b3U+CqVsnPqzf4w=="],
"@discordjs/util": ["@discordjs/util@1.1.1", "", {}, "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g=="],
"@discordjs/util": ["@discordjs/util@1.2.0", "", { "dependencies": { "discord-api-types": "^0.38.33" } }, "sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg=="],
"@discordjs/ws": ["@discordjs/[email protected]", "", { "dependencies": { "@discordjs/collection": "^2.1.0", "@discordjs/rest": "^2.5.1", "@discordjs/util": "^1.1.0", "@sapphire/async-queue": "^1.5.2", "@types/ws": "^8.5.10", "@vladfrangu/async_event_emitter": "^2.2.4", "discord-api-types": "^0.38.1", "tslib": "^2.6.2", "ws": "^8.17.0" } }, "sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw=="],
@@ -442,7 +446,7 @@
"@emmetio/stream-reader-utils": ["@emmetio/[email protected]", "", {}, "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A=="],
"@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="],
"@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
"@esbuild/aix-ppc64": ["@esbuild/[email protected]", "", { "os": "aix", "cpu": "ppc64" }, "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw=="],
@@ -514,49 +518,109 @@
"@img/colour": ["@img/[email protected]", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
"@img/sharp-darwin-arm64": ["@img/[email protected].4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA=="],
"@img/sharp-darwin-arm64": ["@img/[email protected].5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
"@img/sharp-darwin-x64": ["@img/[email protected].4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.3" }, "os": "darwin", "cpu": "x64" }, "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg=="],
"@img/sharp-darwin-x64": ["@img/[email protected].5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
"@img/sharp-libvips-darwin-arm64": ["@img/[email protected].3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw=="],
"@img/sharp-libvips-darwin-arm64": ["@img/[email protected].4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
"@img/sharp-libvips-darwin-x64": ["@img/[email protected].3", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA=="],
"@img/sharp-libvips-darwin-x64": ["@img/[email protected].4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
"@img/sharp-libvips-linux-arm": ["@img/[email protected].3", "", { "os": "linux", "cpu": "arm" }, "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA=="],
"@img/sharp-libvips-linux-arm": ["@img/[email protected].4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
"@img/sharp-libvips-linux-arm64": ["@img/[email protected].3", "", { "os": "linux", "cpu": "arm64" }, "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ=="],
"@img/sharp-libvips-linux-arm64": ["@img/[email protected].4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
"@img/sharp-libvips-linux-ppc64": ["@img/[email protected].3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg=="],
"@img/sharp-libvips-linux-ppc64": ["@img/[email protected].4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w=="],
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg=="],
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm[email protected].3", "", { "os": "linux", "cpu": "arm64" }, "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw=="],
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x[email protected].4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x[email protected].3", "", { "os": "linux", "cpu": "x64" }, "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g=="],
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm[email protected].4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
"@img/sharp-linux-arm": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.3" }, "os": "linux", "cpu": "arm" }, "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA=="],
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linux[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ=="],
"@img/sharp-linux-arm": ["@img/[email protected].5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc[email protected].4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ=="],
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm[email protected].5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.3" }, "os": "linux", "cpu": "s390x" }, "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw=="],
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
"@img/sharp-linux-x64": ["@img/sharp-linux-x[email protected].4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A=="],
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv[email protected].5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA=="],
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl[email protected].4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg=="],
"@img/sharp-linux-x64": ["@img/[email protected].5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.4", "", { "dependencies": { "@emnapi/runtime": "^1.5.0" }, "cpu": "none" }, "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA=="],
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm[email protected].4", "", { "os": "win32", "cpu": "arm64" }, "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA=="],
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x[email protected].5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia[email protected].4", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw=="],
"@img/sharp-wasm32": ["@img/sharp-wasm[email protected].5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
"@img/sharp-win32-x64": ["@img/sharp-win32-x[email protected].4", "", { "os": "win32", "cpu": "x64" }, "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig=="],
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm[email protected].5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
"@img/sharp-win32-ia32": ["@img/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
"@img/sharp-win32-x64": ["@img/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
"@jimp/core": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/file-ops": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "await-to-js": "^3.0.0", "exif-parser": "^0.1.12", "file-type": "^16.0.0", "mime": "3" } }, "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w=="],
"@jimp/diff": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "pixelmatch": "^5.3.0" } }, "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw=="],
"@jimp/file-ops": ["@jimp/[email protected]", "", {}, "sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ=="],
"@jimp/js-bmp": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "bmp-ts": "^1.0.9" } }, "sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw=="],
"@jimp/js-gif": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "gifwrap": "^0.10.1", "omggif": "^1.0.10" } }, "sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g=="],
"@jimp/js-jpeg": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "jpeg-js": "^0.4.4" } }, "sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA=="],
"@jimp/js-png": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "pngjs": "^7.0.0" } }, "sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg=="],
"@jimp/js-tiff": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "utif2": "^4.1.0" } }, "sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw=="],
"@jimp/plugin-blit": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA=="],
"@jimp/plugin-blur": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw=="],
"@jimp/plugin-circle": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw=="],
"@jimp/plugin-color": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "tinycolor2": "^1.6.0", "zod": "^3.23.8" } }, "sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA=="],
"@jimp/plugin-contain": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ=="],
"@jimp/plugin-cover": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA=="],
"@jimp/plugin-crop": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang=="],
"@jimp/plugin-displace": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q=="],
"@jimp/plugin-dither": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0" } }, "sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ=="],
"@jimp/plugin-fisheye": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA=="],
"@jimp/plugin-flip": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg=="],
"@jimp/plugin-hash": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "any-base": "^1.1.0" } }, "sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q=="],
"@jimp/plugin-mask": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA=="],
"@jimp/plugin-print": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/types": "1.6.0", "parse-bmfont-ascii": "^1.0.6", "parse-bmfont-binary": "^1.0.6", "parse-bmfont-xml": "^1.1.6", "simple-xml-to-json": "^1.2.2", "zod": "^3.23.8" } }, "sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A=="],
"@jimp/plugin-quantize": ["@jimp/[email protected]", "", { "dependencies": { "image-q": "^4.0.0", "zod": "^3.23.8" } }, "sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg=="],
"@jimp/plugin-resize": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA=="],
"@jimp/plugin-rotate": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw=="],
"@jimp/plugin-threshold": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w=="],
"@jimp/types": ["@jimp/[email protected]", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg=="],
"@jimp/utils": ["@jimp/[email protected]", "", { "dependencies": { "@jimp/types": "1.6.0", "tinycolor2": "^1.6.0" } }, "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA=="],
"@jridgewell/gen-mapping": ["@jridgewell/[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
@@ -768,7 +832,7 @@
"@radix-ui/rect": ["@radix-ui/[email protected]", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
"@radix-ui/themes": ["@radix-ui/themes@3.2.1", "", { "dependencies": { "@radix-ui/colors": "^3.0.0", "classnames": "^2.3.2", "radix-ui": "^1.1.3", "react-remove-scroll-bar": "^2.3.8" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-WJL2YKAGItkunwm3O4cLTFKCGJTfAfF6Hmq7f5bCo1ggqC9qJQ/wfg/25AAN72aoEM1yqXZQ+pslsw48AFR0Xg=="],
"@radix-ui/themes": ["@radix-ui/themes@3.3.0", "", { "dependencies": { "@radix-ui/colors": "^3.0.0", "classnames": "^2.3.2", "radix-ui": "^1.1.3", "react-remove-scroll-bar": "^2.3.8" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I0/h2CRNTpYNB7Mi3xFIvSsQq5a108d7kK8dTO5zp5b9HR5QJXKag6B8tjpz2ITkVYkFdkGk45doNkSr7OxwNw=="],
"@react-three/drei": ["@react-three/[email protected]", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mediapipe/tasks-vision": "0.10.17", "@monogrid/gainmap-js": "^3.0.6", "@use-gesture/react": "^10.3.1", "camera-controls": "^3.1.0", "cross-env": "^7.0.3", "detect-gpu": "^5.0.56", "glsl-noise": "^0.0.0", "hls.js": "^1.5.17", "maath": "^0.10.8", "meshline": "^3.3.1", "stats-gl": "^2.2.8", "stats.js": "^0.17.0", "suspend-react": "^0.1.3", "three-mesh-bvh": "^0.8.3", "three-stdlib": "^2.35.6", "troika-three-text": "^0.52.4", "tunnel-rat": "^0.1.2", "use-sync-external-store": "^1.4.0", "utility-types": "^3.11.0", "zustand": "^5.0.1" }, "peerDependencies": { "@react-three/fiber": "^9.0.0", "react": "^19", "react-dom": "^19", "three": ">=0.159" }, "optionalPeers": ["react-dom"] }, "sha512-ZSFwRlRaa4zjtB7yHO6Q9xQGuyDCzE7whXBhum92JslcMRC3aouivp0rAzszcVymIoJx6PXmibyP+xr+zKdwLg=="],
@@ -912,6 +976,8 @@
"@tauri-apps/plugin-opener": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-B0LShOYae4CZjN8leiNDbnfjSrTwoZakqKaWpfoH6nXiJwt6Rgj6RnVIffG3DoJiKsffRhMkjmBV9VeilSb4TA=="],
"@tokenizer/token": ["@tokenizer/[email protected]", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
"@tootallnate/quickjs-emscripten": ["@tootallnate/[email protected]", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
"@tweenjs/tween.js": ["@tweenjs/[email protected]", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="],
@@ -926,7 +992,7 @@
"@types/babel__traverse": ["@types/[email protected]", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
"@types/bun": ["@types/[email protected].1", "", { "dependencies": { "bun-types": "1.3.1" } }, "sha512-4jNMk2/K9YJtfqwoAa28c8wK+T7nvJFOjxI4h/7sORWcypRNxBpr+TPNaCfVWq70tLCJsqoFwcf0oI0JU/fvMQ=="],
"@types/bun": ["@types/[email protected].9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
"@types/bytebuffer": ["@types/[email protected]", "", { "dependencies": { "@types/long": "^3.0.0", "@types/node": "*" } }, "sha512-lV4YLiolMdD4upDmr4vnfiwV/FN9Jg33eNTSFMkHqyMKqTIAn5TmFTYsARwXwUXeFU7yzRpECmWV1SOhIvdkRQ=="],
@@ -970,7 +1036,7 @@
"@types/progress": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-iadjw02vte8qWx7U0YM++EybBha2CQLPGu9iJ97whVgJUT5Zq9MjAPYUnbfRI2Kpehimf1QjFJYxD0t8nqzu5w=="],
"@types/react": ["@types/[email protected].2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
"@types/react": ["@types/[email protected].14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
"@types/react-dom": ["@types/[email protected]", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw=="],
@@ -1026,6 +1092,8 @@
"@webgpu/types": ["@webgpu/[email protected]", "", {}, "sha512-cYrHab4d6wuVvDW5tdsfI6/o6vcLMDe6w2Citd1oS51Xxu2ycLCnVo4fqwujfKWijrZMInTJIKcXxteoy21nVA=="],
"abort-controller": ["[email protected]", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
"acorn": ["[email protected]", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"adm-zip": ["[email protected]", "", {}, "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ=="],
@@ -1040,6 +1108,8 @@
"ansi-styles": ["[email protected]", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
"any-base": ["[email protected]", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="],
"anymatch": ["[email protected]", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
"argparse": ["[email protected]", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
@@ -1068,6 +1138,8 @@
"available-typed-arrays": ["[email protected]", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
"await-to-js": ["[email protected]", "", {}, "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g=="],
"axobject-query": ["[email protected]", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
"b4a": ["[email protected]", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q=="],
@@ -1114,6 +1186,8 @@
"bl": ["[email protected]", "", { "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww=="],
"bmp-ts": ["[email protected]", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="],
"boolbase": ["[email protected]", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
"bottleneck": ["[email protected]", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="],
@@ -1142,7 +1216,7 @@
"buffer-from": ["[email protected]", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"bun-types": ["[email protected].1", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-NMrcy7smratanWJ2mMXdpatalovtxVggkj11bScuWuiOoXTiKIu2eVS1/7qbyI/4yHedtsn175n4Sm4JcdHLXw=="],
"bun-types": ["[email protected].9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
"bytebuffer": ["[email protected]", "", { "dependencies": { "long": "~3" } }, "sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ=="],
@@ -1262,7 +1336,7 @@
"cssesc": ["[email protected]", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
"csv-parse": ["[email protected]", "", {}, "sha512-CEE+jwpgLn+MmtCpVcPtiCZpVtB6Z2OKPTr34pycYYoL7sxdOkXDdQ4lRiw6ioC0q6BLqhc6cKweCVvral8yhw=="],
@@ -1312,7 +1386,7 @@
"detect-gpu": ["[email protected]", "", { "dependencies": { "webgl-constants": "^1.1.1" } }, "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w=="],
"detect-libc": ["[email protected].1", "", {}, "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw=="],
"detect-libc": ["[email protected].2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"detect-node-es": ["[email protected]", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
@@ -1328,9 +1402,9 @@
"diff": ["[email protected]", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
"discord-api-types": ["[email protected].26", "", {}, "sha512-xpmPviHjIJ6dFu1eNwNDIGQ3N6qmPUUYFVAx/YZ64h7ZgPkTcKjnciD8bZe8Vbeji7yS5uYljyciunpq0J5NSw=="],
"discord-api-types": ["[email protected].39", "", {}, "sha512-XRdDQvZvID1XvcFftjSmd4dcmMi/RL/jSy5sduBDAvCGFcNFHThdIQXCEBDZFe52lCNEzuIL0QJoKYAmRmxLUA=="],
"discord.js": ["[email protected]2.1", "", { "dependencies": { "@discordjs/builders": "^1.11.2", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.1", "@discordjs/rest": "^2.6.0", "@discordjs/util": "^1.1.1", "@discordjs/ws": "^1.2.3", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.38.16", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "magic-bytes.js": "^1.10.0", "tslib": "^2.6.3", "undici": "6.21.3" } }, "sha512-3k+Kisd/v570Jr68A1kNs7qVhNehDwDJAPe4DZ2Syt+/zobf9zEcuYFvsfIaAOgCa0BiHMfOOKQY4eYINl0z7w=="],
"discord.js": ["[email protected]5.1", "", { "dependencies": { "@discordjs/builders": "^1.13.0", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.2", "@discordjs/rest": "^2.6.0", "@discordjs/util": "^1.2.0", "@discordjs/ws": "^1.2.3", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.38.33", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "magic-bytes.js": "^1.10.0", "tslib": "^2.6.3", "undici": "6.21.3" } }, "sha512-2l0gsPOLPs5t6GFZfQZKnL1OJNYFcuC/ETWsW4VtKVD/tg4ICa9x+jb9bkPffkMdRpRpuUaO/fKkHCBeiCKh8g=="],
"dlv": ["[email protected]", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
@@ -1342,7 +1416,7 @@
"domutils": ["[email protected]", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
"dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
"dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
"dprint-node": ["[email protected]", "", { "dependencies": { "detect-libc": "^1.0.3" } }, "sha512-iVKnUtYfGrYcW1ZAlfR/F59cUVL8QIhWoBJoSjkkdua/dkWIgjZfiLMeTjiB06X0ZLkQ0M2C1VbUj/CxkIf1zg=="],
@@ -1416,10 +1490,16 @@
"etag": ["[email protected]", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
"event-target-shim": ["[email protected]", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
"eventemitter3": ["[email protected]", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
"events": ["[email protected]", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
"events-universal": ["[email protected]", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="],
"exif-parser": ["[email protected]", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="],
"exsolve": ["[email protected]", "", {}, "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw=="],
"extend": ["[email protected]", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
@@ -1514,6 +1594,8 @@
"get-uri": ["[email protected]", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="],
"gifwrap": ["[email protected]", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="],
"giget": ["[email protected]", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
"github-slugger": ["[email protected]", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
@@ -1598,6 +1680,8 @@
"ieee754": ["[email protected]", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"image-q": ["[email protected]", "", { "dependencies": { "@types/node": "16.9.1" } }, "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw=="],
"immediate": ["[email protected]", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
"immer": ["[email protected]", "", {}, "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw=="],
@@ -1702,8 +1786,12 @@
"jake": ["[email protected]", "", { "dependencies": { "async": "^3.2.6", "filelist": "^1.0.4", "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" } }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="],
"jimp": ["[email protected]", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/diff": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-gif": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-blur": "1.6.0", "@jimp/plugin-circle": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-contain": "1.6.0", "@jimp/plugin-cover": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-displace": "1.6.0", "@jimp/plugin-dither": "1.6.0", "@jimp/plugin-fisheye": "1.6.0", "@jimp/plugin-flip": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/plugin-mask": "1.6.0", "@jimp/plugin-print": "1.6.0", "@jimp/plugin-quantize": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/plugin-rotate": "1.6.0", "@jimp/plugin-threshold": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg=="],
"jiti": ["[email protected]", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-VXe6RjJkBPj0ohtqaO8vSWP3ZhAKo66fKrFNCll4BTcwljPLz03pCbaNKfzGP5MbrCYcbJ7v0nOYYwUzTEIdXQ=="],
"jpeg-js": ["[email protected]", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="],
"js-tokens": ["[email protected]", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"js-yaml": ["[email protected]", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
@@ -1746,7 +1834,7 @@
"lodash": ["[email protected]", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
"lodash-es": ["[email protected]1", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="],
"lodash-es": ["[email protected]3", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="],
"lodash.debounce": ["[email protected]", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
@@ -1874,6 +1962,8 @@
"micromatch": ["[email protected]", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"mime": ["[email protected]", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
"mime-db": ["[email protected]", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
"mime-types": ["[email protected]", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
@@ -1934,6 +2024,8 @@
"ohash": ["[email protected]", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
"omggif": ["[email protected]", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="],
"on-finished": ["[email protected]", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
"once": ["[email protected]", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
@@ -1960,6 +2052,12 @@
"parent-module": ["[email protected]", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
"parse-bmfont-ascii": ["[email protected]", "", {}, "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA=="],
"parse-bmfont-binary": ["[email protected]", "", {}, "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA=="],
"parse-bmfont-xml": ["[email protected]", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="],
"parse-css-color": ["[email protected]", "", { "dependencies": { "color-name": "^1.1.4", "hex-rgb": "^4.1.0" } }, "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg=="],
"parse-json": ["[email protected]", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="],
@@ -1982,6 +2080,8 @@
"pathe": ["[email protected]", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"peek-readable": ["[email protected]", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="],
"pend": ["[email protected]", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
"perfect-debounce": ["[email protected]", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
@@ -2000,8 +2100,12 @@
"pinkie-promise": ["[email protected]", "", { "dependencies": { "pinkie": "^2.0.0" } }, "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw=="],
"pixelmatch": ["[email protected]", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="],
"pkg-types": ["[email protected]", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="],
"pngjs": ["[email protected]", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="],
"possible-typed-array-names": ["[email protected]", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
"postcss": ["[email protected]", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
@@ -2018,6 +2122,8 @@
"prismjs": ["[email protected]", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
"process": ["[email protected]", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
"process-nextick-args": ["[email protected]", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
"progress": ["[email protected]", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
@@ -2066,9 +2172,9 @@
"rc9": ["[email protected]", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
"react": ["[email protected].0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
"react": ["[email protected].4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
"react-dom": ["[email protected].0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
"react-dom": ["[email protected].4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
"react-promise-suspense": ["[email protected]", "", { "dependencies": { "fast-deep-equal": "^2.0.1" } }, "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ=="],
@@ -2086,6 +2192,8 @@
"readable-stream": ["[email protected]", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"readable-web-to-node-stream": ["[email protected]", "", { "dependencies": { "readable-stream": "^4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="],
"readdirp": ["[email protected]", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
"reflect.getprototypeof": ["[email protected]", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="],
@@ -2162,7 +2270,7 @@
"safer-buffer": ["[email protected]", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"satori": ["[email protected].3", "", { "dependencies": { "@shuding/opentype.js": "1.4.0-beta.0", "css-background-parser": "^0.1.0", "css-box-shadow": "1.0.0-3", "css-gradient-parser": "^0.0.17", "css-to-react-native": "^3.0.0", "emoji-regex-xs": "^2.0.1", "escape-html": "^1.0.3", "linebreak": "^1.1.0", "parse-css-color": "^0.2.1", "postcss-value-parser": "^4.2.0", "yoga-layout": "^3.2.1" } }, "sha512-T3DzWNmnrfVmk2gCIlAxLRLbGkfp3K7TyRva+Byyojqu83BNvnMeqVeYRdmUw4TKCsyH4RiQ/KuF/I4yEzgR5A=="],
"satori": ["[email protected].4", "", { "dependencies": { "@shuding/opentype.js": "1.4.0-beta.0", "css-background-parser": "^0.1.0", "css-box-shadow": "1.0.0-3", "css-gradient-parser": "^0.0.17", "css-to-react-native": "^3.0.0", "emoji-regex-xs": "^2.0.1", "escape-html": "^1.0.3", "linebreak": "^1.1.0", "parse-css-color": "^0.2.1", "postcss-value-parser": "^4.2.0", "yoga-layout": "^3.2.1" } }, "sha512-HanEzgXHlX3fzpGgxPoR3qI7FDpc/B+uE/KplzA6BkZGlWMaH98B/1Amq+OBF1pYPlGNzAXPYNHlrEVBvRBnHQ=="],
"sax": ["[email protected]", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="],
@@ -2170,7 +2278,7 @@
"seek-bzip": ["[email protected]", "", { "dependencies": { "commander": "^2.8.1" }, "bin": { "seek-bunzip": "bin/seek-bunzip", "seek-table": "bin/seek-bzip-table" } }, "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ=="],
"semver": ["[email protected].2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"semver": ["[email protected].4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
"send": ["[email protected]", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
@@ -2186,7 +2294,7 @@
"setprototypeof": ["[email protected]", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
"sharp": ["[email protected].4", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="],
"sharp": ["[email protected].5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
"shebang-command": ["[email protected]", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
@@ -2204,6 +2312,8 @@
"simple-swizzle": ["[email protected]", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="],
"simple-xml-to-json": ["[email protected]", "", {}, "sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA=="],
"sisteransi": ["[email protected]", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
"smart-buffer": ["[email protected]", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
@@ -2272,6 +2382,8 @@
"strnum": ["[email protected]", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
"strtok3": ["[email protected]", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="],
"supports-preserve-symlinks-flag": ["[email protected]", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"suspend-react": ["[email protected]", "", { "peerDependencies": { "react": ">=17.0" } }, "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ=="],
@@ -2300,6 +2412,8 @@
"tiny-typed-emitter": ["[email protected]", "", {}, "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="],
"tinycolor2": ["[email protected]", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="],
"tinyexec": ["[email protected]", "", {}, "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw=="],
"tinyglobby": ["[email protected]", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
@@ -2310,6 +2424,8 @@
"toidentifier": ["[email protected]", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"token-types": ["[email protected]", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ=="],
"tr46": ["[email protected]", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="],
"trim-lines": ["[email protected]", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
@@ -2430,6 +2546,8 @@
"use-sync-external-store": ["[email protected]", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
"utif2": ["[email protected]", "", { "dependencies": { "pako": "^1.0.11" } }, "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w=="],
"util-deprecate": ["[email protected]", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"utility-types": ["[email protected]", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="],
@@ -2558,6 +2676,8 @@
"ws": ["[email protected]", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"xml-parse-from-string": ["[email protected]", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="],
"xml2js": ["[email protected]", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA=="],
"xmlbuilder": ["[email protected]", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
@@ -2616,14 +2736,24 @@
"@blitzkit/app/typescript": ["[email protected]", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="],
"@blitzkit/bot/prisma": ["[email protected]7.1", "", { "dependencies": { "@prisma/config": "6.17.1", "@prisma/engines": "6.17.1" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-ac6h0sM1Tg3zu8NInY+qhP/S9KhENVaw9n1BrGKQVFu05JT5yT5Qqqmb8tMRIE3ZXvVj4xcRA5yfrsy4X7Yy5g=="],
"@blitzkit/bot/prisma": ["[email protected]9.2", "", { "dependencies": { "@prisma/config": "6.19.2", "@prisma/engines": "6.19.2" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-XTKeKxtQElcq3U9/jHyxSPgiRgeYDKxWTPOf6NkXA0dNj5j40MfEsZkMbyNpwDWCUv7YBFUl7I2VK/6ALbmhEg=="],
"@blitzkit/website/vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="],
"@discordjs/rest/@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="],
"@discordjs/rest/@discordjs/util": ["@discordjs/[email protected]", "", {}, "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g=="],
"@discordjs/rest/discord-api-types": ["[email protected]", "", {}, "sha512-xpmPviHjIJ6dFu1eNwNDIGQ3N6qmPUUYFVAx/YZ64h7ZgPkTcKjnciD8bZe8Vbeji7yS5uYljyciunpq0J5NSw=="],
"@discordjs/ws/@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="],
"@discordjs/ws/@discordjs/util": ["@discordjs/[email protected]", "", {}, "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g=="],
"@discordjs/ws/discord-api-types": ["[email protected]", "", {}, "sha512-xpmPviHjIJ6dFu1eNwNDIGQ3N6qmPUUYFVAx/YZ64h7ZgPkTcKjnciD8bZe8Vbeji7yS5uYljyciunpq0J5NSw=="],
"@jimp/core/file-type": ["[email protected]", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
"@octokit/endpoint/@octokit/types": ["@octokit/[email protected]", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
"@octokit/graphql/@octokit/types": ["@octokit/[email protected]", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
@@ -2634,6 +2764,8 @@
"@octokit/request-error/@octokit/types": ["@octokit/[email protected]", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
"@puppeteer/browsers/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"@rollup/plugin-babel/@rollup/pluginutils": ["@rollup/[email protected]", "", { "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0" } }, "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg=="],
"@rollup/plugin-babel/rollup": ["[email protected]", "", { "optionalDependencies": { "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ=="],
@@ -2654,6 +2786,10 @@
"astro/@astrojs/internal-helpers": ["@astrojs/[email protected]", "", {}, "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw=="],
"astro/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"astro/sharp": ["[email protected]", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="],
"babel-plugin-polyfill-corejs2/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"binarykvparser/long": ["[email protected]", "", { "bundled": true }, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="],
@@ -2694,6 +2830,8 @@
"https-proxy-agent/agent-base": ["[email protected]", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
"image-q/@types/node": ["@types/[email protected]", "", {}, "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="],
"its-fine/@types/react-reconciler": ["@types/[email protected]", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="],
"linebreak/base64-js": ["[email protected]", "", {}, "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw=="],
@@ -2702,12 +2840,18 @@
"micromatch/picomatch": ["[email protected]", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"ndarray-pixels/sharp": ["[email protected]", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="],
"pac-proxy-agent/agent-base": ["[email protected]", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
"pac-proxy-agent/socks-proxy-agent": ["[email protected]", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
"parse-bmfont-xml/xml2js": ["[email protected]", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="],
"parse5/entities": ["[email protected]", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"pixelmatch/pngjs": ["[email protected]", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="],
"prompts/kleur": ["[email protected]", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
"proxy-agent/agent-base": ["[email protected]", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
@@ -2722,6 +2866,8 @@
"readable-stream/safe-buffer": ["[email protected]", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"readable-web-to-node-stream/readable-stream": ["[email protected]", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
"safe-array-concat/isarray": ["[email protected]", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
"safe-push-apply/isarray": ["[email protected]", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
@@ -2754,10 +2900,16 @@
"tunnel-rat/zustand": ["[email protected]", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="],
"typescript-auto-import-cache/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"unbzip2-stream/buffer": ["[email protected]", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
"unicode-trie/pako": ["[email protected]", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="],
"utif2/pako": ["[email protected]", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
"volar-service-typescript/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"vscode-json-languageservice/jsonc-parser": ["[email protected]", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="],
"which-builtin-type/isarray": ["[email protected]", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
@@ -2782,9 +2934,9 @@
"yaml-language-server/yaml": ["[email protected]", "", {}, "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA=="],
"@blitzkit/bot/prisma/@prisma/config": ["@prisma/[email protected]7.1", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.16.12", "empathic": "2.0.0" } }, "sha512-fs8wY6DsvOCzuiyWVckrVs1LOcbY4LZNz8ki4uUIQ28jCCzojTGqdLhN2Jl5lDnC1yI8/gNIKpsWDM8pLhOdwA=="],
"@blitzkit/bot/prisma/@prisma/config": ["@prisma/[email protected]9.2", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ=="],
"@blitzkit/bot/prisma/@prisma/engines": ["@prisma/[email protected]7.1", "", { "dependencies": { "@prisma/debug": "6.17.1", "@prisma/engines-version": "6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac", "@prisma/fetch-engine": "6.17.1", "@prisma/get-platform": "6.17.1" } }, "sha512-D95Ik3GYZkqZ8lSR4EyFOJ/tR33FcYRP8kK61o+WMsyD10UfJwd7+YielflHfKwiGodcqKqoraWw8ElAgMDbPw=="],
"@blitzkit/bot/prisma/@prisma/engines": ["@prisma/[email protected]9.2", "", { "dependencies": { "@prisma/debug": "6.19.2", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/fetch-engine": "6.19.2", "@prisma/get-platform": "6.19.2" } }, "sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A=="],
"@octokit/endpoint/@octokit/types/@octokit/openapi-types": ["@octokit/[email protected]", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="],
@@ -2808,6 +2960,52 @@
"@rollup/plugin-replace/@rollup/pluginutils/picomatch": ["[email protected]", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"astro/sharp/@img/sharp-darwin-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA=="],
"astro/sharp/@img/sharp-darwin-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.3" }, "os": "darwin", "cpu": "x64" }, "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg=="],
"astro/sharp/@img/sharp-libvips-darwin-arm64": ["@img/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw=="],
"astro/sharp/@img/sharp-libvips-darwin-x64": ["@img/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA=="],
"astro/sharp/@img/sharp-libvips-linux-arm": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA=="],
"astro/sharp/@img/sharp-libvips-linux-arm64": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ=="],
"astro/sharp/@img/sharp-libvips-linux-ppc64": ["@img/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg=="],
"astro/sharp/@img/sharp-libvips-linux-s390x": ["@img/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w=="],
"astro/sharp/@img/sharp-libvips-linux-x64": ["@img/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg=="],
"astro/sharp/@img/sharp-libvips-linuxmusl-arm64": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw=="],
"astro/sharp/@img/sharp-libvips-linuxmusl-x64": ["@img/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g=="],
"astro/sharp/@img/sharp-linux-arm": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.3" }, "os": "linux", "cpu": "arm" }, "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA=="],
"astro/sharp/@img/sharp-linux-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ=="],
"astro/sharp/@img/sharp-linux-ppc64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ=="],
"astro/sharp/@img/sharp-linux-s390x": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.3" }, "os": "linux", "cpu": "s390x" }, "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw=="],
"astro/sharp/@img/sharp-linux-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A=="],
"astro/sharp/@img/sharp-linuxmusl-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA=="],
"astro/sharp/@img/sharp-linuxmusl-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg=="],
"astro/sharp/@img/sharp-wasm32": ["@img/[email protected]", "", { "dependencies": { "@emnapi/runtime": "^1.5.0" }, "cpu": "none" }, "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA=="],
"astro/sharp/@img/sharp-win32-arm64": ["@img/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA=="],
"astro/sharp/@img/sharp-win32-ia32": ["@img/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw=="],
"astro/sharp/@img/sharp-win32-x64": ["@img/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig=="],
"astro/sharp/detect-libc": ["[email protected]", "", {}, "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw=="],
"boxen/string-width/emoji-regex": ["[email protected]", "", {}, "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg=="],
"boxen/string-width/strip-ansi": ["[email protected]", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
@@ -2852,8 +3050,62 @@
"favilib/sharp/@img/sharp-win32-x64": ["@img/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="],
"favilib/sharp/detect-libc": ["[email protected]", "", {}, "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw=="],
"favilib/sharp/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"filelist/minimatch/brace-expansion": ["[email protected]", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"ndarray-pixels/sharp/@img/sharp-darwin-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA=="],
"ndarray-pixels/sharp/@img/sharp-darwin-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.3" }, "os": "darwin", "cpu": "x64" }, "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg=="],
"ndarray-pixels/sharp/@img/sharp-libvips-darwin-arm64": ["@img/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw=="],
"ndarray-pixels/sharp/@img/sharp-libvips-darwin-x64": ["@img/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA=="],
"ndarray-pixels/sharp/@img/sharp-libvips-linux-arm": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA=="],
"ndarray-pixels/sharp/@img/sharp-libvips-linux-arm64": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ=="],
"ndarray-pixels/sharp/@img/sharp-libvips-linux-ppc64": ["@img/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg=="],
"ndarray-pixels/sharp/@img/sharp-libvips-linux-s390x": ["@img/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w=="],
"ndarray-pixels/sharp/@img/sharp-libvips-linux-x64": ["@img/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg=="],
"ndarray-pixels/sharp/@img/sharp-libvips-linuxmusl-arm64": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw=="],
"ndarray-pixels/sharp/@img/sharp-libvips-linuxmusl-x64": ["@img/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g=="],
"ndarray-pixels/sharp/@img/sharp-linux-arm": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.3" }, "os": "linux", "cpu": "arm" }, "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA=="],
"ndarray-pixels/sharp/@img/sharp-linux-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ=="],
"ndarray-pixels/sharp/@img/sharp-linux-ppc64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ=="],
"ndarray-pixels/sharp/@img/sharp-linux-s390x": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.3" }, "os": "linux", "cpu": "s390x" }, "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw=="],
"ndarray-pixels/sharp/@img/sharp-linux-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A=="],
"ndarray-pixels/sharp/@img/sharp-linuxmusl-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA=="],
"ndarray-pixels/sharp/@img/sharp-linuxmusl-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg=="],
"ndarray-pixels/sharp/@img/sharp-wasm32": ["@img/[email protected]", "", { "dependencies": { "@emnapi/runtime": "^1.5.0" }, "cpu": "none" }, "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA=="],
"ndarray-pixels/sharp/@img/sharp-win32-arm64": ["@img/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA=="],
"ndarray-pixels/sharp/@img/sharp-win32-ia32": ["@img/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw=="],
"ndarray-pixels/sharp/@img/sharp-win32-x64": ["@img/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig=="],
"ndarray-pixels/sharp/detect-libc": ["[email protected]", "", {}, "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw=="],
"ndarray-pixels/sharp/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"readable-web-to-node-stream/readable-stream/string_decoder": ["[email protected]", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
"steam-appticket/protobufjs/@types/long": ["@types/[email protected]", "", {}, "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="],
"steam-appticket/protobufjs/long": ["[email protected]", "", {}, "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="],
@@ -2868,18 +3120,22 @@
"yaml-language-server/vscode-languageserver/vscode-languageserver-protocol": ["[email protected]", "", { "dependencies": { "vscode-jsonrpc": "6.0.0", "vscode-languageserver-types": "3.16.0" } }, "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A=="],
"@blitzkit/bot/prisma/@prisma/config/effect": ["[email protected]", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/debug": ["@prisma/[email protected]", "", {}, "sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/debug": ["@prisma/debug@6.17.1", "", {}, "sha512-Vf7Tt5Wh9XcndpbmeotuqOMLWPTjEKCsgojxXP2oxE1/xYe7PtnP76hsouG9vis6fctX+TxgmwxTuYi/+xc7dQ=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/engines-version": ["@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "", {}, "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/engines-version": ["@prisma/engines-version@6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac", "", {}, "sha512-17140E3huOuD9lMdJ9+SF/juOf3WR3sTJMVyyenzqUPbuH+89nPhSWcrY+Mf7tmSs6HvaO+7S+HkELinn6bhdg=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/fetch-engine": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.19.2", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/get-platform": "6.19.2" } }, "sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/fetch-engine": ["@prisma/fetch-engine@6.17.1", "", { "dependencies": { "@prisma/debug": "6.17.1", "@prisma/engines-version": "6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac", "@prisma/get-platform": "6.17.1" } }, "sha512-AYZiHOs184qkDMiTeshyJCtyL4yERkjfTkJiSJdYuSfc24m94lTNL5+GFinZ6vVz+ktX4NJzHKn1zIFzGTWrWg=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/get-platform": ["@prisma/get-platform@6.19.2", "", { "dependencies": { "@prisma/debug": "6.19.2" } }, "sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA=="],
"@blitzkit/bot/prisma/@prisma/engines/@prisma/get-platform": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.17.1" } }, "sha512-AKEn6fsfz0r482S5KRDFlIGEaq9wLNcgalD1adL+fPcFFblIKs1sD81kY/utrHdqKuVC6E1XSRpegDK3ZLL4Qg=="],
"astro/sharp/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="],
"boxen/string-width/strip-ansi/ansi-regex": ["[email protected]", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
"favilib/sharp/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="],
"ndarray-pixels/sharp/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="],
"widest-line/string-width/strip-ansi/ansi-regex": ["[email protected]", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
"yaml-language-server/vscode-languageserver/vscode-languageserver-protocol/vscode-jsonrpc": ["[email protected]", "", {}, "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg=="],
+14
View File
@@ -0,0 +1,14 @@
# BlitzKit 1.29.12
## Fixes
- BlitzKit no longer uses BlitzStars for tank averages for some commands
- BlitzKit Performance was created to completely replace BlitzStars but BlitzStars was still used for some older commands
- But since BlitzStars keeps having downtime, it has been completely removed
- Upgraded all dependencies to the latest versions
- The replay command is now properly localized across all languages
- Special Chinese characters are now properly handled
- Commands are now registered synchronously, allowing errors to reveal their exact origins
- Error handling now properly exists the process after logging the error
- The bot now uses Discord's new `clientReady` instead of the ambiguous `ready` event
- Both the armor and model extractors now use the new BlitzKit `SteamVFS`
+20
View File
@@ -0,0 +1,20 @@
# BlitzKit 1.29.13
## Features
- The screenshot button now automatically crops your image so you don't have excessive blank space all around
- Increased the max zoom out distance in Tankopedia to 50m
## Fixes
- Turrets in Tankopedia now stay within a range of -180 and +180 degrees
- Tanks with transparency like the T34 and Herdbreaker are now properly rendered
- This will take a few days to roll out for all tanks (see screenshots below for the fixed models)
- High End Consumables now give a 33% boost instead of 70%
- Static Armor now properly deselects all irrelevant armor plates
- Removed a few debug loggers left behind
- Static Armor now properly rerenders armor plates when their thicknesses are changed
- The Ricochet Visualizer now stays in place when dragging around on mobile
- Reduced the text in the Tankopedia Compare segmented display to fit on smaller screens
- Sorting by tertiary shells no longer crashes for some tanks
- The Tank Filters are now left aligned on smaller screens for readability
+11
View File
@@ -0,0 +1,11 @@
# BlitzKit 1.29.14
## Changes
- BlitzStars has enabled aggressive Cloudflare protections; hence, disabling BlitzKit from using BlitzStar's API
- Disabled the following commands:
- `/stats`
- `/today`
- `/breakdown`
- `/evolution`
- `/full-stats`
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "blitzkit",
"version": "1.29.11",
"version": "1.29.14",
"license": "BlitzKit License",
"private": true,
"scripts": {
@@ -13,7 +13,7 @@
"build:catalogitemaccesssor": "cd packages/scripts && bun run build:catalogitemaccesssor",
"build:ratingleaderboard": "cd packages/scripts && bun run build:ratingleaderboard",
"build:app": "cd packages/app && bun run build",
"dev:bot": "bun run build:bot --dev && bun start:bot",
"dev:bot": "bun run build:bot --dev && bun start:bot --dev",
"start:bot": "bun dist/bot/main.js",
"dev:docs": "vitepress dev docs",
"dev:website": "cd packages/website && bun run dev",
@@ -45,6 +45,7 @@
"dependencies": {
"@prisma/client": "^6.18.0",
"prisma": "^6.18.0",
"sharp": "^0.34.5",
"typescript": "^5.9.3"
}
}
+11 -11
View File
@@ -356,9 +356,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.10.1"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
dependencies = [
"serde",
]
@@ -2105,9 +2105,9 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
name = "num-conv"
version = "0.1.0"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
[[package]]
name = "num-traits"
@@ -3907,30 +3907,30 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.44"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"serde_core",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.6"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
[[package]]
name = "time-macros"
version = "0.2.24"
version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
dependencies = [
"num-conv",
"time-core",
+10 -9
View File
@@ -4,25 +4,26 @@
"@blitzkit/core": "workspace:*",
"@blitzkit/i18n": "workspace:*",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/themes": "^3.2.1",
"@radix-ui/themes": "^3.3.0",
"@resvg/resvg-js": "^2.6.2",
"@types/adm-zip": "^0.5.7",
"@types/bun": "^1.3.9",
"@types/lodash-es": "^4.17.12",
"@types/markdown-escape": "^1.1.3",
"@types/react": "^19.2.2",
"@types/react": "^19.2.14",
"adm-zip": "^0.5.16",
"bepaint": "^0.1.0-beta.3",
"discord.js": "^14.22.1",
"dotenv": "^17.2.2",
"discord.js": "^14.25.1",
"dotenv": "^17.3.1",
"fuzzysort": "^3.1.0",
"lodash-es": "^4.17.21",
"lodash-es": "^4.17.23",
"markdown-escape": "^2.0.0",
"pickleparser": "^0.2.1",
"prisma": "^6.17.1",
"prisma": "^6.19.2",
"protobufjs": "^7.5.4",
"react": "^19.2.0",
"satori": "^0.18.3",
"sharp": "^0.34.4"
"react": "^19.2.4",
"satori": "^0.18.4",
"sharp": "^0.34.5"
},
"private": true,
"scripts": {
+4 -4
View File
@@ -1,7 +1,7 @@
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { translator } from "../core/localization/translator";
import {
COMMANDS_RAW,
commandsArray,
type CommandRegistry,
} from "../events/interactionCreate";
@@ -35,7 +35,7 @@ export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
if (subcommand === "commands") {
return `${strings.bot.commands.about.subcommands.commands.body}${(
await Promise.all(COMMANDS_RAW)
await Promise.all(commandsArray)
)
.sort((a, b) =>
(a.command.name_localizations?.[interaction.locale] ??
@@ -43,7 +43,7 @@ export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
(b.command.name_localizations?.[interaction.locale] ??
b.command.name)
? -1
: 1
: 1,
)
.map(
(registry) =>
@@ -54,7 +54,7 @@ export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
registry.command.description_localizations?.[
interaction.locale
] ?? registry.command.description
}`
}`,
)
.join("\n")}`;
}
+33 -36
View File
@@ -1,49 +1,46 @@
import { getBlitzStarsLinkButton } from '../../core/blitzstars/getBlitzStarsLinkButton';
import { addPeriodicFilterOptions } from '../../core/discord/addPeriodicFilterOptions';
import { addUsernameChoices } from '../../core/discord/addUsernameChoices';
import { autocompleteTanks } from '../../core/discord/autocompleteTanks';
import { autocompleteUsername } from '../../core/discord/autocompleteUsername';
import { buttonRefresh } from '../../core/discord/buttonRefresh';
import { commandToURL } from '../../core/discord/commandToURL';
import { createLocalizedCommand } from '../../core/discord/createLocalizedCommand';
import { getCustomPeriodParams } from '../../core/discord/getCustomPeriodParams';
import { getFiltersFromButton } from '../../core/discord/getFiltersFromButton';
import { getFiltersFromCommand } from '../../core/discord/getFiltersFromCommand';
import { resolvePeriodFromButton } from '../../core/discord/resolvePeriodFromButton';
import { resolvePeriodFromCommand } from '../../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../../core/discord/resolvePlayerFromButton';
import { resolvePlayerFromCommand } from '../../core/discord/resolvePlayerFromCommand';
import type { CommandRegistry } from '../../events/interactionCreate';
import { renderBreakdown } from './render';
import { addPeriodicFilterOptions } from "../../core/discord/addPeriodicFilterOptions";
import { addUsernameChoices } from "../../core/discord/addUsernameChoices";
import { autocompleteTanks } from "../../core/discord/autocompleteTanks";
import { autocompleteUsername } from "../../core/discord/autocompleteUsername";
import { createLocalizedCommand } from "../../core/discord/createLocalizedCommand";
import { getFiltersFromButton } from "../../core/discord/getFiltersFromButton";
import { resolvePeriodFromButton } from "../../core/discord/resolvePeriodFromButton";
import { resolvePlayerFromButton } from "../../core/discord/resolvePlayerFromButton";
import { translator } from "../../core/localization/translator";
import type { CommandRegistry } from "../../events/interactionCreate";
import { renderBreakdown } from "./render";
export const breakdownCommand = new Promise<CommandRegistry>(
async (resolve) => {
resolve({
command: await addPeriodicFilterOptions(
createLocalizedCommand('breakdown'),
createLocalizedCommand("breakdown"),
(option) => option.addStringOption(addUsernameChoices),
),
async handler(interaction) {
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const filters = await getFiltersFromCommand(interaction);
const path = commandToURL(interaction, {
...player,
...getCustomPeriodParams(interaction),
...filters,
});
const { strings } = translator(interaction.locale);
return strings.bot.commands.dead;
return [
...(await renderBreakdown(
player,
period,
filters,
interaction.locale,
)),
buttonRefresh(interaction, path),
await getBlitzStarsLinkButton(player.region, player.id),
];
// const player = await resolvePlayerFromCommand(interaction);
// const period = resolvePeriodFromCommand(player.region, interaction);
// const filters = await getFiltersFromCommand(interaction);
// const path = commandToURL(interaction, {
// ...player,
// ...getCustomPeriodParams(interaction),
// ...filters,
// });
// return [
// ...(await renderBreakdown(
// player,
// period,
// filters,
// interaction.locale,
// )),
// buttonRefresh(interaction, path),
// await getBlitzStarsLinkButton(player.region, player.id),
// ];
},
autocomplete: (interaction) => {
+32 -27
View File
@@ -15,11 +15,16 @@ import { CommandWrapper } from "../../components/CommandWrapper";
import { NoData } from "../../components/NoData";
import { TitleBar } from "../../components/TitleBar";
import { filtersToDescription } from "../../core/blitzkit/filtersToDescription";
import { tankDefinitions } from "../../core/blitzkit/nonBlockingPromises";
import {
averageDefinitions,
tankDefinitions,
} from "../../core/blitzkit/nonBlockingPromises";
import { UserError } from "../../core/blitzkit/userError";
import { filterStats, type StatFilters } from "../../core/blitzstars/filterStats";
import {
filterStats,
type StatFilters,
} from "../../core/blitzstars/filterStats";
import { getStatsInPeriod } from "../../core/blitzstars/getStatsInPeriod";
import { blitzStarsTankAverages } from "../../core/blitzstars/tankAverages";
import type { ResolvedPeriod } from "../../core/discord/resolvePeriodFromCommand";
import type { ResolvedPlayer } from "../../core/discord/resolvePlayerFromCommand";
import { translator } from "../../core/localization/translator";
@@ -31,11 +36,11 @@ export async function renderBreakdown(
{ region, id }: ResolvedPlayer,
{ start, end, name }: ResolvedPeriod,
filters: StatFilters,
locale: Locale
locale: Locale,
) {
const { strings, unwrap } = translator(locale);
const awaitedTankDefinitions = await tankDefinitions;
const awaitedTankAverages = await blitzStarsTankAverages;
const awaitedTankAverages = await averageDefinitions;
const statsInPeriod = await getStatsInPeriod(region, id, start, end, locale);
const { filteredOrder } = await filterStats(statsInPeriod, filters);
const accountInfo = await getAccountInfo(region, id);
@@ -53,14 +58,14 @@ export async function renderBreakdown(
}
filteredOrder.forEach((id) => {
const tankAveragesEntry = awaitedTankAverages[id];
const tankAveragesEntry = awaitedTankAverages.averages[id];
const current = statsInPeriod.diff[id];
const career = tankStats.find((tank) => tank.tank_id === id)!.all;
const currentWN8 = tankAveragesEntry
? calculateWN8(tankAveragesEntry.all, current)
? calculateWN8(tankAveragesEntry.mu, current)
: undefined;
const careerWN8 = tankAveragesEntry
? calculateWN8(tankAveragesEntry.all, career)
? calculateWN8(tankAveragesEntry.mu, career)
: undefined;
orderedCurrentStats.push(current);
@@ -69,65 +74,65 @@ export async function renderBreakdown(
orderedCareerWN8.push(careerWN8);
});
tankStats.forEach((tank) => {
const tankAveragesEntry = awaitedTankAverages[tank.tank_id];
const tankAveragesEntry = awaitedTankAverages.averages[tank.tank_id];
orderedCareerWN8Full.push(
tankAveragesEntry
? calculateWN8(tankAveragesEntry.all, tank.all)
: undefined
? calculateWN8(tankAveragesEntry.mu, tank.all)
: undefined,
);
});
const currentBattles = orderedCurrentStats.reduce(
(accumulator, current) => accumulator + current.battles,
0
0,
);
const careerBattles = tankStats.reduce(
(accumulator, current) => accumulator + current.all.battles,
0
0,
);
const currentWinrate =
orderedCurrentStats.reduce(
(accumulator, current) => accumulator + current.wins,
0
0,
) / currentBattles;
const careerWinrate =
tankStats.reduce(
(accumulator, current) => accumulator + current.all.wins,
0
0,
) / careerBattles;
const currentWN8 =
orderedCurrentWN8.reduce<number>(
(accumulator, current, index) =>
accumulator + (current ?? 0) * orderedCurrentStats[index].battles,
0
0,
) /
orderedCurrentStats.reduce(
(accumulator, current, index) =>
accumulator +
(orderedCurrentWN8[index] === undefined ? 0 : current.battles),
0
0,
);
const careerWN8 =
orderedCareerWN8Full.reduce<number>(
(accumulator, current) => accumulator + (current ?? 0),
0
0,
) /
tankStats.reduce(
(accumulator, current, index) =>
accumulator +
(orderedCareerWN8Full[index] === undefined ? 0 : current.all.battles),
0
0,
);
const currentDamage =
orderedCurrentStats.reduce(
(accumulator, current) => accumulator + current.damage_dealt,
0
0,
) / currentBattles;
const careerDamage =
tankStats.reduce(
(accumulator, current) => accumulator + current.all.damage_dealt,
0
0,
) / careerBattles;
const children: React.JSX.Element[] = [];
@@ -172,7 +177,7 @@ export async function renderBreakdown(
delta: currentDamage - careerDamage,
},
]}
/>
/>,
);
filteredOrder.forEach((id, index) => {
@@ -206,7 +211,7 @@ export async function renderBreakdown(
{
title: strings.bot.commands.breakdown.body.winrate,
current: `${(100 * (current.wins / current.battles)).toFixed(
2
2,
)}%`,
career: `${(100 * (career.wins / career.battles)).toFixed(2)}%`,
delta:
@@ -230,24 +235,24 @@ export async function renderBreakdown(
{
title: strings.bot.commands.breakdown.body.damage,
current: Math.round(
current.damage_dealt / current.battles
current.damage_dealt / current.battles,
).toLocaleString(),
career: Math.round(
career.damage_dealt / career.battles
career.damage_dealt / career.battles,
).toLocaleString(),
delta:
current.damage_dealt / current.battles -
career.damage_dealt / career.battles,
},
]}
/>
/>,
);
});
}
const pages = chunk(
children,
Math.max(Math.ceil(children.length / MAX_PAGES), ROWS_PER_PAGE)
Math.max(Math.ceil(children.length / MAX_PAGES), ROWS_PER_PAGE),
);
if (filteredOrder.length > 0) {
+41 -48
View File
@@ -5,8 +5,6 @@ import * as Graph from "../components/Graph";
import { LineColor } from "../components/Graph/components/Line/constants";
import { NoData } from "../components/NoData";
import { TitleBar } from "../components/TitleBar";
import { resolveTankId } from "../core/blitz/resolveTankId";
import { getBlitzStarsLinkButton } from "../core/blitzstars/getBlitzStarsLinkButton";
import { getPlayerHistories } from "../core/blitzstars/getPlayerHistories";
import { getTankHistories } from "../core/blitzstars/getTankHistories";
import { addPeriodSubCommands } from "../core/discord/addPeriodSubCommands";
@@ -14,20 +12,12 @@ import { addTankChoices } from "../core/discord/addTankChoices";
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
import { buttonRefresh } from "../core/discord/buttonRefresh";
import { commandToURL } from "../core/discord/commandToURL";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { getCustomPeriodParams } from "../core/discord/getCustomPeriodParams";
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
import {
type ResolvedPeriod,
resolvePeriodFromCommand,
} from "../core/discord/resolvePeriodFromCommand";
import { type ResolvedPeriod } from "../core/discord/resolvePeriodFromCommand";
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
import {
type ResolvedPlayer,
resolvePlayerFromCommand,
} from "../core/discord/resolvePlayerFromCommand";
import { type ResolvedPlayer } from "../core/discord/resolvePlayerFromCommand";
import { translator } from "../core/localization/translator";
import type { CommandRegistry } from "../events/interactionCreate";
type EvolutionStatType = "player" | "tank";
@@ -37,7 +27,7 @@ async function render(
{ start, end, name }: ResolvedPeriod,
type: "player" | "tank",
tankId: number | null,
locale: Locale
locale: Locale,
) {
const accountInfo = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
@@ -61,7 +51,7 @@ async function render(
[
history.all.battles,
(history.all.wins / history.all.battles) * 100,
] as Graph.PlotItem
] as Graph.PlotItem,
);
const times = histories.map((history) => history.last_battle_time);
const minTime = Math.min(...times);
@@ -115,7 +105,7 @@ export const evolutionCommand = new Promise<CommandRegistry>(
group: "player",
modify(option: SlashCommandSubcommandGroupBuilder) {
addPeriodSubCommands(option, (option) =>
option.addStringOption(addUsernameChoices)
option.addStringOption(addUsernameChoices),
);
},
},
@@ -125,43 +115,46 @@ export const evolutionCommand = new Promise<CommandRegistry>(
addPeriodSubCommands(option, (option) =>
option
.addStringOption(addTankChoices)
.addStringOption(addUsernameChoices)
.addStringOption(addUsernameChoices),
);
},
},
]),
async handler(interaction) {
const commandGroup =
interaction.options.getSubcommandGroup() as EvolutionStatType;
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const tankIdRaw = interaction.options.getString("tank")!;
const tankId =
commandGroup === "tank"
? await resolveTankId(tankIdRaw, interaction.locale)
: null;
const path = commandToURL(interaction, {
...player,
...getCustomPeriodParams(interaction),
tankId,
});
const { strings } = translator(interaction.locale);
return strings.bot.commands.dead;
return [
await render(
player,
period,
commandGroup,
tankId,
interaction.locale
),
buttonRefresh(interaction, path),
await getBlitzStarsLinkButton(
player.region,
player.id,
tankId ?? undefined
),
];
// const commandGroup =
// interaction.options.getSubcommandGroup() as EvolutionStatType;
// const player = await resolvePlayerFromCommand(interaction);
// const period = resolvePeriodFromCommand(player.region, interaction);
// const tankIdRaw = interaction.options.getString("tank")!;
// const tankId =
// commandGroup === "tank"
// ? await resolveTankId(tankIdRaw, interaction.locale)
// : null;
// const path = commandToURL(interaction, {
// ...player,
// ...getCustomPeriodParams(interaction),
// tankId,
// });
// return [
// await render(
// player,
// period,
// commandGroup,
// tankId,
// interaction.locale
// ),
// buttonRefresh(interaction, path),
// await getBlitzStarsLinkButton(
// player.region,
// player.id,
// tankId ?? undefined
// ),
// ];
},
autocomplete: (interaction) => {
@@ -181,9 +174,9 @@ export const evolutionCommand = new Promise<CommandRegistry>(
period,
commandGroup,
parseInt(url.searchParams.get("tankId") ?? "0") || null,
interaction.locale
interaction.locale,
);
},
});
}
},
);
+40 -47
View File
@@ -3,38 +3,28 @@ import {
getAccountInfo,
getClanAccountInfo,
getTierWeights,
} from '@blitzkit/core';
import { Locale } from 'discord.js';
import { CommandWrapper } from '../components/CommandWrapper';
import { GenericAllStats } from '../components/GenericAllStats';
import { NoData } from '../components/NoData';
import { TierWeights } from '../components/TierWeights';
import { TitleBar } from '../components/TitleBar';
import { filtersToDescription } from '../core/blitzkit/filtersToDescription';
import { filterStats, type StatFilters } from '../core/blitzstars/filterStats';
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
import { getStatsInPeriod } from '../core/blitzstars/getStatsInPeriod';
import { addPeriodicFilterOptions } from '../core/discord/addPeriodicFilterOptions';
import { addUsernameChoices } from '../core/discord/addUsernameChoices';
import { autocompleteTanks } from '../core/discord/autocompleteTanks';
import { autocompleteUsername } from '../core/discord/autocompleteUsername';
import { buttonRefresh } from '../core/discord/buttonRefresh';
import { commandToURL } from '../core/discord/commandToURL';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { getCustomPeriodParams } from '../core/discord/getCustomPeriodParams';
import { getFiltersFromButton } from '../core/discord/getFiltersFromButton';
import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
import {
type ResolvedPeriod,
resolvePeriodFromCommand,
} from '../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
import {
type ResolvedPlayer,
resolvePlayerFromCommand,
} from '../core/discord/resolvePlayerFromCommand';
import type { CommandRegistry } from '../events/interactionCreate';
} from "@blitzkit/core";
import { Locale } from "discord.js";
import { CommandWrapper } from "../components/CommandWrapper";
import { GenericAllStats } from "../components/GenericAllStats";
import { NoData } from "../components/NoData";
import { TierWeights } from "../components/TierWeights";
import { TitleBar } from "../components/TitleBar";
import { filtersToDescription } from "../core/blitzkit/filtersToDescription";
import { filterStats, type StatFilters } from "../core/blitzstars/filterStats";
import { getStatsInPeriod } from "../core/blitzstars/getStatsInPeriod";
import { addPeriodicFilterOptions } from "../core/discord/addPeriodicFilterOptions";
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { getFiltersFromButton } from "../core/discord/getFiltersFromButton";
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
import { type ResolvedPeriod } from "../core/discord/resolvePeriodFromCommand";
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
import { type ResolvedPlayer } from "../core/discord/resolvePlayerFromCommand";
import { translator } from "../core/localization/translator";
import type { CommandRegistry } from "../events/interactionCreate";
async function render(
{ region, id }: ResolvedPlayer,
@@ -43,7 +33,7 @@ async function render(
locale: Locale,
) {
const { nickname } = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
const diffedTankStats = await getStatsInPeriod(
region,
@@ -86,25 +76,28 @@ export const fullStatsCommand = new Promise<CommandRegistry>(
async (resolve) => {
resolve({
command: await addPeriodicFilterOptions(
createLocalizedCommand('full-stats'),
createLocalizedCommand("full-stats"),
(option) => option.addStringOption(addUsernameChoices),
),
async handler(interaction) {
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const filters = await getFiltersFromCommand(interaction);
const path = commandToURL(interaction, {
...player,
...getCustomPeriodParams(interaction),
...filters,
});
const { strings } = translator(interaction.locale);
return strings.bot.commands.dead;
return Promise.all([
render(player, period, filters, interaction.locale),
buttonRefresh(interaction, path),
getBlitzStarsLinkButton(player.region, player.id),
]);
// const player = await resolvePlayerFromCommand(interaction);
// const period = resolvePeriodFromCommand(player.region, interaction);
// const filters = await getFiltersFromCommand(interaction);
// const path = commandToURL(interaction, {
// ...player,
// ...getCustomPeriodParams(interaction),
// ...filters,
// });
// return Promise.all([
// render(player, period, filters, interaction.locale),
// buttonRefresh(interaction, path),
// getBlitzStarsLinkButton(player.region, player.id),
// ]);
},
autocomplete: (interaction) => {
+92 -77
View File
@@ -5,28 +5,29 @@ import {
idToRegion,
tankIcon,
TIER_ROMAN_NUMERALS,
} from '@blitzkit/core';
import { Locale } from 'discord.js';
import { clamp } from 'lodash-es';
import { CommandWrapper } from '../components/CommandWrapper';
import { TitleBar } from '../components/TitleBar';
import { iconPng } from '../core/blitzkit/iconPng';
} from "@blitzkit/core";
import { Locale } from "discord.js";
import { clamp } from "lodash-es";
import { CommandWrapper } from "../components/CommandWrapper";
import { TitleBar } from "../components/TitleBar";
import { iconPng } from "../core/blitzkit/iconPng";
import {
averageDefinitions,
mapDefinitions,
tankDefinitions,
} from '../core/blitzkit/nonBlockingPromises';
import { RenderConfiguration } from '../core/blitzkit/renderConfiguration';
import { blitzStarsTankAverages } from '../core/blitzstars/tankAverages';
import { buttonLink } from '../core/discord/buttonLink';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { translator } from '../core/localization/translator';
import { type CommandRegistry } from '../events/interactionCreate';
import { theme } from '../stitches.config';
} from "../core/blitzkit/nonBlockingPromises";
import { RenderConfiguration } from "../core/blitzkit/renderConfiguration";
import { buttonLink } from "../core/discord/buttonLink";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { localizationObject } from "../core/discord/localizationObject";
import { translator } from "../core/localization/translator";
import { type CommandRegistry } from "../events/interactionCreate";
import { theme } from "../stitches.config";
type WotInspectorReplaySubmission =
| { status: 'error'; data: unknown; error: { message: string } }
| { status: "error"; data: unknown; error: { message: string } }
| {
status: 'ok';
status: "ok";
data: {
download_url: string;
view_url: string;
@@ -209,9 +210,9 @@ function stat(value: string | number, flex = 2) {
<div
style={{
flex,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<span style={{ fontSize: 16 }}>{value}</span>
@@ -227,15 +228,15 @@ async function playerListing(
recordingPlayer = false,
) {
const { unwrap } = translator(locale);
const awaitedTankAverages = await blitzStarsTankAverages;
const awaitedTankAverages = await averageDefinitions;
const awaitedTankDefinitions = await tankDefinitions;
const tank = awaitedTankDefinitions.tanks[player.vehicle_descr];
const blockAccent = recordingPlayer ? '_amber' : '';
const blockAccent = recordingPlayer ? "_amber" : "";
const healthAccent = protagonistTeam
? recordingPlayer
? '_amber'
: '_green'
: '_red';
? "_amber"
: "_green"
: "_red";
// our turret ids are always off by 1 or 2 lol so imma just grab the closest
// TODO: 💀
@@ -245,11 +246,11 @@ async function playerListing(
)[0];
const totalHealth = turret.health + tank.health;
const healthLeft = clamp(player.hitpoints_left / totalHealth, 0, 1);
const tankAveragesEntry = awaitedTankAverages[player.vehicle_descr];
const tankAveragesEntry = awaitedTankAverages.averages[player.vehicle_descr];
const wn8 =
tankAveragesEntry === undefined
? -1
: calculateWN8(tankAveragesEntry.all, {
: calculateWN8(tankAveragesEntry.mu, {
battles: 1,
damage_dealt: player.damage_made,
dropped_capture_points: player.base_defend_points,
@@ -262,8 +263,8 @@ async function playerListing(
<div
key={player.entity_id}
style={{
display: 'flex',
alignItems: 'center',
display: "flex",
alignItems: "center",
gap: 8,
backgroundColor: theme.colors[`appBackground2${blockAccent}`],
padding: 8,
@@ -271,11 +272,11 @@ async function playerListing(
>
<div
style={{
display: 'flex',
display: "flex",
gap: 8,
flex: 1,
overflow: 'hidden',
alignItems: 'center',
overflow: "hidden",
alignItems: "center",
}}
>
<img
@@ -284,22 +285,22 @@ async function playerListing(
style={{
width: 32,
height: 32,
objectFit: 'contain',
objectFit: "contain",
}}
/>
<div
style={{
display: 'flex',
flexDirection: 'column',
display: "flex",
flexDirection: "column",
// align
}}
>
<div
style={{
display: 'flex',
display: "flex",
gap: 4,
alignItems: 'center',
alignItems: "center",
}}
>
<span
@@ -324,23 +325,23 @@ async function playerListing(
style={{
fontSize: 16,
color: theme.colors[`textLowContrast${blockAccent}`],
whiteSpace: 'nowrap',
whiteSpace: "nowrap",
}}
>
{player.name}
{player.clan_tag ? ` [${player.clan_tag}]` : ''}
{player.clan_tag ? ` [${player.clan_tag}]` : ""}
</span>
</div>
</div>
<div
style={{
display: 'flex',
display: "flex",
flex: 1,
}}
>
{stat(player.damage_made.toLocaleString())}
{stat(wn8 === -1 ? '--' : Math.round(wn8).toLocaleString())}
{stat(wn8 === -1 ? "--" : Math.round(wn8).toLocaleString())}
{stat(player.exp.toLocaleString())}
{stat(player.enemies_destroyed, 1)}
</div>
@@ -349,15 +350,15 @@ async function playerListing(
style={{
borderRadius: 2,
backgroundColor: theme.colors[`componentInteractive${healthAccent}`],
display: 'flex',
display: "flex",
width: 4,
height: '100%',
transform: 'scaleY(-1)',
height: "100%",
transform: "scaleY(-1)",
}}
>
<div
style={{
width: '100%',
width: "100%",
height: `${healthLeft * 100}%`,
borderRadius: 2,
backgroundColor: theme.colors[`solidBackground${healthAccent}`],
@@ -373,8 +374,8 @@ function Header() {
<div
style={{
padding: 8,
display: 'flex',
alignItems: 'center',
display: "flex",
alignItems: "center",
gap: 8,
}}
>
@@ -382,16 +383,16 @@ function Header() {
<div
style={{
display: 'flex',
display: "flex",
flex: 1,
}}
>
<div
style={{
flex: 2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<span
@@ -406,9 +407,9 @@ function Header() {
<div
style={{
flex: 2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<span
@@ -423,9 +424,9 @@ function Header() {
<div
style={{
flex: 2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<span
@@ -440,9 +441,9 @@ function Header() {
<div
style={{
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<span
@@ -460,28 +461,42 @@ function Header() {
}
export const replayCommand = new Promise<CommandRegistry>((resolve) => {
const { strings } = translator(Locale.EnglishUS);
resolve({
command: createLocalizedCommand('replay').addAttachmentOption((option) =>
option.setName('file').setDescription('Replay file').setRequired(true),
command: createLocalizedCommand("replay").addAttachmentOption((option) =>
option
.setName(strings.bot.commands.replay.options.file.name)
.setNameLocalizations(
localizationObject(
(strings) => strings.bot.commands.replay.options.file.name,
undefined,
true,
),
)
.setDescription(strings.bot.commands.replay.options.file.description)
.setDescriptionLocalizations(
localizationObject(
(strings) => strings.bot.commands.replay.options.file.description,
),
)
.setRequired(true),
),
async handler(interaction) {
const awaitedMapDefinitions = await mapDefinitions;
const file = interaction.options.getAttachment('file')!;
// const file = {
// url: 'https://cdn.discordapp.com/ephemeral-attachments/1232434891652861972/1232781496016834581/20240328_1530__TresAbhi_M60_1157057448155406708.wotbreplay?ex=662ab4bc&is=6629633c&hm=c784cd10e80232350ddaf291fa987b879c4d0a8083b78298c9eee4fa0d507f6c&',
// };
const file = interaction.options.getAttachment("file")!;
const submissionData = (await fetch(
`https://wotinspector.com/api/replay/upload/?url=${encodeURIComponent(
file.url,
)}`,
).then((response) => response.json())) as WotInspectorReplaySubmission;
if (submissionData.status === 'error') {
if (submissionData.status === "error") {
return `# Uh oh! WoT Inspector didn't like that.\n\nThere was an error processing your replay. Get help on [the official Discord server](https://discord.gg/nDt7AjGJQH).`;
}
const replayId = submissionData.data.download_url.split('/').at(-1)!;
const replayId = submissionData.data.download_url.split("/").at(-1)!;
const replayData = (await fetch(
`https://api.wotinspector.com/v2/blitz/replays/${replayId}/`,
).then((response) => response.json())) as WotInspectorReplay;
@@ -493,7 +508,7 @@ export const replayCommand = new Promise<CommandRegistry>((resolve) => {
await getClanAccountInfo(
idToRegion(replayData.protagonist),
replayData.protagonist,
['clan'],
["clan"],
)
)?.clan;
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
@@ -506,22 +521,22 @@ export const replayCommand = new Promise<CommandRegistry>((resolve) => {
image={clanImage}
description={`${
replayData.protagonist_team === replayData.winner_team
? 'Victory'
: 'Defeat'
? "Victory"
: "Defeat"
} • ${awaitedMapDefinitions.maps[replayData.map_id].name}`}
/>
<div
style={{
display: 'flex',
display: "flex",
gap: 8,
}}
>
<div
style={{
flex: 1,
display: 'flex',
flexDirection: 'column',
display: "flex",
flexDirection: "column",
gap: 4,
}}
>
@@ -547,8 +562,8 @@ export const replayCommand = new Promise<CommandRegistry>((resolve) => {
<div
style={{
flex: 1,
display: 'flex',
flexDirection: 'column',
display: "flex",
flexDirection: "column",
gap: 4,
}}
>
@@ -569,8 +584,8 @@ export const replayCommand = new Promise<CommandRegistry>((resolve) => {
</div>
</div>
</CommandWrapper>,
buttonLink(submissionData.data.view_url, 'WoT Inspector'),
buttonLink(submissionData.data.download_url, 'Download'),
buttonLink(submissionData.data.view_url, "WoT Inspector"),
buttonLink(submissionData.data.download_url, "Download"),
];
},
});
+22 -29
View File
@@ -6,35 +6,25 @@ import { NoData } from "../components/NoData";
import { TitleBar } from "../components/TitleBar";
import { filtersToDescription } from "../core/blitzkit/filtersToDescription";
import { filterStats, type StatFilters } from "../core/blitzstars/filterStats";
import { getBlitzStarsLinkButton } from "../core/blitzstars/getBlitzStarsLinkButton";
import { getStatsInPeriod } from "../core/blitzstars/getStatsInPeriod";
import { addPeriodicFilterOptions } from "../core/discord/addPeriodicFilterOptions";
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
import { buttonRefresh } from "../core/discord/buttonRefresh";
import { commandToURL } from "../core/discord/commandToURL";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { getCustomPeriodParams } from "../core/discord/getCustomPeriodParams";
import { getFiltersFromButton } from "../core/discord/getFiltersFromButton";
import { getFiltersFromCommand } from "../core/discord/getFiltersFromCommand";
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
import {
type ResolvedPeriod,
resolvePeriodFromCommand,
} from "../core/discord/resolvePeriodFromCommand";
import { type ResolvedPeriod } from "../core/discord/resolvePeriodFromCommand";
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
import {
type ResolvedPlayer,
resolvePlayerFromCommand,
} from "../core/discord/resolvePlayerFromCommand";
import { type ResolvedPlayer } from "../core/discord/resolvePlayerFromCommand";
import { translator } from "../core/localization/translator";
import type { CommandRegistry } from "../events/interactionCreate";
async function render(
{ region, id }: ResolvedPlayer,
{ start, end, name }: ResolvedPeriod,
filters: StatFilters,
locale: Locale
locale: Locale,
) {
const { nickname } = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
@@ -44,7 +34,7 @@ async function render(
id,
start,
end,
locale
locale,
);
const { stats, supplementary } = await filterStats(diffedTankStats, filters);
const filterDescriptions = await filtersToDescription(filters, locale);
@@ -73,24 +63,27 @@ export const statsCommand = new Promise<CommandRegistry>(async (resolve) => {
resolve({
command: await addPeriodicFilterOptions(
createLocalizedCommand("stats"),
(option) => option.addStringOption(addUsernameChoices)
(option) => option.addStringOption(addUsernameChoices),
),
async handler(interaction) {
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const filters = await getFiltersFromCommand(interaction);
const path = commandToURL(interaction, {
...player,
...getCustomPeriodParams(interaction),
...filters,
});
const { strings } = translator(interaction.locale);
return strings.bot.commands.dead;
return Promise.all([
render(player, period, filters, interaction.locale),
buttonRefresh(interaction, path),
getBlitzStarsLinkButton(player.region, player.id),
]);
// const player = await resolvePlayerFromCommand(interaction);
// const period = resolvePeriodFromCommand(player.region, interaction);
// const filters = await getFiltersFromCommand(interaction);
// const path = commandToURL(interaction, {
// ...player,
// ...getCustomPeriodParams(interaction),
// ...filters,
// });
// return Promise.all([
// render(player, period, filters, interaction.locale),
// buttonRefresh(interaction, path),
// getBlitzStarsLinkButton(player.region, player.id),
// ]);
},
autocomplete: (interaction) => {
+33 -36
View File
@@ -1,50 +1,47 @@
import { gameDefinitions } from '../core/blitzkit/nonBlockingPromises';
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
import { addFilterOptions } from '../core/discord/addFilterOptions';
import { addUsernameChoices } from '../core/discord/addUsernameChoices';
import { autocompleteTanks } from '../core/discord/autocompleteTanks';
import { autocompleteUsername } from '../core/discord/autocompleteUsername';
import { buttonRefresh } from '../core/discord/buttonRefresh';
import { commandToURL } from '../core/discord/commandToURL';
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
import { getCustomPeriodParams } from '../core/discord/getCustomPeriodParams';
import { getFiltersFromButton } from '../core/discord/getFiltersFromButton';
import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
import { resolvePeriodFromButton } from '../core/discord/resolvePeriodFromButton';
import { resolvePeriodFromCommand } from '../core/discord/resolvePeriodFromCommand';
import { resolvePlayerFromButton } from '../core/discord/resolvePlayerFromButton';
import { resolvePlayerFromCommand } from '../core/discord/resolvePlayerFromCommand';
import { type CommandRegistry } from '../events/interactionCreate';
import { renderBreakdown } from './breakdown/render';
import { gameDefinitions } from "../core/blitzkit/nonBlockingPromises";
import { addFilterOptions } from "../core/discord/addFilterOptions";
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
import { getFiltersFromButton } from "../core/discord/getFiltersFromButton";
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
import { translator } from "../core/localization/translator";
import { type CommandRegistry } from "../events/interactionCreate";
import { renderBreakdown } from "./breakdown/render";
export const todayCommand = new Promise<CommandRegistry>(async (resolve) => {
const awaitedGameDefinitions = await gameDefinitions;
resolve({
command: addFilterOptions(
createLocalizedCommand('today'),
createLocalizedCommand("today"),
awaitedGameDefinitions.nations,
).addStringOption(addUsernameChoices),
async handler(interaction) {
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(
player.region,
interaction,
'today',
);
const filters = await getFiltersFromCommand(interaction);
const path = commandToURL(interaction, {
...player,
...getCustomPeriodParams(interaction, true),
...filters,
});
const { strings } = translator(interaction.locale);
return strings.bot.commands.dead;
return [
...(await renderBreakdown(player, period, filters, interaction.locale)),
buttonRefresh(interaction, path),
await getBlitzStarsLinkButton(player.region, player.id),
];
// const player = await resolvePlayerFromCommand(interaction);
// const period = resolvePeriodFromCommand(
// player.region,
// interaction,
// 'today',
// );
// const filters = await getFiltersFromCommand(interaction);
// const path = commandToURL(interaction, {
// ...player,
// ...getCustomPeriodParams(interaction, true),
// ...filters,
// });
// return [
// ...(await renderBreakdown(player, period, filters, interaction.locale)),
// buttonRefresh(interaction, path),
// await getBlitzStarsLinkButton(player.region, player.id),
// ];
},
autocomplete: (interaction) => {
@@ -1,11 +1,13 @@
import {
fetchAverageDefinitions,
fetchDiscoveredIdsDefinitions,
fetchGameDefinitions,
fetchMapDefinitions,
fetchTankDefinitions,
fetchTankNames,
} from '@blitzkit/core';
} from "@blitzkit/core";
export const averageDefinitions = fetchAverageDefinitions();
export const tankDefinitions = fetchTankDefinitions();
export const gameDefinitions = fetchGameDefinitions();
export const tankNames = fetchTankNames();
+26 -18
View File
@@ -1,29 +1,37 @@
import { usersDatabase } from '../db/users';
import { client } from '../discord/client';
import { usersDatabase } from "../db/users";
import { client } from "../discord/client";
const EXIT_EVENTS = [
'beforeExit',
'exit',
'SIGINT',
'SIGTERM',
'SIGUSR1',
'SIGUSR2',
];
const EXIT_EVENTS = ["SIGINT", "SIGTERM", "SIGUSR1", "SIGUSR2"];
async function cleanup() {
console.log('Cleaning up...');
let cleaningUp = false;
await Promise.all([usersDatabase.$disconnect(), client.destroy()]);
async function cleanup(signal: string) {
if (cleaningUp) return;
cleaningUp = true;
console.log('Gracefully exiting...');
console.log(`Cleaning up... (${signal})`);
try {
await Promise.all([usersDatabase.$disconnect(), client.destroy()]);
} catch (err) {
console.error("Cleanup error:", err);
}
console.log("Gracefully exiting...");
EXIT_EVENTS.forEach((event) => process.off(event, cleanup));
process.exit(0);
}
export function registerProcesses() {
process.on('uncaughtException', console.error);
client.on('error', console.error);
process.on("uncaughtException", (err) => {
console.error("uncaughtException:", err);
});
EXIT_EVENTS.forEach((event) => process.on(event, cleanup));
process.on("unhandledRejection", (err) => {
console.error("unhandledRejection:", err);
});
client.on("error", console.error);
EXIT_EVENTS.forEach((event) => process.on(event, () => cleanup(event)));
}
+15 -11
View File
@@ -3,8 +3,10 @@ import type { SupplementaryStats } from "@blitzkit/core/src/blitz/getAccountInfo
import { calculateWN8 } from "@blitzkit/core/src/statistics/calculateWN8";
import type { BlitzStats } from "@blitzkit/core/src/statistics/compositeStats";
import { sumAllStats } from "@blitzkit/core/src/statistics/sumAllStats";
import { tankDefinitions } from "../blitzkit/nonBlockingPromises";
import { blitzStarsTankAverages } from "./tankAverages";
import {
averageDefinitions,
tankDefinitions,
} from "../blitzkit/nonBlockingPromises";
export interface StatFilters {
nation?: string;
@@ -16,13 +18,13 @@ export interface StatFilters {
export async function filterStats(
{ diff, order }: DiffedTankStats,
filters: StatFilters
filters: StatFilters,
) {
// tank, if provided, takes priority over all other filters
if (filters.tank) filters = { tank: filters.tank };
const awaitedTankDefinitions = await tankDefinitions;
const awaitedTankAverages = await blitzStarsTankAverages;
const awaitedTankAverages = await averageDefinitions;
const filteredOrder = order.filter((id) => {
const entry = awaitedTankDefinitions.tanks[id];
@@ -44,26 +46,28 @@ export async function filterStats(
const stats = sumAllStats(filteredOrder.map((id) => diff[id]));
const battlesOfTanksWithAverages = filteredOrder.reduce<number>(
(accumulator, id) =>
awaitedTankAverages[id] ? accumulator + diff[id].battles : accumulator,
0
awaitedTankAverages.averages[id]
? accumulator + diff[id].battles
: accumulator,
0,
);
const battlesOfTanksWithTankDefinition = filteredOrder.reduce<number>(
(accumulator, id) =>
awaitedTankDefinitions.tanks[id]
? accumulator + diff[id].battles
: accumulator,
0
0,
);
const supplementary = {
WN8:
filteredOrder.reduce<number>(
(accumulator, id) =>
awaitedTankAverages[id]
awaitedTankAverages.averages[id]
? accumulator +
calculateWN8(awaitedTankAverages[id].all, diff[id]) *
calculateWN8(awaitedTankAverages.averages[id].mu, diff[id]) *
diff[id].battles
: accumulator,
0
0,
) / battlesOfTanksWithAverages,
tier:
filteredOrder.reduce<number>(
@@ -72,7 +76,7 @@ export async function filterStats(
? accumulator +
awaitedTankDefinitions.tanks[id]!.tier * diff[id].battles
: accumulator,
0
0,
) / battlesOfTanksWithTankDefinition,
} satisfies SupplementaryStats;
@@ -1,101 +0,0 @@
import { BlitzStats } from '@blitzkit/core';
import { context } from '@blitzkit/core/src/blitzkit/context';
interface SpecialStats {
winrate: number;
damageRatio: number;
kdr: number;
damagePerBattle: number;
killsPerBattle: number;
hitsPerBattle: number;
spotsPerBattle: number;
wpm: number;
dpm: number;
kpm: number;
hitRate: number;
survivalRate: number;
}
export type Percentiles = [
number,
number,
number,
number,
number,
number,
number,
number,
number,
];
export interface SpecialPercentiles {
winRate: Percentiles;
damageRatio: Percentiles;
kdr: Percentiles;
damagePerBattle: Percentiles;
killsPerBattle: Percentiles;
hitsPerBattle: Percentiles;
spotsPerBattle: Percentiles;
wpm: Percentiles;
dpm: Percentiles;
kpm: Percentiles;
hitRate: Percentiles;
survivalRate: Percentiles;
}
export interface MeanSd {
winrateMean: number;
winrateSd: number;
hitRateMean: number;
hitRateSd: number;
survivalRateMean: number;
survivalRateSd: number;
damageRatioMean: number;
damageRatioSd: number;
kdrMean: number;
kdrSd: number;
dpbMean: number;
dpbSd: number;
kpbMean: number;
kpbSd: number;
hpbMean: number;
hpbSd: number;
spbMean: number;
spbSd: number;
}
export interface IndividualTankAverage {
_id: number;
battle_life_time: number;
total_battle_life_time: number;
number_of_players: number;
tank_id: number;
all: BlitzStats;
special: SpecialStats;
percentiles: SpecialPercentiles;
percentiles_player_count: number;
meanSd: MeanSd;
shotEff: number;
last_update: number;
}
export type BlitzStarsTankAverages = Record<number, IndividualTankAverage>;
export const blitzStarsTankAverages = fetch(
'https://www.blitzstars.com/api/tankaverages.json',
)
.then((response) => response.json())
.then((json) => {
if (context === 'server') {
const partialTankAverages: BlitzStarsTankAverages = {};
(json as IndividualTankAverage[]).forEach((individualTankAverage) => {
partialTankAverages[individualTankAverage.tank_id] =
individualTankAverage;
});
return partialTankAverages;
} else {
return json as BlitzStarsTankAverages;
}
});
+5 -5
View File
@@ -1,9 +1,9 @@
import { Client, GatewayIntentBits } from 'discord.js';
import { interactionCreate } from '../../events/interactionCreate';
import { ready } from '../../events/ready';
import { Client, GatewayIntentBits } from "discord.js";
import { interactionCreate } from "../../events/interactionCreate";
import { ready } from "../../events/ready";
export const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
})
.on('ready', ready)
.on('interactionCreate', interactionCreate);
.on("clientReady", ready)
.on("interactionCreate", interactionCreate);
@@ -22,11 +22,11 @@ export function createLocalizedCommand(
command: string,
sub?:
| CreateLocalizedCommandSubcommand[]
| CreateLocalizedCommandSubcommandGroup[]
| CreateLocalizedCommandSubcommandGroup[],
) {
const commandPathItem = command.replaceAll(
"-",
"_"
"_",
) as keyof BlitzKitStrings["bot"]["commands"];
const { strings } = translator(Locale.EnglishUS);
const slashCommand = new SlashCommandBuilder()
@@ -35,14 +35,14 @@ export function createLocalizedCommand(
localizationObject(
(strings) => strings.bot.commands[commandPathItem].name,
undefined,
true
)
true,
),
)
.setDescription(strings.bot.commands[commandPathItem].description)
.setDescriptionLocalizations(
localizationObject(
(strings) => strings.bot.commands[commandPathItem].description
)
(strings) => strings.bot.commands[commandPathItem].description,
),
);
if (sub) {
@@ -56,7 +56,7 @@ export function createLocalizedCommand(
}
).subcommands[subItem.subcommand].name,
undefined,
true
true,
);
const subcommandDescriptionLocalizations = localizationObject(
(strings) =>
@@ -64,7 +64,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
subcommands: Record<string, { description: string }>;
}
).subcommands[subItem.subcommand].description
).subcommands[subItem.subcommand].description,
);
slashCommand.addSubcommand((option) => {
@@ -78,7 +78,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
subcommands: Record<string, { description: string }>;
}
).subcommands[subItem.subcommand].description
).subcommands[subItem.subcommand].description,
)
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
});
@@ -91,7 +91,7 @@ export function createLocalizedCommand(
}
).groups[subItem.group].name,
undefined,
true
true,
);
const subcommandDescriptionLocalizations = localizationObject(
(strings) =>
@@ -99,7 +99,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
groups: Record<string, { description: string }>;
}
).groups[subItem.group].description
).groups[subItem.group].description,
);
slashCommand.addSubcommandGroup((option) => {
@@ -113,7 +113,7 @@ export function createLocalizedCommand(
strings.bot.commands[commandPathItem] as unknown as {
groups: Record<string, { description: string }>;
}
).groups[subItem.group].description
).groups[subItem.group].description,
)
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
});
@@ -1,10 +1,10 @@
import { AutocompleteInteraction, CacheType } from 'discord.js';
import { commands } from '..';
import { AutocompleteInteraction, CacheType } from "discord.js";
import { commands } from "..";
export async function handleAutocomplete(
interaction: AutocompleteInteraction<CacheType>,
) {
const command = (await commands)[interaction.commandName];
const command = commands[interaction.commandName];
if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
@@ -1,13 +1,13 @@
import { ButtonInteraction, CacheType } from 'discord.js';
import { commands } from '..';
import { normalizeInteractionReturnable } from '../../../core/discord/normalizeInteractionReturnable';
import { ButtonInteraction, CacheType } from "discord.js";
import { commands } from "..";
import { normalizeInteractionReturnable } from "../../../core/discord/normalizeInteractionReturnable";
export async function handleButton(interaction: ButtonInteraction<CacheType>) {
await interaction.deferUpdate();
const url = new URL(`https://example.com/${interaction.customId}`);
const commandName = url.pathname.split('/')[1];
const button = (await commands)[commandName]?.button;
const commandName = url.pathname.split("/")[1];
const button = commands[commandName]?.button;
if (!button) {
throw new Error(`Button handler not found for "${commandName}"`);
@@ -16,7 +16,7 @@ export async function handleButton(interaction: ButtonInteraction<CacheType>) {
if (interaction.message.interaction?.user.id !== interaction.user.id) {
interaction.followUp({
ephemeral: true,
content: 'You are not the author of this command.',
content: "You are not the author of this command.",
});
return;
}
@@ -17,12 +17,11 @@ import { translator } from "../../../core/localization/translator";
import type { Writeable } from "../../../types/writable";
export async function handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>
interaction: ChatInputCommandInteraction<CacheType>,
) {
await interaction.deferReply();
const awaitedCommands = await commands;
const registry = awaitedCommands[interaction.commandName];
const registry = commands[interaction.commandName];
try {
const returnable = await registry.handler(interaction);
@@ -36,7 +35,7 @@ export async function handleChatInputCommand(
if (typeof object === "string") {
chunks.push([object]);
} else chunks.at(-1)?.push(object!);
}
},
);
let index = 0;
@@ -59,7 +58,7 @@ export async function handleChatInputCommand(
} else if (psa.data.type === "image") {
if (!reply.files) reply.files = [];
(reply.files as Writeable<typeof reply.files>).push(
new AttachmentBuilder(psa.data.image)
new AttachmentBuilder(psa.data.image),
);
reply.content = reply.content ?? psa.data.title;
}
@@ -72,7 +71,7 @@ export async function handleChatInputCommand(
(
reply.components[0] as ActionRowBuilder<ButtonBuilder>
).addComponents(
psa.data.links.map(({ title, url }) => buttonLink(url, title))
psa.data.links.map(({ title, url }) => buttonLink(url, title)),
);
}
}
@@ -103,7 +102,7 @@ export async function handleChatInputCommand(
} else if (psa.data.type === "image") {
if (!followUp.files) followUp.files = [];
(followUp.files as Writeable<typeof followUp.files>).push(
new AttachmentBuilder(psa.data.image)
new AttachmentBuilder(psa.data.image),
);
followUp.content = followUp.content ?? psa.data.title;
}
@@ -116,7 +115,7 @@ export async function handleChatInputCommand(
(
followUp.components[0] as ActionRowBuilder<ButtonBuilder>
).addComponents(
psa.data.links.map(({ title, url }) => buttonLink(url, title))
psa.data.links.map(({ title, url }) => buttonLink(url, title)),
);
}
@@ -133,7 +132,7 @@ export async function handleChatInputCommand(
new ButtonBuilder()
.setLabel(strings.bot.common.errors.get_help)
.setURL("https://discord.gg/nDt7AjGJQH")
.setStyle(ButtonStyle.Link)
.setStyle(ButtonStyle.Link),
),
];
if (error instanceof UserError) {
@@ -72,13 +72,13 @@ interface CommandRegistryImplicit extends CommandRegistryBase {
interface CommandRegistryExplicit extends CommandRegistryBase {
handlesInteraction?: false;
handler: (
interaction: ChatInputCommandInteraction<CacheType>
interaction: ChatInputCommandInteraction<CacheType>,
) => InteractionReturnable;
}
export type CommandRegistry = CommandRegistryImplicit | CommandRegistryExplicit;
export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
export const commandsArray: Promise<CommandRegistry>[] = [
// auctionCommand,
permissionsCommand,
debugCommand,
@@ -101,34 +101,28 @@ export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
replayCommand,
];
export const commands = Promise.allSettled(COMMANDS_RAW).then((rawCommands) => {
return rawCommands.reduce<Record<string, CommandRegistry>>(
(commands, registry, index) => {
if (registry.status === "rejected") {
console.warn(
`Command ${index} failed to load; skipping...`,
registry.reason
);
return commands;
}
return { ...commands, [registry.value.command.name]: registry.value };
},
{}
);
});
export const commands: Record<string, CommandRegistry> = {};
const commandsFulfilled: CommandRegistry[] = [];
let index = 0;
for (const registry of await Promise.allSettled(commandsArray)) {
if (registry.status === "rejected") {
console.warn(`Command ${index} rejected`, registry.reason);
continue;
}
commandsFulfilled.push(registry.value);
commands[registry.value.command.name] = registry.value;
index++;
}
const rest = new REST().setToken(assertSecret(import.meta.env.DISCORD_TOKEN));
const body = commandsFulfilled.map((registry) => registry.command.toJSON());
const applicationCommandsRoute = Routes.applicationCommands(
assertSecret(import.meta.env.DISCORD_CLIENT_ID),
);
commands.then((awaitedCommands) => {
const body = Object.values(awaitedCommands).map((registry) =>
registry.command.toJSON()
);
rest.put(
Routes.applicationCommands(assertSecret(import.meta.env.DISCORD_CLIENT_ID)),
{ body }
);
});
await rest.put(applicationCommandsRoute, { body });
export async function interactionCreate(interaction: Interaction<CacheType>) {
if (interaction.isAutocomplete()) {
+14 -14
View File
@@ -1,27 +1,27 @@
import { assertSecret } from '@blitzkit/core';
import { ActivityType, ShardingManager } from 'discord.js';
import { assertSecret } from "@blitzkit/core";
import { ActivityType, ShardingManager } from "discord.js";
import {
discoveredIdsDefinitions,
tankDefinitions,
} from './core/blitzkit/nonBlockingPromises';
} from "./core/blitzkit/nonBlockingPromises";
let manager: ShardingManager;
let iteration = 0;
const interval = setInterval(async () => {
iteration++;
console.log(`Attempting launch on iteration ${++iteration}`);
console.log(`Attempting launch on iteration ${iteration}`);
const manager = new ShardingManager('dist/bot/workers/bot.js', {
manager?.respawnAll();
manager = new ShardingManager("dist/bot/workers/bot.js", {
token: assertSecret(import.meta.env.DISCORD_TOKEN),
});
const shards = await manager
.on('shardCreate', (shard) => {
.on("shardCreate", (shard) => {
clearInterval(interval);
console.log(`🟡 Launching shard ${shard.id}`);
shard.on('ready', () => console.log(`🟢 Launched shard ${shard.id}`));
shard.on("ready", () => console.log(`🟢 Launched shard ${shard.id}`));
})
.spawn();
.spawn({ timeout: 60000 });
try {
let servers = 0;
@@ -29,7 +29,7 @@ const interval = setInterval(async () => {
let users = 0;
for (const [, shard] of shards) {
const guilds = (await shard.fetchClientValue('guilds.cache')) as any;
const guilds = (await shard.fetchClientValue("guilds.cache")) as any;
servers += guilds.length;
@@ -66,7 +66,7 @@ const interval = setInterval(async () => {
for (const guild of client.guilds.cache.values()) {
try {
const botMember = await guild.members.fetch(client.user.id);
await botMember.setNickname('BlitzKit');
await botMember.setNickname("BlitzKit");
} catch {}
}
},
@@ -74,8 +74,8 @@ const interval = setInterval(async () => {
);
} catch (error) {
console.warn(
'An error occurred when setting up presence, ignoring to keep the process alive',
"An error occurred when setting up presence, ignoring to keep the process alive",
error,
);
}
}, 5000);
}, 15000);
+3 -3
View File
@@ -1,6 +1,6 @@
import { assertSecret } from '@blitzkit/core';
import { registerProcesses } from '../core/blitzkit/processes';
import { client } from '../core/discord/client';
import { assertSecret } from "@blitzkit/core";
import { registerProcesses } from "../core/blitzkit/processes";
import { client } from "../core/discord/client";
console.log(`🟡 Launching bot ${client.shard?.ids[0]}`);
+1 -1
View File
@@ -35,7 +35,7 @@ for (const locale in stringsRaw) {
const localeStrings = stringsRaw[locale];
STRINGS[locale] = merge(
stringsRaw[locales.default],
localeStrings
localeStrings,
) as BlitzKitStrings;
}
+12 -3
View File
@@ -357,9 +357,18 @@
},
"commands": {
"dead": "# Stat Commands Are Dead\n\nThe BlitzKit Discord bot used to use BlitzStars to fetch periodic statistics. BlitzStars has enabled aggressive Cloudflare protections; hence, disabling BlitzKit from using BlitzStar's API. This has impacted the following commands:\n\n- `/stats`\n- `/today`\n- `/breakdown`\n- `/evolution`\n- `/full-stats`\n\nPlease use [Aftermath](<https://amth.one/invite>) as an alternative which is completely independent of BlitzStars. BlitzKit-hosted stat commands will return in the near future.",
"replay": {
"name": "replay",
"description": "Display replay results"
"description": "Display replay results",
"options": {
"file": {
"name": "file",
"description": "Replay file"
}
}
},
"research": {
@@ -1132,8 +1141,8 @@
"title": "Characteristics",
"compare": {
"label": "Compare",
"class": "Tier {tier} {class}",
"tier": "All of tier {tier}",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "All tanks"
},
"values": {
+4 -4
View File
@@ -493,7 +493,7 @@
"description": "Search clans",
"options": {
"limit": {
"name": "limit",
"name": "",
"description": "The max number of clan results (default: {limit})"
}
},
@@ -507,7 +507,7 @@
"description": "Search players",
"options": {
"limit": {
"name": "limit",
"name": "",
"description": "The max number of player results (default: {limit})"
}
},
@@ -531,7 +531,7 @@
},
"options": {
"limit": {
"name": "limit",
"name": "",
"description": "How many neighbors to display (default: {count})"
},
"season": {
@@ -675,7 +675,7 @@
"active": "{name} (Active)",
"no_tanks_found": {
"body": "No tanks found.",
"search_again": "Try searching again.",
"search_again": "",
"clear_filters": "Try clearing filters."
},
"sort": {
+2 -2
View File
@@ -24,7 +24,7 @@
"shells": {
"ap": "ББ",
"ap_cr": "БП",
"hc": "ОФ",
"hc": "КС",
"he": "ОФ"
},
"player_count_period": {
@@ -39,7 +39,7 @@
"branches": {
"local": "dev",
"dev": "бета",
"opentest": "открытый тест",
"opentest": "общий тест",
"preview": "превью"
},
"locales": {
+12 -19
View File
@@ -1,15 +1,10 @@
import { build } from "esbuild";
import { cp, readdir, rm } from "fs/promises";
import { argv } from "process";
const dev = argv.includes("--dev");
const projectDir = "../..";
const srcRoot = `${projectDir}/packages/bot`;
const distRoot = `${projectDir}/dist/bot`;
const modulesRoot = dev
? "../../packages/bot/node_modules"
: "../../node_modules";
const modulesRoot = "../../node_modules";
const workers = await readdir(`${srcRoot}/src/workers`);
await rm(distRoot, { recursive: true, force: true });
@@ -30,9 +25,9 @@ build({
},
external: ["sharp"],
minifyIdentifiers: false, // causes goofy ahh issues
minifySyntax: !dev,
minifyWhitespace: !dev,
sourcemap: !dev,
minifySyntax: true,
minifyWhitespace: true,
sourcemap: true,
jsxImportSource: "react",
jsx: "automatic",
});
@@ -44,18 +39,16 @@ for (const module of await readdir(`${modulesRoot}/@resvg`)) {
.map((file) =>
cp(
`${modulesRoot}/@resvg/${module}/${file}`,
`${distRoot}/workers/${file}`
)
)
`${distRoot}/workers/${file}`,
),
),
);
}
if (!dev) {
await cp(`${projectDir}/prisma`, `${distRoot}/prisma`, { recursive: true });
await cp(`${projectDir}/prisma`, `${distRoot}/prisma`, { recursive: true });
for (const file of await readdir(`${modulesRoot}/prisma`).then((files) =>
files.filter((file) => file.endsWith(".node"))
)) {
cp(`${modulesRoot}/prisma/${file}`, `${distRoot}/prisma/${file}`);
}
for (const file of await readdir(`${modulesRoot}/prisma`).then((files) =>
files.filter((file) => file.endsWith(".node")),
)) {
cp(`${modulesRoot}/prisma/${file}`, `${distRoot}/prisma/${file}`);
}
+11 -11
View File
@@ -6,7 +6,7 @@ import {
} from "@blitzkit/core";
import { Accessor, Document, Node, Scene } from "@gltf-transform/core";
import { times } from "lodash-es";
import { SteamVFS } from "../vfs/vfs";
import { SteamVFS } from "../vfs/steam";
import {
vertexAttributeGLTFName,
vertexAttributeGltfVectorSizes,
@@ -16,10 +16,10 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
const sc2Path = `Data/3d/Tanks/CollisionMeshes/${fileName}.sc2`;
const scgPath = `Data/3d/Tanks/CollisionMeshes/${fileName}.scg`;
const sc2 = new Sc2ReadStream(
(await vfs.file(sc2Path)).buffer as ArrayBuffer
(await vfs.file(sc2Path)).buffer as ArrayBuffer,
).sc2();
const scg = new ScgReadStream(
(await vfs.file(scgPath)).buffer as ArrayBuffer
(await vfs.file(scgPath)).buffer as ArrayBuffer,
).scg();
const document = new Document();
const scene = document.createScene();
@@ -29,7 +29,7 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
hierarchies.forEach((hierarchy) => {
const components = times(
hierarchy.components.count,
(index) => hierarchy.components[index.toString().padStart(4, "0")]
(index) => hierarchy.components[index.toString().padStart(4, "0")],
);
components.forEach((component) => {
@@ -43,7 +43,7 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
if (!polygonGroup) {
console.warn(
`Missing polygon group ${batch["rb.datasource"]} (${hierarchy.name}); skipping...`
`Missing polygon group ${batch["rb.datasource"]} (${hierarchy.name}); skipping...`,
);
break;
@@ -73,7 +73,7 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
VertexAttribute.TANGENT,
attributes
.get(VertexAttribute.TANGENT)!
.map((tangent) => [...tangent, 1])
.map((tangent) => [...tangent, 1]),
);
}
@@ -94,7 +94,7 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
hardJointIndices.forEach((hardJointIndex) => {
const node = document.createNode(
`${hierarchy.name}_armor_${hardJointIndex}`
`${hierarchy.name}_armor_${hardJointIndex}`,
);
const mesh = document.createMesh(batch["##name"]);
const indicesAccessor = document
@@ -104,9 +104,9 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
new Uint16Array(
polygonGroup.indices.filter(
(index) =>
vertexHardJointIndices.get(index) === hardJointIndex
)
)
vertexHardJointIndices.get(index) === hardJointIndex,
),
),
)
.setBuffer(buffer);
const primitive = document
@@ -127,7 +127,7 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
default:
throw new TypeError(
`Unhandled component type: ${component["comp.typename"]}`
`Unhandled component type: ${component["comp.typename"]}`,
);
}
});
@@ -9,7 +9,7 @@ import { Document, Material, Node, Scene } from "@gltf-transform/core";
import { dedup, prune } from "@gltf-transform/functions";
import { times } from "lodash-es";
import { dirname } from "path";
import { SteamVFS } from "../../vfs/vfs";
import { SteamVFS } from "../../vfs/steam";
import { readBaseColor } from "../readBaseColor";
import { readNormal } from "../readNormal";
import { readRoughnessMetallic } from "../readRoughnessMetallic";
@@ -29,10 +29,10 @@ export async function extractModel(vfs: SteamVFS, path: string) {
const sc2Path = `Data/3d/${path}.sc2`;
const scgPath = `Data/3d/${path}.scg`;
const sc2 = new Sc2ReadStream(
(await vfs.file(sc2Path)).buffer as ArrayBuffer
(await vfs.file(sc2Path)).buffer as ArrayBuffer,
).sc2();
const scg = new ScgReadStream(
(await vfs.file(scgPath)).buffer as ArrayBuffer
(await vfs.file(scgPath)).buffer as ArrayBuffer,
).scg();
const document = new Document();
const scene = document.createScene();
@@ -61,20 +61,17 @@ export async function extractModel(vfs: SteamVFS, path: string) {
}
if (textures) {
const { image: baseColor, hasAlpha } = await readBaseColor(
`Data/3d/${dirname(path)}/${textures.baseColorMap ?? textures.albedo}`,
textures.miscMap
? `Data/3d/${dirname(path)}/${textures.miscMap}`
: undefined,
);
material.setBaseColorTexture(
document
.createTexture(node.materialName)
.setMimeType("image/webp")
.setImage(
await readBaseColor(
`Data/3d/${dirname(path)}/${
textures.baseColorMap ?? textures.albedo
}`,
textures.miscMap
? `Data/3d/${dirname(path)}/${textures.miscMap}`
: undefined
)
)
.setImage(baseColor),
);
if (node.configCount) {
@@ -83,15 +80,7 @@ export async function extractModel(vfs: SteamVFS, path: string) {
configIndex < node.configCount;
configIndex++
) {
const archive = node[`configArchive_${configIndex}`];
if (
archive.configName !== "Default" ||
!archive.enabledPresets?.AlphaTest
) {
continue;
}
if (!hasAlpha) continue;
material.setAlphaMode("BLEND").setDoubleSided(true);
}
}
@@ -103,9 +92,9 @@ export async function extractModel(vfs: SteamVFS, path: string) {
.setMimeType("image/webp")
.setImage(
await readRoughnessMetallic(
`Data/3d/${dirname(path)}/${textures.baseRMMap}`
)
)
`Data/3d/${dirname(path)}/${textures.baseRMMap}`,
),
),
);
}
@@ -121,9 +110,9 @@ export async function extractModel(vfs: SteamVFS, path: string) {
`Data/3d/${dirname(path)}/${
textures.baseNormalMap ?? textures.normalmap
}`,
isBase
)
)
isBase,
),
),
);
}
@@ -157,7 +146,7 @@ export async function extractModel(vfs: SteamVFS, path: string) {
const node = document.createNode(hierarchy.name);
const components = times(
hierarchy.components.count,
(index) => hierarchy.components[index.toString().padStart(4, "0")]
(index) => hierarchy.components[index.toString().padStart(4, "0")],
);
components.forEach((component) => {
@@ -194,7 +183,7 @@ export async function extractModel(vfs: SteamVFS, path: string) {
}
if (polygonGroup === undefined) {
throw new Error(
`Missing polygon group ${batch["rb.datasource"]}`
`Missing polygon group ${batch["rb.datasource"]}`,
);
}
@@ -255,7 +244,7 @@ export async function extractModel(vfs: SteamVFS, path: string) {
default: {
if (ERROR_ON_UNKNOWN_COMPONENT) {
throw new Error(
`Unhandled component type: ${component["comp.typename"]}`
`Unhandled component type: ${component["comp.typename"]}`,
);
}
}
@@ -2,6 +2,7 @@ import sharp from "sharp";
import { readTexture } from "./readTexture";
export async function readBaseColor(path: string, occlusionPath?: string) {
let hasAlpha = false;
const baseRaw = await readTexture(path);
const occlusionRaw = occlusionPath
? await readTexture(occlusionPath)
@@ -30,10 +31,13 @@ export async function readBaseColor(path: string, occlusionPath?: string) {
c = occlusion![occlusionI] / 255;
}
const alpha = base[i * 4 + 3];
hasAlpha ||= alpha < 255;
combined[i * 4 + 0] = Math.round(base[i * 4 + 0] * c);
combined[i * 4 + 1] = Math.round(base[i * 4 + 1] * c);
combined[i * 4 + 2] = Math.round(base[i * 4 + 2] * c);
combined[i * 4 + 3] = base[i * 4 + 3];
combined[i * 4 + 3] = alpha;
}
const image = await sharp(combined, {
@@ -42,5 +46,5 @@ export async function readBaseColor(path: string, occlusionPath?: string) {
.webp()
.toBuffer();
return image;
return { hasAlpha, image };
}
+3 -2
View File
@@ -32,12 +32,13 @@
"compare-versions": "^6.1.1",
"fuzzysort": "^3.1.0",
"immer": "^10.1.3",
"jimp": "^1.6.0",
"lodash-es": "^4.17.21",
"markdown-to-jsx": "^7.7.13",
"pwa-install-handler": "^2.6.3",
"quicklime": "^1.2.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-promise-suspense": "^0.3.4",
"three": "^0.180.0",
"three-stdlib": "^2.36.0",
@@ -1,5 +1,5 @@
import { I_HAT, J_HAT } from "@blitzkit/core";
import { useThree } from "@react-three/fiber";
import { invalidate, useThree } from "@react-three/fiber";
import { clamp } from "lodash-es";
import type { QuicklimeEvent } from "quicklime";
import { useEffect, useMemo, type ComponentProps } from "react";
@@ -91,7 +91,7 @@ export function StaticArmorSceneComponent({
color = new Color(
clamp(1 - (7 / 8) * xClamped, 0, 1),
0,
clamp(1 - (1 / 8) * xClamped, 0, 1)
clamp(1 - (1 / 8) * xClamped, 0, 1),
);
opacity = clamp(x + 1 / 2, 0, 1);
break;
@@ -115,7 +115,7 @@ export function StaticArmorSceneComponent({
opacity: 0,
userData: { opacity0: opacity },
}),
[thickness]
[thickness],
);
const outlineMaterial = useMemo(
() =>
@@ -126,7 +126,7 @@ export function StaticArmorSceneComponent({
opacity: 0,
transparent: true,
}),
[thickness]
[thickness],
);
useEffect(() => {
@@ -165,8 +165,11 @@ export function StaticArmorSceneComponent({
}
surfaceMaterial.needsUpdate = true;
invalidate();
}
handleHighlightArmor();
function handleTransitionEvent(event: QuicklimeEvent<number>) {
surfaceMaterial.opacity = surfaceMaterial.userData.opacity0 * event.data;
outlineMaterial.opacity = event.data;
@@ -180,7 +183,7 @@ export function StaticArmorSceneComponent({
const unsubscribes = [
Tankopedia.on(
(state) => state.highlightArmor?.name,
handleHighlightArmor
handleHighlightArmor,
),
() => transitionEvent.off(handleTransitionEvent),
];
@@ -194,14 +197,14 @@ export function StaticArmorSceneComponent({
const { clip } = props;
const gunOrigin = unrotateDavaVector(props.gunOrigin.clone());
const neckOrigin = unrotateDavaVector(props.hullOrigin.clone()).add(
unrotateDavaVector(props.turretOrigin.clone())
unrotateDavaVector(props.turretOrigin.clone()),
);
const barrelOrigin = neckOrigin.clone().add(gunOrigin);
const distanceToBarrel = clip.distanceToPoint(barrelOrigin);
const point = new Vector3();
function handleModelTransform(
event: QuicklimeEvent<ModelTransformEventData>
event: QuicklimeEvent<ModelTransformEventData>,
) {
clip.normal
.set(0, 0, -1)
@@ -266,7 +269,7 @@ export function StaticArmorSceneComponent({
const surfaceNormal = event
.normal!.clone()
.applyQuaternion(
event.object.getWorldQuaternion(new Quaternion())
event.object.getWorldQuaternion(new Quaternion()),
);
const angle = surfaceNormal.angleTo(cameraNormal);
const thicknessAngled =
@@ -38,7 +38,7 @@ export function ConsumablesManager({
timers
? consumable.duration === undefined
? undefined
: consumable.duration * (hasHighEndConsumables ? 1.7 : 1)
: consumable.duration * (hasHighEndConsumables ? 1.33 : 1)
: undefined
}
cooldown={
@@ -1,26 +1,3 @@
<script>
import locales from "@blitzkit/i18n/locales.json";
import { getBestLocale } from "../core/i18n/getBestLocale";
const isAPI = window.location.pathname.startsWith("/api");
const isI18nPath = locales.supported.some(({ locale }) =>
window.location.pathname.startsWith(`/${locale}/`)
);
const bestLocale = getBestLocale();
const currentPath = locales.supported.find(({ locale }) =>
window.location.pathname.startsWith(`/${locale}/`)
);
if (
!isAPI && // not an api, duh!
localStorage.getItem("preferred-locale") !== null && // no preference, so probably google's crawler
bestLocale !== currentPath?.locale // we need to redirect
) {
window.location.pathname = isI18nPath
? window.location.pathname.replace(
`/${currentPath?.locale}`,
bestLocale === undefined ? "" : `/${bestLocale}`
)
: `/${bestLocale}${window.location.pathname}`;
}
</script>
@@ -6,7 +6,8 @@ import {
Popover,
type ButtonProps,
} from "@radix-ui/themes";
import type { RefObject } from "react";
import { Jimp } from "jimp";
import { useCallback, type RefObject } from "react";
import { useLocale } from "../hooks/useLocale";
import { screenshotReadyEvent } from "./Tankopedia/HeroSection/components/TankSandbox/components/SceneProps";
@@ -18,6 +19,35 @@ interface Props extends ButtonProps {
export function ScreenshotButton({ canvas, name, children, ...props }: Props) {
const { strings } = useLocale();
const screenshot = useCallback(async () => {
if (!canvas.current) {
throw new Error("Canvas not found");
}
screenshotReadyEvent.dispatch(true);
const blob = await new Promise<Blob>((resolve, reject) => {
requestAnimationFrame(() => {
canvas.current.toBlob((blob) => {
screenshotReadyEvent.dispatch(false);
if (!blob) {
reject(new Error("Failed to capture screenshot"));
} else {
resolve(blob);
}
});
});
});
const buffer = await blob.arrayBuffer();
const image = await Jimp.fromBuffer(buffer);
image.autocrop();
return image;
}, [canvas]);
return (
<Popover.Root>
<Popover.Trigger>
@@ -37,23 +67,13 @@ export function ScreenshotButton({ canvas, name, children, ...props }: Props) {
<Flex direction="column" gap="2">
<Popover.Close>
<Button
onClick={() => {
screenshotReadyEvent.dispatch(true);
onClick={async () => {
const image = await screenshot();
const anchor = document.createElement("a");
requestAnimationFrame(() => {
if (!canvas.current) return;
const anchor = document.createElement("a");
anchor.setAttribute("download", `${name}.png`);
anchor.setAttribute(
"href",
canvas.current.toDataURL("image/png")
);
anchor.click();
screenshotReadyEvent.dispatch(false);
});
anchor.setAttribute("download", `${name}.png`);
anchor.setAttribute("href", await image.getBase64("image/png"));
anchor.click();
}}
>
<DownloadIcon />
@@ -63,22 +83,16 @@ export function ScreenshotButton({ canvas, name, children, ...props }: Props) {
<Popover.Close>
<Button
variant="outline"
onClick={() => {
screenshotReadyEvent.dispatch(true);
requestAnimationFrame(() => {
if (!canvas.current) return;
canvas.current.toBlob((blob) => {
if (!blob) return;
navigator.clipboard.write([
new ClipboardItem({ "image/png": blob }),
]);
});
screenshotReadyEvent.dispatch(false);
onClick={async () => {
const image = await screenshot();
const buffer = await image.getBuffer("image/png");
const blob = new Blob([buffer as unknown as ArrayBuffer], {
type: "image/png",
});
navigator.clipboard.write([
new ClipboardItem({ "image/png": blob }),
]);
}}
>
<CopyIcon />
@@ -3,12 +3,12 @@ import {
resolveDpm,
unionBoundingBox,
type TankDefinition,
} from '@blitzkit/core';
import { useMemo } from 'react';
import { awaitableModelDefinitions } from '../../../core/awaitables/modelDefinitions';
import { resolveReload } from '../../../core/blitzkit/resolveReload';
import { TankSort } from '../../../stores/tankopediaSort';
import { TankCard } from '../../TankCard';
} from "@blitzkit/core";
import { useMemo } from "react";
import { awaitableModelDefinitions } from "../../../core/awaitables/modelDefinitions";
import { resolveReload } from "../../../core/blitzkit/resolveReload";
import { TankSort } from "../../../stores/tankopediaSort";
import { TankCard } from "../../TankCard";
interface TankSearchCardProps {
tank: TankDefinition;
@@ -20,7 +20,7 @@ const modelDefinitions = await awaitableModelDefinitions;
export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
const by = TankSort.use((state) => state.by);
const discriminator = useMemo(() => {
if (by.startsWith('meta')) return undefined;
if (by.startsWith("meta")) return undefined;
const turret = tank.turrets.at(-1)!;
const gun = turret.guns.at(-1)!;
@@ -34,53 +34,53 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
const gunModelDefinition = turretModelDefinition.guns[gun.id];
switch (by) {
case 'fire.aimTime':
case "fire.aimTime":
return gun.aim_time.toFixed(2);
case 'fire.caliber':
case "fire.caliber":
return shell0.caliber.toFixed(0);
case 'fire.damage':
case "fire.damage":
return shell0.armor_damage.toFixed(0);
case 'fire.moduleDamage':
case "fire.moduleDamage":
return shell0.module_damage.toFixed(0);
case 'fire.dispersionMoving':
case "fire.dispersionMoving":
return tracks.dispersion_move.toFixed(3);
case 'fire.dispersionStill':
case "fire.dispersionStill":
return gun.dispersion_base.toFixed(3);
case 'fire.dpm':
case "fire.dpm":
return resolveDpm(gun, shell0).toFixed(0);
case 'fire.dpmPremium':
return shell1 ? resolveDpm(gun, shell1).toFixed(0) : '--';
case 'fire.reload':
case "fire.dpmPremium":
return shell1 ? resolveDpm(gun, shell1).toFixed(0) : "--";
case "fire.reload":
return resolveReload(gun).toFixed(2);
case 'fire.standardPenetration':
return shell0.penetration.near.toFixed(0);
case 'fire.premiumPenetration':
return shell1 ? shell1.penetration.near.toFixed(0) : '--';
case 'fire.tertiaryPenetration':
return shell1 ? shell2.penetration.near.toFixed(0) : '--';
case 'fire.shellVelocity':
case "fire.standardPenetration":
return shell0?.penetration.near.toFixed(0);
case "fire.premiumPenetration":
return shell1 ? shell1?.penetration.near.toFixed(0) : "--";
case "fire.tertiaryPenetration":
return shell1 ? shell2?.penetration.near.toFixed(0) : "--";
case "fire.shellVelocity":
return shell0.velocity.toFixed(0);
case 'fire.shellCapacity':
case "fire.shellCapacity":
return gun.shell_capacity.toFixed(0);
case 'fire.shellRange':
case "fire.shellRange":
return shell0.range.toFixed(0);
case 'fire.gunDepression':
case "fire.gunDepression":
return (
gunModelDefinition.pitch.max +
(tankModelDefinition.initial_turret_rotation?.pitch ?? 0)
).toFixed(1);
case 'fire.gunElevation':
case "fire.gunElevation":
return (
-gunModelDefinition.pitch.min -
(tankModelDefinition.initial_turret_rotation?.pitch ?? 0)
).toFixed(1);
case 'maneuverability.forwardsSpeed':
case "maneuverability.forwardsSpeed":
return tank.speed_forwards.toFixed(0);
case 'maneuverability.backwardsSpeed':
case "maneuverability.backwardsSpeed":
return tank.speed_backwards.toFixed(0);
case 'maneuverability.power':
case "maneuverability.power":
return engine.power.toFixed(0);
case 'maneuverability.powerToWeight':
case "maneuverability.powerToWeight":
return (
(1000 * engine.power) /
(tank.weight +
@@ -89,7 +89,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
turret.weight +
gun.weight)
).toFixed(1);
case 'maneuverability.weight':
case "maneuverability.weight":
return (
(tank.weight +
engine.weight +
@@ -98,19 +98,19 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
gun.weight) /
1000
).toFixed(1);
case 'maneuverability.traverseSpeed':
case "maneuverability.traverseSpeed":
return tracks.traverse_speed.toFixed(1);
case 'survivability.health':
case "survivability.health":
return (tank.health + turret.health).toFixed(0);
case 'survivability.viewRange':
case "survivability.viewRange":
return turret.view_range.toFixed(0);
case 'survivability.camouflageStill':
case "survivability.camouflageStill":
return (tank.camouflage_still * 100).toFixed(0);
case 'survivability.camouflageMoving':
case "survivability.camouflageMoving":
return (tank.camouflage_moving * 100).toFixed(0);
case 'survivability.camouflageShooting':
case "survivability.camouflageShooting":
return (tank.camouflage_still * gun.camouflage_loss * 100).toFixed(0);
case 'survivability.volume': {
case "survivability.volume": {
const dimensions = normalizeBoundingBox(
unionBoundingBox(
tankModelDefinition.bounding_box,
@@ -121,7 +121,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
return (dimensions.x * dimensions.y * dimensions.z).toFixed(0);
}
case 'survivability.length': {
case "survivability.length": {
const bounds = normalizeBoundingBox(
unionBoundingBox(
tankModelDefinition.bounding_box,
@@ -129,7 +129,7 @@ const consumablesArray = Object.values(consumableDefinitions.consumables)
.filter(
(consumable) =>
!consumable.game_mode_exclusive &&
consumable.name.locales[locales.default]
consumable.name.locales[locales.default],
)
.map((consumable) => consumable.id);
const provisionsArray = Array.from(
@@ -137,7 +137,7 @@ const provisionsArray = Array.from(
.filter(
(provision) =>
!provision.game_mode_exclusive &&
provision.name.locales[locales.default]
provision.name.locales[locales.default],
)
.reduce((uniqueMap, consumable) => {
if (!uniqueMap.has(consumable.name.locales[locales.default])) {
@@ -146,7 +146,7 @@ const provisionsArray = Array.from(
return uniqueMap;
}, new Map<string, number>())
.values()
.values(),
);
const shellTypeIcons: Record<ShellType, string> = {
[ShellType.AP]: "ap",
@@ -171,7 +171,7 @@ const TANK_TYPE_COLORS: Record<TankType, string> = {
};
const GUN_TYPES = Object.keys(
GUN_TYPE_ICONS
GUN_TYPE_ICONS,
) as (keyof typeof GUN_TYPE_ICONS)[];
const MAX_ICONS = 4;
@@ -180,7 +180,12 @@ const TIERS = times(10, (i) => 10 - i);
export function FilterControl() {
return (
<Flex align="center" justify="center" gap="2" wrap="wrap">
<Flex
align="center"
justify={{ initial: "start", md: "center" }}
gap="2"
wrap="wrap"
>
<TiersFilter />
<ClassFilter />
<TypeFilter />
@@ -346,7 +351,7 @@ function NationsFilter() {
mr="-2"
style={{
backgroundImage: `url(${asset(
`flags/scratched/${nation}.webp`
`flags/scratched/${nation}.webp`,
)})`,
backgroundSize: "100%",
backgroundRepeat: "no-repeat",
@@ -437,7 +442,7 @@ function ClassFilter() {
TankFilters.mutate((draft) => {
if (selected) {
draft.classes = draft.classes.filter(
(c) => c !== tankClass
(c) => c !== tankClass,
);
} else {
draft.classes = [...draft.classes, tankClass];
@@ -683,7 +688,7 @@ function IndividualShellFilter({
src={asset(
`icons/shells/${shellTypeIcons[shells[index]]}${
premium ? "_premium" : ""
}.webp`
}.webp`,
)}
/>
)}
@@ -718,7 +723,7 @@ function IndividualShellFilter({
src={asset(
`icons/shells/${shellTypeIcons[shellType]}${
premium ? "_premium" : ""
}.webp`
}.webp`,
)}
style={{ width: "1.25em", height: "1.25em" }}
/>
@@ -917,7 +922,7 @@ function ConsumablesFilter() {
TankFilters.mutate((draft) => {
if (selected) {
draft.consumables = draft.consumables.filter(
(n) => n !== consumable
(n) => n !== consumable,
);
} else {
draft.consumables = [...draft.consumables, consumable];
@@ -1011,7 +1016,7 @@ function ProvisionsFilter() {
TankFilters.mutate((draft) => {
if (selected) {
draft.provisions = draft.provisions.filter(
(n) => n !== provision
(n) => n !== provision,
);
} else {
draft.provisions = [...draft.provisions, provision];
@@ -1140,7 +1145,7 @@ function GameModeAbilitiesFilter() {
TankFilters.mutate((draft) => {
if (selected) {
draft.abilities = draft.abilities.filter(
(n) => n !== consumable
(n) => n !== consumable,
);
} else {
draft.abilities = [...draft.abilities, consumable];
@@ -1189,7 +1194,7 @@ function GameModeAbilitiesFilter() {
TankFilters.mutate((draft) => {
if (selected) {
draft.powers = draft.powers.filter(
(n) => n !== provision
(n) => n !== provision,
);
} else {
draft.powers = [...draft.powers, provision];
@@ -30,9 +30,11 @@ export function RicochetVisualizer({ stats }: StatsAcceptorProps) {
<Flex direction="column" mb="6" align="center">
<VisualizerCard
mb="0"
style={{ width: "100%" }}
style={{ width: "100%", touchAction: "none" }}
ref={container}
onPointerMove={(event) => {
event.preventDefault();
if (!container.current || explodes) return;
const rect = container.current.getBoundingClientRect();
@@ -174,7 +176,7 @@ export function RicochetVisualizer({ stats }: StatsAcceptorProps) {
? "-"
: literals(strings.common.units.deg, {
value: radToDeg(
Math.min(normalization, Math.abs(angle))
Math.min(normalization, Math.abs(angle)),
).toFixed(0),
})
}
@@ -55,17 +55,17 @@ export function Controls({
const protagonistHullOrigin = new Vector3(
protagonistTrackModelDefinition.origin.x,
protagonistTrackModelDefinition.origin.y,
-protagonistTrackModelDefinition.origin.z
-protagonistTrackModelDefinition.origin.z,
);
const protagonistTurretOrigin = new Vector3(
protagonistModelDefinition.turret_origin.x,
protagonistModelDefinition.turret_origin.y,
-protagonistModelDefinition.turret_origin.z
-protagonistModelDefinition.turret_origin.z,
);
const protagonistGunOrigin = new Vector3(
protagonistTurretModelDefinition.gun_origin.x,
protagonistTurretModelDefinition.gun_origin.y,
-protagonistTurretModelDefinition.gun_origin.z
-protagonistTurretModelDefinition.gun_origin.z,
);
const antagonistGunHeight =
protagonistTrackModelDefinition.origin.y +
@@ -106,12 +106,12 @@ export function Controls({
const hasImprovedVerticalStabilizer = hasEquipment(
122,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const hasDownImprovedVerticalStabilizer = hasEquipment(
124,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
switch (event) {
@@ -122,7 +122,7 @@ export function Controls({
protagonistGunModelDefinition.pitch,
protagonistTurretModelDefinition.yaw,
hasImprovedVerticalStabilizer,
hasDownImprovedVerticalStabilizer
hasDownImprovedVerticalStabilizer,
);
camera.position
@@ -134,14 +134,14 @@ export function Controls({
new Vector3(
0,
poseDistances[event] * Math.sin(pitch),
poseDistances[event] * -Math.cos(pitch)
)
poseDistances[event] * -Math.cos(pitch),
),
);
camera.lookAt(
protagonistHullOrigin
.clone()
.add(protagonistTurretOrigin)
.add(protagonistGunOrigin)
.add(protagonistGunOrigin),
);
orbitControls.current?.target.set(0, antagonistGunHeight, 0);
@@ -155,7 +155,7 @@ export function Controls({
protagonistGunModelDefinition.pitch,
protagonistTurretModelDefinition.yaw,
hasImprovedVerticalStabilizer,
hasDownImprovedVerticalStabilizer
hasDownImprovedVerticalStabilizer,
);
camera.position
@@ -167,8 +167,8 @@ export function Controls({
new Vector3(
0,
poseDistances[event] * Math.sin(pitch),
poseDistances[event] * -Math.cos(pitch)
)
poseDistances[event] * -Math.cos(pitch),
),
);
orbitControls.current?.target
.set(0, 0, 0)
@@ -179,8 +179,8 @@ export function Controls({
new Vector3(
0,
0.5 * poseDistances[event] * Math.sin(pitch),
0.5 * poseDistances[event] * -Math.cos(pitch)
)
0.5 * poseDistances[event] * -Math.cos(pitch),
),
);
break;
@@ -251,7 +251,7 @@ export function Controls({
return (
<OrbitControls
enableRotate={enableRotate}
maxDistance={20}
maxDistance={40}
minDistance={5}
enableZoom={zoomable}
zoomSpeed={zoomable ? undefined : 0}
@@ -47,7 +47,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
const gunModelDefinition = turretModelDefinition.guns[protagonistGun.id];
const display = Tankopedia.use((state) => state.display);
const hideTankModelUnderArmor = TankopediaPersistent.use(
(state) => state.hideTankModelUnderArmor
(state) => state.hideTankModelUnderArmor,
);
useImperativeHandle(ref, () => canvas.current!, []);
@@ -76,7 +76,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
gunModelDefinition.pitch,
turretModelDefinition.yaw,
hasImprovedVerticalStabilizer,
hasDownImprovedVerticalStabilizer
hasDownImprovedVerticalStabilizer,
);
modelTransformEvent.dispatch({ pitch, yaw });
@@ -90,7 +90,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
0,
gunModelDefinition.pitch,
turretModelDefinition.yaw,
hasImprovedVerticalStabilizer
hasImprovedVerticalStabilizer,
);
modelTransformEvent.dispatch({ pitch, yaw });
@@ -104,7 +104,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
0,
gunModelDefinition.pitch,
turretModelDefinition.yaw,
hasImprovedVerticalStabilizer
hasImprovedVerticalStabilizer,
);
modelTransformEvent.dispatch({ pitch, yaw });
@@ -126,7 +126,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
modelTransformEvent.last!.yaw,
gunModelDefinition.pitch,
turretModelDefinition.yaw,
hasImprovedVerticalStabilizer
hasImprovedVerticalStabilizer,
);
modelTransformEvent.dispatch({ pitch, yaw });
@@ -146,8 +146,6 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
}
}, [display]);
console.log(TankopediaDisplay[display]);
return (
<SmartCanvas
resize={{ debounce: 0 }}
@@ -196,5 +194,5 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
<InitialAligner />
</SmartCanvas>
);
}
},
);
@@ -2,9 +2,9 @@ import {
normalizeAngleRad,
type PitchLimits,
type YawLimits,
} from '@blitzkit/core';
import { clamp } from 'lodash-es';
import { degToRad } from 'three/src/math/MathUtils.js';
} from "@blitzkit/core";
import { clamp } from "lodash-es";
import { degToRad } from "three/src/math/MathUtils.js";
export const DEFAULT_PITCH_TRANSITION = 15;
@@ -87,5 +87,5 @@ export function applyPitchYawLimits(
newPitch = clamp(newPitch, lowerPitch, upperPitch);
return [newPitch, newYaw] as const;
return [newPitch, normalizeAngleRad(newYaw)] as const;
}
@@ -1,5 +1,5 @@
import type { ComponentProps, ReactNode } from "react";
import { Mesh, Object3D } from "three";
import { Mesh, MeshStandardMaterial, Object3D } from "three";
export function jsxTree(
node: Object3D,
@@ -7,14 +7,14 @@ export function jsxTree(
mesh?: (
mesh: Mesh,
props: ComponentProps<"mesh">,
key: string
key: string,
) => ReactNode;
group?: (
object3d: Object3D,
props: ComponentProps<"group">,
key: string
key: string,
) => ReactNode;
}
},
): ReactNode {
if (node instanceof Mesh) {
const props = {
@@ -25,6 +25,10 @@ export function jsxTree(
scale: node.scale,
};
if (props.material instanceof MeshStandardMaterial) {
props.material.depthWrite = true;
}
return mergers?.mesh ? (
mergers.mesh(node, props, node.uuid)
) : (
@@ -5,11 +5,11 @@ export function getBestLocale() {
localStorage.getItem("preferred-locale") ??
navigator.language.split("-")[0];
const isSupported = locales.supported.some(
({ locale }) => locale === desiredLocale
({ locale }) => locale === desiredLocale,
);
const isDefault = desiredLocale === locales.default;
if (!isSupported || isDefault) return undefined;
if (!isSupported || isDefault) return locales.default;
return desiredLocale;
}
@@ -12,7 +12,8 @@ export const getStaticPaths = (async () => {
.map((tank) =>
parentPaths.map((parent) => ({
params: { ...parent.params, id: tank.id },
}))
props: parent.props,
})),
)
.flat();
}) satisfies GetStaticPaths;