[Scummvm-git-logs] scummvm-web master -> 268f08ffd3528d98deb620c36858dcc02e7b8e2d

lephilousophe noreply at scummvm.org
Fri Dec 26 21:07:44 UTC 2025


This automated email contains information about 11 new commits which have been
pushed to the 'scummvm-web' repo located at https://api.github.com/repos/scummvm/scummvm-web .

Summary:
9a44c490e9 DUMPER-COMPANION: Really migrate ESLint config
995713c81f DUMPER-COMPANION: Move away from ESLint deprecated semi rule
2ce0c74867 DUMPER-COMPANION: Enforce indentation
6d58a8ade5 DUMPER-COMPANION: Remove useless rules
2af2c1b94f DUMPER-COMPANION: Transform components into functions
9c14ac1f01 DUMPER-COMPANION: Various stylistic fixes
9582f7ed0e DUMPER-COMPANION: Add typing for struct module
79f7201888 DUMPER-COMPANION: More typing fixes
1566f937ad DUMPER-COMPANION: Enable more linting
ef72913077 DUMPER-COMPANION: Add preact linting
268f08ffd3 WEB: Run npm install


Commit: 9a44c490e9e826078e47e542471011e55aa03599
    https://github.com/scummvm/scummvm-web/commit/9a44c490e9e826078e47e542471011e55aa03599
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: Really migrate ESLint config

Remove obsolete eslintrc dependency and simplify typescript one.
The new configuration file should be equivalent to the old one.

Changed paths:
    dumper-companion/eslint.config.mjs
    dumper-companion/package-lock.json
    dumper-companion/package.json


diff --git a/dumper-companion/eslint.config.mjs b/dumper-companion/eslint.config.mjs
index bfde0b2c..33273dcd 100644
--- a/dumper-companion/eslint.config.mjs
+++ b/dumper-companion/eslint.config.mjs
@@ -1,58 +1,55 @@
+import eslint from '@eslint/js';
 import globals from "globals";
-import typescriptEslint from "@typescript-eslint/eslint-plugin";
-import tsParser from "@typescript-eslint/parser";
-import path from "node:path";
-import { fileURLToPath } from "node:url";
-import js from "@eslint/js";
-import { FlatCompat } from "@eslint/eslintrc";
-
-const __filename = fileURLToPath(import.meta.url);
-const __dirname = path.dirname(__filename);
-const compat = new FlatCompat({
-    baseDirectory: __dirname,
-    recommendedConfig: js.configs.recommended,
-    allConfig: js.configs.all
-});
-
-export default [{
-    ignores: ["node_modules", "index.js"],
-}, ...compat.extends("eslint:recommended"), {
-    languageOptions: {
-        globals: {
-            ...globals.browser,
-            ...globals.node,
+import { defineConfig } from 'eslint/config';
+import tseslint from 'typescript-eslint';
+
+export default defineConfig(
+    eslint.configs.recommended,
+    {
+        name: "global ignores",
+        ignores: ["node_modules", "index.js"],
+    },
+    {
+	name: "global settings",
+        languageOptions: {
+            ecmaVersion: "latest",
+            sourceType: "module",
         },
 
-        ecmaVersion: "latest",
-        sourceType: "module",
+        rules: {
+            "no-constant-condition": "off",
+            "no-sparse-arrays": "off",
+        },
     },
-
-    rules: {
-        "no-constant-condition": "off",
-        "no-sparse-arrays": "off",
+    {
+	name: "webpack specific",
+        files: ["webpack.config.js"],
+        languageOptions: {
+            globals: {
+                ...globals.node,
+            },
+        },
     },
-}, ...compat.extends(
-    "plugin:@typescript-eslint/eslint-recommended",
-    "plugin:@typescript-eslint/recommended",
-).map(config => ({
-    ...config,
-    files: ["**/*.ts", "**/*.tsx"],
-})), {
-    files: ["**/*.ts", "**/*.tsx"],
-
-    plugins: {
-        "@typescript-eslint": typescriptEslint,
+    {
+	name: "browser specific",
+        files: ["src/**"],
+        languageOptions: {
+            globals: {
+                ...globals.browser,
+            },
+        },
     },
+    {
+	name: "typescript specific",
+        files: ["**/*.ts", "**/*.tsx"],
 
-    languageOptions: {
-        parser: tsParser,
-    },
+	extends: [tseslint.configs.recommended],
 
-    rules: {
-	"@typescript-eslint/no-empty-object-type": "off",
-	"@typescript-eslint/no-unsafe-function-type": "error",
-	"@typescript-eslint/no-wrapper-object-types": "error",
+        rules: {
+            "@typescript-eslint/no-empty-object-type": "off",
+            "@typescript-eslint/no-unsafe-function-type": "error",
+            "@typescript-eslint/no-wrapper-object-types": "error",
 
-        semi: [2, "always"],
-    },
-}];
+            semi: [2, "always"],
+        },
+     });
diff --git a/dumper-companion/package-lock.json b/dumper-companion/package-lock.json
index 35b1a897..9c92a9d4 100644
--- a/dumper-companion/package-lock.json
+++ b/dumper-companion/package-lock.json
@@ -16,12 +16,10 @@
         "webpack-cli": "^6.0.1"
       },
       "devDependencies": {
-        "@eslint/eslintrc": "^3.3.3",
         "@eslint/js": "^9.39.1",
-        "@typescript-eslint/eslint-plugin": "^8.49.0",
-        "@typescript-eslint/parser": "^8.49.0",
         "eslint": "^9.39.1",
-        "globals": "^16.5.0"
+        "globals": "^16.5.0",
+        "typescript-eslint": "^8.50.0"
       }
     },
     "node_modules/@discoveryjs/json-ext": {
@@ -316,17 +314,17 @@
       }
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.49.0.tgz",
-      "integrity": "sha512-JXij0vzIaTtCwu6SxTh8qBc66kmf1xs7pI4UOiMDFVct6q86G0Zs7KRcEoJgY3Cav3x5Tq0MF5jwgpgLqgKG3A==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.1.tgz",
+      "integrity": "sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "8.49.0",
-        "@typescript-eslint/type-utils": "8.49.0",
-        "@typescript-eslint/utils": "8.49.0",
-        "@typescript-eslint/visitor-keys": "8.49.0",
+        "@typescript-eslint/scope-manager": "8.50.1",
+        "@typescript-eslint/type-utils": "8.50.1",
+        "@typescript-eslint/utils": "8.50.1",
+        "@typescript-eslint/visitor-keys": "8.50.1",
         "ignore": "^7.0.0",
         "natural-compare": "^1.4.0",
         "ts-api-utils": "^2.1.0"
@@ -339,7 +337,7 @@
         "url": "https://opencollective.com/typescript-eslint"
       },
       "peerDependencies": {
-        "@typescript-eslint/parser": "^8.49.0",
+        "@typescript-eslint/parser": "^8.50.1",
         "eslint": "^8.57.0 || ^9.0.0",
         "typescript": ">=4.8.4 <6.0.0"
       }
@@ -355,17 +353,16 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.49.0.tgz",
-      "integrity": "sha512-N9lBGA9o9aqb1hVMc9hzySbhKibHmB+N3IpoShyV6HyQYRGIhlrO5rQgttypi+yEeKsKI4idxC8Jw6gXKD4THA==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.1.tgz",
+      "integrity": "sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==",
       "dev": true,
       "license": "MIT",
-      "peer": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "8.49.0",
-        "@typescript-eslint/types": "8.49.0",
-        "@typescript-eslint/typescript-estree": "8.49.0",
-        "@typescript-eslint/visitor-keys": "8.49.0",
+        "@typescript-eslint/scope-manager": "8.50.1",
+        "@typescript-eslint/types": "8.50.1",
+        "@typescript-eslint/typescript-estree": "8.50.1",
+        "@typescript-eslint/visitor-keys": "8.50.1",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -381,14 +378,14 @@
       }
     },
     "node_modules/@typescript-eslint/project-service": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.49.0.tgz",
-      "integrity": "sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.1.tgz",
+      "integrity": "sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/tsconfig-utils": "^8.49.0",
-        "@typescript-eslint/types": "^8.49.0",
+        "@typescript-eslint/tsconfig-utils": "^8.50.1",
+        "@typescript-eslint/types": "^8.50.1",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -403,14 +400,14 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.49.0.tgz",
-      "integrity": "sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.1.tgz",
+      "integrity": "sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.49.0",
-        "@typescript-eslint/visitor-keys": "8.49.0"
+        "@typescript-eslint/types": "8.50.1",
+        "@typescript-eslint/visitor-keys": "8.50.1"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -421,9 +418,9 @@
       }
     },
     "node_modules/@typescript-eslint/tsconfig-utils": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.49.0.tgz",
-      "integrity": "sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.1.tgz",
+      "integrity": "sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -438,15 +435,15 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.49.0.tgz",
-      "integrity": "sha512-KTExJfQ+svY8I10P4HdxKzWsvtVnsuCifU5MvXrRwoP2KOlNZ9ADNEWWsQTJgMxLzS5VLQKDjkCT/YzgsnqmZg==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.1.tgz",
+      "integrity": "sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.49.0",
-        "@typescript-eslint/typescript-estree": "8.49.0",
-        "@typescript-eslint/utils": "8.49.0",
+        "@typescript-eslint/types": "8.50.1",
+        "@typescript-eslint/typescript-estree": "8.50.1",
+        "@typescript-eslint/utils": "8.50.1",
         "debug": "^4.3.4",
         "ts-api-utils": "^2.1.0"
       },
@@ -463,9 +460,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz",
-      "integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.1.tgz",
+      "integrity": "sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -477,16 +474,16 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.49.0.tgz",
-      "integrity": "sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.1.tgz",
+      "integrity": "sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/project-service": "8.49.0",
-        "@typescript-eslint/tsconfig-utils": "8.49.0",
-        "@typescript-eslint/types": "8.49.0",
-        "@typescript-eslint/visitor-keys": "8.49.0",
+        "@typescript-eslint/project-service": "8.50.1",
+        "@typescript-eslint/tsconfig-utils": "8.50.1",
+        "@typescript-eslint/types": "8.50.1",
+        "@typescript-eslint/visitor-keys": "8.50.1",
         "debug": "^4.3.4",
         "minimatch": "^9.0.4",
         "semver": "^7.6.0",
@@ -531,16 +528,16 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.49.0.tgz",
-      "integrity": "sha512-N3W7rJw7Rw+z1tRsHZbK395TWSYvufBXumYtEGzypgMUthlg0/hmCImeA8hgO2d2G4pd7ftpxxul2J8OdtdaFA==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.1.tgz",
+      "integrity": "sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.7.0",
-        "@typescript-eslint/scope-manager": "8.49.0",
-        "@typescript-eslint/types": "8.49.0",
-        "@typescript-eslint/typescript-estree": "8.49.0"
+        "@typescript-eslint/scope-manager": "8.50.1",
+        "@typescript-eslint/types": "8.50.1",
+        "@typescript-eslint/typescript-estree": "8.50.1"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -555,13 +552,13 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.49.0.tgz",
-      "integrity": "sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==",
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.1.tgz",
+      "integrity": "sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.49.0",
+        "@typescript-eslint/types": "8.50.1",
         "eslint-visitor-keys": "^4.2.1"
       },
       "engines": {
@@ -803,7 +800,6 @@
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
       "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
       "license": "MIT",
-      "peer": true,
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -969,7 +965,6 @@
         }
       ],
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "baseline-browser-mapping": "^2.9.0",
         "caniuse-lite": "^1.0.30001759",
@@ -1200,7 +1195,6 @@
       "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
       "dev": true,
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.8.0",
         "@eslint-community/regexpp": "^4.12.1",
@@ -2061,7 +2055,6 @@
       "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
       "dev": true,
       "license": "MIT",
-      "peer": true,
       "engines": {
         "node": ">=12"
       },
@@ -2287,7 +2280,6 @@
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
       "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "fast-deep-equal": "^3.1.3",
         "fast-uri": "^3.0.1",
@@ -2590,6 +2582,30 @@
         "node": ">=14.17"
       }
     },
