diff --git a/pages/.editorconfig b/pages/.editorconfig
deleted file mode 100644
index 9aa5361..0000000
--- a/pages/.editorconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-indent_style = space
-indent_size = 2
-insert_final_newline = true
\ No newline at end of file
diff --git a/pages/.gitignore b/pages/.gitignore
deleted file mode 100644
index a14702c..0000000
--- a/pages/.gitignore
+++ /dev/null
@@ -1,34 +0,0 @@
-# dependencies (bun install)
-node_modules
-
-# output
-out
-dist
-*.tgz
-
-# code coverage
-coverage
-*.lcov
-
-# logs
-logs
-_.log
-report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
-
-# dotenv environment variable files
-.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# caches
-.eslintcache
-.cache
-*.tsbuildinfo
-
-# IntelliJ based IDEs
-.idea
-
-# Finder (MacOS) folder config
-.DS_Store
diff --git a/pages/.oxfmtrc.json b/pages/.oxfmtrc.json
deleted file mode 100644
index 8182154..0000000
--- a/pages/.oxfmtrc.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "$schema": "./node_modules/oxfmt/configuration_schema.json",
- "ignorePatterns": [
- "output/raw/**/index_main.json",
- "output/raw/**/index_initial.json"
- ],
- "useTabs": false,
- "printWidth": 120,
- "tabWidth": 2,
- "endOfLine": "lf",
- "arrowParens": "always",
- "bracketSameLine": false,
- "bracketSpacing": true,
- "htmlWhitespaceSensitivity": "css",
- "insertFinalNewline": true,
- "jsxSingleQuote": true,
- "objectWrap": "preserve",
- "proseWrap": "preserve",
- "quoteProps": "as-needed",
- "semi": true,
- "singleQuote": true,
- "trailingComma": "all"
-}
diff --git a/pages/.parcelrc b/pages/.parcelrc
deleted file mode 100644
index becb72f..0000000
--- a/pages/.parcelrc
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "extends": "@parcel/config-default",
- "transformers": {
- "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
- }
-}
diff --git a/pages/.vscode/settings.json b/pages/.vscode/settings.json
deleted file mode 100644
index d539965..0000000
--- a/pages/.vscode/settings.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "editor.formatOnSave": true,
- "editor.defaultFormatter": "biomejs.biome",
- "[json]": {
- "editor.defaultFormatter": "biomejs.biome"
- },
- "[javascript]": {
- "editor.defaultFormatter": "biomejs.biome"
- },
- "[javascriptreact]": {
- "editor.defaultFormatter": "biomejs.biome"
- },
- "[typescript]": {
- "editor.defaultFormatter": "biomejs.biome"
- },
- "[typescriptreact]": {
- "editor.defaultFormatter": "biomejs.biome"
- },
- "editor.codeActionsOnSave": {
- "source.fixAll.biome": "explicit",
- "source.organizeImports.biome": "explicit"
- }
-}
diff --git a/pages/README.md b/pages/README.md
deleted file mode 100644
index 1e8d114..0000000
--- a/pages/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# pages
-
-A very simple and very lame information display page written in HTML, CSS, and TypeScript
-
-## For dev
-
-Live server:
-
-```bash
-bun x parcel
-```
-
-Build:
-
-```bash
-bun x parcel build
-```
diff --git a/pages/biome.json b/pages/biome.json
deleted file mode 100644
index 86ebb55..0000000
--- a/pages/biome.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
- "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
- "files": { "ignoreUnknown": false, "includes": ["**"] },
- "formatter": {
- "enabled": true,
- "useEditorconfig": true,
- "formatWithErrors": false,
- "indentStyle": "space",
- "indentWidth": 2,
- "lineEnding": "lf",
- "lineWidth": 120,
- "attributePosition": "auto",
- "bracketSpacing": true
- },
- "linter": { "enabled": false, "rules": { "recommended": true } },
- "javascript": {
- "formatter": {
- "jsxQuoteStyle": "single",
- "quoteProperties": "asNeeded",
- "trailingCommas": "all",
- "semicolons": "always",
- "arrowParentheses": "always",
- "bracketSameLine": false,
- "quoteStyle": "single",
- "attributePosition": "auto",
- "bracketSpacing": true
- }
- },
- "assist": {
- "enabled": true,
- "actions": {
- "source": {
- "organizeImports": "on"
- }
- }
- }
-}
diff --git a/pages/bun.lock b/pages/bun.lock
deleted file mode 100644
index 7345d63..0000000
--- a/pages/bun.lock
+++ /dev/null
@@ -1,517 +0,0 @@
-{
- "lockfileVersion": 1,
- "configVersion": 1,
- "workspaces": {
- "": {
- "name": "pages",
- "dependencies": {
- "bootstrap": "^5.3.8",
- "bootstrap-icons": "^1.13.1",
- "ky": "^1.14.3",
- "luxon": "^3.7.2",
- "qs": "^6.15.0",
- "semver": "^7.7.4",
- "uuid": "^13.0.0",
- },
- "devDependencies": {
- "@biomejs/biome": "^2.4.4",
- "@parcel/transformer-typescript-tsc": "^2.16.4",
- "@tsconfig/bun": "^1.0.10",
- "@tsconfig/node24": "^24.0.4",
- "@tsconfig/recommended": "^1.0.13",
- "@tsconfig/strictest": "^2.0.8",
- "@types/bootstrap": "^5.2.10",
- "@types/bun": "latest",
- "@types/luxon": "^3.7.1",
- "@types/qs": "^6.14.0",
- "@types/semver": "^7.7.1",
- "oxfmt": "^0.35.0",
- "parcel": "^2.16.4",
- },
- "peerDependencies": {
- "typescript": "^5",
- },
- },
- },
- "packages": {
- "@biomejs/biome": ["@biomejs/biome@2.4.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.4", "@biomejs/cli-darwin-x64": "2.4.4", "@biomejs/cli-linux-arm64": "2.4.4", "@biomejs/cli-linux-arm64-musl": "2.4.4", "@biomejs/cli-linux-x64": "2.4.4", "@biomejs/cli-linux-x64-musl": "2.4.4", "@biomejs/cli-win32-arm64": "2.4.4", "@biomejs/cli-win32-x64": "2.4.4" }, "bin": { "biome": "bin/biome" } }, "sha512-tigwWS5KfJf0cABVd52NVaXyAVv4qpUXOWJ1rxFL8xF1RVoeS2q/LK+FHgYoKMclJCuRoCWAPy1IXaN9/mS61Q=="],
-
- "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-jZ+Xc6qvD6tTH5jM6eKX44dcbyNqJHssfl2nnwT6vma6B1sj7ZLTGIk6N5QwVBs5xGN52r3trk5fgd3sQ9We9A=="],
-
- "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dh1a/+W+SUCXhEdL7TiX3ArPTFCQKJTI1mGncZNWfO+6suk+gYA4lNyJcBB+pwvF49uw0pEbUS49BgYOY4hzUg=="],
-
- "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-V/NFfbWhsUU6w+m5WYbBenlEAz8eYnSqRMDMAW3K+3v0tYVkNyZn8VU0XPxk/lOqNXLSCCrV7FmV/u3SjCBShg=="],
-
- "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+sPAXq3bxmFwhVFJnSwkSF5Rw2ZAJMH3MF6C9IveAEOdSpgajPhoQhbbAK12SehN9j2QrHpk4J/cHsa/HqWaYQ=="],
-
- "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-R4+ZCDtG9kHArasyBO+UBD6jr/FcFCTH8QkNTOCu0pRJzCWyWC4EtZa2AmUZB5h3e0jD7bRV2KvrENcf8rndBg=="],
-
- "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gGvFTGpOIQDb5CQ2VC0n9Z2UEqlP46c4aNgHmAMytYieTGEcfqhfCFnhs6xjt0S3igE6q5GLuIXtdQt3Izok+g=="],
-
- "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-trzCqM7x+Gn832zZHgr28JoYagQNX4CZkUZhMUac2YxvvyDRLJDrb5m9IA7CaZLlX6lTQmADVfLEKP1et1Ma4Q=="],
-
- "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.4", "", { "os": "win32", "cpu": "x64" }, "sha512-gnOHKVPFAAPrpoPt2t+Q6FZ7RPry/FDV3GcpU53P3PtLNnQjBmKyN2Vh/JtqXet+H4pme8CC76rScwdjDcT1/A=="],
-
- "@lezer/common": ["@lezer/common@1.5.1", "", {}, "sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw=="],
-
- "@lezer/lr": ["@lezer/lr@1.4.8", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA=="],
-
- "@lmdb/lmdb-darwin-arm64": ["@lmdb/lmdb-darwin-arm64@2.8.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw=="],
-
- "@lmdb/lmdb-darwin-x64": ["@lmdb/lmdb-darwin-x64@2.8.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug=="],
-
- "@lmdb/lmdb-linux-arm": ["@lmdb/lmdb-linux-arm@2.8.5", "", { "os": "linux", "cpu": "arm" }, "sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg=="],
-
- "@lmdb/lmdb-linux-arm64": ["@lmdb/lmdb-linux-arm64@2.8.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww=="],
-
- "@lmdb/lmdb-linux-x64": ["@lmdb/lmdb-linux-x64@2.8.5", "", { "os": "linux", "cpu": "x64" }, "sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ=="],
-
- "@lmdb/lmdb-win32-x64": ["@lmdb/lmdb-win32-x64@2.8.5", "", { "os": "win32", "cpu": "x64" }, "sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ=="],
-
- "@mischnic/json-sourcemap": ["@mischnic/json-sourcemap@0.1.1", "", { "dependencies": { "@lezer/common": "^1.0.0", "@lezer/lr": "^1.0.0", "json5": "^2.2.1" } }, "sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w=="],
-
- "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw=="],
-
- "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw=="],
-
- "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3", "", { "os": "linux", "cpu": "arm" }, "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw=="],
-
- "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg=="],
-
- "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3", "", { "os": "linux", "cpu": "x64" }, "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg=="],
-
- "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="],
-
- "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.35.0", "", { "os": "android", "cpu": "arm" }, "sha512-BaRKlM3DyG81y/xWTsE6gZiv89F/3pHe2BqX2H4JbiB8HNVlWWtplzgATAE5IDSdwChdeuWLDTQzJ92Lglw3ZA=="],
-
- "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.35.0", "", { "os": "android", "cpu": "arm64" }, "sha512-/O+EbuAJYs6nde/anv+aID6uHsGQApyE9JtYBo/79KyU8e6RBN3DMbT0ix97y1SOnCglurmL2iZ+hlohjP2PnQ=="],
-
- "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.35.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-pGqRtqlNdn9d4VrmGUWVyQjkw79ryhI6je9y2jfqNUIZCfqceob+R97YYAoG7C5TFyt8ILdLVoN+L2vw/hSFyA=="],
-
- "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.35.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8GmsDcSozTPjrCJeGpp+sCmS9+9V5yRrdEZ1p/sTWxPG5nYeAfSLuS0nuEYjXSO+CtdSbStIW6dxa+4NM58yRw=="],
-
- "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.35.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QyfKfTe0ytHpFKHAcHCGQEzN45QSqq1AHJOYYxQMgLM3KY4xu8OsXHpCnINjDsV4XGnQzczJDU9e04Zmd8XqIQ=="],
-
- "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-u+kv3JD6P3J38oOyUaiCqgY5TNESzBRZJ5lyZQ6c2czUW2v5SIN9E/KWWa9vxoc+P8AFXQFUVrdzGy1tK+nbPQ=="],
-
- "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.35.0", "", { "os": "linux", "cpu": "arm" }, "sha512-1NiZroCiV57I7Pf8kOH4XGR366kW5zir3VfSMBU2D0V14GpYjiYmPYFAoJboZvp8ACnZKUReWyMkNKSa5ad58A=="],
-
- "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.35.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-7Q0Xeg7ZnW2nxnZ4R7aF6DEbCFls4skgHZg+I63XitpNvJCbVIU8MFOTZlvZGRsY9+rPgWPQGeUpLHlyx0wvMA=="],
-
- "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.35.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Okqi+uhYFxwKz8hcnUftNNwdm8BCkf6GSCbcz9xJxYMm87k1E4p7PEmAAbhLTk7cjSdDre6TDL0pDzNX+Y22Q=="],
-
- "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.35.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9k66pbZQXM/lBJWys3Xbc5yhl4JexyfqkEf/tvtq8976VIJnLAAL3M127xHA3ifYSqxdVHfVGTg84eiBHCGcNw=="],
-
- "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.35.0", "", { "os": "linux", "cpu": "none" }, "sha512-aUcY9ofKPtjO52idT6t0SAQvEF6ctjzUQa1lLp7GDsRpSBvuTrBQGeq0rYKz3gN8dMIQ7mtMdGD9tT4LhR8jAQ=="],
-
- "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.35.0", "", { "os": "linux", "cpu": "none" }, "sha512-C6yhY5Hvc2sGM+mCPek9ZLe5xRUOC/BvhAt2qIWFAeXMn4il04EYIjl3DsWiJr0xDMTJhvMOmD55xTRPlNp39w=="],
-
- "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.35.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-RG2hlvOMK4OMZpO3mt8MpxLQ0AAezlFqhn5mI/g5YrVbPFyoCv9a34AAvbSJS501ocOxlFIRcKEuw5hFvddf9g=="],
-
- "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-wzmh90Pwvqj9xOKHJjkQYBpydRkaXG77ZvDz+iFDRRQpnqIEqGm5gmim2s6vnZIkDGsvKCuTdtxm0GFmBjM1+w=="],
-
- "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.35.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+HCqYCJPCUy5I+b2cf+gUVaApfgtoQT3HdnSg/l7NIcLHOhKstlYaGyrFZLmUpQt4WkFbpGKZZayG6zjRU0KFA=="],
-
- "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.35.0", "", { "os": "none", "cpu": "arm64" }, "sha512-kFYmWfR9YL78XyO5ws+1dsxNvZoD973qfVMNFOS4e9bcHXGF7DvGC2tY5UDFwyMCeB33t3sDIuGONKggnVNSJA=="],
-
- "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.35.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-uD/NGdM65eKNCDGyTGdO8e9n3IHX+wwuorBvEYrPJXhDXL9qz6gzddmXH8EN04ejUXUujlq4FsoSeCfbg0Y+Jg=="],
-
- "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.35.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-oSRD2k8J2uxYDEKR2nAE/YTY9PobOEnhZgCmspHu0+yBQ665yH8lFErQVSTE7fcGJmJp/cC6322/gc8VFuQf7g=="],
-
- "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.35.0", "", { "os": "win32", "cpu": "x64" }, "sha512-WCDJjlS95NboR0ugI2BEwzt1tYvRDorDRM9Lvctls1SLyKYuNRCyrPwp1urUPFBnwgBNn9p2/gnmo7gFMySRoQ=="],
-
- "@parcel/bundler-default": ["@parcel/bundler-default@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/graph": "3.6.4", "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" } }, "sha512-Nb8peNvhfm1+660CLwssWh4weY+Mv6vEGS6GPKqzJmTMw50udi0eS1YuWFzvmhSiu1KsYcUD37mqQ1LuIDtWoA=="],
-
- "@parcel/cache": ["@parcel/cache@2.16.4", "", { "dependencies": { "@parcel/fs": "2.16.4", "@parcel/logger": "2.16.4", "@parcel/utils": "2.16.4", "lmdb": "2.8.5" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-+uCyeElSga2MBbmbXpIj/WVKH7TByCrKaxtHbelfKKIJpYMgEHVjO4cuc7GUfTrUAmRUS8ZGvnX7Etgq6/jQhw=="],
-
- "@parcel/codeframe": ["@parcel/codeframe@2.16.4", "", { "dependencies": { "chalk": "^4.1.2" } }, "sha512-s64aMfOJoPrXhKH+Y98ahX0O8aXWvTR+uNlOaX4yFkpr4FFDnviLcGngDe/Yo4Qq2FJZ0P6dNswbJTUH9EGxkQ=="],
-
- "@parcel/compressor-raw": ["@parcel/compressor-raw@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4" } }, "sha512-IK8IpNhw61B2HKgA1JhGhO9y+ZJFRZNTEmvhN1NdLdPqvgEXm2EunT+m6D9z7xeoeT6XnUKqM0eRckEdD0OXbA=="],
-
- "@parcel/config-default": ["@parcel/config-default@2.16.4", "", { "dependencies": { "@parcel/bundler-default": "2.16.4", "@parcel/compressor-raw": "2.16.4", "@parcel/namer-default": "2.16.4", "@parcel/optimizer-css": "2.16.4", "@parcel/optimizer-html": "2.16.4", "@parcel/optimizer-image": "2.16.4", "@parcel/optimizer-svg": "2.16.4", "@parcel/optimizer-swc": "2.16.4", "@parcel/packager-css": "2.16.4", "@parcel/packager-html": "2.16.4", "@parcel/packager-js": "2.16.4", "@parcel/packager-raw": "2.16.4", "@parcel/packager-svg": "2.16.4", "@parcel/packager-wasm": "2.16.4", "@parcel/reporter-dev-server": "2.16.4", "@parcel/resolver-default": "2.16.4", "@parcel/runtime-browser-hmr": "2.16.4", "@parcel/runtime-js": "2.16.4", "@parcel/runtime-rsc": "2.16.4", "@parcel/runtime-service-worker": "2.16.4", "@parcel/transformer-babel": "2.16.4", "@parcel/transformer-css": "2.16.4", "@parcel/transformer-html": "2.16.4", "@parcel/transformer-image": "2.16.4", "@parcel/transformer-js": "2.16.4", "@parcel/transformer-json": "2.16.4", "@parcel/transformer-node": "2.16.4", "@parcel/transformer-postcss": "2.16.4", "@parcel/transformer-posthtml": "2.16.4", "@parcel/transformer-raw": "2.16.4", "@parcel/transformer-react-refresh-wrap": "2.16.4", "@parcel/transformer-svg": "2.16.4" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-kBxuTY/5trEVnvXk92l7LVkYjNuz3SaqWymFhPjEnc8GY4ZVdcWrWdXWTB9hUhpmRYJctFCyGvM0nN05JTiM2g=="],
-
- "@parcel/core": ["@parcel/core@2.16.4", "", { "dependencies": { "@mischnic/json-sourcemap": "^0.1.1", "@parcel/cache": "2.16.4", "@parcel/diagnostic": "2.16.4", "@parcel/events": "2.16.4", "@parcel/feature-flags": "2.16.4", "@parcel/fs": "2.16.4", "@parcel/graph": "3.6.4", "@parcel/logger": "2.16.4", "@parcel/package-manager": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/profiler": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/types": "2.16.4", "@parcel/utils": "2.16.4", "@parcel/workers": "2.16.4", "base-x": "^3.0.11", "browserslist": "^4.24.5", "clone": "^2.1.2", "dotenv": "^16.5.0", "dotenv-expand": "^11.0.7", "json5": "^2.2.3", "msgpackr": "^1.11.2", "nullthrows": "^1.1.1", "semver": "^7.7.1" } }, "sha512-a0CgrW5A5kwuSu5J1RFRoMQaMs9yagvfH2jJMYVw56+/7NRI4KOtu612SG9Y1ERWfY55ZwzyFxtLWvD6LO+Anw=="],
-
- "@parcel/diagnostic": ["@parcel/diagnostic@2.16.4", "", { "dependencies": { "@mischnic/json-sourcemap": "^0.1.1", "nullthrows": "^1.1.1" } }, "sha512-YN5CfX7lFd6yRLxyZT4Sj3sR6t7nnve4TdXSIqapXzQwL7Bw+sj79D95wTq2rCm3mzk5SofGxFAXul2/nG6gcQ=="],
-
- "@parcel/error-overlay": ["@parcel/error-overlay@2.16.4", "", {}, "sha512-e8KYKnMsfmQnqIhsUWBUZAXlDK30wkxsAGle1tZ0gOdoplaIdVq/WjGPatHLf6igLM76c3tRn2vw8jZFput0jw=="],
-
- "@parcel/events": ["@parcel/events@2.16.4", "", {}, "sha512-slWQkBRAA7o0cN0BLEd+yCckPmlVRVhBZn5Pn6ktm4EzEtrqoMzMeJOxxH8TXaRzrQDYnTcnYIHFgXWd4kkUfg=="],
-
- "@parcel/feature-flags": ["@parcel/feature-flags@2.16.4", "", {}, "sha512-nYdx53siKPLYikHHxfzgjzzgxdrjquK6DMnuSgOTyIdRG4VHdEN0+NqKijRLuVgiUFo/dtxc2h+amwqFENMw8w=="],
-
- "@parcel/fs": ["@parcel/fs@2.16.4", "", { "dependencies": { "@parcel/feature-flags": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/types-internal": "2.16.4", "@parcel/utils": "2.16.4", "@parcel/watcher": "^2.0.7", "@parcel/workers": "2.16.4" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g=="],
-
- "@parcel/graph": ["@parcel/graph@3.6.4", "", { "dependencies": { "@parcel/feature-flags": "2.16.4", "nullthrows": "^1.1.1" } }, "sha512-Cj9yV+/k88kFhE+D+gz0YuNRpvNOCVDskO9pFqkcQhGbsGq6kg2XpZ9V7HlYraih31xf8Vb589bZOwjKIiHixQ=="],
-
- "@parcel/logger": ["@parcel/logger@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/events": "2.16.4" } }, "sha512-QR8QLlKo7xAy9JBpPDAh0RvluaixqPCeyY7Fvo2K7hrU3r85vBNNi06pHiPbWoDmB4x1+QoFwMaGnJOHR+/fMA=="],
-
- "@parcel/markdown-ansi": ["@parcel/markdown-ansi@2.16.4", "", { "dependencies": { "chalk": "^4.1.2" } }, "sha512-0+oQApAVF3wMcQ6d1ZfZ0JsRzaMUYj9e4U+naj6YEsFsFGOPp+pQYKXBf1bobQeeB7cPKPT3SUHxFqced722Hw=="],
-
- "@parcel/namer-default": ["@parcel/namer-default@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "nullthrows": "^1.1.1" } }, "sha512-CE+0lFg881sJq575EXxj2lKUn81tsS5itpNUUErHxit195m3PExyAhoXM6ed/SXxwi+uv+T5FS/jjDLBNuUFDA=="],
-
- "@parcel/node-resolver-core": ["@parcel/node-resolver-core@3.7.4", "", { "dependencies": { "@mischnic/json-sourcemap": "^0.1.1", "@parcel/diagnostic": "2.16.4", "@parcel/fs": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1", "semver": "^7.7.1" } }, "sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA=="],
-
- "@parcel/optimizer-css": ["@parcel/optimizer-css@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/utils": "2.16.4", "browserslist": "^4.24.5", "lightningcss": "^1.30.1", "nullthrows": "^1.1.1" } }, "sha512-aqdXCtmvpcXYgJFGk2DtXF34wuM2TD1fZorKMrJdKB9sSkWVRs1tq6RAXQrbi0ZPDH9wfE/9An3YdkTex7RHuQ=="],
-
- "@parcel/optimizer-html": ["@parcel/optimizer-html@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/utils": "2.16.4" } }, "sha512-vg/R2uuSni+NYYUUV8m+5bz8p5zBv8wc/nNleoBnGuCDwn7uaUwTZ8Gt9CjZO8jjG0xCLILoc/TW+e2FF3pfgQ=="],
-
- "@parcel/optimizer-image": ["@parcel/optimizer-image@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/utils": "2.16.4", "@parcel/workers": "2.16.4" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-2RV54WnvMYr18lxSx7Zlx/DXpJwMzOiPxDnoFyvaUoYutvgHO6chtcgFgh1Bvw/PoI95vYzlTkZ8QfUOk5A0JA=="],
-
- "@parcel/optimizer-svg": ["@parcel/optimizer-svg@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/utils": "2.16.4" } }, "sha512-22+BqIffCrVErg8y2XwhasbTaFNn75OKXZ3KTDBIfOSAZKLUKs1iHfDXETzTRN7cVcS+Q36/6EHd7N/RA8i1fg=="],
-
- "@parcel/optimizer-swc": ["@parcel/optimizer-swc@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/utils": "2.16.4", "@swc/core": "^1.11.24", "nullthrows": "^1.1.1" } }, "sha512-+URqwnB6u1gqaLbG1O1DDApH+UVj4WCbK9No1fdxLBxQ9a84jyli25o1kK1hYB9Nb/JMyYNnEBfvYUW6RphOxw=="],
-
- "@parcel/package-manager": ["@parcel/package-manager@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/fs": "2.16.4", "@parcel/logger": "2.16.4", "@parcel/node-resolver-core": "3.7.4", "@parcel/types": "2.16.4", "@parcel/utils": "2.16.4", "@parcel/workers": "2.16.4", "@swc/core": "^1.11.24", "semver": "^7.7.1" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-obWv9gZgdnkT3Kd+fBkKjhdNEY7zfOP5gVaox5i4nQstVCaVnDlMv5FwLEXwehL+WbwEcGyEGGxOHHkAFKk7Cg=="],
-
- "@parcel/packager-css": ["@parcel/packager-css@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/utils": "2.16.4", "lightningcss": "^1.30.1", "nullthrows": "^1.1.1" } }, "sha512-rWRtfiX+VVIOZvq64jpeNUKkvWAbnokfHQsk/js1s5jD4ViNQgPcNLiRaiIANjymqL6+dQqWvGUSW2a5FAZYfg=="],
-
- "@parcel/packager-html": ["@parcel/packager-html@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/types": "2.16.4", "@parcel/utils": "2.16.4" } }, "sha512-AWo5f6SSqBsg2uWOsX0gPX8hCx2iE6GYLg2Z4/cDy2mPlwDICN8/bxItEztSZFmObi+ti26eetBKRDxAUivyIQ=="],
-
- "@parcel/packager-js": ["@parcel/packager-js@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/types": "2.16.4", "@parcel/utils": "2.16.4", "globals": "^13.24.0", "nullthrows": "^1.1.1" } }, "sha512-L2o39f/fhta+hxto7w8OTUKdstY+te5BmHZREckbQm0KTBg93BG7jB0bfoxLSZF0d8uuAYIVXjzeHNqha+du1g=="],
-
- "@parcel/packager-raw": ["@parcel/packager-raw@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4" } }, "sha512-A9j60G9OmbTkEeE4WRMXCiErEprHLs9NkUlC4HXCxmSrPMOVaMaMva2LdejE3A9kujZqYtYfuc8+a+jN+Nro4w=="],
-
- "@parcel/packager-svg": ["@parcel/packager-svg@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/types": "2.16.4", "@parcel/utils": "2.16.4" } }, "sha512-LT9l7eInFrAZJ6w3mYzAUgDq3SIzYbbQyW46Dz26M9lJQbf6uCaATUTac3BEHegW0ikDuw4OOGHK41BVqeeusg=="],
-
- "@parcel/packager-wasm": ["@parcel/packager-wasm@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4" } }, "sha512-AY96Aqu/RpmaSZK2RGkIrZWjAperDw8DAlxLAiaP1D/RPVnikZtl5BmcUt/Wz3PrzG7/q9ZVqqKkWsLmhkjXZQ=="],
-
- "@parcel/plugin": ["@parcel/plugin@2.16.4", "", { "dependencies": { "@parcel/types": "2.16.4" } }, "sha512-aN2VQoRGC1eB41ZCDbPR/Sp0yKOxe31oemzPx1nJzOuebK2Q6FxSrJ9Bjj9j/YCaLzDtPwelsuLOazzVpXJ6qg=="],
-
- "@parcel/profiler": ["@parcel/profiler@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/events": "2.16.4", "@parcel/types-internal": "2.16.4", "chrome-trace-event": "^1.0.2" } }, "sha512-R3JhfcnoReTv2sVFHPR2xKZvs3d3IRrBl9sWmAftbIJFwT4rU70/W7IdwfaJVkD/6PzHq9mcgOh1WKL4KAxPdA=="],
-
- "@parcel/reporter-cli": ["@parcel/reporter-cli@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/types": "2.16.4", "@parcel/utils": "2.16.4", "chalk": "^4.1.2", "term-size": "^2.2.1" } }, "sha512-DQx9TwcTZrDv828+tcwEi//xyW7OHTGzGX1+UEVxPp0mSzuOmDn0zfER8qNIqGr1i4D/FXhb5UJQDhGHV8mOpQ=="],
-
- "@parcel/reporter-dev-server": ["@parcel/reporter-dev-server@2.16.4", "", { "dependencies": { "@parcel/codeframe": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/utils": "2.16.4" } }, "sha512-YWvay25htQDifpDRJ0+yFh6xUxKnbfeJxYkPYyuXdxpEUhq4T0UWW0PbPCN/wFX7StgeUTXq5Poeo/+eys9m3w=="],
-
- "@parcel/reporter-tracer": ["@parcel/reporter-tracer@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/utils": "2.16.4", "chrome-trace-event": "^1.0.3", "nullthrows": "^1.1.1" } }, "sha512-JKnlXpPepak0/ZybmZn9JtyjJiDBWYrt7ZUlXQhQb0xzNcd/k+RqfwVkTKIwyFHsWtym0cwibkvsi2bWFzS7tw=="],
-
- "@parcel/resolver-default": ["@parcel/resolver-default@2.16.4", "", { "dependencies": { "@parcel/node-resolver-core": "3.7.4", "@parcel/plugin": "2.16.4" } }, "sha512-wJe9XQS0hn/t32pntQpJbls3ZL8mGVVhK9L7s7BTmZT9ufnvP2nif1psJz/nbgnP9LF6mLSk43OdMJKpoStsjQ=="],
-
- "@parcel/runtime-browser-hmr": ["@parcel/runtime-browser-hmr@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/utils": "2.16.4" } }, "sha512-asx7p3NjUSfibI3bC7+8+jUIGHWVk2Zuq9SjJGCGDt+auT9A4uSGljnsk1BWWPqqZ0WILubq4czSAqm0+wt4cw=="],
-
- "@parcel/runtime-js": ["@parcel/runtime-js@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" } }, "sha512-gUKmsjg+PULQBu2QbX0QKll9tXSqHPO8NrfxHwWb2lz5xDKDos1oV0I7BoMWbHhUHkoToXZrm654oGViujtVUA=="],
-
- "@parcel/runtime-rsc": ["@parcel/runtime-rsc@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" } }, "sha512-CHkotYE/cNiUjJmrc5FD9YhlFp1UF5wMNNJmoWaL40eBzsqcaV0sSn5V3bNapwewn3wrMYgdPgvOTHfaZaG73A=="],
-
- "@parcel/runtime-service-worker": ["@parcel/runtime-service-worker@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" } }, "sha512-FT0Q58bf5Re+dq5cL2XHbxqHHFZco6qtRijeVpT3TSPMRPlniMArypSytTeZzVNL7h/hxjWsNu7fRuC0yLB5hA=="],
-
- "@parcel/rust": ["@parcel/rust@2.16.4", "", { "optionalDependencies": { "@parcel/rust-darwin-arm64": "2.16.4", "@parcel/rust-darwin-x64": "2.16.4", "@parcel/rust-linux-arm-gnueabihf": "2.16.4", "@parcel/rust-linux-arm64-gnu": "2.16.4", "@parcel/rust-linux-arm64-musl": "2.16.4", "@parcel/rust-linux-x64-gnu": "2.16.4", "@parcel/rust-linux-x64-musl": "2.16.4", "@parcel/rust-win32-x64-msvc": "2.16.4" }, "peerDependencies": { "napi-wasm": "^1.1.2" }, "optionalPeers": ["napi-wasm"] }, "sha512-RBMKt9rCdv6jr4vXG6LmHtxzO5TuhQvXo1kSoSIF7fURRZ81D1jzBtLxwLmfxCPsofJNqWwdhy5vIvisX+TLlQ=="],
-
- "@parcel/rust-darwin-arm64": ["@parcel/rust-darwin-arm64@2.16.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P3Se36H9EO1fOlwXqQNQ+RsVKTGn5ztRSUGbLcT8ba6oOMmU1w7J4R810GgsCbwCuF10TJNUMkuD3Q2Sz15Q3Q=="],
-
- "@parcel/rust-darwin-x64": ["@parcel/rust-darwin-x64@2.16.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-8aNKNyPIx3EthYpmVJevIdHmFsOApXAEYGi3HU69jTxLgSIfyEHDdGE9lEsMvhSrd/SSo4/euAtiV+pqK04wnA=="],
-
- "@parcel/rust-linux-arm-gnueabihf": ["@parcel/rust-linux-arm-gnueabihf@2.16.4", "", { "os": "linux", "cpu": "arm" }, "sha512-QrvqiSHaWRLc0JBHgUHVvDthfWSkA6AFN+ikV1UGENv4j2r/QgvuwJiG0VHrsL6pH5dRqj0vvngHzEgguke9DA=="],
-
- "@parcel/rust-linux-arm64-gnu": ["@parcel/rust-linux-arm64-gnu@2.16.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-f3gBWQHLHRUajNZi3SMmDQiEx54RoRbXtZYQNuBQy7+NolfFcgb1ik3QhkT7xovuTF/LBmaqP3UFy0PxvR/iwQ=="],
-
- "@parcel/rust-linux-arm64-musl": ["@parcel/rust-linux-arm64-musl@2.16.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-cwml18RNKsBwHyZnrZg4jpecXkWjaY/mCArocWUxkFXjjB97L56QWQM9W86f2/Y3HcFcnIGJwx1SDDKJrV6OIA=="],
-
- "@parcel/rust-linux-x64-gnu": ["@parcel/rust-linux-x64-gnu@2.16.4", "", { "os": "linux", "cpu": "x64" }, "sha512-0xIjQaN8hiG0F9R8coPYidHslDIrbfOS/qFy5GJNbGA3S49h61wZRBMQqa7JFW4+2T8R0J9j0SKHhLXpbLXrIg=="],
-
- "@parcel/rust-linux-x64-musl": ["@parcel/rust-linux-x64-musl@2.16.4", "", { "os": "linux", "cpu": "x64" }, "sha512-fYn21GIecHK9RoZPKwT9NOwxwl3Gy3RYPR6zvsUi0+hpFo19Ph9EzFXN3lT8Pi5KiwQMCU4rsLb5HoWOBM1FeA=="],
-
- "@parcel/rust-win32-x64-msvc": ["@parcel/rust-win32-x64-msvc@2.16.4", "", { "os": "win32", "cpu": "x64" }, "sha512-TcpWC3I1mJpfP2++018lgvM7UX0P8IrzNxceBTHUKEIDMwmAYrUKAQFiaU0j1Ldqk6yP8SPZD3cvphumsYpJOQ=="],
-
- "@parcel/source-map": ["@parcel/source-map@2.1.1", "", { "dependencies": { "detect-libc": "^1.0.3" } }, "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew=="],
-
- "@parcel/transformer-babel": ["@parcel/transformer-babel@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/utils": "2.16.4", "browserslist": "^4.24.5", "json5": "^2.2.3", "nullthrows": "^1.1.1", "semver": "^7.7.1" } }, "sha512-CMDUOQYX7+cmeyHxHSFnoPcwvXNL7rRFE+Q06uVFzsYYiVhbwGF/1J5Bx4cW3Froumqla4YTytTsEteJEybkdA=="],
-
- "@parcel/transformer-css": ["@parcel/transformer-css@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/utils": "2.16.4", "browserslist": "^4.24.5", "lightningcss": "^1.30.1", "nullthrows": "^1.1.1" } }, "sha512-VG/+DbDci2HKe20GFRDs65ZQf5GUFfnmZAa1BhVl/MO+ijT3XC3eoVUy5cExRkq4VLcPY4ytL0g/1T2D6x7lBQ=="],
-
- "@parcel/transformer-html": ["@parcel/transformer-html@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4" } }, "sha512-w6JErYTeNS+KAzUAER18NHFIFFvxiLGd4Fht1UYcb/FDjJdLAMB/FljyEs0Rto/WAhZ2D0MuSL25HQh837R62g=="],
-
- "@parcel/transformer-image": ["@parcel/transformer-image@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/utils": "2.16.4", "@parcel/workers": "2.16.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-ZzIn3KvvRqMfcect4Dy+57C9XoQXZhpVJKBdQWMp9wM1qJEgsVgGDcaSBYCs/UYSKMRMP6Wm20pKCt408RkQzg=="],
-
- "@parcel/transformer-js": ["@parcel/transformer-js@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/utils": "2.16.4", "@parcel/workers": "2.16.4", "@swc/helpers": "^0.5.0", "browserslist": "^4.24.5", "nullthrows": "^1.1.1", "regenerator-runtime": "^0.14.1", "semver": "^7.7.1" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-FD2fdO6URwAGBPidb3x1dDgLBt972mko0LelcSU05aC/pcKaV9mbCtINbPul1MlStzkxDelhuImcCYIyerheVQ=="],
-
- "@parcel/transformer-json": ["@parcel/transformer-json@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "json5": "^2.2.3" } }, "sha512-pB3ZNqgokdkBCJ+4G0BrPYcIkyM9K1HVk0GvjzcLEFDKsoAp8BGEM68FzagFM/nVq9anYTshIaoh349GK0M/bg=="],
-
- "@parcel/transformer-node": ["@parcel/transformer-node@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4" } }, "sha512-7t43CPGfMJk1LqFokwxHSsRi+kKC2QvDXaMtqiMShmk50LCwn81WgzuFvNhMwf6lSiBihWupGwF3Fqksg+aisg=="],
-
- "@parcel/transformer-postcss": ["@parcel/transformer-postcss@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/utils": "2.16.4", "clone": "^2.1.2", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", "semver": "^7.7.1" } }, "sha512-jfmh9ho03H+qwz9S1b/a/oaOmgfMovtHKYDweIGMjKULKIee3AFRqo8RZIOuUMjDuqHWK8SqQmjery4syFV3Xw=="],
-
- "@parcel/transformer-posthtml": ["@parcel/transformer-posthtml@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/utils": "2.16.4" } }, "sha512-+GXsmGx1L25KQGQnwclgEuQe1t4QU+IoDkgN+Ikj+EnQCOWG4/ts2VpMBeqP5F18ZT4cCSRafj6317o/2lSGJg=="],
-
- "@parcel/transformer-raw": ["@parcel/transformer-raw@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4" } }, "sha512-7WDUPq+bW11G9jKxaQIVL+NPGolV99oq/GXhpjYip0SaGaLzRCW7gEk60cftuk0O7MsDaX5jcAJm3G/AX+LJKg=="],
-
- "@parcel/transformer-react-refresh-wrap": ["@parcel/transformer-react-refresh-wrap@2.16.4", "", { "dependencies": { "@parcel/error-overlay": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/utils": "2.16.4", "react-refresh": "^0.16.0" } }, "sha512-MiLNZrsGQJTANKKa4lzZyUbGj/en0Hms474mMdQkCBFg6GmjfmXwaMMgtTfPA3ZwSp2+3LeObCyca/f9B2gBZQ=="],
-
- "@parcel/transformer-svg": ["@parcel/transformer-svg@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/plugin": "2.16.4", "@parcel/rust": "2.16.4" } }, "sha512-0dm4cQr/WpfQP6N0xjFtwdLTxcONDfoLgTOMk4eNUWydHipSgmLtvUk/nOc/FWkwztRScfAObtZXOiPOd3Oy9A=="],
-
- "@parcel/transformer-typescript-tsc": ["@parcel/transformer-typescript-tsc@2.16.4", "", { "dependencies": { "@parcel/plugin": "2.16.4", "@parcel/source-map": "^2.1.1", "@parcel/ts-utils": "2.16.4" }, "peerDependencies": { "typescript": ">=3.0.0" } }, "sha512-zi/Z6jWrrcAm1JkR3660MgMyis0A4GOSdfWhzmO9Ljf3UpWnQ+JgDkkLgdeXXuCJPmwyHLnZIbg7avcJyPCRZg=="],
-
- "@parcel/ts-utils": ["@parcel/ts-utils@2.16.4", "", { "dependencies": { "nullthrows": "^1.1.1" }, "peerDependencies": { "typescript": ">=3.0.0" } }, "sha512-hOYaQvtyq72jKqBjhtSBVn8vATZuaLnvauVRSDPH1DFOgQaPnM1r71Gw5djx6KMk+Tcpa5NyHNJmLVlVAIQ2tA=="],
-
- "@parcel/types": ["@parcel/types@2.16.4", "", { "dependencies": { "@parcel/types-internal": "2.16.4", "@parcel/workers": "2.16.4" } }, "sha512-ctx4mBskZHXeDVHg4OjMwx18jfYH9BzI/7yqbDQVGvd5lyA+/oVVzYdpele2J2i2sSaJ87cA8nb57GDQ8kHAqA=="],
-
- "@parcel/types-internal": ["@parcel/types-internal@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/feature-flags": "2.16.4", "@parcel/source-map": "^2.1.1", "utility-types": "^3.11.0" } }, "sha512-PE6Qmt5cjzBxX+6MPLiF7r+twoC+V9Skt3zyuBQ+H1c0i9o07Bbz2NKX10nvlPukfmW6Fu/1RvTLkzBZR1bU6A=="],
-
- "@parcel/utils": ["@parcel/utils@2.16.4", "", { "dependencies": { "@parcel/codeframe": "2.16.4", "@parcel/diagnostic": "2.16.4", "@parcel/logger": "2.16.4", "@parcel/markdown-ansi": "2.16.4", "@parcel/rust": "2.16.4", "@parcel/source-map": "^2.1.1", "chalk": "^4.1.2", "nullthrows": "^1.1.1" } }, "sha512-lkmxQHcHyOWZLbV8t+h2CGZIkPiBurLm/TS5wNT7+tq0qt9KbVwL7FP2K93TbXhLMGTmpI79Bf3qKniPM167Mw=="],
-
- "@parcel/watcher": ["@parcel/watcher@2.5.6", "", { "dependencies": { "detect-libc": "^2.0.3", "is-glob": "^4.0.3", "node-addon-api": "^7.0.0", "picomatch": "^4.0.3" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.6", "@parcel/watcher-darwin-arm64": "2.5.6", "@parcel/watcher-darwin-x64": "2.5.6", "@parcel/watcher-freebsd-x64": "2.5.6", "@parcel/watcher-linux-arm-glibc": "2.5.6", "@parcel/watcher-linux-arm-musl": "2.5.6", "@parcel/watcher-linux-arm64-glibc": "2.5.6", "@parcel/watcher-linux-arm64-musl": "2.5.6", "@parcel/watcher-linux-x64-glibc": "2.5.6", "@parcel/watcher-linux-x64-musl": "2.5.6", "@parcel/watcher-win32-arm64": "2.5.6", "@parcel/watcher-win32-ia32": "2.5.6", "@parcel/watcher-win32-x64": "2.5.6" } }, "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ=="],
-
- "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.6", "", { "os": "android", "cpu": "arm64" }, "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A=="],
-
- "@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA=="],
-
- "@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg=="],
-
- "@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.6", "", { "os": "freebsd", "cpu": "x64" }, "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng=="],
-
- "@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.6", "", { "os": "linux", "cpu": "arm" }, "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ=="],
-
- "@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.6", "", { "os": "linux", "cpu": "arm" }, "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg=="],
-
- "@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA=="],
-
- "@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA=="],
-
- "@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ=="],
-
- "@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg=="],
-
- "@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q=="],
-
- "@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.6", "", { "os": "win32", "cpu": "ia32" }, "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g=="],
-
- "@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.6", "", { "os": "win32", "cpu": "x64" }, "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw=="],
-
- "@parcel/workers": ["@parcel/workers@2.16.4", "", { "dependencies": { "@parcel/diagnostic": "2.16.4", "@parcel/logger": "2.16.4", "@parcel/profiler": "2.16.4", "@parcel/types-internal": "2.16.4", "@parcel/utils": "2.16.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@parcel/core": "^2.16.4" } }, "sha512-dkBEWqnHXDZnRbTZouNt4uEGIslJT+V0c8OH1MPOfjISp1ucD6/u9ET8k9d/PxS9h1hL53og0SpBuuSEPLDl6A=="],
-
- "@popperjs/core": ["@popperjs/core@2.11.8", "", {}, "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="],
-
- "@swc/core": ["@swc/core@1.15.13", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.13", "@swc/core-darwin-x64": "1.15.13", "@swc/core-linux-arm-gnueabihf": "1.15.13", "@swc/core-linux-arm64-gnu": "1.15.13", "@swc/core-linux-arm64-musl": "1.15.13", "@swc/core-linux-x64-gnu": "1.15.13", "@swc/core-linux-x64-musl": "1.15.13", "@swc/core-win32-arm64-msvc": "1.15.13", "@swc/core-win32-ia32-msvc": "1.15.13", "@swc/core-win32-x64-msvc": "1.15.13" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-0l1gl/72PErwUZuavcRpRAQN9uSst+Nk++niC5IX6lmMWpXoScYx3oq/narT64/sKv/eRiPTaAjBFGDEQiWJIw=="],
-
- "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ztXusRuC5NV2w+a6pDhX13CGioMLq8CjX5P4XgVJ21ocqz9t19288Do0y8LklplDtwcEhYGTNdMbkmUT7+lDTg=="],
-
- "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-cVifxQUKhaE7qcO/y9Mq6PEhoyvN9tSLzCnnFZ4EIabFHBuLtDDO6a+vLveOy98hAs5Qu1+bb5Nv0oa1Pihe3Q=="],
-
- "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.13", "", { "os": "linux", "cpu": "arm" }, "sha512-t+xxEzZ48enl/wGGy7SRYd7kImWQ/+wvVFD7g5JZo234g6/QnIgZ+YdfIyjHB+ZJI3F7a2IQHS7RNjxF29UkWw=="],
-
- "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-VndeGvKmTXFn6AGwjy0Kg8i7HccOCE7Jt/vmZwRxGtOfNZM1RLYRQ7MfDLo6T0h1Bq6eYzps3L5Ma4zBmjOnOg=="],
-
- "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-SmZ9m+XqCB35NddHCctvHFLqPZDAs5j8IgD36GoutufDJmeq2VNfgk5rQoqNqKmAK3Y7iFdEmI76QoHIWiCLyw=="],
-
- "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.13", "", { "os": "linux", "cpu": "x64" }, "sha512-5rij+vB9a29aNkHq72EXI2ihDZPszJb4zlApJY4aCC/q6utgqFA6CkrfTfIb+O8hxtG3zP5KERETz8mfFK6A0A=="],
-
- "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.13", "", { "os": "linux", "cpu": "x64" }, "sha512-OlSlaOK9JplQ5qn07WiBLibkOw7iml2++ojEXhhR3rbWrNEKCD7sd8+6wSavsInyFdw4PhLA+Hy6YyDBIE23Yw=="],
-
- "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-zwQii5YVdsfG8Ti9gIKgBKZg8qMkRZxl+OlYWUT5D93Jl4NuNBRausP20tfEkQdAPSRrMCSUZBM6FhW7izAZRg=="],
-
- "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.13", "", { "os": "win32", "cpu": "ia32" }, "sha512-hYXvyVVntqRlYoAIDwNzkS3tL2ijP3rxyWQMNKaxcCxxkCDto/w3meOK/OB6rbQSkNw0qTUcBfU9k+T0ptYdfQ=="],
-
- "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.13", "", { "os": "win32", "cpu": "x64" }, "sha512-XTzKs7c/vYCcjmcwawnQvlHHNS1naJEAzcBckMI5OJlnrcgW8UtcX9NHFYvNjGtXuKv0/9KvqL4fuahdvlNGKw=="],
-
- "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
-
- "@swc/helpers": ["@swc/helpers@0.5.19", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA=="],
-
- "@swc/types": ["@swc/types@0.1.25", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g=="],
-
- "@tsconfig/bun": ["@tsconfig/bun@1.0.10", "", {}, "sha512-5AV5YknQjNyoYzZ/8NG0dawqew/wH+x7ANiCfCIn29qo0cdbd1EryvFD1k5NSZWLBMOI/fGqMIaxi58GPIP9Cg=="],
-
- "@tsconfig/node24": ["@tsconfig/node24@24.0.4", "", {}, "sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA=="],
-
- "@tsconfig/recommended": ["@tsconfig/recommended@1.0.13", "", {}, "sha512-sySRuBfMKyKO/j2ZAhR8kSembhjuPEV4Ra3AHtmWLq51+iGaudr45crPSzNC5b7/Ctrh9dfUpBuTlYrH6rM58Q=="],
-
- "@tsconfig/strictest": ["@tsconfig/strictest@2.0.8", "", {}, "sha512-XnQ7vNz5HRN0r88GYf1J9JJjqtZPiHt2woGJOo2dYqyHGGcd6OLGqSlBB6p1j9mpzja6Oe5BoPqWmeDx6X9rLw=="],
-
- "@types/bootstrap": ["@types/bootstrap@5.2.10", "", { "dependencies": { "@popperjs/core": "^2.9.2" } }, "sha512-F2X+cd6551tep0MvVZ6nM8v7XgGN/twpdNDjqS1TUM7YFNEtQYWk+dKAnH+T1gr6QgCoGMPl487xw/9hXooa2g=="],
-
- "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
-
- "@types/luxon": ["@types/luxon@3.7.1", "", {}, "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg=="],
-
- "@types/node": ["@types/node@25.3.1", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-hj9YIJimBCipHVfHKRMnvmHg+wfhKc0o4mTtXh9pKBjC8TLJzz0nzGmLi5UJsYAUgSvXFHgb0V2oY10DUFtImw=="],
-
- "@types/qs": ["@types/qs@6.14.0", "", {}, "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ=="],
-
- "@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="],
-
- "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
-
- "base-x": ["base-x@3.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA=="],
-
- "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="],
-
- "bootstrap": ["bootstrap@5.3.8", "", { "peerDependencies": { "@popperjs/core": "^2.11.8" } }, "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg=="],
-
- "bootstrap-icons": ["bootstrap-icons@1.13.1", "", {}, "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw=="],
-
- "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
-
- "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
-
- "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
-
- "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
-
- "caniuse-lite": ["caniuse-lite@1.0.30001774", "", {}, "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA=="],
-
- "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
-
- "chrome-trace-event": ["chrome-trace-event@1.0.4", "", {}, "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ=="],
-
- "clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="],
-
- "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
-
- "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
-
- "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
-
- "detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
-
- "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
-
- "dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="],
-
- "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
-
- "electron-to-chromium": ["electron-to-chromium@1.5.302", "", {}, "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg=="],
-
- "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
-
- "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
-
- "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
-
- "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
-
- "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
-
- "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
-
- "get-port": ["get-port@4.2.0", "", {}, "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw=="],
-
- "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
-
- "globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="],
-
- "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
-
- "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
-
- "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
-
- "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
-
- "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
-
- "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
-
- "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
-
- "ky": ["ky@1.14.3", "", {}, "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw=="],
-
- "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
-
- "lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
-
- "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
-
- "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
-
- "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
-
- "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
-
- "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
-
- "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
-
- "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
-
- "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
-
- "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
-
- "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
-
- "lmdb": ["lmdb@2.8.5", "", { "dependencies": { "msgpackr": "^1.9.5", "node-addon-api": "^6.1.0", "node-gyp-build-optional-packages": "5.1.1", "ordered-binary": "^1.4.1", "weak-lru-cache": "^1.2.2" }, "optionalDependencies": { "@lmdb/lmdb-darwin-arm64": "2.8.5", "@lmdb/lmdb-darwin-x64": "2.8.5", "@lmdb/lmdb-linux-arm": "2.8.5", "@lmdb/lmdb-linux-arm64": "2.8.5", "@lmdb/lmdb-linux-x64": "2.8.5", "@lmdb/lmdb-win32-x64": "2.8.5" }, "bin": { "download-lmdb-prebuilds": "bin/download-prebuilds.js" } }, "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ=="],
-
- "luxon": ["luxon@3.7.2", "", {}, "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew=="],
-
- "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
-
- "msgpackr": ["msgpackr@1.11.8", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA=="],
-
- "msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="],
-
- "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
-
- "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.1.1", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-test": "build-test.js", "node-gyp-build-optional-packages-optional": "optional.js" } }, "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw=="],
-
- "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
-
- "nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="],
-
- "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
-
- "ordered-binary": ["ordered-binary@1.6.1", "", {}, "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w=="],
-
- "oxfmt": ["oxfmt@0.35.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.35.0", "@oxfmt/binding-android-arm64": "0.35.0", "@oxfmt/binding-darwin-arm64": "0.35.0", "@oxfmt/binding-darwin-x64": "0.35.0", "@oxfmt/binding-freebsd-x64": "0.35.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.35.0", "@oxfmt/binding-linux-arm-musleabihf": "0.35.0", "@oxfmt/binding-linux-arm64-gnu": "0.35.0", "@oxfmt/binding-linux-arm64-musl": "0.35.0", "@oxfmt/binding-linux-ppc64-gnu": "0.35.0", "@oxfmt/binding-linux-riscv64-gnu": "0.35.0", "@oxfmt/binding-linux-riscv64-musl": "0.35.0", "@oxfmt/binding-linux-s390x-gnu": "0.35.0", "@oxfmt/binding-linux-x64-gnu": "0.35.0", "@oxfmt/binding-linux-x64-musl": "0.35.0", "@oxfmt/binding-openharmony-arm64": "0.35.0", "@oxfmt/binding-win32-arm64-msvc": "0.35.0", "@oxfmt/binding-win32-ia32-msvc": "0.35.0", "@oxfmt/binding-win32-x64-msvc": "0.35.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-QYeXWkP+aLt7utt5SLivNIk09glWx9QE235ODjgcEZ3sd1VMaUBSpLymh6ZRCA76gD2rMP4bXanUz/fx+nLM9Q=="],
-
- "parcel": ["parcel@2.16.4", "", { "dependencies": { "@parcel/config-default": "2.16.4", "@parcel/core": "2.16.4", "@parcel/diagnostic": "2.16.4", "@parcel/events": "2.16.4", "@parcel/feature-flags": "2.16.4", "@parcel/fs": "2.16.4", "@parcel/logger": "2.16.4", "@parcel/package-manager": "2.16.4", "@parcel/reporter-cli": "2.16.4", "@parcel/reporter-dev-server": "2.16.4", "@parcel/reporter-tracer": "2.16.4", "@parcel/utils": "2.16.4", "chalk": "^4.1.2", "commander": "^12.1.0", "get-port": "^4.2.0" }, "bin": { "parcel": "lib/bin.js" } }, "sha512-RQlrqs4ujYNJpTQi+dITqPKNhRWEqpjPd1YBcGp50Wy3FcJHpwu0/iRm7XWz2dKU/Bwp2qCcVYPIeEDYi2uOUw=="],
-
- "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
-
- "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
-
- "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
-
- "qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="],
-
- "react-refresh": ["react-refresh@0.16.0", "", {}, "sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A=="],
-
- "regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="],
-
- "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
-
- "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
-
- "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
-
- "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
-
- "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
-
- "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
-
- "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
-
- "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
-
- "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="],
-
- "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
-
- "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="],
-
- "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
-
- "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
-
- "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
-
- "utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="],
-
- "uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="],
-
- "weak-lru-cache": ["weak-lru-cache@1.2.2", "", {}, "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw=="],
-
- "@parcel/watcher/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
-
- "lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
-
- "lmdb/node-addon-api": ["node-addon-api@6.1.0", "", {}, "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA=="],
-
- "msgpackr-extract/node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="],
-
- "node-gyp-build-optional-packages/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
-
- "msgpackr-extract/node-gyp-build-optional-packages/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
- }
-}
diff --git a/pages/package.json b/pages/package.json
deleted file mode 100644
index ef0e629..0000000
--- a/pages/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "ak-endfield-api-archive-pages",
- "source": "src/index.html",
- "type": "module",
- "private": true,
- "targets": {
- "default": {
- "distDir": "dist",
- "sourceMap": false
- }
- },
- "devDependencies": {
- "@biomejs/biome": "^2.4.4",
- "@parcel/transformer-typescript-tsc": "^2.16.4",
- "@tsconfig/bun": "^1.0.10",
- "@tsconfig/node24": "^24.0.4",
- "@tsconfig/recommended": "^1.0.13",
- "@tsconfig/strictest": "^2.0.8",
- "@types/bootstrap": "^5.2.10",
- "@types/bun": "latest",
- "@types/luxon": "^3.7.1",
- "@types/qs": "^6.14.0",
- "@types/semver": "^7.7.1",
- "oxfmt": "^0.35.0",
- "parcel": "^2.16.4"
- },
- "peerDependencies": {
- "typescript": "^5"
- },
- "dependencies": {
- "bootstrap": "^5.3.8",
- "bootstrap-icons": "^1.13.1",
- "ky": "^1.14.3",
- "luxon": "^3.7.2",
- "qs": "^6.15.0",
- "semver": "^7.7.4",
- "uuid": "^13.0.0"
- }
-}
diff --git a/pages/src/about.html b/pages/src/about.html
deleted file mode 100644
index 506c3c7..0000000
--- a/pages/src/about.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
- Arknights: Endfield API Archive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Arknights: Endfield API Archive
-
-
-
- About this website
-
- This site functions as a simplified display page for data from the
- ak-endfield-api-archive repository.
-
-
- The
- ak-endfield-api-archive
- repository automatically records various API data changes for
- Arknights: Endfield. It also archives not only API changes but also
- some packages and raw binary data. This is useful for certain users
- interested in analyzing and researching game data.
-
- Disclaimer
-
- This project has no affiliation with Hypergryph (GRYPHLINE) and was
- created solely for
- private use, educational, and research purposes.
-
- Copyright for the archived API data and binary data belongs to their
- respective copyright holders.
-
-
- I assume no responsibility whatsoever.
- PLEASE USE IT AT YOUR OWN RISK.
-
- Thanks
-
-
- Vivi029
-
- Added Windows Google Play Games channel
-
-
-
-
-
-
-
- (C) daydreamer-json and contributors
-
-
-
-
-
-
-
diff --git a/pages/src/assets/css/about.css b/pages/src/assets/css/about.css
deleted file mode 100644
index 81aee59..0000000
--- a/pages/src/assets/css/about.css
+++ /dev/null
@@ -1,8 +0,0 @@
-#endmin-thumbsup {
- width: 200px;
- position: fixed;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- z-index: -1000;
-}
diff --git a/pages/src/assets/css/essentials.css b/pages/src/assets/css/essentials.css
deleted file mode 100644
index 3b45aa7..0000000
--- a/pages/src/assets/css/essentials.css
+++ /dev/null
@@ -1,66 +0,0 @@
-@import "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Roboto:ital,wght@0,100..900;1,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Noto+Sans+JP:wght@100..900&family=Noto+Sans+SC:wght@100..900&family=Noto+Sans+TC:wght@100..900&display=swap";
-@import "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200";
-/* @import "../fonts/line_seed/line_seed.css"; */
-@import "../fonts/iosevka/Iosevka.css";
-/* @import "../fonts/novecento_sans/novecento_sans.css"; */
-@import "../fonts/novecento_sans/novecento_sans_wide_number_only.css";
-/* @import "../fonts/novecento_sans/novecento_sans_normal_number_only.css"; */
-@import "../fonts/harmonyos_sans/harmonyos_sans.css";
-/* @import "../fonts/dseg/dseg.css"; */
-
-:root {
- /* --ddjson-custom-font-main: 'Malgun Gothic'; */
- /* --ddjson-custom-font-main:
- "Inter", "LINE Seed JP (Web)", "Noto Sans JP", "Noto Sans SC", "SF Pro",
- -apple-system, "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen",
- "Ubuntu", "Helvetica Neue", "Helvetica", "Arial", sans-serif, system-ui; */
- --ddjson-custom-font-main:
- "Novecento Sans Wide (Number Only)", "HarmonyOS Sans", "Noto Sans JP",
- "Noto Sans SC", "SF Pro", -apple-system, "BlinkMacSystemFont", "Segoe UI",
- "Roboto", "Oxygen", "Ubuntu", "Helvetica Neue", "Helvetica", "Arial",
- sans-serif, system-ui;
- --ddjson-custom-font-mono:
- "Iosevka Web", "JetBrains Mono", "SF Mono", "Noto Sans JP", "Noto Sans SC",
- "SFMono-Regular", "Menlo", "Monaco", "Consolas", "Liberation Mono",
- "Courier New", monospace, sans-serif, system-ui;
-}
-
-html,
-body {
- font-family: var(--ddjson-custom-font-main);
- font-feature-settings:
- "liga" 1,
- "calt" 1,
- "palt";
- word-break: auto-phrase;
-}
-
-.font-monospace {
- font-family: var(--ddjson-custom-font-mono) !important;
- font-feature-settings: "palt" 0 !important;
-}
-
-pre,
-code,
-kbd,
-samp,
-tt {
- font-family: var(--ddjson-custom-font-mono);
- font-feature-settings: "palt" 0;
-}
-
-.material-symbols-outlined {
- font-variation-settings:
- "FILL" 0,
- "wght" 400,
- "GRAD" 0,
- "opsz" 24;
- font-size: inherit;
-}
-
-.user-drag-none {
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
diff --git a/pages/src/assets/css/index.css b/pages/src/assets/css/index.css
deleted file mode 100644
index 8504fff..0000000
--- a/pages/src/assets/css/index.css
+++ /dev/null
@@ -1,15 +0,0 @@
-#debug-log-inner {
- display: block;
- white-space: pre-wrap !important;
-}
-
-#debug-log-inner div {
- padding-left: 15ch;
- text-indent: -15ch;
- margin: 0;
-}
-
-.accordion-button {
- padding: calc(var(--bs-accordion-btn-padding-y) / 1.5)
- calc(var(--bs-accordion-btn-padding-x) / 1.5);
-}
diff --git a/pages/src/assets/ts/api.ts b/pages/src/assets/ts/api.ts
deleted file mode 100644
index f43288f..0000000
--- a/pages/src/assets/ts/api.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import ky from 'ky';
-import { BASE_URL, gameTargets, launcherTargets, launcherWebApiLang } from './utils/constants.js';
-
-const apiCache = new Map>();
-
-export function fetchJson(url: string): Promise {
- if (!apiCache.has(url)) {
- const promise = ky
- .get(url)
- .json()
- .catch((err) => {
- apiCache.delete(url);
- throw err;
- });
- apiCache.set(url, promise);
- }
- return apiCache.get(url) as Promise;
-}
-
-export async function preloadData() {
- const promises: Promise[] = [];
- promises.push(fetchJson(`${BASE_URL}/mirror_file_list.json`));
- const launcherWebApiFolderNames = ['announcement', 'banner', 'main_bg_image', 'sidebar', 'single_ent'];
- for (const target of gameTargets) {
- promises.push(fetchJson(`${BASE_URL}/akEndfield/launcher/game/${target.dirName}/all.json`));
- promises.push(fetchJson(`${BASE_URL}/akEndfield/launcher/game/${target.dirName}/all_patch.json`));
- for (const apiName of launcherWebApiFolderNames) {
- for (const lang of launcherWebApiLang[target.region]) {
- promises.push(fetchJson(`${BASE_URL}/akEndfield/launcher/web/${target.dirName}/${apiName}/${lang}/all.json`));
- }
- }
- }
- const resTargets = [
- { region: 'os', channel: 6 },
- { region: 'cn', channel: 1 },
- ];
- const platforms = ['Windows', 'Android', 'iOS', 'PlayStation'];
- for (const target of resTargets) {
- for (const platform of platforms) {
- promises.push(fetchJson(`${BASE_URL}/akEndfield/launcher/game_resources/${target.channel}/${platform}/all.json`));
- }
- }
- for (const region of launcherTargets) {
- for (const app of region.apps) {
- promises.push(fetchJson(`${BASE_URL}/akEndfield/launcher/launcher/${app}/${region.channel}/all.json`));
- promises.push(fetchJson(`${BASE_URL}/akEndfield/launcher/launcherExe/${app}/${region.channel}/all.json`));
- }
- }
-
- await Promise.all(promises);
-}
diff --git a/pages/src/assets/ts/essentials.ts b/pages/src/assets/ts/essentials.ts
deleted file mode 100644
index 25c33c4..0000000
--- a/pages/src/assets/ts/essentials.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'bootstrap';
-import 'bootstrap/dist/css/bootstrap.min.css';
-import 'bootstrap-icons/font/bootstrap-icons.min.css';
-
-document.addEventListener('DOMContentLoaded', () => {
- const setTheme = (theme: string) => {
- document.documentElement.setAttribute('data-bs-theme', theme);
- };
- const getPreferredTheme = (): 'light' | 'dark' => {
- return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
- };
- setTheme(getPreferredTheme());
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
- setTheme(getPreferredTheme());
- });
-});
diff --git a/pages/src/assets/ts/index.ts b/pages/src/assets/ts/index.ts
deleted file mode 100644
index d37f100..0000000
--- a/pages/src/assets/ts/index.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { fetchJson, preloadData } from './api.js';
-import { renderGamePackages } from './renderers/gamePackages.js';
-import { renderLaunchers } from './renderers/launchers.js';
-import { renderOverview } from './renderers/overview.js';
-import { renderPatches } from './renderers/patches.js';
-import { renderResources } from './renderers/resources.js';
-import { renderWebPretty } from './renderers/webPretty.js';
-import type { MirrorFileEntry } from './types.js';
-import { BASE_URL } from './utils/constants.js';
-
-document.addEventListener('DOMContentLoaded', () => {
- main();
-});
-
-let mirrorFileDb: MirrorFileEntry[] = [];
-
-async function main() {
- const contentDiv = document.getElementById('content');
- if (!contentDiv) return;
-
- await preloadData();
-
- try {
- mirrorFileDb = await fetchJson(`${BASE_URL}/mirror_file_list.json`);
- } catch (e) {
- console.warn('Failed to fetch mirror list', e);
- }
-
- const tabsHtml = `
-
- Overview
- Game Packages
- Patches
- Resources
- Launcher
- Web
-
-
- `;
- contentDiv.innerHTML = tabsHtml;
-
- await Promise.all([
- renderOverview(document.getElementById('tab-overview')!, mirrorFileDb),
- renderGamePackages(document.getElementById('tab-game')!, mirrorFileDb),
- renderPatches(document.getElementById('tab-patch')!, mirrorFileDb),
- renderResources(document.getElementById('tab-resources')!),
- renderLaunchers(document.getElementById('tab-launcher')!, mirrorFileDb),
- renderWebPretty(document.getElementById('tab-web-pretty')!),
- ]);
-}
diff --git a/pages/src/assets/ts/renderers/gamePackages.ts b/pages/src/assets/ts/renderers/gamePackages.ts
deleted file mode 100644
index 7186f3b..0000000
--- a/pages/src/assets/ts/renderers/gamePackages.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../api.js';
-import type { MirrorFileEntry, StoredData } from '../types.js';
-import { BASE_URL, FILE_SIZE_OPTS, gameTargets } from '../utils/constants.js';
-import math from '../utils/math.js';
-import { generateDownloadLinks } from '../utils/ui.js';
-
-export async function renderGamePackages(container: HTMLElement, mirrorFileDb: MirrorFileEntry[]) {
- for (const target of gameTargets) {
- const url = `${BASE_URL}/akEndfield/launcher/game/${target.dirName}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- const section = document.createElement('div');
- section.className = 'mb-5';
- section.innerHTML = `${target.region === 'cn' ? 'China' : 'Global'}, ${target.name} `;
-
- const accordion = document.createElement('div');
- accordion.className = 'accordion';
- accordion.id = `accordion-game-${target.dirName}`;
-
- // Reverse order to show latest first
- const list = [...data].reverse();
- for (let i = 0; i < list.length; i++) {
- const e = list[i];
- if (!e) continue;
- const version = e.rsp.version;
- const dateStr = DateTime.fromISO(e.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss');
- const packedSize = math.arrayTotal(e.rsp.pkg.packs.map((f: any) => parseInt(f.package_size)));
- const unpackedSize = parseInt(e.rsp.pkg.total_size) - packedSize;
-
- let rows = '';
- const fileName = (f: any) => new URL(f.url).pathname.split('/').pop() ?? '';
- for (const f of e.rsp.pkg.packs) {
- rows += `
- ${fileName(f)}
- ${f.md5}
- ${math.formatFileSize(parseInt(f.package_size), FILE_SIZE_OPTS)}
- ${generateDownloadLinks(f.url, mirrorFileDb)}
- `;
- }
-
- const itemId = `game-${target.dirName}-${i}`;
- const isExpanded = false;
- const item = document.createElement('div');
- item.className = 'accordion-item';
- item.innerHTML = `
-
-
-
-
- Unpacked Size ${math.formatFileSize(unpackedSize, FILE_SIZE_OPTS)}
- Packed Size ${math.formatFileSize(packedSize, FILE_SIZE_OPTS)}
-
-
-
- File MD5 Checksum Size DL
- ${rows}
-
-
-
-
- `;
- accordion.appendChild(item);
- }
- section.appendChild(accordion);
- container.appendChild(section);
- } catch (err) {
- // Ignore 404 or errors
- }
- }
-}
diff --git a/pages/src/assets/ts/renderers/launchers.ts b/pages/src/assets/ts/renderers/launchers.ts
deleted file mode 100644
index b3cc0e6..0000000
--- a/pages/src/assets/ts/renderers/launchers.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../api.js';
-import type { MirrorFileEntry, StoredData } from '../types.js';
-import { BASE_URL, FILE_SIZE_OPTS, launcherTargets } from '../utils/constants.js';
-import math from '../utils/math.js';
-import { generateDownloadLinks } from '../utils/ui.js';
-
-export async function renderLaunchers(container: HTMLElement, mirrorFileDb: MirrorFileEntry[]) {
- for (const region of launcherTargets) {
- for (const app of region.apps) {
- const section = document.createElement('div');
- section.className = 'mb-5';
- section.innerHTML = `${region.id.toUpperCase()} ${app} `;
-
- const accordion = document.createElement('div');
- accordion.className = 'accordion';
- accordion.id = `accordion-launcher-${region.id}-${app}`;
- let itemIndex = 0;
-
- // Zip
- try {
- const urlZip = `${BASE_URL}/akEndfield/launcher/launcher/${app}/${region.channel}/all.json`;
- const dataZip = await fetchJson[]>(urlZip);
-
- let rows = '';
- for (const e of [...dataZip].reverse()) {
- const dateStr = DateTime.fromISO(e.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss');
- const fileName = new URL(e.rsp.zip_package_url).pathname.split('/').pop() ?? '';
- const unpacked = parseInt(e.rsp.total_size) - parseInt(e.rsp.package_size);
-
- rows += `
- ${dateStr}
- ${e.rsp.version}
- ${fileName}
- ${e.rsp.md5}
- ${math.formatFileSize(unpacked, FILE_SIZE_OPTS)}
- ${math.formatFileSize(parseInt(e.rsp.package_size), FILE_SIZE_OPTS)}
- ${generateDownloadLinks(e.rsp.zip_package_url, mirrorFileDb)}
- `;
- }
-
- const itemId = `launcher-zip-${region.id}-${app}`;
- const isExpanded = false;
- itemIndex++;
-
- const item = document.createElement('div');
- item.className = 'accordion-item';
- item.innerHTML = `
-
-
-
-
-
-
-
- Date
- Version
- File
- MD5 Checksum
- Unpacked
- Packed
- DL
-
-
- ${rows}
-
-
-
-
- `;
- accordion.appendChild(item);
- } catch (e) {}
-
- // Exe
- try {
- const urlExe = `${BASE_URL}/akEndfield/launcher/launcherExe/${app}/${region.channel}/all.json`;
- const dataExe = await fetchJson[]>(urlExe);
-
- let rows = '';
- for (const e of [...dataExe].reverse()) {
- const dateStr = DateTime.fromISO(e.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss');
- const fileName = new URL(e.rsp.exe_url).pathname.split('/').pop() ?? '';
-
- rows += `
- ${dateStr}
- ${e.rsp.version}
- ${fileName}
- ${math.formatFileSize(parseInt(e.rsp.exe_size), FILE_SIZE_OPTS)}
- ${generateDownloadLinks(e.rsp.exe_url, mirrorFileDb)}
- `;
- }
-
- const itemId = `launcher-exe-${region.id}-${app}`;
- const isExpanded = false;
- itemIndex++;
-
- const item = document.createElement('div');
- item.className = 'accordion-item';
- item.innerHTML = `
-
-
-
-
-
-
-
- Date
- Version
- File
- Size
- DL
-
-
- ${rows}
-
-
-
-
- `;
- accordion.appendChild(item);
- } catch (e) {}
-
- if (accordion.childElementCount > 0) {
- section.appendChild(accordion);
- container.appendChild(section);
- }
- }
- }
-}
diff --git a/pages/src/assets/ts/renderers/overview.ts b/pages/src/assets/ts/renderers/overview.ts
deleted file mode 100644
index 1476018..0000000
--- a/pages/src/assets/ts/renderers/overview.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../api.js';
-import type { MirrorFileEntry, StoredData } from '../types.js';
-import { BASE_URL, FILE_SIZE_OPTS, gameTargets, launcherTargets } from '../utils/constants.js';
-import math from '../utils/math.js';
-
-export async function renderOverview(container: HTMLElement, mirrorFileDb: MirrorFileEntry[]) {
- const mirrorOrigSet = new Set();
- for (const m of mirrorFileDb) {
- try {
- const u = new URL(m.orig);
- u.search = '';
- mirrorOrigSet.add(u.toString());
- } catch {}
- }
-
- const countedUrls = new Set();
- let totalMirrorSize = 0;
-
- const checkAndAddSize = (url: string, size: number) => {
- if (!url || isNaN(size)) return;
- try {
- const u = new URL(url);
- u.search = '';
- const cleanUrl = u.toString();
- if (countedUrls.has(cleanUrl)) return;
- if (mirrorOrigSet.has(cleanUrl)) {
- totalMirrorSize += size;
- countedUrls.add(cleanUrl);
- }
- } catch {}
- };
-
- const section = document.createElement('div');
- const sectionIn = document.createElement('div');
- section.className = 'card mb-3';
- sectionIn.className = 'card-body';
-
- const [globalPkg, chinaPkg] = await Promise.all([
- (async () => {
- const url = `${BASE_URL}/akEndfield/launcher/game/6/all.json`;
- const dat = await fetchJson[]>(url);
- const latest = dat.at(-1);
- if (!latest) return { version: '---', date: '---' };
- return {
- version: latest.rsp.version,
- date: DateTime.fromISO(latest.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss'),
- };
- })(),
- (async () => {
- const url = `${BASE_URL}/akEndfield/launcher/game/1/all.json`;
- const dat = await fetchJson[]>(url);
- const latest = dat.at(-1);
- if (!latest) return { version: '---', date: '---' };
- return {
- version: latest.rsp.version,
- date: DateTime.fromISO(latest.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss'),
- };
- })(),
- ]);
-
- sectionIn.innerHTML = `
- Latest Game Packages
-
-
-
- ${globalPkg.version}
- ${globalPkg.date}
- Latest Version (Global)
-
-
-
-
- ${chinaPkg.version}
- ${chinaPkg.date}
- Latest Version (China)
-
-
-
- `;
-
- const tableWrapper = document.createElement('div');
- tableWrapper.className = 'table-responsive';
-
- const table = document.createElement('table');
- table.className = 'table table-striped table-bordered table-sm align-middle text-nowrap';
- table.innerHTML = `
-
-
- Region
- Channel
- Version
- Packed
- Unpacked
-
-
-
- `;
- const tbody = table.querySelector('tbody')!;
- tableWrapper.appendChild(table);
- sectionIn.appendChild(tableWrapper);
- section.appendChild(sectionIn);
- container.appendChild(section);
-
- // 1. Game Packages
- for (const target of gameTargets) {
- const url = `${BASE_URL}/akEndfield/launcher/game/${target.dirName}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- if (!data || data.length === 0) continue;
-
- const latest = data[data.length - 1];
- if (!latest) continue;
- const version = latest.rsp.version;
- const packedSize = math.arrayTotal(latest.rsp.pkg.packs.map((f: any) => parseInt(f.package_size)));
- const totalSize = parseInt(latest.rsp.pkg.total_size);
- const unpackedSize = totalSize - packedSize;
-
- const row = document.createElement('tr');
- row.innerHTML = `
- ${target.region === 'cn' ? 'China' : 'Global'}
- ${target.name}
- ${version}
- ${math.formatFileSize(packedSize, FILE_SIZE_OPTS)}
- ${math.formatFileSize(unpackedSize, FILE_SIZE_OPTS)}
- `;
- tbody.appendChild(row);
-
- for (const entry of data) {
- if (entry.rsp.pkg && entry.rsp.pkg.packs) {
- for (const pack of entry.rsp.pkg.packs) {
- checkAndAddSize(pack.url, parseInt(pack.package_size));
- }
- }
- }
- } catch (e) {
- console.warn('Overview: Failed to fetch game data', target.name, e);
- }
- }
-
- // 2. Patches
- for (const target of gameTargets) {
- const url = `${BASE_URL}/akEndfield/launcher/game/${target.dirName}/all_patch.json`;
- try {
- const data = await fetchJson[]>(url);
- for (const entry of data) {
- if (!entry.rsp.patch) continue;
- if (entry.rsp.patch.url) {
- checkAndAddSize(entry.rsp.patch.url, parseInt(entry.rsp.patch.package_size));
- }
- if (entry.rsp.patch.patches) {
- for (const p of entry.rsp.patch.patches) {
- checkAndAddSize(p.url, parseInt(p.package_size));
- }
- }
- }
- } catch (e) {}
- }
-
- // 4. Launchers
- for (const region of launcherTargets) {
- for (const app of region.apps) {
- try {
- const urlZip = `${BASE_URL}/akEndfield/launcher/launcher/${app}/${region.channel}/all.json`;
- const dataZip = await fetchJson[]>(urlZip);
- for (const e of dataZip) {
- checkAndAddSize(e.rsp.zip_package_url, parseInt(e.rsp.package_size));
- }
- } catch (e) {}
- try {
- const urlExe = `${BASE_URL}/akEndfield/launcher/launcherExe/${app}/${region.channel}/all.json`;
- const dataExe = await fetchJson[]>(urlExe);
- for (const e of dataExe) {
- checkAndAddSize(e.rsp.exe_url, parseInt(e.rsp.exe_size));
- }
- } catch (e) {}
- }
- }
-
- // 3. Latest Game Resources (Global)
- {
- const resPlatforms = ['Windows', 'Android', 'iOS', 'PlayStation'];
- const resData = await Promise.all(
- resPlatforms.map(async (p) => {
- try {
- const url = `${BASE_URL}/akEndfield/launcher/game_resources/6/${p}/all.json`;
- const dat = await fetchJson[]>(url);
- return dat.at(-1);
- } catch {
- return undefined;
- }
- }),
- );
-
- const resSection = document.createElement('div');
- resSection.className = 'card mb-3';
- const resSectionIn = document.createElement('div');
- resSectionIn.className = 'card-body';
- resSectionIn.innerHTML = `
- Latest Game Resources
-
- ${resPlatforms
- .map((p, i) => {
- const item = resData[i];
- if (!item) {
- return `
-
- `;
- }
-
- const version = (() => {
- const initialRes = item.rsp.resources.find((e: any) => e.name === 'initial');
- const mainRes = item.rsp.resources.find((e: any) => e.name === 'main');
- if (!initialRes || !mainRes) return '---';
- if (initialRes.version === mainRes.version) return mainRes.version;
- return item.rsp.res_version;
- })();
-
- const dateStr = DateTime.fromISO(item.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss');
-
- return `
-
-
- ${version}
- ${dateStr}
- ${p}
-
-
- `;
- })
- .join('')}
-
- `;
- resSection.appendChild(resSectionIn);
- container.appendChild(resSection);
- }
-
- const mirrorSection = document.createElement('div');
- mirrorSection.className = 'card';
- mirrorSection.innerHTML = `
-
-
Mirror Statistics
-
- ${math.formatFileSize(totalMirrorSize, { ...FILE_SIZE_OPTS, unit: 'G' })}
- uploaded to mirror
-
-
- `;
- container.appendChild(mirrorSection);
-}
diff --git a/pages/src/assets/ts/renderers/patches.ts b/pages/src/assets/ts/renderers/patches.ts
deleted file mode 100644
index 013ecea..0000000
--- a/pages/src/assets/ts/renderers/patches.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../api.js';
-import type { MirrorFileEntry, StoredData } from '../types.js';
-import { BASE_URL, FILE_SIZE_OPTS, gameTargets } from '../utils/constants.js';
-import math from '../utils/math.js';
-import { generateDownloadLinks } from '../utils/ui.js';
-
-export async function renderPatches(container: HTMLElement, mirrorFileDb: MirrorFileEntry[]) {
- for (const target of gameTargets) {
- const url = `${BASE_URL}/akEndfield/launcher/game/${target.dirName}/all_patch.json`;
- try {
- const data = await fetchJson[]>(url);
- if (data.length === 0) continue;
-
- const section = document.createElement('div');
- section.className = 'mb-5';
- section.innerHTML = `${target.region === 'cn' ? 'China' : 'Global'}, ${target.name} `;
-
- const accordion = document.createElement('div');
- accordion.className = 'accordion';
- accordion.id = `accordion-patch-${target.dirName}`;
-
- let itemIndex = 0;
- for (const e of [...data].reverse()) {
- if (!e.rsp.patch) continue;
- const version = e.rsp.version;
- const reqVersion = e.rsp.request_version;
- const dateStr = DateTime.fromISO(e.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss');
- const packedSize = math.arrayTotal(e.rsp.patch.patches.map((f: any) => parseInt(f.package_size)));
- const unpackedSize = parseInt(e.rsp.patch.total_size) - packedSize;
-
- let rows = '';
- const fileName = (url: string) => new URL(url).pathname.split('/').pop() ?? '';
- if (e.rsp.patch.url) {
- rows += `
- ${fileName(e.rsp.patch.url)}
- ${e.rsp.patch.md5}
- ${math.formatFileSize(parseInt(e.rsp.patch.package_size), FILE_SIZE_OPTS)}
- ${generateDownloadLinks(e.rsp.patch.url, mirrorFileDb)}
- `;
- }
- for (const f of e.rsp.patch.patches) {
- rows += `
- ${fileName(f.url)}
- ${f.md5}
- ${math.formatFileSize(parseInt(f.package_size), FILE_SIZE_OPTS)}
- ${generateDownloadLinks(f.url, mirrorFileDb)}
- `;
- }
-
- const itemId = `patch-${target.dirName}-${itemIndex}`;
- const isExpanded = false;
- itemIndex++;
-
- const item = document.createElement('div');
- item.className = 'accordion-item';
- item.innerHTML = `
-
-
-
-
- Unpacked Size ${math.formatFileSize(unpackedSize, FILE_SIZE_OPTS)}
- Packed Size ${math.formatFileSize(packedSize, FILE_SIZE_OPTS)}
-
-
-
- File MD5 Checksum Size DL
- ${rows}
-
-
-
-
- `;
- accordion.appendChild(item);
- }
- section.appendChild(accordion);
- container.appendChild(section);
- } catch (err) {
- // Ignore
- }
- }
-}
diff --git a/pages/src/assets/ts/renderers/resources.ts b/pages/src/assets/ts/renderers/resources.ts
deleted file mode 100644
index 1c8a883..0000000
--- a/pages/src/assets/ts/renderers/resources.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { DateTime } from 'luxon';
-import * as semver from 'semver';
-import { fetchJson } from '../api.js';
-import type { StoredData } from '../types.js';
-import { BASE_URL } from '../utils/constants.js';
-
-export async function renderResources(container: HTMLElement) {
- const platforms = ['Windows', 'Android', 'iOS', 'PlayStation'];
- const targets = [
- { region: 'os', channel: 6 },
- { region: 'cn', channel: 1 },
- ];
-
- for (const target of targets) {
- const section = document.createElement('div');
- section.className = 'mb-5';
- section.innerHTML = `${target.region === 'cn' ? 'China' : 'Global'} `;
-
- const accordion = document.createElement('div');
- accordion.className = 'accordion';
- accordion.id = `accordion-res-${target.region}-${target.channel}`;
- let itemIndex = 0;
-
- for (const platform of platforms) {
- const url = `${BASE_URL}/akEndfield/launcher/game_resources/${target.channel}/${platform}/all.json`;
- try {
- const data = await fetchJson[]>(url);
-
- // Group by res_version
- const resVersionMap = new Map; versions: Set }>();
- for (const e of data) {
- const resVer = e.rsp.res_version;
- if (!resVersionMap.has(resVer)) {
- resVersionMap.set(resVer, { rsp: e, versions: new Set() });
- }
- resVersionMap.get(resVer)!.versions.add(e.req.version);
- }
-
- const resVersionSet = Array.from(resVersionMap.values()).map((d) => ({
- resVersion: d.rsp.rsp.res_version,
- rsp: d.rsp,
- versions: Array.from(d.versions).sort(semver.rcompare),
- }));
-
- const sortedSet = resVersionSet.reverse();
- let rows = '';
- for (let i = 0; i < sortedSet.length; i++) {
- const item = sortedSet[i]!;
- const nextItem = sortedSet[i + 1];
- // Newest first
- const currentDate = DateTime.fromISO(item.rsp.updatedAt);
- const dateStr = currentDate.toFormat('yyyy/MM/dd HH:mm:ss');
-
- const intervalStr = (() => {
- if (nextItem) {
- const nextDate = DateTime.fromISO(nextItem.rsp.updatedAt);
- const diff = currentDate.diff(nextDate);
- return diff.toFormat('dd:hh:mm:ss');
- }
- return '-';
- })();
-
- const initialRes = item.rsp.rsp.resources.find((e: any) => e.name === 'initial');
- const mainRes = item.rsp.rsp.resources.find((e: any) => e.name === 'main');
- const isKick = JSON.parse(item.rsp.rsp.configs).kick_flag === true;
-
- rows += `
- ${dateStr}
- ${intervalStr}
- ${initialRes.version}
- ${mainRes.version}
- ${isKick ? '✅' : ''}
- ${item.versions.join(', ')}
- `;
- }
-
- const itemId = `res-${target.region}-${target.channel}-${platform}`;
- const isExpanded = false;
- itemIndex++;
-
- const item = document.createElement('div');
- item.className = 'accordion-item';
- item.innerHTML = `
-
-
-
-
-
-
-
- Date
- Interval
- Initial
- Main
- Kick
- Game version
-
-
- ${rows}
-
-
-
-
- `;
- accordion.appendChild(item);
- } catch (err) {
- // Ignore
- }
- }
- if (accordion.childElementCount > 0) {
- section.appendChild(accordion);
- container.appendChild(section);
- }
- }
-}
diff --git a/pages/src/assets/ts/renderers/web.ts b/pages/src/assets/ts/renderers/web.ts
deleted file mode 100644
index 8919f92..0000000
--- a/pages/src/assets/ts/renderers/web.ts
+++ /dev/null
@@ -1,157 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../api.js';
-import type { StoredData } from '../types.js';
-import { BASE_URL, gameTargets, launcherWebApiLang } from '../utils/constants.js';
-
-const apiTypes = ['announcement', 'banner', 'main_bg_image', 'sidebar', 'single_ent'];
-
-export async function renderWeb(container: HTMLElement) {
- for (const target of gameTargets) {
- const section = document.createElement('div');
- section.className = 'mb-5';
- section.innerHTML = `${target.region === 'cn' ? 'China' : 'Global'}, ${target.name} `;
-
- const langs = launcherWebApiLang[target.region] || [];
- const defaultLang = target.region === 'os' ? 'en-us' : 'zh-cn';
-
- // Language Selector
- const langSelectGroup = document.createElement('div');
- langSelectGroup.className = 'input-group mb-3';
- langSelectGroup.innerHTML = 'Language ';
-
- const langSelect = document.createElement('select');
- langSelect.className = 'form-select';
-
- langs.forEach((lang) => {
- const option = document.createElement('option');
- option.value = lang;
- option.textContent = lang;
- if (lang === defaultLang) {
- option.selected = true;
- }
- langSelect.appendChild(option);
- });
- langSelectGroup.appendChild(langSelect);
-
- if (langs.length <= 1) {
- langSelectGroup.style.display = 'none';
- }
-
- section.appendChild(langSelectGroup);
-
- const accordion = document.createElement('div');
- accordion.className = 'accordion';
- accordion.id = `accordion-web-${target.dirName}`;
-
- const renderApiList = async (lang: string) => {
- accordion.innerHTML = 'Loading...
';
-
- const results = await Promise.all(
- apiTypes.map(async (apiType) => {
- const url = `${BASE_URL}/akEndfield/launcher/web/${target.dirName}/${apiType}/${lang}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- if (!data || data.length === 0) return null;
- return { apiType, list: [...data].reverse() };
- } catch (e) {
- console.warn(`Failed to load ${url}`, e);
- return null;
- }
- }),
- );
-
- accordion.innerHTML = '';
- const validResults = results.filter((r): r is NonNullable => r !== null);
-
- if (validResults.length === 0) {
- accordion.innerHTML = 'No data found.
';
- return;
- }
-
- validResults.forEach(({ apiType, list }, idx) => {
- const itemId = `web-${target.dirName}-${lang}-${apiType}`;
-
- const item = document.createElement('div');
- item.className = 'accordion-item';
-
- // Header
- const header = document.createElement('h2');
- header.className = 'accordion-header';
- header.id = `heading-${itemId}`;
- header.innerHTML = `
-
- ${apiType}
-
- `;
- item.appendChild(header);
-
- // Body
- const collapse = document.createElement('div');
- collapse.id = `collapse-${itemId}`;
- collapse.className = 'accordion-collapse collapse';
- collapse.setAttribute('aria-labelledby', `heading-${itemId}`);
- collapse.setAttribute('data-bs-parent', `#${accordion.id}`);
-
- const body = document.createElement('div');
- body.className = 'accordion-body';
-
- // Select for UpdatedAt
- const selectGroup = document.createElement('div');
- selectGroup.className = 'input-group mb-3';
- selectGroup.innerHTML = `History `;
-
- const select = document.createElement('select');
- select.className = 'form-select';
- select.ariaLabel = 'Select version';
-
- list.forEach((entry, idx) => {
- const dateStr = DateTime.fromISO(entry.updatedAt).toFormat('yyyy/MM/dd HH:mm:ss');
- const option = document.createElement('option');
- option.value = idx.toString();
- option.textContent = `${dateStr}`;
- select.appendChild(option);
- });
- selectGroup.appendChild(select);
- body.appendChild(selectGroup);
-
- // Content Area
- const contentArea = document.createElement('pre');
- contentArea.className = 'p-3 border rounded overflow-auto';
- contentArea.style.maxHeight = '500px';
- contentArea.style.fontSize = '0.875rem';
-
- const updateContent = (index: number) => {
- const entry = list[index];
- if (entry) {
- contentArea.textContent = JSON.stringify(entry.rsp, null, 2);
- }
- };
-
- // Initial render for this item
- updateContent(0);
-
- select.addEventListener('change', (e) => {
- const val = parseInt((e.target as HTMLSelectElement).value, 10);
- updateContent(val);
- });
-
- body.appendChild(contentArea);
- collapse.appendChild(body);
- item.appendChild(collapse);
- accordion.appendChild(item);
- });
- };
-
- langSelect.addEventListener('change', (e) => {
- renderApiList((e.target as HTMLSelectElement).value);
- });
-
- section.appendChild(accordion);
- container.appendChild(section);
-
- // Initial load
- if (defaultLang) {
- renderApiList(defaultLang);
- }
- }
-}
diff --git a/pages/src/assets/ts/renderers/webPretty.ts b/pages/src/assets/ts/renderers/webPretty.ts
deleted file mode 100644
index b74c18b..0000000
--- a/pages/src/assets/ts/renderers/webPretty.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { renderAnnouncement } from './webPretty/announcement.js';
-import { renderBanner } from './webPretty/banner.js';
-import { renderMainBgImage } from './webPretty/mainBgImage.js';
-import { renderSidebar } from './webPretty/sidebar.js';
-import { renderSingleEnt } from './webPretty/singleEnt.js';
-
-export async function renderWebPretty(container: HTMLElement) {
- container.innerHTML = '';
- await renderAnnouncement(container);
- await renderBanner(container);
- await renderMainBgImage(container);
- await renderSingleEnt(container);
- await renderSidebar(container);
-}
diff --git a/pages/src/assets/ts/renderers/webPretty/announcement.ts b/pages/src/assets/ts/renderers/webPretty/announcement.ts
deleted file mode 100644
index 9e1d3d1..0000000
--- a/pages/src/assets/ts/renderers/webPretty/announcement.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../../api.js';
-import type { LauncherWebAnnouncement, StoredData } from '../../types.js';
-import { BASE_URL, gameTargets, launcherWebApiLang } from '../../utils/constants.js';
-
-export async function renderAnnouncement(container: HTMLElement) {
- const outerCard = document.createElement('div');
- outerCard.className = 'card mb-3';
-
- const header = document.createElement('div');
- header.className = 'card-header d-flex justify-content-between align-items-center';
- header.style.cursor = 'pointer';
- header.setAttribute('data-bs-toggle', 'collapse');
- header.setAttribute('data-bs-target', '#collapseAnnouncement');
- header.setAttribute('role', 'button');
- header.innerHTML = 'Announcement ';
- outerCard.appendChild(header);
-
- const collapseDiv = document.createElement('div');
- collapseDiv.id = 'collapseAnnouncement';
- collapseDiv.className = 'collapse';
- outerCard.appendChild(collapseDiv);
-
- const outerCardBody = document.createElement('div');
- outerCardBody.className = 'card-body';
- collapseDiv.appendChild(outerCardBody);
-
- // --- UI Controls ---
- const controls = document.createElement('div');
- controls.className = 'row g-3 mb-4';
-
- const targetCol = document.createElement('div');
- targetCol.className = 'col-md-6';
- targetCol.innerHTML = 'Target ';
- const targetSelect = document.createElement('select');
- targetSelect.className = 'form-select';
- gameTargets.forEach((target, idx) => {
- const option = document.createElement('option');
- option.value = idx.toString();
- option.textContent = `${target.region === 'cn' ? 'China' : 'Global'} - ${target.name}`;
- targetSelect.appendChild(option);
- });
- targetCol.appendChild(targetSelect);
-
- const langCol = document.createElement('div');
- langCol.className = 'col-md-6';
- langCol.innerHTML = 'Language ';
- const langSelect = document.createElement('select');
- langSelect.className = 'form-select';
- langCol.appendChild(langSelect);
-
- controls.appendChild(targetCol);
- controls.appendChild(langCol);
- outerCardBody.appendChild(controls);
-
- const contentDiv = document.createElement('div');
- outerCardBody.appendChild(contentDiv);
-
- // --- Logic ---
- const updateLanguages = () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const langs = launcherWebApiLang[target.region] || [];
- const defaultLang = target.region === 'os' ? 'en-us' : 'zh-cn';
-
- langSelect.innerHTML = '';
- langs.forEach((lang) => {
- const option = document.createElement('option');
- option.value = lang;
- option.textContent = lang;
- if (lang === defaultLang) option.selected = true;
- langSelect.appendChild(option);
- });
-
- langCol.style.display = langs.length <= 1 ? 'none' : 'block';
- };
-
- const renderContent = async () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const lang = langSelect.value;
-
- if (!lang) {
- contentDiv.innerHTML = 'No language selected.
';
- return;
- }
-
- contentDiv.innerHTML = 'Loading announcements...
';
-
- const url = `${BASE_URL}/akEndfield/launcher/web/${target.dirName}/announcement/${lang}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- if (!data || data.length === 0) {
- contentDiv.innerHTML = 'No data found.
';
- return;
- }
-
- const tabsMap = new Map<
- string,
- { tabName: string; announcements: Map }
- >();
- const sortedData = [...data].sort(
- (a, b) => DateTime.fromISO(b.updatedAt).toMillis() - DateTime.fromISO(a.updatedAt).toMillis(),
- );
-
- for (const entry of sortedData) {
- if (!entry.rsp || !entry.rsp.tabs) continue;
- for (const tab of entry.rsp.tabs) {
- if (!tabsMap.has(tab.tab_id)) {
- tabsMap.set(tab.tab_id, { tabName: tab.tabName, announcements: new Map() });
- }
- const targetTab = tabsMap.get(tab.tab_id)!;
- for (const ann of tab.announcements) {
- if (!targetTab.announcements.has(ann.id)) {
- targetTab.announcements.set(ann.id, ann);
- }
- }
- }
- }
-
- contentDiv.innerHTML = '';
- if (tabsMap.size === 0) {
- contentDiv.innerHTML = 'No announcements found.
';
- return;
- }
-
- for (const [_tabId, tabData] of tabsMap) {
- const card = document.createElement('div');
- card.className = 'card mb-4 shadow-sm';
-
- const cardHeader = document.createElement('div');
- cardHeader.className = 'card-header bg-secondary text-white fw-bold py-1';
- cardHeader.textContent = tabData.tabName;
- card.appendChild(cardHeader);
-
- const listGroup = document.createElement('ul');
- listGroup.className = 'list-group list-group-flush';
-
- const sortedAnnouncements = Array.from(tabData.announcements.values()).sort(
- (a, b) => parseInt(b.start_ts, 10) - parseInt(a.start_ts, 10),
- );
-
- for (const ann of sortedAnnouncements) {
- const item = document.createElement('li');
- item.className = 'list-group-item py-2';
- const date = DateTime.fromMillis(parseInt(ann.start_ts, 10)).toFormat('yyyy/MM/dd HH:mm');
-
- item.innerHTML = `
-
-
${date}
-
${ann.content}
-
- ${ann.need_token ? '
Auth ' : ''}
- ${ann.jump_url ? `
Link ` : ''}
-
ID:${ann.id}
-
-
- `;
- listGroup.appendChild(item);
- }
- card.appendChild(listGroup);
- contentDiv.appendChild(card);
- }
- } catch (e) {
- console.warn(`Failed to load ${url}`, e);
- contentDiv.innerHTML = 'Failed to load data.
';
- }
- };
-
- targetSelect.addEventListener('change', () => {
- updateLanguages();
- renderContent();
- });
- langSelect.addEventListener('change', renderContent);
-
- updateLanguages();
- renderContent();
- container.appendChild(outerCard);
-}
diff --git a/pages/src/assets/ts/renderers/webPretty/banner.ts b/pages/src/assets/ts/renderers/webPretty/banner.ts
deleted file mode 100644
index 7356452..0000000
--- a/pages/src/assets/ts/renderers/webPretty/banner.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../../api.js';
-import type { LauncherWebBanner, StoredData } from '../../types.js';
-import { BASE_URL, gameTargets, launcherWebApiLang } from '../../utils/constants.js';
-
-export async function renderBanner(container: HTMLElement) {
- const outerCard = document.createElement('div');
- outerCard.className = 'card mb-3';
-
- const header = document.createElement('div');
- header.className = 'card-header d-flex justify-content-between align-items-center';
- header.style.cursor = 'pointer';
- header.setAttribute('data-bs-toggle', 'collapse');
- header.setAttribute('data-bs-target', '#collapseBanner');
- header.setAttribute('role', 'button');
- header.innerHTML = 'Banner ';
- outerCard.appendChild(header);
-
- const collapseDiv = document.createElement('div');
- collapseDiv.id = 'collapseBanner';
- collapseDiv.className = 'collapse';
- outerCard.appendChild(collapseDiv);
-
- const outerCardBody = document.createElement('div');
- outerCardBody.className = 'card-body';
- collapseDiv.appendChild(outerCardBody);
-
- // --- UI Controls ---
- const controls = document.createElement('div');
- controls.className = 'row g-3 mb-4';
-
- const targetCol = document.createElement('div');
- targetCol.className = 'col-md-6';
- targetCol.innerHTML = 'Target ';
- const targetSelect = document.createElement('select');
- targetSelect.className = 'form-select';
- gameTargets.forEach((target, idx) => {
- const option = document.createElement('option');
- option.value = idx.toString();
- option.textContent = `${target.region === 'cn' ? 'China' : 'Global'} - ${target.name}`;
- targetSelect.appendChild(option);
- });
- targetCol.appendChild(targetSelect);
-
- const langCol = document.createElement('div');
- langCol.className = 'col-md-6';
- langCol.innerHTML = 'Language ';
- const langSelect = document.createElement('select');
- langSelect.className = 'form-select';
- langCol.appendChild(langSelect);
-
- controls.appendChild(targetCol);
- controls.appendChild(langCol);
- outerCardBody.appendChild(controls);
-
- const contentDiv = document.createElement('div');
- outerCardBody.appendChild(contentDiv);
-
- // --- Logic ---
- const updateLanguages = () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const langs = launcherWebApiLang[target.region] || [];
- const defaultLang = target.region === 'os' ? 'en-us' : 'zh-cn';
-
- langSelect.innerHTML = '';
- langs.forEach((lang) => {
- const option = document.createElement('option');
- option.value = lang;
- option.textContent = lang;
- if (lang === defaultLang) option.selected = true;
- langSelect.appendChild(option);
- });
-
- langCol.style.display = langs.length <= 1 ? 'none' : 'block';
- };
-
- const getMirrorUrl = (url: string) => {
- try {
- const u = new URL(url);
- return `https://raw.githubusercontent.com/daydreamer-json/ak-endfield-api-archive/refs/heads/main/output/raw/${u.hostname}${u.pathname}`;
- } catch {
- return url;
- }
- };
-
- const renderContent = async () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const lang = langSelect.value;
-
- if (!lang) {
- contentDiv.innerHTML = 'No language selected.
';
- return;
- }
-
- contentDiv.innerHTML = 'Loading banners...
';
-
- const url = `${BASE_URL}/akEndfield/launcher/web/${target.dirName}/banner/${lang}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- if (!data || data.length === 0) {
- contentDiv.innerHTML = 'No data found.
';
- return;
- }
-
- // Collect unique banners by ID from the entire history
- const bannerMap = new Map();
- const sortedData = [...data].sort(
- (a, b) => DateTime.fromISO(b.updatedAt).toMillis() - DateTime.fromISO(a.updatedAt).toMillis(),
- );
-
- for (const entry of sortedData) {
- if (!entry.rsp || !entry.rsp.banners) continue;
- for (const banner of entry.rsp.banners) {
- if (!bannerMap.has(banner.id)) {
- bannerMap.set(banner.id, { banner, firstSeen: entry.updatedAt });
- }
- }
- }
-
- contentDiv.innerHTML = '';
- if (bannerMap.size === 0) {
- contentDiv.innerHTML = 'No banners found.
';
- return;
- }
-
- const row = document.createElement('div');
- row.className = 'row row-cols-1 row-cols-md-3 row-cols-lg-4 g-3';
- contentDiv.appendChild(row);
-
- for (const [id, { banner, firstSeen }] of bannerMap) {
- const col = document.createElement('div');
- col.className = 'col';
-
- const dateStr = DateTime.fromISO(firstSeen).toFormat('yyyy/MM/dd HH:mm');
- const mirrorUrl = getMirrorUrl(banner.url);
- const linkUrl = banner.jump_url || mirrorUrl;
-
- col.innerHTML = `
-
-
-
-
-
- ${banner.need_token ? 'Auth ' : ''}
-
-
-
-
- ID: ${id}
- ${dateStr}
-
-
-
-
- `;
- row.appendChild(col);
- }
- } catch (e) {
- console.warn(`Failed to load ${url}`, e);
- contentDiv.innerHTML = 'Failed to load data.
';
- }
- };
-
- targetSelect.addEventListener('change', () => {
- updateLanguages();
- renderContent();
- });
- langSelect.addEventListener('change', renderContent);
-
- updateLanguages();
- renderContent();
- container.appendChild(outerCard);
-}
diff --git a/pages/src/assets/ts/renderers/webPretty/mainBgImage.ts b/pages/src/assets/ts/renderers/webPretty/mainBgImage.ts
deleted file mode 100644
index f815104..0000000
--- a/pages/src/assets/ts/renderers/webPretty/mainBgImage.ts
+++ /dev/null
@@ -1,174 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../../api.js';
-import type { LauncherWebMainBgImage, StoredData } from '../../types.js';
-import { BASE_URL, gameTargets, launcherWebApiLang } from '../../utils/constants.js';
-
-export async function renderMainBgImage(container: HTMLElement) {
- const outerCard = document.createElement('div');
- outerCard.className = 'card mb-3';
-
- const header = document.createElement('div');
- header.className = 'card-header d-flex justify-content-between align-items-center';
- header.style.cursor = 'pointer';
- header.setAttribute('data-bs-toggle', 'collapse');
- header.setAttribute('data-bs-target', '#collapseMainBgImage');
- header.setAttribute('role', 'button');
- header.innerHTML = 'Main Background Image ';
- outerCard.appendChild(header);
-
- const collapseDiv = document.createElement('div');
- collapseDiv.id = 'collapseMainBgImage';
- collapseDiv.className = 'collapse';
- outerCard.appendChild(collapseDiv);
-
- const outerCardBody = document.createElement('div');
- outerCardBody.className = 'card-body';
- collapseDiv.appendChild(outerCardBody);
-
- // --- UI Controls ---
- const controls = document.createElement('div');
- controls.className = 'row g-3 mb-4';
-
- const targetCol = document.createElement('div');
- targetCol.className = 'col-md-6';
- targetCol.innerHTML = 'Target ';
- const targetSelect = document.createElement('select');
- targetSelect.className = 'form-select';
- gameTargets.forEach((target, idx) => {
- const option = document.createElement('option');
- option.value = idx.toString();
- option.textContent = `${target.region === 'cn' ? 'China' : 'Global'} - ${target.name}`;
- targetSelect.appendChild(option);
- });
- targetCol.appendChild(targetSelect);
-
- const langCol = document.createElement('div');
- langCol.className = 'col-md-6';
- langCol.innerHTML = 'Language ';
- const langSelect = document.createElement('select');
- langSelect.className = 'form-select';
- langCol.appendChild(langSelect);
-
- controls.appendChild(targetCol);
- controls.appendChild(langCol);
- outerCardBody.appendChild(controls);
-
- const contentDiv = document.createElement('div');
- outerCardBody.appendChild(contentDiv);
-
- // --- Logic ---
- const updateLanguages = () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const langs = launcherWebApiLang[target.region] || [];
- const defaultLang = target.region === 'os' ? 'en-us' : 'zh-cn';
-
- langSelect.innerHTML = '';
- langs.forEach((lang) => {
- const option = document.createElement('option');
- option.value = lang;
- option.textContent = lang;
- if (lang === defaultLang) option.selected = true;
- langSelect.appendChild(option);
- });
-
- langCol.style.display = langs.length <= 1 ? 'none' : 'block';
- };
-
- const getMirrorUrl = (url: string) => {
- try {
- const u = new URL(url);
- return `https://raw.githubusercontent.com/daydreamer-json/ak-endfield-api-archive/refs/heads/main/output/raw/${u.hostname}${u.pathname}`;
- } catch {
- return url;
- }
- };
-
- const renderContent = async () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const lang = langSelect.value;
-
- if (!lang) {
- contentDiv.innerHTML = 'No language selected.
';
- return;
- }
-
- contentDiv.innerHTML = 'Loading background images...
';
-
- const url = `${BASE_URL}/akEndfield/launcher/web/${target.dirName}/main_bg_image/${lang}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- if (!data || data.length === 0) {
- contentDiv.innerHTML = 'No data found.
';
- return;
- }
-
- // Collect unique images by MD5 from the entire history
- const imageMap = new Map();
- const sortedData = [...data].sort(
- (a, b) => DateTime.fromISO(b.updatedAt).toMillis() - DateTime.fromISO(a.updatedAt).toMillis(),
- );
-
- for (const entry of sortedData) {
- if (!entry.rsp || !entry.rsp.main_bg_image) continue;
- const img = entry.rsp.main_bg_image;
- if (!imageMap.has(img.md5)) {
- imageMap.set(img.md5, { image: img, firstSeen: entry.updatedAt });
- }
- }
-
- contentDiv.innerHTML = '';
- if (imageMap.size === 0) {
- contentDiv.innerHTML = 'No images found.
';
- return;
- }
-
- const row = document.createElement('div');
- row.className = 'row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3';
- contentDiv.appendChild(row);
-
- for (const [md5, { image, firstSeen }] of imageMap) {
- const col = document.createElement('div');
- col.className = 'col';
-
- const dateStr = DateTime.fromISO(firstSeen).toFormat('yyyy/MM/dd HH:mm');
- const mirrorUrl = getMirrorUrl(image.url);
- const linkUrl = image.video_url ? getMirrorUrl(image.video_url) : mirrorUrl;
-
- col.innerHTML = `
-
-
-
-
-
- ${image.video_url ? 'Video ' : ''}
-
-
-
-
- ${md5}
- ${dateStr}
-
-
-
-
- `;
- row.appendChild(col);
- }
- } catch (e) {
- console.warn(`Failed to load ${url}`, e);
- contentDiv.innerHTML = 'Failed to load data.
';
- }
- };
-
- targetSelect.addEventListener('change', () => {
- updateLanguages();
- renderContent();
- });
- langSelect.addEventListener('change', renderContent);
-
- updateLanguages();
- renderContent();
- container.appendChild(outerCard);
-}
diff --git a/pages/src/assets/ts/renderers/webPretty/sidebar.ts b/pages/src/assets/ts/renderers/webPretty/sidebar.ts
deleted file mode 100644
index 81eb8c2..0000000
--- a/pages/src/assets/ts/renderers/webPretty/sidebar.ts
+++ /dev/null
@@ -1,195 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../../api.js';
-import type { LauncherWebSidebar, StoredData } from '../../types.js';
-import { BASE_URL, gameTargets, launcherWebApiLang } from '../../utils/constants.js';
-
-export async function renderSidebar(container: HTMLElement) {
- const outerCard = document.createElement('div');
- outerCard.className = 'card mb-3';
-
- const header = document.createElement('div');
- header.className = 'card-header d-flex justify-content-between align-items-center';
- header.style.cursor = 'pointer';
- header.setAttribute('data-bs-toggle', 'collapse');
- header.setAttribute('data-bs-target', '#collapseSidebar');
- header.setAttribute('role', 'button');
- header.innerHTML = 'Sidebar ';
- outerCard.appendChild(header);
-
- const collapseDiv = document.createElement('div');
- collapseDiv.id = 'collapseSidebar';
- collapseDiv.className = 'collapse';
- outerCard.appendChild(collapseDiv);
-
- const outerCardBody = document.createElement('div');
- outerCardBody.className = 'card-body';
- collapseDiv.appendChild(outerCardBody);
-
- // --- UI Controls ---
- const controls = document.createElement('div');
- controls.className = 'row g-3 mb-4';
-
- const targetCol = document.createElement('div');
- targetCol.className = 'col-md-6';
- targetCol.innerHTML = 'Target ';
- const targetSelect = document.createElement('select');
- targetSelect.className = 'form-select';
- gameTargets.forEach((target, idx) => {
- const option = document.createElement('option');
- option.value = idx.toString();
- option.textContent = `${target.region === 'cn' ? 'China' : 'Global'} - ${target.name}`;
- targetSelect.appendChild(option);
- });
- targetCol.appendChild(targetSelect);
-
- const langCol = document.createElement('div');
- langCol.className = 'col-md-6';
- langCol.innerHTML = 'Language ';
- const langSelect = document.createElement('select');
- langSelect.className = 'form-select';
- langCol.appendChild(langSelect);
-
- controls.appendChild(targetCol);
- controls.appendChild(langCol);
- outerCardBody.appendChild(controls);
-
- const contentDiv = document.createElement('div');
- outerCardBody.appendChild(contentDiv);
-
- // --- Logic ---
- const updateLanguages = () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const langs = launcherWebApiLang[target.region] || [];
- const defaultLang = target.region === 'os' ? 'en-us' : 'zh-cn';
-
- langSelect.innerHTML = '';
- langs.forEach((lang) => {
- const option = document.createElement('option');
- option.value = lang;
- option.textContent = lang;
- if (lang === defaultLang) option.selected = true;
- langSelect.appendChild(option);
- });
-
- langCol.style.display = langs.length <= 1 ? 'none' : 'block';
- };
-
- const getMirrorUrl = (url: string) => {
- try {
- const u = new URL(url);
- return `https://raw.githubusercontent.com/daydreamer-json/ak-endfield-api-archive/refs/heads/main/output/raw/${u.hostname}${u.pathname}`;
- } catch {
- return url;
- }
- };
-
- const renderContent = async () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const lang = langSelect.value;
-
- if (!lang) {
- contentDiv.innerHTML = 'No language selected.
';
- return;
- }
-
- contentDiv.innerHTML = 'Loading sidebar data...
';
-
- const url = `${BASE_URL}/akEndfield/launcher/web/${target.dirName}/sidebar/${lang}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- if (!data || data.length === 0) {
- contentDiv.innerHTML = 'No data found.
';
- return;
- }
-
- // Collect the latest sidebar configuration
- const sortedData = [...data].sort(
- (a, b) => DateTime.fromISO(b.updatedAt).toMillis() - DateTime.fromISO(a.updatedAt).toMillis(),
- );
-
- // We only show the latest version as sidebars are usually state-dependent
- const latest = sortedData[0];
- if (!latest || !latest.rsp || !latest.rsp.sidebars) {
- contentDiv.innerHTML = 'No active sidebars.
';
- return;
- }
-
- contentDiv.innerHTML = '';
- const row = document.createElement('div');
- row.className = 'row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3';
- contentDiv.appendChild(row);
-
- for (const item of latest.rsp.sidebars) {
- const col = document.createElement('div');
- col.className = 'col';
-
- const card = document.createElement('div');
- card.className = 'card h-100 shadow-sm';
-
- let innerHtml = `
-
-
-
${item.media}
- ${item.need_token ? 'Auth ' : ''}
-
- `;
-
- if (item.pic) {
- innerHtml += `
-
-
-
${item.pic.description}
-
- `;
- }
-
- if (item.jump_url) {
- innerHtml += `
-
Open Link
- `;
- }
-
- if (item.sidebar_labels && item.sidebar_labels.length > 0) {
- innerHtml += '
';
- }
-
- innerHtml += '
';
- card.innerHTML = innerHtml;
- col.appendChild(card);
- row.appendChild(col);
- }
-
- const infoDiv = document.createElement('div');
- infoDiv.className = 'text-muted small mt-3 text-end';
- infoDiv.textContent = `Last updated: ${DateTime.fromISO(latest.updatedAt).toFormat('yyyy/MM/dd HH:mm')}`;
- contentDiv.appendChild(infoDiv);
- } catch (e) {
- console.warn(`Failed to load ${url}`, e);
- contentDiv.innerHTML = 'Failed to load data.
';
- }
- };
-
- targetSelect.addEventListener('change', () => {
- updateLanguages();
- renderContent();
- });
- langSelect.addEventListener('change', renderContent);
-
- updateLanguages();
- renderContent();
- container.appendChild(outerCard);
-}
diff --git a/pages/src/assets/ts/renderers/webPretty/singleEnt.ts b/pages/src/assets/ts/renderers/webPretty/singleEnt.ts
deleted file mode 100644
index 2a49a22..0000000
--- a/pages/src/assets/ts/renderers/webPretty/singleEnt.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-import { DateTime } from 'luxon';
-import { fetchJson } from '../../api.js';
-import type { LauncherWebSingleEnt, StoredData } from '../../types.js';
-import { BASE_URL, gameTargets, launcherWebApiLang } from '../../utils/constants.js';
-
-export async function renderSingleEnt(container: HTMLElement) {
- const outerCard = document.createElement('div');
- outerCard.className = 'card mb-3';
-
- const header = document.createElement('div');
- header.className = 'card-header d-flex justify-content-between align-items-center';
- header.style.cursor = 'pointer';
- header.setAttribute('data-bs-toggle', 'collapse');
- header.setAttribute('data-bs-target', '#collapseSingleEnt');
- header.setAttribute('role', 'button');
- header.innerHTML = 'Single Ent. ';
- outerCard.appendChild(header);
-
- const collapseDiv = document.createElement('div');
- collapseDiv.id = 'collapseSingleEnt';
- collapseDiv.className = 'collapse';
- outerCard.appendChild(collapseDiv);
-
- const outerCardBody = document.createElement('div');
- outerCardBody.className = 'card-body';
- collapseDiv.appendChild(outerCardBody);
-
- // --- UI Controls ---
- const controls = document.createElement('div');
- controls.className = 'row g-3 mb-4';
-
- const targetCol = document.createElement('div');
- targetCol.className = 'col-md-6';
- targetCol.innerHTML = 'Target ';
- const targetSelect = document.createElement('select');
- targetSelect.className = 'form-select';
- gameTargets.forEach((target, idx) => {
- const option = document.createElement('option');
- option.value = idx.toString();
- option.textContent = `${target.region === 'cn' ? 'China' : 'Global'} - ${target.name}`;
- targetSelect.appendChild(option);
- });
- targetCol.appendChild(targetSelect);
-
- const langCol = document.createElement('div');
- langCol.className = 'col-md-6';
- langCol.innerHTML = 'Language ';
- const langSelect = document.createElement('select');
- langSelect.className = 'form-select';
- langCol.appendChild(langSelect);
-
- controls.appendChild(targetCol);
- controls.appendChild(langCol);
- outerCardBody.appendChild(controls);
-
- const contentDiv = document.createElement('div');
- outerCardBody.appendChild(contentDiv);
-
- // --- Logic ---
- const updateLanguages = () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const langs = launcherWebApiLang[target.region] || [];
- const defaultLang = target.region === 'os' ? 'en-us' : 'zh-cn';
-
- langSelect.innerHTML = '';
- langs.forEach((lang) => {
- const option = document.createElement('option');
- option.value = lang;
- option.textContent = lang;
- if (lang === defaultLang) option.selected = true;
- langSelect.appendChild(option);
- });
-
- langCol.style.display = langs.length <= 1 ? 'none' : 'block';
- };
-
- const getMirrorUrl = (url: string) => {
- if (!url) return '';
- try {
- const u = new URL(url);
- return `https://raw.githubusercontent.com/daydreamer-json/ak-endfield-api-archive/refs/heads/main/output/raw/${u.hostname}${u.pathname}`;
- } catch {
- return url;
- }
- };
-
- const renderContent = async () => {
- const targetIdx = parseInt(targetSelect.value, 10);
- const target = gameTargets[targetIdx]!;
- const lang = langSelect.value;
-
- if (!lang) {
- contentDiv.innerHTML = 'No language selected.
';
- return;
- }
-
- contentDiv.innerHTML = 'Loading single entry data...
';
-
- const url = `${BASE_URL}/akEndfield/launcher/web/${target.dirName}/single_ent/${lang}/all.json`;
- try {
- const data = await fetchJson[]>(url);
- if (!data || data.length === 0) {
- contentDiv.innerHTML = 'No data found.
';
- return;
- }
-
- // Collect unique visuals by MD5 from the entire history
- const entMap = new Map();
- const sortedData = [...data].sort(
- (a, b) => DateTime.fromISO(b.updatedAt).toMillis() - DateTime.fromISO(a.updatedAt).toMillis(),
- );
-
- for (const entry of sortedData) {
- if (!entry.rsp || !entry.rsp.single_ent) continue;
- const ent = entry.rsp.single_ent;
- const key = ent.version_md5 || ent.version_url;
- if (!entMap.has(key)) {
- entMap.set(key, { ent, firstSeen: entry.updatedAt });
- }
- }
-
- contentDiv.innerHTML = '';
- if (entMap.size === 0) {
- contentDiv.innerHTML = 'No data found.
';
- return;
- }
-
- const row = document.createElement('div');
- row.className = 'row row-cols-1 row-cols-md-2 g-4';
- contentDiv.appendChild(row);
-
- for (const [_key, { ent, firstSeen }] of entMap) {
- const col = document.createElement('div');
- col.className = 'col';
-
- const card = document.createElement('div');
- card.className = 'card h-100 shadow-sm';
-
- let innerHtml = `
-
-
- First seen: ${DateTime.fromISO(firstSeen).toFormat('yyyy/MM/dd HH:mm')}
- ${ent.need_token ? 'Auth ' : ''}
-
-
-
Version Image
-
-
-
-
MD5: ${ent.version_md5}
-
- `;
-
- if (ent.button_url) {
- innerHtml += `
-
-
Action Button
-
-
-
-
Normal
-
- ${
- ent.button_hover_url
- ? `
-
-
-
Hover
-
- `
- : ''
- }
-
-
- `;
- }
-
- if (ent.jump_url) {
- innerHtml += `
-
Jump URL
- `;
- }
-
- innerHtml += '
';
- card.innerHTML = innerHtml;
- col.appendChild(card);
- row.appendChild(col);
- }
- } catch (e) {
- console.warn(`Failed to load ${url}`, e);
- contentDiv.innerHTML = 'Failed to load data.
';
- }
- };
-
- targetSelect.addEventListener('change', () => {
- updateLanguages();
- renderContent();
- });
- langSelect.addEventListener('change', renderContent);
-
- updateLanguages();
- renderContent();
- container.appendChild(outerCard);
-}
diff --git a/pages/src/assets/ts/types.ts b/pages/src/assets/ts/types.ts
deleted file mode 100644
index eafb940..0000000
--- a/pages/src/assets/ts/types.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-export interface MirrorFileEntry {
- orig: string;
- mirror: string;
- origStatus: boolean;
-}
-
-export interface StoredData {
- req: any;
- rsp: T;
- updatedAt: string;
-}
-
-export interface LauncherWebAnnouncement {
- data_version: string;
- tabs: {
- tabName: string;
- announcements: {
- content: string;
- jump_url: string;
- start_ts: string;
- id: string;
- need_token: boolean;
- }[];
- tab_id: string;
- }[];
-}
-
-export interface LauncherWebBanner {
- data_version: string;
- banners: {
- url: string;
- md5: string;
- jump_url: string;
- id: string;
- need_token: boolean;
- }[];
-}
-
-export interface LauncherWebMainBgImage {
- data_version: string;
- main_bg_image: {
- url: string;
- md5: string;
- video_url: string;
- };
-}
-
-export interface LauncherWebSingleEnt {
- single_ent: {
- version_url: string;
- version_md5: string;
- jump_url: string;
- button_url: string;
- button_md5: string;
- button_hover_url: string;
- button_hover_md5: string;
- need_token: boolean;
- };
-}
-
-export interface LauncherWebSidebar {
- data_version: string;
- sidebars: {
- display_type: 'DisplayType_RESERVE';
- media: string;
- pic: { url: string; md5: string; description: string } | null;
- sidebar_labels: { content: string; jump_url: string; need_token: boolean }[];
- grid_info: null;
- jump_url: string;
- need_token: boolean;
- }[];
-}
diff --git a/pages/src/assets/ts/utils/constants.ts b/pages/src/assets/ts/utils/constants.ts
deleted file mode 100644
index 7f177e9..0000000
--- a/pages/src/assets/ts/utils/constants.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-export const BASE_URL =
- 'https://raw.githubusercontent.com/daydreamer-json/ak-endfield-api-archive/refs/heads/main/output';
-
-export const FILE_SIZE_OPTS = {
- decimals: 2,
- decimalPadding: true,
- useBinaryUnit: true,
- useBitUnit: false,
- unitVisible: true,
- unit: null,
-};
-
-export const gameTargets = [
- { name: 'Official', region: 'os' as const, dirName: '6', channel: 6 },
- { name: 'Epic', region: 'os' as const, dirName: '801', channel: 6 },
- { name: 'Google Play', region: 'os' as const, dirName: '802', channel: 6 },
- { name: 'Official', region: 'cn' as const, dirName: '1', channel: 1 },
- { name: 'Bilibili', region: 'cn' as const, dirName: '2', channel: 2 },
-];
-
-export const launcherTargets = [
- { id: 'os', apps: ['EndField', 'Official'], channel: 6 },
- { id: 'cn', apps: ['EndField', 'Arknights', 'Official'], channel: 1 },
-];
-
-export const launcherWebApiLang = {
- os: [
- 'de-de',
- 'en-us',
- 'es-mx',
- 'fr-fr',
- 'id-id',
- 'it-it',
- 'ja-jp',
- 'ko-kr',
- 'pt-br',
- 'ru-ru',
- 'th-th',
- 'vi-vn',
- 'zh-cn',
- 'zh-tw',
- ] as const,
- cn: ['zh-cn'] as const,
-};
diff --git a/pages/src/assets/ts/utils/logger.ts b/pages/src/assets/ts/utils/logger.ts
deleted file mode 100644
index 58e1f45..0000000
--- a/pages/src/assets/ts/utils/logger.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { DateTime } from 'luxon';
-
-export default {
- write(message: string) {
- const debugLogElement = document.querySelector('#debug-log code');
- if (!debugLogElement) return;
- const prettyMessage = `${DateTime.now().toFormat('HH:mm:ss.SSS')} > ${message}`;
- const divEl = document.createElement('div');
- divEl.textContent = prettyMessage;
- debugLogElement.appendChild(divEl);
- },
-};
diff --git a/pages/src/assets/ts/utils/math.ts b/pages/src/assets/ts/utils/math.ts
deleted file mode 100644
index 2613df0..0000000
--- a/pages/src/assets/ts/utils/math.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-import logger from './logger.js';
-
-export default {
- arrayMax(array: Array) {
- return array.reduce((a, b) => Math.max(a, b));
- },
-
- arrayMin(array: Array) {
- return array.reduce((a, b) => Math.min(a, b));
- },
-
- arrayTotal(array: Array) {
- return array.reduce((acc, f) => acc + f, 0);
- },
-
- arrayAvg(array: Array) {
- return this.arrayTotal(array) / array.length;
- },
-
- rounder(method: 'floor' | 'ceil' | 'round', num: number, n: number) {
- const pow = Math.pow(10, n);
- let result: number;
- switch (method) {
- case 'floor':
- result = Math.floor(num * pow) / pow;
- break;
- case 'ceil':
- result = Math.ceil(num * pow) / pow;
- break;
- case 'round':
- result = Math.round(num * pow) / pow;
- break;
- }
- return {
- orig: result,
- padded: result.toFixed(n),
- };
- },
-
- formatFileSize(
- bytes: number,
- options: {
- decimals: number;
- decimalPadding: boolean;
- useBinaryUnit: boolean;
- useBitUnit: boolean;
- unitVisible: boolean;
- unit: 'B' | 'K' | 'M' | 'G' | 'T' | 'P' | 'E' | 'Z' | 'Y' | null;
- },
- ) {
- const k = options.useBinaryUnit ? 1024 : 1000;
- const dm = options.decimals < 0 ? 0 : options.decimals;
-
- const baseUnits = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
- const binaryUnitSuffix = options.useBitUnit ? 'ib' : 'iB';
- const siUnitSuffix = options.useBitUnit ? 'b' : 'B';
-
- const getUnitString = (i: number) => {
- if (i === 0) return options.useBitUnit ? 'b' : 'B';
- return baseUnits[i] + (options.useBinaryUnit ? binaryUnitSuffix : siUnitSuffix);
- };
-
- let value = bytes < 0 ? 0 : Math.floor(bytes);
- if (options.useBitUnit) {
- value *= 8;
- }
-
- let i: number;
- if (options.unit !== null) {
- i = baseUnits.indexOf(options.unit);
- if (i === -1) throw new Error(`Invalid unit: ${options.unit}`);
- } else {
- if (value === 0) {
- i = 0;
- } else {
- i = Math.floor(Math.log(value) / Math.log(k));
- i = Math.max(0, Math.min(baseUnits.length - 1, i)); // clamp
- }
- }
-
- const resultValue = value / Math.pow(k, i);
-
- let formattedValue: string;
- if (options.decimalPadding) {
- formattedValue = resultValue.toFixed(dm);
- } else {
- formattedValue = resultValue.toFixed(dm).replace(/\.?0+$/, '');
- }
-
- return formattedValue + (options.unitVisible ? ' ' + getUnitString(i) : '');
- },
-
- secureRandomFloatInRange(min: number, max: number): number {
- if (min > max) [min, max] = [max, min];
- const crypto = globalThis.crypto;
- if (!crypto) {
- throw new Error('Cryptographically secure random float number gen is not available');
- }
- const randomValues = new Uint32Array(2);
- crypto.getRandomValues(randomValues);
- const highBits = randomValues[1]! & 0x1fffff; // 0x1FFFFF = 2^21 - 1
- const lowBits = randomValues[0];
- const combined = highBits * 0x100000000 + lowBits!; // 0x100000000 = 2^32
- const randomFraction = combined / 0x20000000000000; // 0x20000000000000 = 2^53
- return randomFraction * (max - min) + min;
- },
-
- secureRandomIntInRange(min: number, max: number, writeLog: boolean = false): number {
- if (min === max) {
- writeLog ? logger.write(`randomInt: Range=${min}-${max}, Output=${min}`) : undefined;
- return min;
- }
- if (min > max) [min, max] = [max, min];
- const crypto = globalThis.crypto;
- if (!crypto) {
- throw new Error('Cryptographically secure random int number gen is not available');
- }
-
- // convert to integer anyway
- const minInt = Math.ceil(min);
- const maxInt = Math.floor(max);
-
- // safe integer check
- if (!Number.isSafeInteger(minInt) || !Number.isSafeInteger(maxInt)) {
- throw new Error('Range boundaries must be within safe integer limits');
- }
-
- // valid range check
- if (minInt > maxInt) {
- throw new Error('Invalid range after integer conversion: min > max');
- }
-
- const range = maxInt - minInt + 1;
-
- if (range <= 0 || range > Number.MAX_SAFE_INTEGER) {
- throw new Error(`Range size must be between 1 and ${Number.MAX_SAFE_INTEGER} inclusive`);
- }
-
- // 53-bit random num gen
- const MAX_53 = BigInt(1) << BigInt(53); // 2^53
- const rangeBigInt = BigInt(range);
- const maxAcceptable = MAX_53 - (MAX_53 % rangeBigInt);
-
- // generate
- const randomBuffer = new Uint32Array(2);
- while (true) {
- crypto.getRandomValues(randomBuffer);
- const highBits = randomBuffer[1]! & 0x1fffff; // use lower 21-bit only
- const lowBits = randomBuffer[0];
- const combined = BigInt(highBits) * BigInt(0x100000000) + BigInt(lowBits!); // 0x100000000 = 2^32
- // accept condition: combined < maxAcceptable
- if (combined < maxAcceptable) {
- const offset = Number(combined % rangeBigInt); // 0 to range-1
- writeLog
- ? logger.write(
- `randomInt: Range=${min}-${max}, Raw=0x${new Uint8Array(randomBuffer).toHex()}, Output=${minInt + offset}`,
- )
- : undefined;
- return minInt + offset;
- }
- }
- },
-};
diff --git a/pages/src/assets/ts/utils/ui.ts b/pages/src/assets/ts/utils/ui.ts
deleted file mode 100644
index 9772812..0000000
--- a/pages/src/assets/ts/utils/ui.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import type { MirrorFileEntry } from '../types.js';
-
-export function generateDownloadLinks(url: string, mirrorFileDb: MirrorFileEntry[]) {
- const cleanUrl = new URL(url);
- cleanUrl.search = '';
- const mirrorEntry = mirrorFileDb.find((g) => g.orig.includes(cleanUrl.toString()));
-
- const links: string[] = [];
- if (!mirrorEntry || mirrorEntry.origStatus === true) {
- links.push(`Orig `);
- }
- if (mirrorEntry) {
- links.push(`Mirror `);
- }
- return links.join(' / ');
-}
diff --git a/pages/src/designTest.html b/pages/src/designTest.html
deleted file mode 100644
index 5feb8d7..0000000
--- a/pages/src/designTest.html
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
-
- Arknights: Endfield API Archive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Arknights: Endfield Font Design Test
-
-
- 武陵 四号谷地
- トリアンゲロス
-
- //リソース整合性を確認中… (77.42%)
-
- 2560×1440 Fullscreen
-
-
- The quick brown fox jumps over the lazy dog. 1234567890
-
- English alphabet: HarmonyOS Sans by Huawei Technologies
- Number (120% size): Novecento Sans Wide by Synthview Type Design
- Japanese glyph: Noto Sans JP by Adobe and Google
-
-
-
-
- CSS Priority:
- EN: "Novecento Sans Wide (Number Only)", "HarmonyOS Sans", "Noto Sans
- SC" JP: "Novecento Sans Wide (Number Only)", "Noto Sans JP"
-
-
-
-
-
- Open Debug Log
-
- (C) daydreamer-json
-
-
-
-
-
-
-
diff --git a/pages/src/index.html b/pages/src/index.html
deleted file mode 100644
index 3a2c494..0000000
--- a/pages/src/index.html
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
-
- Arknights: Endfield API Archive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Arknights: Endfield API Archive
-
-
-
-
-
-
- Open Debug Log
-
-
- (C) daydreamer-json and contributors
-
-
-
-
-
-
-
-
diff --git a/pages/tsconfig.json b/pages/tsconfig.json
deleted file mode 100644
index 10a63f3..0000000
--- a/pages/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": [
- // "@tsconfig/bun",
- "@tsconfig/recommended",
- "@tsconfig/node24",
- "@tsconfig/strictest"
- ],
- "compilerOptions": {
- // Environment setup & latest features
- "lib": ["ESNext", "DOM"]
- // "target": "ESNext"
- },
- "include": ["src/**/*"],
- "exclude": ["node_modules"]
-}
\ No newline at end of file