+    "node_modules/typescript-eslint": {
+      "version": "8.50.1",
+      "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.50.1.tgz",
+      "integrity": "sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@typescript-eslint/eslint-plugin": "8.50.1",
+        "@typescript-eslint/parser": "8.50.1",
+        "@typescript-eslint/typescript-estree": "8.50.1",
+        "@typescript-eslint/utils": "8.50.1"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0",
+        "typescript": ">=4.8.4 <6.0.0"
+      }
+    },
     "node_modules/undici-types": {
       "version": "7.16.0",
       "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
@@ -2654,7 +2670,6 @@
       "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz",
       "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@types/eslint-scope": "^3.7.7",
         "@types/estree": "^1.0.8",
@@ -2703,7 +2718,6 @@
       "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz",
       "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@discoveryjs/json-ext": "^0.6.1",
         "@webpack-cli/configtest": "^3.0.1",
diff --git a/dumper-companion/package.json b/dumper-companion/package.json
index 96cfbc95..87c8d0e0 100644
--- a/dumper-companion/package.json
+++ b/dumper-companion/package.json
@@ -7,12 +7,10 @@
     "lint": "eslint ."
   },
   "devDependencies": {
-    "@eslint/eslintrc": "^3.3.3",
     "@eslint/js": "^9.39.1",
-    "@typescript-eslint/eslint-plugin": "^8.49.0",
-    "@typescript-eslint/parser": "^8.49.0",
     "eslint": "^9.39.1",
-    "globals": "^16.5.0"
+    "globals": "^16.5.0",
+    "typescript-eslint": "^8.50.0"
   },
   "dependencies": {
     "@zip.js/zip.js": "^2.8.11",


Commit: 995713c81f1771123cb1b061d52ba6b32d11b14d
    https://github.com/scummvm/scummvm-web/commit/995713c81f1771123cb1b061d52ba6b32d11b14d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: Move away from ESLint deprecated semi rule

Stylistic rules are now provided by a plugin.
Also apply to all files.

Changed paths:
    dumper-companion/eslint.config.mjs
    dumper-companion/package-lock.json
    dumper-companion/package.json
    dumper-companion/src/struct.js


diff --git a/dumper-companion/eslint.config.mjs b/dumper-companion/eslint.config.mjs
index 33273dcd..a662af15 100644
--- a/dumper-companion/eslint.config.mjs
+++ b/dumper-companion/eslint.config.mjs
@@ -1,6 +1,7 @@
 import eslint from '@eslint/js';
 import globals from "globals";
 import { defineConfig } from 'eslint/config';
+import stylistic from '@stylistic/eslint-plugin';
 import tseslint from 'typescript-eslint';
 
 export default defineConfig(
@@ -16,9 +17,14 @@ export default defineConfig(
             sourceType: "module",
         },
 
+        plugins: {
+            "@stylistic": stylistic,
+        },
+
         rules: {
             "no-constant-condition": "off",
             "no-sparse-arrays": "off",
+            "@stylistic/semi": ["error", "always"],
         },
     },
     {
@@ -49,7 +55,5 @@ export default defineConfig(
             "@typescript-eslint/no-empty-object-type": "off",
             "@typescript-eslint/no-unsafe-function-type": "error",
             "@typescript-eslint/no-wrapper-object-types": "error",
-
-            semi: [2, "always"],
         },
      });
diff --git a/dumper-companion/package-lock.json b/dumper-companion/package-lock.json
index 9c92a9d4..4e3726f7 100644
--- a/dumper-companion/package-lock.json
+++ b/dumper-companion/package-lock.json
@@ -17,6 +17,7 @@
       },
       "devDependencies": {
         "@eslint/js": "^9.39.1",
+        "@stylistic/eslint-plugin": "^5.6.1",
         "eslint": "^9.39.1",
         "globals": "^16.5.0",
         "typescript-eslint": "^8.50.0"
@@ -272,6 +273,40 @@
         "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
+    "node_modules/@stylistic/eslint-plugin": {
+      "version": "5.6.1",
+      "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.6.1.tgz",
+      "integrity": "sha512-JCs+MqoXfXrRPGbGmho/zGS/jMcn3ieKl/A8YImqib76C8kjgZwq5uUFzc30lJkMvcchuRn6/v8IApLxli3Jyw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.9.0",
+        "@typescript-eslint/types": "^8.47.0",
+        "eslint-visitor-keys": "^4.2.1",
+        "espree": "^10.4.0",
+        "estraverse": "^5.3.0",
+        "picomatch": "^4.0.3"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "peerDependencies": {
+        "eslint": ">=9.0.0"
+      }
+    },
+    "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+      "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
     "node_modules/@types/eslint": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
diff --git a/dumper-companion/package.json b/dumper-companion/package.json
index 87c8d0e0..c2a3b5c2 100644
--- a/dumper-companion/package.json
+++ b/dumper-companion/package.json
@@ -8,6 +8,7 @@
   },
   "devDependencies": {
     "@eslint/js": "^9.39.1",
+    "@stylistic/eslint-plugin": "^5.6.1",
     "eslint": "^9.39.1",
     "globals": "^16.5.0",
     "typescript-eslint": "^8.50.0"
diff --git a/dumper-companion/src/struct.js b/dumper-companion/src/struct.js
index 28cf8397..70b8fe18 100644
--- a/dumper-companion/src/struct.js
+++ b/dumper-companion/src/struct.js
@@ -27,12 +27,12 @@
  */
 
 
-const rechk = /^([<>])?(([1-9]\d*)?([xcbB?hHiIlLfdsp]))*$/
-const refmt = /([1-9]\d*)?([xcbB?hHiIlLfdsp])/g
-const str = (v,o,c) => new Uint8Array(v.buffer, v.byteOffset + o, c)
-const rts = (v,o,c,s) => new Uint8Array(v.buffer, v.byteOffset + o, c).set(s)
-const pst = (v,o,c) => str(v, o + 1, Math.min(v.getUint8(o), c - 1))
-const tsp = (v,o,c,s) => { v.setUint8(o, s.length); rts(v, o + 1, c - 1, s) }
+const rechk = /^([<>])?(([1-9]\d*)?([xcbB?hHiIlLfdsp]))*$/;
+const refmt = /([1-9]\d*)?([xcbB?hHiIlLfdsp])/g;
+const str = (v,o,c) => new Uint8Array(v.buffer, v.byteOffset + o, c);
+const rts = (v,o,c,s) => new Uint8Array(v.buffer, v.byteOffset + o, c).set(s);
+const pst = (v,o,c) => str(v, o + 1, Math.min(v.getUint8(o), c - 1));
+const tsp = (v,o,c,s) => { v.setUint8(o, s.length); rts(v, o + 1, c - 1, s); };
 const lut = le => ({
     x: c=>[1,c,0],
     c: c=>[c,1,o=>({u:v=>str(v, o, 1)      , p:(v,c)=>rts(v, o, 1, c)     })],
@@ -49,42 +49,42 @@ const lut = le => ({
     d: c=>[c,8,o=>({u:v=>v.getFloat64(o,le), p:(v,d)=>v.setFloat64(o,d,le)})],
     s: c=>[1,c,o=>({u:v=>str(v,o,c), p:(v,s)=>rts(v,o,c,s.slice(0,c    ) )})],
     p: c=>[1,c,o=>({u:v=>pst(v,o,c), p:(v,s)=>tsp(v,o,c,s.slice(0,c - 1) )})]
-})
-const errbuf = new RangeError("Structure larger than remaining buffer")
-const errval = new RangeError("Not enough values for structure")
+});
+const errbuf = new RangeError("Structure larger than remaining buffer");
+const errval = new RangeError("Not enough values for structure");
 export default function struct(format) {
-    let fns = [], size = 0, m = rechk.exec(format)
-    if (!m) { throw new RangeError("Invalid format string") }
-    const t = lut('<' === m[1]), lu = (n, c) => t[c](n ? parseInt(n, 10) : 1)
+    let fns = [], size = 0, m = rechk.exec(format);
+    if (!m) { throw new RangeError("Invalid format string"); }
+    const t = lut('<' === m[1]), lu = (n, c) => t[c](n ? parseInt(n, 10) : 1);
     while ((m = refmt.exec(format))) { ((r, s, f) => {
-        for (let i = 0; i < r; ++i, size += s) { if (f) {fns.push(f(size))} }
-    })(...lu(...m.slice(1)))}
+        for (let i = 0; i < r; ++i, size += s) { if (f) {fns.push(f(size));} }
+    })(...lu(...m.slice(1)));};
     const unpack_from = (arr, offs) => {
-        if (arr.byteLength < (offs|0) + size) { throw errbuf }
-        let v = new DataView(arr.buffer, arr.byteOffset + (offs|0))
-        return fns.map(f => f.u(v))
-    }
+        if (arr.byteLength < (offs|0) + size) { throw errbuf; }
+        let v = new DataView(arr.buffer, arr.byteOffset + (offs|0));
+        return fns.map(f => f.u(v));
+    };
     const pack_into = (arrb, offs, ...values) => {
-        if (values.length < fns.length) { throw errval }
-        if (arrb.byteLength < offs + size) { throw errbuf }
-        const v = new DataView(arrb, offs)
-        new Uint8Array(arrb, offs, size).fill(0)
-        fns.forEach((f, i) => f.p(v, values[i]))
-    }
+        if (values.length < fns.length) { throw errval; }
+        if (arrb.byteLength < offs + size) { throw errbuf; }
+        const v = new DataView(arrb, offs);
+        new Uint8Array(arrb, offs, size).fill(0);
+        fns.forEach((f, i) => f.p(v, values[i]));
+    };
     const pack = (...values) => {
-        let b = new ArrayBuffer(size)
-        pack_into(b, 0, ...values)
-        return new Uint8Array(b)
-    }
-    const unpack = arr => unpack_from(arr, 0)
+        let b = new ArrayBuffer(size);
+        pack_into(b, 0, ...values);
+        return new Uint8Array(b);
+    };
+    const unpack = arr => unpack_from(arr, 0);
     function* iter_unpack(arrb) {
         for (let offs = 0; offs + size <= arrb.byteLength; offs += size) {
             yield unpack_from(arrb, offs);
         }
-    }
+    };
     return Object.freeze({
-        unpack, pack, unpack_from, pack_into, iter_unpack, format, size})
-}
+        unpack, pack, unpack_from, pack_into, iter_unpack, format, size});
+};
 /*
 const pack = (format, ...values) => struct(format).pack(...values)
 const unpack = (format, buffer) => struct(format).unpack(buffer)


Commit: 2ce0c748679d647821d2a5dcbf25dd2a3cf747f0
    https://github.com/scummvm/scummvm-web/commit/2ce0c748679d647821d2a5dcbf25dd2a3cf747f0
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: Enforce indentation

Changed paths:
    dumper-companion/eslint.config.mjs
    dumper-companion/src/hfs/btree.ts
    dumper-companion/src/hfs/directory.ts
    dumper-companion/src/hfs/main.ts
    dumper-companion/webpack.config.js


diff --git a/dumper-companion/eslint.config.mjs b/dumper-companion/eslint.config.mjs
index a662af15..527c902c 100644
--- a/dumper-companion/eslint.config.mjs
+++ b/dumper-companion/eslint.config.mjs
@@ -11,7 +11,7 @@ export default defineConfig(
         ignores: ["node_modules", "index.js"],
     },
     {
-	name: "global settings",
+        name: "global settings",
         languageOptions: {
             ecmaVersion: "latest",
             sourceType: "module",
@@ -24,11 +24,12 @@ export default defineConfig(
         rules: {
             "no-constant-condition": "off",
             "no-sparse-arrays": "off",
+            "@stylistic/indent": ["error", 4, { "SwitchCase": 0 }],
             "@stylistic/semi": ["error", "always"],
         },
     },
     {
-	name: "webpack specific",
+        name: "webpack specific",
         files: ["webpack.config.js"],
         languageOptions: {
             globals: {
@@ -37,7 +38,7 @@ export default defineConfig(
         },
     },
     {
-	name: "browser specific",
+        name: "browser specific",
         files: ["src/**"],
         languageOptions: {
             globals: {
@@ -46,14 +47,15 @@ export default defineConfig(
         },
     },
     {
-	name: "typescript specific",
+        name: "typescript specific",
         files: ["**/*.ts", "**/*.tsx"],
 
-	extends: [tseslint.configs.recommended],
+        extends: [tseslint.configs.recommended],
 
         rules: {
             "@typescript-eslint/no-empty-object-type": "off",
             "@typescript-eslint/no-unsafe-function-type": "error",
             "@typescript-eslint/no-wrapper-object-types": "error",
         },
-     });
+    },
+);
diff --git a/dumper-companion/src/hfs/btree.ts b/dumper-companion/src/hfs/btree.ts
index 320bffc3..21f521fd 100644
--- a/dumper-companion/src/hfs/btree.ts
+++ b/dumper-companion/src/hfs/btree.ts
@@ -67,7 +67,7 @@ export function dump_btree(buf: Uint8Array): Uint8Array[] {
     // Ask about the header record in the header node
     // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const [bthDepth, bthRoot, bthNRecs, bthFNode, bthLNode, bthNodeSize, bthKeyLen, bthNNodes, bthFree]
-    = struct('>HLLLLHHLL').unpack_from(header_rec);
+        = struct('>HLLLLHHLL').unpack_from(header_rec);
     // print('btree', bthDepth, bthRoot, bthNRecs, bthFNode, bthLNode, bthNodeSize, bthKeyLen, bthNNodes, bthFree)
 
     // And iterate through the linked list of leaf nodes
diff --git a/dumper-companion/src/hfs/directory.ts b/dumper-companion/src/hfs/directory.ts
index 23f021aa..a783efa6 100644
--- a/dumper-companion/src/hfs/directory.ts
+++ b/dumper-companion/src/hfs/directory.ts
@@ -108,11 +108,11 @@ export class AbstractFolder {
 }
 
 function hfs_ts_to_date(hfs_ts) {
-	const HFS_UTC_OFFSET = 2082844800;
-	if (!hfs_ts) {
-		return new Date();
-	}
-	return new Date((hfs_ts - HFS_UTC_OFFSET) * 1000);
+    const HFS_UTC_OFFSET = 2082844800;
+    if (!hfs_ts) {
+        return new Date();
+    }
+    return new Date((hfs_ts - HFS_UTC_OFFSET) * 1000);
 }
 
 
diff --git a/dumper-companion/src/hfs/main.ts b/dumper-companion/src/hfs/main.ts
index 5ed2b184..586911e2 100644
--- a/dumper-companion/src/hfs/main.ts
+++ b/dumper-companion/src/hfs/main.ts
@@ -90,7 +90,7 @@ export class Volume extends AbstractFolder {
             from_volume = from_volume.subarray(magicOffset);
         }
 
-	/* eslint-disable @typescript-eslint/no-unused-vars */
+        /* eslint-disable @typescript-eslint/no-unused-vars */
         const [drSigWord, drCrDate, drLsMod, drAtrb, drNmFls,
             drVBMSt, drAllocPtr, drNmAlBlks, drAlBlkSiz, drClpSiz, drAlBlSt,
             drNxtCNID, drFreeBks, drVN, drVolBkUp, drVSeqNum,
@@ -98,8 +98,8 @@ export class Volume extends AbstractFolder {
             drFndrInfo, drVCSize, drVBMCSize, drCtlCSize,
             drXTFlSize, drXTExtRec,
             drCTFlSize, drCTExtRec]
-	/* eslint-enable @typescript-eslint/no-unused-vars */
-        = struct('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHL12sL12s').unpack_from(from_volume, 1024);
+            = struct('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHL12sL12s').unpack_from(from_volume, 1024);
+        /* eslint-enable @typescript-eslint/no-unused-vars */
 
         this.crdate = drCrDate;
         this.mddate = drLsMod;
@@ -151,10 +151,10 @@ export class Volume extends AbstractFolder {
             const datarec = val.subarray(2);
 
             if (datatype === 'dir') {
-		/* eslint-disable @typescript-eslint/no-unused-vars */
+                /* eslint-disable @typescript-eslint/no-unused-vars */
                 const [dirFlags, dirVal, dirDirID, dirCrDat, dirMdDat, dirBkDat, dirUsrInfo, dirFndrInfo]
-                = struct('>HHLLLL16s16s').unpack_from(datarec);
-		/* eslint-enable @typescript-eslint/no-unused-vars */
+                    = struct('>HHLLLL16s16s').unpack_from(datarec);
+                /* eslint-enable @typescript-eslint/no-unused-vars */
 
                 const f = new MacFolder();
                 cnids[dirDirID] = f;
@@ -164,15 +164,15 @@ export class Volume extends AbstractFolder {
                 f.mddate = dirMdDat;
                 f.bkdate = dirBkDat;
             } else if (datatype === 'file') {
-		/* eslint-disable @typescript-eslint/no-unused-vars */
+                /* eslint-disable @typescript-eslint/no-unused-vars */
                 const [filFlags, filTyp, filUsrWds, filFlNum,
                     filStBlk, filLgLen, filPyLen,
                     filRStBlk, filRLgLen, filRPyLen,
                     filCrDat, filMdDat, filBkDat,
                     filFndrInfo, filClpSize,
                     filExtRec, filRExtRec]
-                = struct('>BB16sLHLLHLLLLL16sH12s12sxxxx').unpack_from(datarec);
-		/* eslint-enable @typescript-eslint/no-unused-vars */
+                    = struct('>BB16sLHLLHLLLLL16sH12s12sxxxx').unpack_from(datarec);
+                /* eslint-enable @typescript-eslint/no-unused-vars */
 
                 const f = new MacFile();
                 cnids[filFlNum] = f;
diff --git a/dumper-companion/webpack.config.js b/dumper-companion/webpack.config.js
index a1d54e93..f70792c1 100644
--- a/dumper-companion/webpack.config.js
+++ b/dumper-companion/webpack.config.js
@@ -1,26 +1,26 @@
 const TerserPlugin = require('terser-webpack-plugin');
 
 module.exports = {
-  context: __dirname + "/src",
-  entry: "./index.tsx",
-  output: {
-    path: __dirname,
-    filename: "index.js"
-  },
-  resolve: {
-    extensions: [".ts", ".tsx", ".js"]
-  },
-  module: {
-    rules: [
-      { test: /\.tsx?$/, loader: "ts-loader" }
-    ]
-  },
-  plugins: [],
-  optimization: {
-    minimizer: [
-      new TerserPlugin({
-        extractComments: false,
-      }),
-    ],
-  },
+    context: __dirname + "/src",
+    entry: "./index.tsx",
+    output: {
+        path: __dirname,
+        filename: "index.js"
+    },
+    resolve: {
+        extensions: [".ts", ".tsx", ".js"]
+    },
+    module: {
+        rules: [
+            { test: /\.tsx?$/, loader: "ts-loader" }
+        ]
+    },
+    plugins: [],
+    optimization: {
+        minimizer: [
+            new TerserPlugin({
+                extractComments: false,
+            }),
+        ],
+    },
 };


Commit: 6d58a8ade58e7abf40b9020d9b88d0b71638c794
    https://github.com/scummvm/scummvm-web/commit/6d58a8ade58e7abf40b9020d9b88d0b71638c794
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: Remove useless rules

They are bundled in recommended already.

Changed paths:
    dumper-companion/eslint.config.mjs
    dumper-companion/src/encoding.ts


diff --git a/dumper-companion/eslint.config.mjs b/dumper-companion/eslint.config.mjs
index 527c902c..02713744 100644
--- a/dumper-companion/eslint.config.mjs
+++ b/dumper-companion/eslint.config.mjs
@@ -22,8 +22,6 @@ export default defineConfig(
         },
 
         rules: {
-            "no-constant-condition": "off",
-            "no-sparse-arrays": "off",
             "@stylistic/indent": ["error", 4, { "SwitchCase": 0 }],
             "@stylistic/semi": ["error", "always"],
         },
@@ -54,8 +52,6 @@ export default defineConfig(
 
         rules: {
             "@typescript-eslint/no-empty-object-type": "off",
-            "@typescript-eslint/no-unsafe-function-type": "error",
-            "@typescript-eslint/no-wrapper-object-types": "error",
         },
     },
 );
diff --git a/dumper-companion/src/encoding.ts b/dumper-companion/src/encoding.ts
index afd78c78..77e72b18 100644
--- a/dumper-companion/src/encoding.ts
+++ b/dumper-companion/src/encoding.ts
@@ -135,6 +135,7 @@ export function decodeMacRoman(str: Uint8Array): string {
  * https://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/JAPANESE.TXT
  */
 
+/* eslint-disable no-sparse-arrays */
 const macJapaneseMap = {
     '81': [' ','、','。',',','.','・',':',';','?','!','゛','゜','´','`','¨','^',' ̄','_','ヽ','ヾ','ゝ','ゞ','〃','仝','々','〆','〇','ー','—','‐','/','\','〜','‖','|','…','‥','‘','’','“','”','(',')','〔','〕','[',']','{','}','〈','〉','《','》','「','」','『','』','【','】','+','−','±','×',,'÷','=','≠','<','>','≦','≧','∞','∴','♂','♀','°','′','″','℃','¥','$','¢','£','%','#','&','*','@','§','☆','★','○','●','◎','◇','◆','□','■','△','▲','▽','▼','※','〒','→','←','↑','↓','〓',,,,,,,,,,,,'∈','∋','⊆','⊇','⊂','⊃','∪','∩',,,,,,,,,'∧','∨','¬','⇒','⇔','∀','∃',,,,,,,,,,,,'∠','⊥','⌒','∂','∇','≡','≒','≪','≫','√','∽','∝','∵','∫','∬',,,,,,,,'Å','‰','♯','♭','♪','†','‡','¶',,,,,'◯'],
     '82': [,,,,,,,,,,,,,,,'0','1','2','3','4','5','6','7','8','9',,,,,,,,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',,,,,,,,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',,,,,'ぁ','あ','ぃ','い','ぅ','う','ぇ','え','ぉ','お','か','が','き','ぎ','く','ぐ','け','げ','こ','ご','さ','ざ','し','じ','す','ず','せ','ぜ','そ','ぞ','た','だ','ち','ぢ','っ','つ','づ','て','で','と','ど','な','に','ぬ','ね','の','は','ば','ぱ','ひ','び','ぴ','ふ','ぶ','ぷ','へ','べ','ぺ','ほ','ぼ','ぽ','ま','み','む','め','も','ゃ','や','ゅ','ゆ','ょ','よ','ら','り','る','れ','ろ','ゎ','わ','ゐ','ゑ','を','ん'],
@@ -182,6 +183,7 @@ const macJapaneseMap = {
     'ec': [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'ぁ',,'ぃ',,'ぅ',,'ぇ',,'ぉ',,,,,,,,,,,,,,,,,,,,,,,,,,'っ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'ゃ',,'ゅ',,'ょ',,,,,,,'ゎ'],
     'ed': ['ァ',,'ィ',,'ゥ',,'ェ',,'ォ',,,,,,,,,,,,,,,,,,,,,,,,,,'ッ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'ャ',,'ュ',,'ョ',,,,,,,'ヮ',,,,,,,'ヵ','ヶ']
 };
+/* eslint-enable no-sparse-arrays */
 
 export function decodeMacJapanese(str: Uint8Array, log: (string) => void): string {
     let res = '';


Commit: 2af2c1b94fc1e48bd5aafb1cd11dc2b78eeb99c5
    https://github.com/scummvm/scummvm-web/commit/2af2c1b94fc1e48bd5aafb1cd11dc2b78eeb99c5
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: Transform components into functions

This is the recommended way to write preact components.

Changed paths:
    dumper-companion/src/App.tsx
    dumper-companion/src/Dumper.tsx
    dumper-companion/src/Punycoder.tsx


diff --git a/dumper-companion/src/App.tsx b/dumper-companion/src/App.tsx
index 3a119e5d..aaf30a78 100644
--- a/dumper-companion/src/App.tsx
+++ b/dumper-companion/src/App.tsx
@@ -1,16 +1,9 @@
-import { Component, ComponentChild } from 'preact';
 import Dumper from './Dumper';
 import Punycoder from './Punycoder';
 
-export type Props = {};
-
-export type State = {};
-
-export default class App extends Component<Props, State> {
-    render(): ComponentChild {
-        return <div class="app">
-            <Dumper/>
-            <Punycoder/>
-        </div>;
-    }
+export default function App() {
+    return (<div class="app">
+        <Dumper/>
+        <Punycoder/>
+    </div>);
 }
diff --git a/dumper-companion/src/Dumper.tsx b/dumper-companion/src/Dumper.tsx
index 40af0bc5..0c324448 100644
--- a/dumper-companion/src/Dumper.tsx
+++ b/dumper-companion/src/Dumper.tsx
@@ -1,171 +1,189 @@
-import { Component, ComponentChild } from 'preact';
+import { ComponentChild } from 'preact';
+import { useState, useEffect } from 'preact/hooks';
 import { fs } from '@zip.js/zip.js';
 import { Volume } from './hfs/main';
 import { Language, getLanguages } from './encoding';
 
-export type Props = {};
-
-export type State = {
-    image: File;
+type DumpSettings = {
     imageName: string;
     lang: Language;
-    busy: boolean;
     unicode: boolean;
     forceMacBinary: boolean;
-    logs: ComponentChild[];
-    dumpPercent: number;
-    lastLogWasDumpPercent: boolean;
+    log: (msg: ComponentChild | Error) => void;
+    updateDumpPercent: (dumpPercent: number) => void;
+    finished: () => void;
 };
 
-export default class Dumper extends Component<Props, State> {
-    constructor() {
-        super();
-        this.state = {
-            image: null,
-            imageName: null,
-            lang: Language.EN,
-            unicode: true,
-            forceMacBinary: false,
-            busy: false,
-            logs: [],
-            dumpPercent: -1,
-            lastLogWasDumpPercent: false
-        };
-    }
-
-    componentDidMount(): void {
-        this.log('Waiting for input...');
-    }
-
-    render(): ComponentChild {
-        return <div class="dumper">
-            <div class="in box">
-                <h2>Input</h2>
-
-                <div>
-                    <p>Select the game's disk image:</p>
-                    <input disabled={this.state.busy} class="file" type="file" accept=".dsk,.image,.img,.iso,.toast,.cdr,.diskcopy,.dcpy,.dc42" onInput={this.handleImage.bind(this)}/>
-                </div>
-
-                <div>
-                    <p>Select the game's language:</p>
-                    <select disabled={this.state.busy} value={this.state.lang as string} onInput={this.handleLanguage.bind(this)}>
-                        {getLanguages().map(lang => <option value={lang}>{lang}</option>)}
-                    </select>
-                </div>
-
-                <div>
-                    <input disabled={this.state.busy} type="checkbox" id="unicode" checked={this.state.unicode} onInput={this.handleUnicode.bind(this)}></input>
-                    <label for="unicode">Allow Unicode file names</label>
-                </div>
-
-                <div>
-                    <input disabled={this.state.busy} type="checkbox" id="forceMacBinary" checked={this.state.forceMacBinary} onInput={this.handleForceMacBinary.bind(this)}></input>
-                    <label for="forceMacBinary">Always use MacBinary encoding (use only when explicitly needed for an engine)</label>
-                </div>
-
-                <div>
-                    <button disabled={this.state.busy || this.state.image == null} onClick={this.handleDump.bind(this)}>Dump!</button>
-                </div>
-            </div>
-            <div class="out box">
-                <h2>Output</h2>
-                <ul class="log">{this.state.logs}</ul>
-            </div>
-        </div>;
+async function dumpVolume(file: ArrayBuffer, s: DumpSettings): Promise<void> {
+    s.log('Parsing volume...');
+    try {
+        const volume = new Volume();
+        volume.read(new Uint8Array(file));
+
+        s.updateDumpPercent(0);
+
+        const zipFS = new fs.FS();
+        volume.dumpToZip(zipFS.root, s.lang, !s.unicode, s.forceMacBinary, s.log);
+        const blob = await zipFS.exportBlob({
+            level: 0,
+            onprogress: (index: number, max: number): undefined => {
+                const percent = Math.floor(index / max * 100);
+                s.updateDumpPercent(percent);
+            }
+        });
+        const volumeURL = URL.createObjectURL(blob);
+        s.log('Success! Next steps:');
+        s.log(<span>1. <a href={volumeURL} download={`${s.imageName}.zip`}>Click here to download your game data.</a></span>);
+        s.log('2. Unzip the game data.');
+        s.log('3. Add the directory to ScummVM.');
+    } catch (err) {
+        s.log(err);
     }
+    s.finished();
+}
 
-    log(msg: ComponentChild | Error, callback?: () => void): void {
+export default function Dumper() {
+    type Image = {
+        file: File;
+        name: string;
+    };
+
+    type Progress = {
+        busy: boolean;
+        logs: ComponentChild[];
+        lastLogWasDumpPercent: boolean;
+        dumpPercent: number;
+    };
+
+    const [image, setImage] = useState<Image>({file: null, name: null});
+    const [lang, setLang] = useState(Language.EN);
+    const [unicode, setUnicode] = useState(true);
+    const [forceMacBinary, setForceMacBinary] = useState(false);
+    const [progress, setProgress] = useState<Progress>({busy: false, logs: [], lastLogWasDumpPercent: false, dumpPercent: -1});
+
+    function log(msg: ComponentChild | Error): void {
         console.log(msg);
         if (msg instanceof Error) {
             msg = msg.toString();
         }
-        this.setState(({ logs }) => ({
-            logs: [...logs, <li>{msg}</li>],
-            lastLogWasDumpPercent: false
-        }), callback);
+
+        setProgress((p: Progress): Progress => {
+            const logs = [...p.logs, <li key={p.logs.length}>{msg}</li>];
+            const lastLogWasDumpPercent = false;
+            return {...p, logs, lastLogWasDumpPercent};
+        });
     }
 
-    updateDumpPercent(percent: number, callback?: () => void): void {
-        if (percent !== this.state.dumpPercent) {
-            const msg = `Dumping volume... ${percent}%`;
+    function updateDumpPercent(dumpPercent: number): void {
+        setProgress((p: Progress): Progress => {
+            if (dumpPercent === p.dumpPercent) {
+                return p;
+            }
+
+            const msg = `Dumping volume... ${dumpPercent}%`;
+            // The function is not really pure anymore, but seen from preact that should do it
             console.log(msg);
-            this.setState(({ logs, lastLogWasDumpPercent }) => ({
-                logs: lastLogWasDumpPercent
-                    ? [...logs.slice(0, -1), <li>{msg}</li>]
-                    : [...logs, <li>{msg}</li>],
-                dumpPercent: percent,
-                lastLogWasDumpPercent: true
-            }), callback);
-        }
+
+            const logs = p.lastLogWasDumpPercent
+                ? [...p.logs.slice(0, -1), <li key={p.logs.length-1}>{msg}</li>]
+                : [...p.logs, <li key={p.logs.length}>{msg}</li>];
+            const lastLogWasDumpPercent = true;
+            return {...p, logs, lastLogWasDumpPercent, dumpPercent};
+        });
+    }
+
+    function starting(): void {
+        setProgress({busy: true, logs: [], lastLogWasDumpPercent: false, dumpPercent: -1});
     }
 
-    handleImage(e: Event): void {
-        const image = (e.target as HTMLInputElement).files[0];
-        const imageName = image.name.replace(/\.\w+$/, '');
-        this.setState(() => ({ image, imageName }));
+    function finished(): void {
+        setProgress((p: Progress): Progress => {
+            return {...p, busy:false, dumpPercent: -1};
+        });
+    }
+
+    function handleImage(e: Event): void {
+        const file = (e.target as HTMLInputElement).files[0];
+        const name = file.name.replace(/\.\w+$/, '');
+        setImage({file, name});
     }
 
-    handleLanguage(e: Event): void {
+    function handleLanguage(e: Event): void {
         const lang = (e.target as HTMLSelectElement).value as Language;
-        this.setState(() => ({ lang }));
+        setLang(lang);
     }
 
-    handleUnicode(e: Event): void {{
+    function handleUnicode(e: Event): void {{
         const unicode = (e.target as HTMLInputElement).checked;
-        this.setState(() => ({ unicode }));
+        setUnicode(unicode);
     }}
 
-    handleForceMacBinary(e: Event): void {{
+    function handleForceMacBinary(e: Event): void {{
         const forceMacBinary = (e.target as HTMLInputElement).checked;
-        this.setState(() => ({ forceMacBinary }));
+        setForceMacBinary(forceMacBinary);
     }}
 
-    handleDump(): void {
-        this.log(`Loading volume "${this.state.imageName}"...`);
-        this.setState(() => ({ busy: true }), () => {
-            const reader = new FileReader();
-            reader.addEventListener('load', () => {
-                this.parseVolume(reader.result as ArrayBuffer);
-            });
-            reader.readAsArrayBuffer(this.state.image);
+    function handleDump(): void {
+        starting();
+        log(`Loading volume "${image.name}"...`);
+        const reader = new FileReader();
+        reader.addEventListener('load', () => {
+            dumpVolume(reader.result as ArrayBuffer, {
+                imageName: image.name,
+                lang,
+                unicode,
+                forceMacBinary,
+                log,
+                updateDumpPercent,
+                finished
+            } as DumpSettings);
         });
+        reader.readAsArrayBuffer(image.file);
     }
 
-    parseVolume(file: ArrayBuffer): void {
-        this.log('Parsing volume...', () => {
-            try {
-                const volume = new Volume();
-                volume.read(new Uint8Array(file));
-                this.dumpVolume(volume);
-            } catch (err) {
-                this.log(err);
-                this.setState(() => ({ busy: false, dumpPercent: -1 }));
-            }
+    useEffect((): void => {
+        setProgress((p: Progress): Progress => {
+            const logs = [<li key={p.logs.length}>Waiting for input...</li>];
+            const lastLogWasDumpPercent = false;
+            return {...p, logs, lastLogWasDumpPercent};
         });
-    }
+    }, []);
 
-    dumpVolume(volume: Volume): void {
-        this.updateDumpPercent(0, async () => {
-            try {
-                const zipFS = new fs.FS();
-                volume.dumpToZip(zipFS.root, this.state.lang, !this.state.unicode, this.state.forceMacBinary, this.log.bind(this));
-                const blob = await zipFS.exportBlob({
-                    level: 0,
-                    onprogress: (index: number, max: number): undefined => {
-                        const percent = Math.floor(index / max * 100);
-                        this.updateDumpPercent(percent);
-                    }
-                });
-                const volumeURL = URL.createObjectURL(blob);
-                this.log('Success! Next steps:');
-                this.log(<span>1. <a href={volumeURL} download={this.state.imageName + '.zip'}>Click here to download your game data.</a></span>);
-                this.log('2. Unzip the game data.');
-                this.log('3. Add the directory to ScummVM.');
-            } catch (err) {
-                this.log(err);
-            }
-            this.setState(() => ({ busy: false, dumpPercent: -1 }));
-        });
-    }
+    const busy = progress.busy;
+
+    return (<div class="dumper">
+        <div class="in box">
+            <h2>Input</h2>
+
+            <div>
+                <p>Select the game's disk image:</p>
+                <input disabled={busy} class="file" type="file" accept=".dsk,.image,.img,.iso,.toast,.cdr,.diskcopy,.dcpy,.dc42" onInput={handleImage}/>
+            </div>
+
+            <div>
+                <p>Select the game's language:</p>
+                <select disabled={busy} value={lang} onInput={handleLanguage}>
+                    {getLanguages().map((lang, i) => <option key={i} value={lang}>{lang}</option>)}
+                </select>
+            </div>
+
+            <div>
+                <input disabled={busy} type="checkbox" id="unicode" checked={unicode} onInput={handleUnicode}/>
+                <label for="unicode">Allow Unicode file names</label>
+            </div>
+
+            <div>
+                <input disabled={busy} type="checkbox" id="forceMacBinary" checked={forceMacBinary} onInput={handleForceMacBinary}/>
+                <label for="forceMacBinary">Always use MacBinary encoding (use only when explicitly needed for an engine)</label>
+            </div>
+
+            <div>
+                <button disabled={busy || image == null} onClick={handleDump}>Dump!</button>
+            </div>
+        </div>
+        <div class="out box">
+            <h2>Output</h2>
+            <ul class="log">{progress.logs}</ul>
+        </div>
+    </div>);
 }
diff --git a/dumper-companion/src/Punycoder.tsx b/dumper-companion/src/Punycoder.tsx
index eba834a9..ae5554cb 100644
--- a/dumper-companion/src/Punycoder.tsx
+++ b/dumper-companion/src/Punycoder.tsx
@@ -1,67 +1,48 @@
-import { Component, ComponentChild } from 'preact';
+import { useState } from 'preact/hooks';
 import * as punycode from 'punycode/';
 import { escapeString, unescapeString } from './encoding';
 
-export type Props = {};
+export default function Punycoder() {
+    const [text, setText] = useState('');
 
-export type State = {
-    text: string;
-};
-
-export default class Punycoder extends Component<Props, State> {
-    constructor() {
-        super();
-        this.state = {
-            text: ''
-        };
-    }
-
-    render(): ComponentChild {
-        return <div class="punycoder box">
-            <h2>Punycoder</h2>
-            <p>
-                For platforms that don't support Unicode file names, ScummVM uses
-                a variant of <a href="https://en.wikipedia.org/wiki/Punycode">Punycode</a>.
-                You can use this to manually encode/decode file names:
-            </p>
-            <div>
-                <input type="text" placeholder="File name" value={this.state.text} onInput={this.handleText.bind(this)}></input>
-                <button onClick={this.encode.bind(this)}>Encode</button>
-                <button onClick={this.decode.bind(this)}>Decode</button>
-            </div>
-        </div>;
+    function handleText(e: Event): void {
+        const newText = (e.target as HTMLInputElement).value;
+        setText(newText);
     }
 
-    handleText(e: Event): void {
-        const text = (e.target as HTMLInputElement).value;
-        this.setState(() => ({ text }));
+    function invalidPunycode(): void {
+        setText('Invalid Punycode!');
     }
 
-    encode(): void {
-        this.setState({
-            text: 'xn--' + punycode.encode(escapeString(this.state.text))
-        });
+    function encode(): void {
+        setText(`xn--${punycode.encode(escapeString(text))}`);
     }
 
-    decode(): void {
-        if (!this.state.text.startsWith("xn--")) {
-            this.invalidPunycode();
+    function decode(): void {
+        if (!text.startsWith("xn--")) {
+            invalidPunycode();
             return;
         }
 
-        const input = this.state.text.slice(4);
+        const input = text.slice(4);
         try {
-            this.setState({
-                text: unescapeString(punycode.decode(input))
-            });
+            setText(unescapeString(punycode.decode(input)));
         } catch /*(e)*/ {
-            this.invalidPunycode();
+            invalidPunycode();
         }
     }
 
-    invalidPunycode(): void {
-        this.setState({
-            text: 'Invalid Punycode!'
-        });
-    }
+    return (<div class="punycoder box">
+        <h2>Punycoder</h2>
+        <p>
+            For platforms that don't support Unicode file names, ScummVM uses
+            a variant of <a href="https://en.wikipedia.org/wiki/Punycode">Punycode</a>.
+            You can use this to manually encode/decode file names:
+        </p>
+        <div>
+            <input type="text" placeholder="File name" value={text} onInput={handleText}/>
+            <button onClick={encode}>Encode</button>
+            <button onClick={decode}>Decode</button>
+        </div>
+    </div>);
 }


Commit: 9c14ac1f01ddb1643c1d38a10e850be76950af1a
    https://github.com/scummvm/scummvm-web/commit/9c14ac1f01ddb1643c1d38a10e850be76950af1a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: Various stylistic fixes

Changed paths:
    dumper-companion/src/encoding.ts
    dumper-companion/src/hfs/main.ts
    dumper-companion/src/util.ts
    dumper-companion/webpack.config.js


diff --git a/dumper-companion/src/encoding.ts b/dumper-companion/src/encoding.ts
index 77e72b18..1540a41d 100644
--- a/dumper-companion/src/encoding.ts
+++ b/dumper-companion/src/encoding.ts
@@ -52,7 +52,7 @@ export function escapeString(str: string): string {
         } else if ('<>:"/\\|?*\x7f'.includes(ch) || codePoint(ch) < 0x20) {
             // Escape characters forbidden on Windows
             // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
-            res += '\x81' + String.fromCodePoint(0x80 + codePoint(ch));
+            res += `\x81${String.fromCodePoint(0x80 + codePoint(ch))}`;
         } else {
             res += ch;
         }
@@ -99,7 +99,7 @@ export function encodeFileName(str: Uint8Array, lang: Language, puny: boolean, l
         const punycodeStr = punycode.encode(escapedStr);
         // If there are no special characters, the punycoder just adds a '-' to the end.
         if (forcePunycode || escapedStr !== punycodeStr.slice(0, -1)) {
-            return 'xn--' + punycodeStr;
+            return `xn--${punycodeStr}`;
         }
     }
 
@@ -198,17 +198,18 @@ export function decodeMacJapanese(str: Uint8Array, log: (string) => void): strin
             if (i >= str.length) {
                 log(`Warning: Mac Japanese sequence 0x${byteToHex(hi)}XX missing second byte, decoding as Mac Roman`);
                 return decodeMacRoman(str);
-            } else {
-                const lo = str[i];
-                const hiKey = hi.toString(16);
-                const loKey = lo - 0x40;
-                if (macJapaneseMap[hiKey] == null || macJapaneseMap[hiKey][loKey] == null) {
-                    log(`Warning: No mapping for Mac Japanese sequence 0x${byteToHex(hi)}${byteToHex(lo)}, decoding as Mac Roman`);
-                    return decodeMacRoman(str);
-                } else {
-                    res += macJapaneseMap[hiKey][loKey];
-                }
             }
+
+            const lo = str[i];
+            const hiKey = hi.toString(16);
+            const loKey = lo - 0x40;
+
+            if (macJapaneseMap[hiKey] == null || macJapaneseMap[hiKey][loKey] == null) {
+                log(`Warning: No mapping for Mac Japanese sequence 0x${byteToHex(hi)}${byteToHex(lo)}, decoding as Mac Roman`);
+                return decodeMacRoman(str);
+            }
+
+            res += macJapaneseMap[hiKey][loKey];
         } else if (hi === 0xA0) { // no-break space
             res += '\u00A0';
         } else if (hi >= 0xA1 && hi <= 0xDF) { // Katakana
diff --git a/dumper-companion/src/hfs/main.ts b/dumper-companion/src/hfs/main.ts
index 586911e2..8235a75f 100644
--- a/dumper-companion/src/hfs/main.ts
+++ b/dumper-companion/src/hfs/main.ts
@@ -36,7 +36,7 @@ import struct from '../struct';
 
 function _get_every_extent(nblocks: number, firstrecord: Uint8Array, cnid: number, xoflow: {[key: string]: Uint8Array}, fork: string): [number, number][] {
     let accum = 0;
-    const extlist = [];
+    const extlist: [number, number][] = [];
 
     for (const [a, b] of btree.unpack_extent_record(firstrecord)) {
         if (!b) continue;
@@ -45,7 +45,7 @@ function _get_every_extent(nblocks: number, firstrecord: Uint8Array, cnid: numbe
     }
 
     while (accum < nblocks) {
-        const nextrecord = xoflow[cnid + ',' + fork + ',' + accum];
+        const nextrecord = xoflow[`${cnid},${fork},${accum}`];
         for (const [a, b] of btree.unpack_extent_record(nextrecord)) {
             if (!b) continue;
             accum += b;
@@ -130,7 +130,7 @@ export class Volume extends AbstractFolder {
                 fork = 'rsrc';
             else if (xkrFkType === 0)
                 fork = 'data';
-            extoflow[xkrFNum + ',' + fork + ',' + xkrFABN] = extrec;
+            extoflow[`${xkrFNum},${fork},${xkrFABN}`] = extrec;
         }
 
         const cnids: {[id: number]: FileOrFolder} = {};
diff --git a/dumper-companion/src/util.ts b/dumper-companion/src/util.ts
index aea9582a..ea213a6a 100644
--- a/dumper-companion/src/util.ts
+++ b/dumper-companion/src/util.ts
@@ -8,7 +8,7 @@ export function codePoint(charStr: string): number {
 
 export function byteToHex(byte: number): string {
     const res = byte.toString(16);
-    return (res.length === 1) ? '0' + res : res;
+    return (res.length === 1) ? `0${res}` : res;
 }
 
 const encoder = new TextEncoder();
diff --git a/dumper-companion/webpack.config.js b/dumper-companion/webpack.config.js
index f70792c1..ba24e968 100644
--- a/dumper-companion/webpack.config.js
+++ b/dumper-companion/webpack.config.js
@@ -1,7 +1,7 @@
 const TerserPlugin = require('terser-webpack-plugin');
 
 module.exports = {
-    context: __dirname + "/src",
+    context: `${__dirname}/src`,
     entry: "./index.tsx",
     output: {
         path: __dirname,


Commit: 9582f7ed0ef05add6e419b55732769a50468ce74
    https://github.com/scummvm/scummvm-web/commit/9582f7ed0ef05add6e419b55732769a50468ce74
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: Add typing for struct module

Changed paths:
  A dumper-companion/src/struct.d.ts
    dumper-companion/src/hfs/btree.ts
    dumper-companion/src/hfs/main.ts


diff --git a/dumper-companion/src/hfs/btree.ts b/dumper-companion/src/hfs/btree.ts
index 21f521fd..c3f78c50 100644
--- a/dumper-companion/src/hfs/btree.ts
+++ b/dumper-companion/src/hfs/btree.ts
@@ -32,8 +32,8 @@ import struct from '../struct';
 
 export function unpack_extent_record(record: Uint8Array): [number, number][] {
     /* Extract up to three (first_block, block_count) tuples from a 12-byte extent record */
-    const [a, b, c, d, e, f] = struct('>6H').unpack(record);
-    const l = [];
+    const [a, b, c, d, e, f] = struct<[number, number, number, number, number, number]>('>6H').unpack(record);
+    const l: [number, number][] = [];
     if (b) l.push([a, b]);
     if (d) l.push([c, d]);
     if (f) l.push([e, f]);
@@ -43,12 +43,12 @@ export function unpack_extent_record(record: Uint8Array): [number, number][] {
 
 function _unpack_btree_node(buf: Uint8Array, start: number): [number, number, number, number, Uint8Array[]] {
     /* Slice a btree node into records, including the 14-byte node descriptor */
-    const [ndFLink, ndBLink, ndType, ndNHeight, ndNRecs] = struct('>LLBBH').unpack_from(buf, start);
-    const offsets = struct(`>${ndNRecs+1}H`).unpack_from(buf, start+512-2*(ndNRecs+1)).reverse();
+    const [ndFLink, ndBLink, ndType, ndNHeight, ndNRecs] = struct<[number, number, number, number, number]>('>LLBBH').unpack_from(buf, start);
+    const offsets = struct<number[]>(`>${ndNRecs+1}H`).unpack_from(buf, start+512-2*(ndNRecs+1)).reverse();
     const records: Uint8Array[] = [];
     for (let i = 0; i < offsets.length - 1; i++) {
-        const i_start = offsets[i];
-        const i_stop = offsets[i + 1];
+        const i_start: number = offsets[i];
+        const i_stop: number = offsets[i + 1];
         records.push(buf.subarray(start+i_start, start+i_stop));
     }
     return [ndFLink, ndBLink, ndType, ndNHeight, records];
@@ -67,12 +67,12 @@ export function dump_btree(buf: Uint8Array): Uint8Array[] {
     // Ask about the header record in the header node
     // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const [bthDepth, bthRoot, bthNRecs, bthFNode, bthLNode, bthNodeSize, bthKeyLen, bthNNodes, bthFree]
-        = struct('>HLLLLHHLL').unpack_from(header_rec);
+        = struct<[number, number, number, number, number, number, number, number, number]>('>HLLLLHHLL').unpack_from(header_rec);
     // print('btree', bthDepth, bthRoot, bthNRecs, bthFNode, bthLNode, bthNodeSize, bthKeyLen, bthNNodes, bthFree)
 
     // And iterate through the linked list of leaf nodes
     const res: Uint8Array[] = [];
-    let this_leaf = bthFNode;
+    let this_leaf: number = bthFNode;
     while (true) {
         // eslint-disable-next-line @typescript-eslint/no-unused-vars
         const [ndFLink, ndBLink, ndType, ndNHeight, records] = _unpack_btree_node(buf, 512*this_leaf);
diff --git a/dumper-companion/src/hfs/main.ts b/dumper-companion/src/hfs/main.ts
index 8235a75f..9dda97e0 100644
--- a/dumper-companion/src/hfs/main.ts
+++ b/dumper-companion/src/hfs/main.ts
@@ -98,7 +98,13 @@ export class Volume extends AbstractFolder {
             drFndrInfo, drVCSize, drVBMCSize, drCtlCSize,
             drXTFlSize, drXTExtRec,
             drCTFlSize, drCTExtRec]
-            = struct('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHL12sL12s').unpack_from(from_volume, 1024);
+            = struct<[Uint8Array, number, number, number, number,
+                number, number, number, number, number, number,
+                number, number, Uint8Array, number, number,
+                number, number, number, number, number, number,
+                Uint8Array, number, number, number,
+                number, Uint8Array,
+                number, Uint8Array]>('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHL12sL12s').unpack_from(from_volume, 1024);
         /* eslint-enable @typescript-eslint/no-unused-vars */
 
         this.crdate = drCrDate;
@@ -124,7 +130,7 @@ export class Volume extends AbstractFolder {
         const extoflow: {[key: string]: Uint8Array} = {};
         for (const rec of btree.dump_btree(getfork(drXTFlSize, drXTExtRec, 3, 'data'))) {
             if (rec[0] !== 7) continue;
-            const [xkrFkType, xkrFNum, xkrFABN, extrec] = struct('>xBLH12s').unpack_from(rec);
+            const [xkrFkType, xkrFNum, xkrFABN, extrec] = struct<[number, number, number, Uint8Array]>('>xBLH12s').unpack_from(rec);
             let fork: string;
             if (xkrFkType === 0xFF)
                 fork = 'rsrc';
@@ -144,7 +150,7 @@ export class Volume extends AbstractFolder {
             const key = rec.subarray(2, 1+rec_len);
             const val = rec.subarray(bitmanip.pad_up(1+rec_len, 2));
 
-            const [ckrParID, namelen] = struct('>LB').unpack_from(key);
+            const [ckrParID, namelen] = struct<[number, number]>('>LB').unpack_from(key);
             const ckrCName = key.subarray(5, 5+namelen);
 
             const datatype = [null, 'dir', 'file', 'dthread', 'fthread'][val[0]];
@@ -153,7 +159,7 @@ export class Volume extends AbstractFolder {
             if (datatype === 'dir') {
                 /* eslint-disable @typescript-eslint/no-unused-vars */
                 const [dirFlags, dirVal, dirDirID, dirCrDat, dirMdDat, dirBkDat, dirUsrInfo, dirFndrInfo]
-                    = struct('>HHLLLL16s16s').unpack_from(datarec);
+                    = struct<[number, number, number, number, number, number, Uint8Array, Uint8Array]>('>HHLLLL16s16s').unpack_from(datarec);
                 /* eslint-enable @typescript-eslint/no-unused-vars */
 
                 const f = new MacFolder();
@@ -171,7 +177,12 @@ export class Volume extends AbstractFolder {
                     filCrDat, filMdDat, filBkDat,
                     filFndrInfo, filClpSize,
                     filExtRec, filRExtRec]
-                    = struct('>BB16sLHLLHLLLLL16sH12s12sxxxx').unpack_from(datarec);
+                    = struct<[number, number, Uint8Array, number,
+                        number, number, number,
+                        number, number, number,
+                        number, number, number,
+                        Uint8Array, number,
+                        Uint8Array, Uint8Array]>('>BB16sLHLLHLLLLL16sH12s12sxxxx').unpack_from(datarec);
                 /* eslint-enable @typescript-eslint/no-unused-vars */
 
                 const f = new MacFile();
@@ -181,7 +192,7 @@ export class Volume extends AbstractFolder {
                 f.crdate = filCrDat;
                 f.mddate = filMdDat;
                 f.bkdate = filBkDat;
-                [f.type, f.creator, f.flags, f.x, f.y] = struct('>4s4sHHH').unpack_from(filUsrWds);
+                [f.type, f.creator, f.flags, f.x, f.y] = struct<[Uint8Array, Uint8Array, number, number, number]>('>4s4sHHH').unpack_from(filUsrWds);
 
                 f.data = getfork(filLgLen, filExtRec, filFlNum, 'data');
                 f.rsrc = getfork(filRLgLen, filRExtRec, filFlNum, 'rsrc');
diff --git a/dumper-companion/src/struct.d.ts b/dumper-companion/src/struct.d.ts
new file mode 100644
index 00000000..3611a3de
--- /dev/null
+++ b/dumper-companion/src/struct.d.ts
@@ -0,0 +1,11 @@
+export type StructValue = number | boolean | Uint8Array;
+
+export default function struct<T extends StructValue[],>(format: string): Readonly<{
+    pack: (...values: StructValue[]) => Uint8Array;
+    pack_into: (arrb: Uint8Array, offs: number, ...values: T) => void;
+    iter_unpack: (arrb: Uint8Array) => Generator<T, void, void>;
+    unpack: (arr: Uint8Array) => T;
+    unpack_from: (arr: Uint8Array, offs?: number) => T;
+    format: string;
+    size: number;
+}>;


Commit: 79f72018881df45edd98179fda0069d51d6913eb
    https://github.com/scummvm/scummvm-web/commit/79f72018881df45edd98179fda0069d51d6913eb
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T20:55:42Z

Commit Message:
DUMPER-COMPANION: More typing fixes

Changed paths:
    dumper-companion/src/Dumper.tsx
    dumper-companion/src/Punycoder.tsx
    dumper-companion/src/encoding.ts


diff --git a/dumper-companion/src/Dumper.tsx b/dumper-companion/src/Dumper.tsx
index 0c324448..1259a52e 100644
--- a/dumper-companion/src/Dumper.tsx
+++ b/dumper-companion/src/Dumper.tsx
@@ -37,7 +37,7 @@ async function dumpVolume(file: ArrayBuffer, s: DumpSettings): Promise<void> {
         s.log('2. Unzip the game data.');
         s.log('3. Add the directory to ScummVM.');
     } catch (err) {
-        s.log(err);
+        s.log(err as Error);
     }
     s.finished();
 }
@@ -128,7 +128,7 @@ export default function Dumper() {
         log(`Loading volume "${image.name}"...`);
         const reader = new FileReader();
         reader.addEventListener('load', () => {
-            dumpVolume(reader.result as ArrayBuffer, {
+            void dumpVolume(reader.result as ArrayBuffer, {
                 imageName: image.name,
                 lang,
                 unicode,
diff --git a/dumper-companion/src/Punycoder.tsx b/dumper-companion/src/Punycoder.tsx
index ae5554cb..838f7438 100644
--- a/dumper-companion/src/Punycoder.tsx
+++ b/dumper-companion/src/Punycoder.tsx
@@ -1,5 +1,5 @@
 import { useState } from 'preact/hooks';
-import * as punycode from 'punycode/';
+import * as punycode from 'punycode';
 import { escapeString, unescapeString } from './encoding';
 
 export default function Punycoder() {
diff --git a/dumper-companion/src/encoding.ts b/dumper-companion/src/encoding.ts
index 1540a41d..a104de84 100644
--- a/dumper-companion/src/encoding.ts
+++ b/dumper-companion/src/encoding.ts
@@ -1,4 +1,4 @@
-import * as punycode from 'punycode/';
+import * as punycode from 'punycode';
 import { codePoint, byteToHex } from "./util";
 
 
@@ -19,7 +19,9 @@ export enum Language {
 
 
 export function getLanguages(): string[] {
-    return Object.keys(Language).map(key => Language[key]);
+    return Object.keys(Language).map(
+        // Typecast to string as the key obviously exists
+        (key: string): string => Language[key] as string);
 }
 
 
@@ -136,7 +138,7 @@ export function decodeMacRoman(str: Uint8Array): string {
  */
 
 /* eslint-disable no-sparse-arrays */
-const macJapaneseMap = {
+const macJapaneseMap: Record<string, string[]> = {
     '81': [' ','、','。',',','.','・',':',';','?','!','゛','゜','´','`','¨','^',' ̄','_','ヽ','ヾ','ゝ','ゞ','〃','仝','々','〆','〇','ー','—','‐','/','\','〜','‖','|','…','‥','‘','’','“','”','(',')','〔','〕','[',']','{','}','〈','〉','《','》','「','」','『','』','【','】','+','−','±','×',,'÷','=','≠','<','>','≦','≧','∞','∴','♂','♀','°','′','″','℃','¥','$','¢','£','%','#','&','*','@','§','☆','★','○','●','◎','◇','◆','□','■','△','▲','▽','▼','※','〒','→','←','↑','↓','〓',,,,,,,,,,,,'∈','∋','⊆','⊇','⊂','⊃','∪','∩',,,,,,,,,'∧','∨','¬','⇒','⇔','∀','∃',,,,,,,,,,,,'∠','⊥','⌒','∂','∇','≡','≒','≪','≫','√','∽','∝','∵','∫','∬',,,,,,,,'Å','‰','♯','♭','♪','†','‡','¶',,,,,'◯'],
     '82': [,,,,,,,,,,,,,,,'0','1','2','3','4','5','6','7','8','9',,,,,,,,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',,,,,,,,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',,,,,'ぁ','あ','ぃ','い','ぅ','う','ぇ','え','ぉ','お','か','が','き','ぎ','く','ぐ','け','げ','こ','ご','さ','ざ','し','じ','す','ず','せ','ぜ','そ','ぞ','た','だ','ち','ぢ','っ','つ','づ','て','で','と','ど','な','に','ぬ','ね','の','は','ば','ぱ','ひ','び','ぴ','ふ','ぶ','ぷ','へ','べ','ぺ','ほ','ぼ','ぽ','ま','み','む','め','も','ゃ','や','ゅ','ゆ','ょ','よ','ら','り','る','れ','ろ','ゎ','わ','ゐ','ゑ','を','ん'],
     '83': ['ァ','ア','ィ','イ','ゥ','ウ','ェ','エ','ォ','オ','カ','ガ','キ','ギ','ク','グ','ケ','ゲ','コ','ゴ','サ','ザ','シ','ジ','ス','ズ','セ','ゼ','ソ','ゾ','タ','ダ','チ','ヂ','ッ','ツ','ヅ','テ','デ','ト','ド','ナ','ニ','ヌ','ネ','ノ','ハ','バ','パ','ヒ','ビ','ピ','フ','ブ','プ','ヘ','ベ','ペ','ホ','ボ','ポ','マ','ミ',,'ム','メ','モ','ャ','ヤ','ュ','ユ','ョ','ヨ','ラ','リ','ル','レ','ロ','ヮ','ワ','ヰ','ヱ','ヲ','ン','ヴ','ヵ','ヶ',,,,,,,,,'Α','Β','Γ','Δ','Ε','Ζ','Η','Θ','Ι','Κ','Λ','Μ','Ν','Ξ','Ο','Π','Ρ','Σ','Τ','Υ','Φ','Χ','Ψ','Ω',,,,,,,,,'α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','σ','τ','υ','φ','χ','ψ','ω'],
@@ -204,7 +206,7 @@ export function decodeMacJapanese(str: Uint8Array, log: (string) => void): strin
             const hiKey = hi.toString(16);
             const loKey = lo - 0x40;
 
-            if (macJapaneseMap[hiKey] == null || macJapaneseMap[hiKey][loKey] == null) {
+            if (!(hiKey in macJapaneseMap) || !(loKey in macJapaneseMap[hiKey])) {
                 log(`Warning: No mapping for Mac Japanese sequence 0x${byteToHex(hi)}${byteToHex(lo)}, decoding as Mac Roman`);
                 return decodeMacRoman(str);
             }


Commit: 1566f937adf3b28e0add7678be8f898cfe4a7987
    https://github.com/scummvm/scummvm-web/commit/1566f937adf3b28e0add7678be8f898cfe4a7987
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T21:00:26Z

Commit Message:
DUMPER-COMPANION: Enable more linting

Add type checking linting and enable back all rules.

Changed paths:
    dumper-companion/eslint.config.mjs


diff --git a/dumper-companion/eslint.config.mjs b/dumper-companion/eslint.config.mjs
index 02713744..a31496ec 100644
--- a/dumper-companion/eslint.config.mjs
+++ b/dumper-companion/eslint.config.mjs
@@ -1,6 +1,6 @@
 import eslint from '@eslint/js';
-import globals from "globals";
 import { defineConfig } from 'eslint/config';
+import globals from 'globals';
 import stylistic from '@stylistic/eslint-plugin';
 import tseslint from 'typescript-eslint';
 
@@ -48,10 +48,12 @@ export default defineConfig(
         name: "typescript specific",
         files: ["**/*.ts", "**/*.tsx"],
 
-        extends: [tseslint.configs.recommended],
-
-        rules: {
-            "@typescript-eslint/no-empty-object-type": "off",
+        extends: [tseslint.configs.recommendedTypeChecked],
+        languageOptions: {
+            parserOptions: {
+                projectService: true,
+                jsxPragma: null,
+            },
         },
     },
 );


Commit: ef72913077ab04013d0585d489fb1fc75b7a8598
    https://github.com/scummvm/scummvm-web/commit/ef72913077ab04013d0585d489fb1fc75b7a8598
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T21:00:26Z

Commit Message:
DUMPER-COMPANION: Add preact linting

Changed paths:
    dumper-companion/eslint.config.mjs
    dumper-companion/package-lock.json
    dumper-companion/package.json


diff --git a/dumper-companion/eslint.config.mjs b/dumper-companion/eslint.config.mjs
index a31496ec..97b43b12 100644
--- a/dumper-companion/eslint.config.mjs
+++ b/dumper-companion/eslint.config.mjs
@@ -1,11 +1,13 @@
 import eslint from '@eslint/js';
 import { defineConfig } from 'eslint/config';
+import preact from 'eslint-config-preact';
 import globals from 'globals';
 import stylistic from '@stylistic/eslint-plugin';
 import tseslint from 'typescript-eslint';
 
 export default defineConfig(
     eslint.configs.recommended,
+    preact,
     {
         name: "global ignores",
         ignores: ["node_modules", "index.js"],
diff --git a/dumper-companion/package-lock.json b/dumper-companion/package-lock.json
index 4e3726f7..65dd0140 100644
--- a/dumper-companion/package-lock.json
+++ b/dumper-companion/package-lock.json
@@ -19,10 +19,349 @@
         "@eslint/js": "^9.39.1",
         "@stylistic/eslint-plugin": "^5.6.1",
         "eslint": "^9.39.1",
+        "eslint-config-preact": "^2.0.0",
         "globals": "^16.5.0",
         "typescript-eslint": "^8.50.0"
       }
     },
+    "node_modules/@babel/code-frame": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+      "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.27.1",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
+      "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
+      "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.27.1",
+        "@babel/generator": "^7.28.5",
+        "@babel/helper-compilation-targets": "^7.27.2",
+        "@babel/helper-module-transforms": "^7.28.3",
+        "@babel/helpers": "^7.28.4",
+        "@babel/parser": "^7.28.5",
+        "@babel/template": "^7.27.2",
+        "@babel/traverse": "^7.28.5",
+        "@babel/types": "^7.28.5",
+        "@jridgewell/remapping": "^2.3.5",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/core/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/eslint-parser": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.5.tgz",
+      "integrity": "sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
+        "eslint-visitor-keys": "^2.1.0",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": "^10.13.0 || ^12.13.0 || >=14.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.11.0",
+        "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0"
+      }
+    },
+    "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@babel/eslint-parser/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
+      "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.28.5",
+        "@babel/types": "^7.28.5",
+        "@jridgewell/gen-mapping": "^0.3.12",
+        "@jridgewell/trace-mapping": "^0.3.28",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.27.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+      "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.27.2",
+        "@babel/helper-validator-option": "^7.27.1",
+        "browserslist": "^4.24.0",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-globals": {
+      "version": "7.28.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+      "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+      "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.27.1",
+        "@babel/types": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.28.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+      "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.27.1",
+        "@babel/helper-validator-identifier": "^7.27.1",
+        "@babel/traverse": "^7.28.3"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+      "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+      "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+      "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+      "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.28.4",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+      "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/template": "^7.27.2",
+        "@babel/types": "^7.28.4"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
+      "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.28.5"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-class-properties": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+      "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-jsx": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz",
+      "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.27.2",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+      "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.27.1",
+        "@babel/parser": "^7.27.2",
+        "@babel/types": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
+      "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.27.1",
+        "@babel/generator": "^7.28.5",
+        "@babel/helper-globals": "^7.28.0",
+        "@babel/parser": "^7.28.5",
+        "@babel/template": "^7.27.2",
+        "@babel/types": "^7.28.5",
+        "debug": "^4.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
+      "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.27.1",
+        "@babel/helper-validator-identifier": "^7.28.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@discoveryjs/json-ext": {
       "version": "0.6.3",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
@@ -238,6 +577,17 @@
         "@jridgewell/trace-mapping": "^0.3.24"
       }
     },
+    "node_modules/@jridgewell/remapping": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+      "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
     "node_modules/@jridgewell/resolve-uri": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
@@ -273,6 +623,47 @@
         "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
+    "node_modules/@mdn/browser-compat-data": {
+      "version": "5.7.6",
+      "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.7.6.tgz",
+      "integrity": "sha512-7xdrMX0Wk7grrTZQwAoy1GkvPMFoizStUoL+VmtUkAxegbCCec+3FKwOM6yc/uGU5+BEczQHXAlWiqvM8JeENg==",
+      "dev": true,
+      "license": "CC0-1.0"
+    },
+    "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
+      "version": "5.1.1-v1",
+      "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
+      "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "eslint-scope": "5.1.1"
+      }
+    },
+    "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
     "node_modules/@stylistic/eslint-plugin": {
       "version": "5.6.1",
       "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.6.1.tgz",
@@ -942,48 +1333,222 @@
       "dev": true,
       "license": "Python-2.0"
     },
-    "node_modules/balanced-match": {
+    "node_modules/array-buffer-byte-length": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+      "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
       "dev": true,
-      "license": "MIT"
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "is-array-buffer": "^3.0.5"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "node_modules/baseline-browser-mapping": {
-      "version": "2.9.7",
-      "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz",
-      "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==",
-      "license": "Apache-2.0",
-      "bin": {
-        "baseline-browser-mapping": "dist/cli.js"
+    "node_modules/array-includes": {
+      "version": "3.1.9",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
+      "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.4",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.24.0",
+        "es-object-atoms": "^1.1.1",
+        "get-intrinsic": "^1.3.0",
+        "is-string": "^1.1.1",
+        "math-intrinsics": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/brace-expansion": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
-      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+    "node_modules/array.prototype.findlast": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+      "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.2",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.0.0",
+        "es-shim-unscopables": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/braces": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
-      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+    "node_modules/array.prototype.flat": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+      "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
-        "fill-range": "^7.1.1"
+        "call-bind": "^1.0.8",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.5",
+        "es-shim-unscopables": "^1.0.2"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/browserslist": {
-      "version": "4.28.1",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+    "node_modules/array.prototype.flatmap": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+      "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.5",
+        "es-shim-unscopables": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array.prototype.tosorted": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+      "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.3",
+        "es-errors": "^1.3.0",
+        "es-shim-unscopables": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/arraybuffer.prototype.slice": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+      "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "array-buffer-byte-length": "^1.0.1",
+        "call-bind": "^1.0.8",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.5",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "is-array-buffer": "^3.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/ast-metadata-inferer": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.8.1.tgz",
+      "integrity": "sha512-ht3Dm6Zr7SXv6t1Ra6gFo0+kLDglHGrEbYihTkcycrbHw7WCcuhBzPlJYHEsIpycaUwzsJHje+vUcxXUX4ztTA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@mdn/browser-compat-data": "^5.6.19"
+      }
+    },
+    "node_modules/async-function": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+      "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/available-typed-arrays": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+      "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "possible-typed-array-names": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/baseline-browser-mapping": {
+      "version": "2.9.7",
+      "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz",
+      "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==",
+      "license": "Apache-2.0",
+      "bin": {
+        "baseline-browser-mapping": "dist/cli.js"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+      "license": "MIT",
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.28.1",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
       "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
       "funding": [
         {
@@ -1020,6 +1585,56 @@
       "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
       "license": "MIT"
     },
+    "node_modules/call-bind": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+      "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.0",
+        "es-define-property": "^1.0.0",
+        "get-intrinsic": "^1.2.4",
+        "set-function-length": "^1.2.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/call-bound": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+      "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "get-intrinsic": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -1126,6 +1741,13 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/cross-spawn": {
       "version": "7.0.6",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -1140,6 +1762,60 @@
         "node": ">= 8"
       }
     },
+    "node_modules/data-view-buffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+      "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "es-errors": "^1.3.0",
+        "is-data-view": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/data-view-byte-length": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+      "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "es-errors": "^1.3.0",
+        "is-data-view": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/inspect-js"
+      }
+    },
+    "node_modules/data-view-byte-offset": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+      "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "is-data-view": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/debug": {
       "version": "4.4.3",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
@@ -1165,6 +1841,70 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/define-data-property": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/define-properties": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+      "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "define-data-property": "^1.0.1",
+        "has-property-descriptors": "^1.0.0",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/electron-to-chromium": {
       "version": "1.5.267",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
@@ -1196,47 +1936,224 @@
         "node": ">=4"
       }
     },
-    "node_modules/es-module-lexer": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
-      "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
-      "license": "MIT"
+    "node_modules/es-abstract": {
+      "version": "1.24.1",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
+      "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "array-buffer-byte-length": "^1.0.2",
+        "arraybuffer.prototype.slice": "^1.0.4",
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.4",
+        "data-view-buffer": "^1.0.2",
+        "data-view-byte-length": "^1.0.2",
+        "data-view-byte-offset": "^1.0.1",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.1.1",
+        "es-set-tostringtag": "^2.1.0",
+        "es-to-primitive": "^1.3.0",
+        "function.prototype.name": "^1.1.8",
+        "get-intrinsic": "^1.3.0",
+        "get-proto": "^1.0.1",
+        "get-symbol-description": "^1.1.0",
+        "globalthis": "^1.0.4",
+        "gopd": "^1.2.0",
+        "has-property-descriptors": "^1.0.2",
+        "has-proto": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "internal-slot": "^1.1.0",
+        "is-array-buffer": "^3.0.5",
+        "is-callable": "^1.2.7",
+        "is-data-view": "^1.0.2",
+        "is-negative-zero": "^2.0.3",
+        "is-regex": "^1.2.1",
+        "is-set": "^2.0.3",
+        "is-shared-array-buffer": "^1.0.4",
+        "is-string": "^1.1.1",
+        "is-typed-array": "^1.1.15",
+        "is-weakref": "^1.1.1",
+        "math-intrinsics": "^1.1.0",
+        "object-inspect": "^1.13.4",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.7",
+        "own-keys": "^1.0.1",
+        "regexp.prototype.flags": "^1.5.4",
+        "safe-array-concat": "^1.1.3",
+        "safe-push-apply": "^1.0.0",
+        "safe-regex-test": "^1.1.0",
+        "set-proto": "^1.0.0",
+        "stop-iteration-iterator": "^1.1.0",
+        "string.prototype.trim": "^1.2.10",
+        "string.prototype.trimend": "^1.0.9",
+        "string.prototype.trimstart": "^1.0.8",
+        "typed-array-buffer": "^1.0.3",
+        "typed-array-byte-length": "^1.0.3",
+        "typed-array-byte-offset": "^1.0.4",
+        "typed-array-length": "^1.0.7",
+        "unbox-primitive": "^1.1.0",
+        "which-typed-array": "^1.1.19"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "node_modules/escalade": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
-      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+      "dev": true,
       "license": "MIT",
       "engines": {
-        "node": ">=6"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
       "dev": true,
       "license": "MIT",
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/eslint": {
-      "version": "9.39.2",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
-      "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
+    "node_modules/es-iterator-helpers": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz",
+      "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@eslint-community/eslint-utils": "^4.8.0",
-        "@eslint-community/regexpp": "^4.12.1",
-        "@eslint/config-array": "^0.21.1",
-        "@eslint/config-helpers": "^0.4.2",
-        "@eslint/core": "^0.17.0",
-        "@eslint/eslintrc": "^3.3.1",
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.4",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.24.1",
+        "es-errors": "^1.3.0",
+        "es-set-tostringtag": "^2.1.0",
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.3.0",
+        "globalthis": "^1.0.4",
+        "gopd": "^1.2.0",
+        "has-property-descriptors": "^1.0.2",
+        "has-proto": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "internal-slot": "^1.1.0",
+        "iterator.prototype": "^1.1.5",
+        "safe-array-concat": "^1.1.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-module-lexer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
+      "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
+      "license": "MIT"
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-shim-unscopables": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+      "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-to-primitive": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+      "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-callable": "^1.2.7",
+        "is-date-object": "^1.0.5",
+        "is-symbol": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint": {
+      "version": "9.39.2",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
+      "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.8.0",
+        "@eslint-community/regexpp": "^4.12.1",
+        "@eslint/config-array": "^0.21.1",
+        "@eslint/config-helpers": "^0.4.2",
+        "@eslint/core": "^0.17.0",
+        "@eslint/eslintrc": "^3.3.1",
         "@eslint/js": "9.39.2",
         "@eslint/plugin-kit": "^0.4.1",
         "@humanfs/node": "^0.16.6",
@@ -1284,6 +2201,137 @@
         }
       }
     },
+    "node_modules/eslint-config-preact": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-preact/-/eslint-config-preact-2.0.0.tgz",
+      "integrity": "sha512-TFj70lEE7y3R9DQAFJ/clRfVmyaXdwE3q56gA9zm+iTmlpYjtZKtV1jv/jtgdF2LqgvJjlGlGE1rHVwE9yNdkg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "^7.13.16",
+        "@babel/eslint-parser": "^7.27.5",
+        "@babel/plugin-syntax-class-properties": "^7.12.13",
+        "@babel/plugin-syntax-jsx": "^7.12.13",
+        "@eslint/js": "^9.29.0",
+        "eslint-plugin-compat": "^6.0.2",
+        "eslint-plugin-react": "^7.37.5",
+        "eslint-plugin-react-hooks": "^5.2.0",
+        "globals": "^16.2.0"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.1 || ^9.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-compat": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-6.0.2.tgz",
+      "integrity": "sha512-1ME+YfJjmOz1blH0nPZpHgjMGK4kjgEeoYqGCqoBPQ/mGu/dJzdoP0f1C8H2jcWZjzhZjAMccbM/VdXhPORIfA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@mdn/browser-compat-data": "^5.5.35",
+        "ast-metadata-inferer": "^0.8.1",
+        "browserslist": "^4.24.2",
+        "caniuse-lite": "^1.0.30001687",
+        "find-up": "^5.0.0",
+        "globals": "^15.7.0",
+        "lodash.memoize": "^4.1.2",
+        "semver": "^7.6.2"
+      },
+      "engines": {
+        "node": ">=18.x"
+      },
+      "peerDependencies": {
+        "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-compat/node_modules/globals": {
+      "version": "15.15.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
+      "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint-plugin-react": {
+      "version": "7.37.5",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
+      "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "array-includes": "^3.1.8",
+        "array.prototype.findlast": "^1.2.5",
+        "array.prototype.flatmap": "^1.3.3",
+        "array.prototype.tosorted": "^1.1.4",
+        "doctrine": "^2.1.0",
+        "es-iterator-helpers": "^1.2.1",
+        "estraverse": "^5.3.0",
+        "hasown": "^2.0.2",
+        "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+        "minimatch": "^3.1.2",
+        "object.entries": "^1.1.9",
+        "object.fromentries": "^2.0.8",
+        "object.values": "^1.2.1",
+        "prop-types": "^15.8.1",
+        "resolve": "^2.0.0-next.5",
+        "semver": "^6.3.1",
+        "string.prototype.matchall": "^4.0.12",
+        "string.prototype.repeat": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      },
+      "peerDependencies": {
+        "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
+      }
+    },
+    "node_modules/eslint-plugin-react-hooks": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
+      "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-react/node_modules/resolve": {
+      "version": "2.0.0-next.5",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
+      "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-core-module": "^2.13.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/eslint-plugin-react/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
     "node_modules/eslint-scope": {
       "version": "8.4.0",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
@@ -1546,6 +2594,22 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/for-each": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+      "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-callable": "^1.2.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/function-bind": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -1555,6 +2619,114 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/function.prototype.name": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+      "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.3",
+        "define-properties": "^1.2.1",
+        "functions-have-names": "^1.2.3",
+        "hasown": "^2.0.2",
+        "is-callable": "^1.2.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/functions-have-names": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/generator-function": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
+      "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+      "dev": true,
+      "license": "MIT",
+      "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"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/get-symbol-description": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+      "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/glob-parent": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -1587,12 +2759,55 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/globalthis": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+      "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "define-properties": "^1.2.1",
+        "gopd": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
       "license": "ISC"
     },
+    "node_modules/has-bigints": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+      "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -1602,8 +2817,66 @@
         "node": ">=8"
       }
     },
-    "node_modules/hasown": {
-      "version": "2.0.2",
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-define-property": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-proto": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+      "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
       "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
       "license": "MIT",
@@ -1667,25 +2940,381 @@
       "dev": true,
       "license": "MIT",
       "engines": {
-        "node": ">=0.8.19"
+        "node": ">=0.8.19"
+      }
+    },
+    "node_modules/internal-slot": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+      "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "hasown": "^2.0.2",
+        "side-channel": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/interpret": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+      "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/is-array-buffer": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+      "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.3",
+        "get-intrinsic": "^1.2.6"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-async-function": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+      "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "async-function": "^1.0.0",
+        "call-bound": "^1.0.3",
+        "get-proto": "^1.0.1",
+        "has-tostringtag": "^1.0.2",
+        "safe-regex-test": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-bigint": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+      "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "has-bigints": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-boolean-object": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+      "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-callable": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.16.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+      "license": "MIT",
+      "dependencies": {
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-data-view": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+      "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "get-intrinsic": "^1.2.6",
+        "is-typed-array": "^1.1.13"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-date-object": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+      "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-finalizationregistry": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+      "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-generator-function": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
+      "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.4",
+        "generator-function": "^2.0.0",
+        "get-proto": "^1.0.1",
+        "has-tostringtag": "^1.0.2",
+        "safe-regex-test": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-map": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+      "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-negative-zero": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+      "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-number-object": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+      "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "license": "MIT",
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-regex": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+      "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "gopd": "^1.2.0",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-set": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+      "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-shared-array-buffer": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+      "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-string": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+      "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/interpret": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
-      "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+    "node_modules/is-symbol": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+      "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+      "dev": true,
       "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "has-symbols": "^1.1.0",
+        "safe-regex-test": "^1.1.0"
+      },
       "engines": {
-        "node": ">=10.13.0"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/is-core-module": {
-      "version": "2.16.1",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
-      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+    "node_modules/is-typed-array": {
+      "version": "1.1.15",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+      "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
-        "hasown": "^2.0.2"
+        "which-typed-array": "^1.1.16"
       },
       "engines": {
         "node": ">= 0.4"
@@ -1694,50 +3323,59 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+    "node_modules/is-weakmap": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+      "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
       "dev": true,
       "license": "MIT",
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+    "node_modules/is-weakref": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+      "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "is-extglob": "^2.1.1"
+        "call-bound": "^1.0.3"
       },
       "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.12.0"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/is-plain-object": {
+    "node_modules/is-weakset": {
       "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
-      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+      "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
-        "isobject": "^3.0.1"
+        "call-bound": "^1.0.3",
+        "get-intrinsic": "^1.2.6"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/isarray": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+      "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -1753,6 +3391,24 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/iterator.prototype": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
+      "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "define-data-property": "^1.1.4",
+        "es-object-atoms": "^1.0.0",
+        "get-intrinsic": "^1.2.6",
+        "get-proto": "^1.0.0",
+        "has-symbols": "^1.1.0",
+        "set-function-name": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/jest-worker": {
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -1782,6 +3438,13 @@
         "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/js-yaml": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
@@ -1795,6 +3458,19 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
+    "node_modules/jsesc": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/json-buffer": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
@@ -1822,6 +3498,35 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsx-ast-utils": {
+      "version": "3.3.5",
+      "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+      "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "array-includes": "^3.1.6",
+        "array.prototype.flat": "^1.3.1",
+        "object.assign": "^4.1.4",
+        "object.values": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
     "node_modules/keyv": {
       "version": "4.5.4",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -1884,6 +3589,13 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/lodash.memoize": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+      "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -1891,6 +3603,39 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -1982,6 +3727,114 @@
       "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
       "license": "MIT"
     },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.13.4",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+      "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.assign": {
+      "version": "4.1.7",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+      "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.3",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.0.0",
+        "has-symbols": "^1.1.0",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object.entries": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz",
+      "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.4",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.fromentries": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+      "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.2",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object.values": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+      "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.3",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/optionator": {
       "version": "0.9.4",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -2000,6 +3853,24 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/own-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+      "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "get-intrinsic": "^1.2.6",
+        "object-keys": "^1.1.1",
+        "safe-push-apply": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/p-limit": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -2161,6 +4032,16 @@
         "node": ">=8"
       }
     },
+    "node_modules/possible-typed-array-names": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+      "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/preact": {
       "version": "10.28.0",
       "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.0.tgz",
@@ -2181,6 +4062,18 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/prop-types": {
+      "version": "15.8.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "loose-envify": "^1.4.0",
+        "object-assign": "^4.1.1",
+        "react-is": "^16.13.1"
+      }
+    },
     "node_modules/punycode": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -2199,6 +4092,13 @@
         "safe-buffer": "^5.1.0"
       }
     },
+    "node_modules/react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/rechoir": {
       "version": "0.8.0",
       "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
@@ -2211,6 +4111,50 @@
         "node": ">= 10.13.0"
       }
     },
+    "node_modules/reflect.getprototypeof": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+      "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.9",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.0.0",
+        "get-intrinsic": "^1.2.7",
+        "get-proto": "^1.0.1",
+        "which-builtin-type": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/regexp.prototype.flags": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+      "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "define-properties": "^1.2.1",
+        "es-errors": "^1.3.0",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "set-function-name": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/require-from-string": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -2271,6 +4215,26 @@
         "node": ">=4"
       }
     },
+    "node_modules/safe-array-concat": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+      "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.2",
+        "get-intrinsic": "^1.2.6",
+        "has-symbols": "^1.1.0",
+        "isarray": "^2.0.5"
+      },
+      "engines": {
+        "node": ">=0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -2291,6 +4255,41 @@
       ],
       "license": "MIT"
     },
+    "node_modules/safe-push-apply": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+      "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "isarray": "^2.0.5"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/safe-regex-test": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+      "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "is-regex": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/schema-utils": {
       "version": "4.3.3",
       "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
@@ -2365,6 +4364,55 @@
         "randombytes": "^2.1.0"
       }
     },
+    "node_modules/set-function-length": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+      "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.4",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/set-function-name": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+      "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
+        "functions-have-names": "^1.2.3",
+        "has-property-descriptors": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/set-proto": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+      "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/shallow-clone": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@@ -2398,6 +4446,82 @@
         "node": ">=8"
       }
     },
+    "node_modules/side-channel": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+      "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+      "dev": true,
+      "license": "MIT",
+      "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"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-list": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+      "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-map": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+      "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-weakmap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+      "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+      "dev": true,
+      "license": "MIT",
+      "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"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/source-map": {
       "version": "0.7.6",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
@@ -2426,6 +4550,118 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/stop-iteration-iterator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+      "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "internal-slot": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/string.prototype.matchall": {
+      "version": "4.0.12",
+      "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
+      "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.3",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.6",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.0.0",
+        "get-intrinsic": "^1.2.6",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "internal-slot": "^1.1.0",
+        "regexp.prototype.flags": "^1.5.3",
+        "set-function-name": "^2.0.2",
+        "side-channel": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.repeat": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+      "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "node_modules/string.prototype.trim": {
+      "version": "1.2.10",
+      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+      "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.2",
+        "define-data-property": "^1.1.4",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.5",
+        "es-object-atoms": "^1.0.0",
+        "has-property-descriptors": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimend": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+      "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.2",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimstart": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+      "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/strip-json-comments": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -2603,6 +4839,84 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/typed-array-buffer": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+      "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "es-errors": "^1.3.0",
+        "is-typed-array": "^1.1.14"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/typed-array-byte-length": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+      "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "for-each": "^0.3.3",
+        "gopd": "^1.2.0",
+        "has-proto": "^1.2.0",
+        "is-typed-array": "^1.1.14"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typed-array-byte-offset": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+      "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.8",
+        "for-each": "^0.3.3",
+        "gopd": "^1.2.0",
+        "has-proto": "^1.2.0",
+        "is-typed-array": "^1.1.15",
+        "reflect.getprototypeof": "^1.0.9"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typed-array-length": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+      "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "is-typed-array": "^1.1.13",
+        "possible-typed-array-names": "^1.0.0",
+        "reflect.getprototypeof": "^1.0.6"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/typescript": {
       "version": "5.9.3",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
@@ -2641,6 +4955,25 @@
         "typescript": ">=4.8.4 <6.0.0"
       }
     },
+    "node_modules/unbox-primitive": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+      "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "has-bigints": "^1.0.2",
+        "has-symbols": "^1.1.0",
+        "which-boxed-primitive": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/undici-types": {
       "version": "7.16.0",
       "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
@@ -2859,6 +5192,95 @@
         "node": ">= 8"
       }
     },
+    "node_modules/which-boxed-primitive": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+      "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-bigint": "^1.1.0",
+        "is-boolean-object": "^1.2.1",
+        "is-number-object": "^1.1.1",
+        "is-string": "^1.1.1",
+        "is-symbol": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-builtin-type": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+      "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "function.prototype.name": "^1.1.6",
+        "has-tostringtag": "^1.0.2",
+        "is-async-function": "^2.0.0",
+        "is-date-object": "^1.1.0",
+        "is-finalizationregistry": "^1.1.0",
+        "is-generator-function": "^1.0.10",
+        "is-regex": "^1.2.1",
+        "is-weakref": "^1.0.2",
+        "isarray": "^2.0.5",
+        "which-boxed-primitive": "^1.1.0",
+        "which-collection": "^1.0.2",
+        "which-typed-array": "^1.1.16"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-collection": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+      "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-map": "^2.0.3",
+        "is-set": "^2.0.3",
+        "is-weakmap": "^2.0.2",
+        "is-weakset": "^2.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-typed-array": {
+      "version": "1.1.19",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+      "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.4",
+        "for-each": "^0.3.5",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/wildcard": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
@@ -2875,6 +5297,13 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true,
+      "license": "ISC"
+    },
     "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/dumper-companion/package.json b/dumper-companion/package.json
index c2a3b5c2..5bf81699 100644
--- a/dumper-companion/package.json
+++ b/dumper-companion/package.json
@@ -6,13 +6,6 @@
     "build-dev": "webpack --mode=development",
     "lint": "eslint ."
   },
-  "devDependencies": {
-    "@eslint/js": "^9.39.1",
-    "@stylistic/eslint-plugin": "^5.6.1",
-    "eslint": "^9.39.1",
-    "globals": "^16.5.0",
-    "typescript-eslint": "^8.50.0"
-  },
   "dependencies": {
     "@zip.js/zip.js": "^2.8.11",
     "preact": "^10.28.0",
@@ -20,5 +13,13 @@
     "ts-loader": "^9.5.4",
     "webpack": "^5.104.1",
     "webpack-cli": "^6.0.1"
+  },
+  "devDependencies": {
+    "@eslint/js": "^9.39.1",
+    "@stylistic/eslint-plugin": "^5.6.1",
+    "eslint": "^9.39.1",
+    "eslint-config-preact": "^2.0.0",
+    "globals": "^16.5.0",
+    "typescript-eslint": "^8.50.0"
   }
 }


Commit: 268f08ffd3528d98deb620c36858dcc02e7b8e2d
    https://github.com/scummvm/scummvm-web/commit/268f08ffd3528d98deb620c36858dcc02e7b8e2d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-12-26T21:00:26Z

Commit Message:
WEB: Run npm install

Changed paths:
    package-lock.json


diff --git a/package-lock.json b/package-lock.json
index e062f9dc..a98cc883 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -387,7 +387,6 @@
         }
       ],
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "baseline-browser-mapping": "^2.9.0",
         "caniuse-lite": "^1.0.30001759",
@@ -613,7 +612,6 @@
         }
       ],
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "nanoid": "^3.3.11",
         "picocolors": "^1.1.1",




More information about the Scummvm-git-logs mailing list