/tests/__mocks__/browser.ts"],
+ collectCoverageFrom: [
+ "src/core/engine/**/*.ts",
+ "src/platform/audio/**/*.ts",
+ ],
+ coverageDirectory: "coverage",
+ coverageReporters: ["text", "json", "html"],
+ verbose: true,
+};
diff --git a/Build/package-lock.json b/Build/package-lock.json
index e3894de..9363f07 100644
--- a/Build/package-lock.json
+++ b/Build/package-lock.json
@@ -8,83 +8,116 @@
"name": "htmlplayer",
"version": "2.0.0",
"dependencies": {
+ "@audiflo/libflo": "^0.1.3",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
- "@dnd-kit/utilities": "^3.2.2",
- "@flo-audio/libflo-audio": "^0.1.2",
- "@flo-audio/reflo": "^0.1.2",
- "@fontsource/caveat": "^5.2.8",
- "@fontsource/inter": "^5.2.8",
- "@fontsource/jetbrains-mono": "^5.2.8",
- "@fontsource/poppins": "^5.2.7",
- "@nisoku/satori-log": "^0.1.2",
- "@radix-ui/react-collapsible": "^1.1.12",
- "@radix-ui/react-dialog": "^1.1.15",
- "@radix-ui/react-dropdown-menu": "^2.1.16",
- "@radix-ui/react-select": "^2.2.6",
- "@radix-ui/react-separator": "^1.1.8",
- "@radix-ui/react-slider": "^1.3.6",
- "@radix-ui/react-slot": "^1.2.4",
- "@radix-ui/react-switch": "^1.2.6",
- "@radix-ui/react-tooltip": "^1.2.8",
+ "@fontsource/caveat": "^5.3.0",
+ "@fontsource/inter": "^5.3.0",
+ "@fontsource/jetbrains-mono": "^5.3.0",
+ "@fontsource/poppins": "^5.3.0",
+ "@gsap/react": "^2.1.2",
+ "@nisoku/satori": "^0.1.3",
+ "@radix-ui/react-collapsible": "^1.1.20",
+ "@radix-ui/react-dialog": "^1.1.23",
+ "@radix-ui/react-dropdown-menu": "^2.1.24",
+ "@radix-ui/react-select": "^2.3.7",
+ "@radix-ui/react-separator": "^1.1.15",
+ "@radix-ui/react-slider": "^1.4.7",
+ "@radix-ui/react-slot": "^1.3.3",
+ "@radix-ui/react-switch": "^1.3.7",
+ "@radix-ui/react-tooltip": "^1.2.16",
"@reactour/tour": "^3.8.0",
- "@tauri-apps/api": "^2.10.1",
- "@tauri-apps/plugin-dialog": "^2.6.0",
- "@tauri-apps/plugin-fs": "^2.4.5",
- "@tauri-apps/plugin-notification": "^2.3.3",
- "@tauri-apps/plugin-opener": "^2.5.3",
- "@uppy/core": "^5.2.0",
- "@uppy/dashboard": "^5.1.1",
- "@uppy/react": "^5.2.0",
+ "@tauri-apps/api": "^2.11.1",
+ "@tauri-apps/plugin-dialog": "^2.7.3",
+ "@tauri-apps/plugin-fs": "^2.5.2",
+ "@tauri-apps/plugin-notification": "^2.4.0",
+ "@tauri-apps/plugin-opener": "^2.5.5",
+ "@uppy/core": "^6.0.1",
+ "@uppy/dashboard": "^6.0.0",
+ "@uppy/react": "^6.0.0",
"@web-scrobbler/metadata-filter": "^3.2.0",
- "dompurify": "^3.3.3",
- "i18next": "^25.8.18",
+ "@zag-js/marquee": "^1.44.0",
+ "@zag-js/react": "^1.44.0",
+ "dompurify": "^3.4.15",
+ "dsssp": "^0.8.0",
+ "gsap": "^3.15.0",
+ "i18next": "^26.4.2",
"i18next-browser-languagedetector": "^8.2.1",
- "i18next-http-backend": "^3.0.2",
- "lodash": "^4.17.23",
+ "i18next-http-backend": "^4.0.2",
"lucide-react": "^0.577.0",
- "music-metadata": "^11.12.3",
- "react": "^19.2.4",
- "react-dom": "^19.2.4",
- "react-i18next": "^16.5.8",
- "react-icons": "^5.6.0",
- "sonner": "^2.0.7",
- "vite-plugin-singlefile": "^2.3.2",
- "zustand": "^5.0.12"
+ "m3u-parser-generator": "^5.0.2",
+ "music-metadata": "^11.16.0",
+ "react": "^19.3.0",
+ "react-dom": "^19.3.0",
+ "react-i18next": "^17.0.15",
+ "react-icons": "^5.7.0",
+ "sonner": "^2.0.8",
+ "tone": "^15.1.22",
+ "vite-plugin-singlefile": "^2.3.3",
+ "zustand": "^5.0.15"
},
"devDependencies": {
- "@tauri-apps/cli": "^2.10.1",
- "@types/jasmine": "^6.0.0",
+ "@babel/plugin-transform-runtime": "^7.29.0",
+ "@tauri-apps/cli": "^2.11.5",
"@types/jest": "^30.0.0",
- "@types/lodash": "^4.17.24",
- "@types/node": "^25.5.0",
- "@types/react": "^19.2.14",
- "@types/react-dom": "^19.2.3",
- "@typescript-eslint/eslint-plugin": "^8.57.0",
- "@typescript-eslint/parser": "^8.57.0",
- "@vite-pwa/assets-generator": "^1.0.2",
- "@vitejs/plugin-react": "^5.2.0",
+ "@types/node": "^26.6.2",
+ "@types/react": "^19.3.0",
+ "@types/react-dom": "^19.3.0",
+ "@typescript-eslint/eslint-plugin": "^8.70.1",
+ "@typescript-eslint/parser": "^8.70.1",
+ "@vite-pwa/assets-generator": "^1.0.4",
+ "@vitejs/plugin-react": "^6.1.1",
"cloc": "^2.11.0",
"cross-env": "^10.1.0",
- "eslint": "^9.39.4",
+ "eslint": "^9.39.5",
"eslint-plugin-react": "^7.37.5",
+ "jest": "^30.5.2",
+ "jest-environment-jsdom": "^30.5.2",
"npm-check-updates": "^19.6.3",
- "prettier": "^3.8.1",
- "vite": "^7.3.1",
- "vite-plugin-pwa": "^1.2.0",
- "vite-plugin-top-level-await": "^1.6.0",
+ "prettier": "^3.9.8",
+ "ts-jest": "^29.4.12",
+ "vite": "^8.3.0",
+ "vite-plugin-pwa": "^1.3.0",
"vite-plugin-wasm": "^3.6.0",
- "workbox-window": "^7.4.0"
+ "workbox-precaching": "^7.4.1",
+ "workbox-routing": "^7.4.1"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
}
},
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@audiflo/libflo": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@audiflo/libflo/-/libflo-0.1.3.tgz",
+ "integrity": "sha512-QXqCwnxG4MD8b+jAgWTokPjOKV0evfqsZsOvQWRSqjumkDan0PU+mF16FgyMgj9rRkAruPbctQvuwU/cqRtrfQ==",
+ "license": "Apache-2.0"
+ },
"node_modules/@babel/code-frame": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
- "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/helper-validator-identifier": "^7.29.7",
"js-tokens": "^4.0.0",
"picocolors": "^1.1.1"
},
@@ -93,9 +126,9 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
- "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -103,21 +136,21 @@
}
},
"node_modules/@babel/core": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
- "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-compilation-targets": "^7.28.6",
- "@babel/helper-module-transforms": "^7.28.6",
- "@babel/helpers": "^7.28.6",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/traverse": "^7.29.0",
- "@babel/types": "^7.29.0",
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-compilation-targets": "^7.29.7",
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helpers": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7",
"@jridgewell/remapping": "^2.3.5",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
@@ -144,14 +177,14 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.29.1",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
- "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz",
+ "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.29.0",
- "@babel/types": "^7.29.0",
+ "@babel/parser": "^7.29.8",
+ "@babel/types": "^7.29.8",
"@jridgewell/gen-mapping": "^0.3.12",
"@jridgewell/trace-mapping": "^0.3.28",
"jsesc": "^3.0.2"
@@ -174,14 +207,14 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
- "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.28.6",
- "@babel/helper-validator-option": "^7.27.1",
+ "@babel/compat-data": "^7.29.7",
+ "@babel/helper-validator-option": "^7.29.7",
"browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
@@ -299,9 +332,9 @@
}
},
"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==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -323,29 +356,29 @@
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
- "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
- "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.28.6",
- "@babel/helper-validator-identifier": "^7.28.5",
- "@babel/traverse": "^7.28.6"
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
@@ -368,9 +401,9 @@
}
},
"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==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -428,9 +461,9 @@
}
},
"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==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -438,9 +471,9 @@
}
},
"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==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -448,9 +481,9 @@
}
},
"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==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -473,27 +506,27 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
- "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
- "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.29.0"
+ "@babel/types": "^7.29.8"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -599,6 +632,61 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.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-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-syntax-import-assertions": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz",
@@ -631,6 +719,174 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+ "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+ "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-syntax-unicode-sets-regex": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
@@ -1070,16 +1326,16 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz",
- "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.8.tgz",
+ "integrity": "sha512-6iSnEK0zlkLKU4heofK/AdmRD4e2SHVpJMtrwnTCzhnaM98ria4rTrOXBBi45BTTYnJtO8txnPsX4fChYXkmeA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.28.3",
- "@babel/helper-plugin-utils": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5",
- "@babel/traverse": "^7.28.5"
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helper-plugin-utils": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.8"
},
"engines": {
"node": ">=6.9.0"
@@ -1307,38 +1563,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
- "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
- "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/plugin-transform-react-jsx-source": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
- "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
- "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/plugin-transform-regenerator": {
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz",
@@ -1388,6 +1612,37 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-runtime": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.7.tgz",
+ "integrity": "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-plugin-utils": "^7.29.7",
+ "babel-plugin-polyfill-corejs2": "^0.4.14",
+ "babel-plugin-polyfill-corejs3": "^0.13.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.5",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-runtime/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/plugin-transform-shorthand-properties": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
@@ -1647,42 +1902,42 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
- "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
+ "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
- "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.28.6",
- "@babel/parser": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz",
+ "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0",
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.8",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.8",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.8",
"debug": "^4.3.1"
},
"engines": {
@@ -1690,19 +1945,26 @@
}
},
"node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@borewit/text-codec": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz",
@@ -1720,23 +1982,138 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@dnd-kit/accessibility": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
- "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
"license": "MIT",
- "dependencies": {
- "tslib": "^2.0.0"
+ "engines": {
+ "node": ">=18"
},
"peerDependencies": {
- "react": ">=16.8.0"
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
}
},
- "node_modules/@dnd-kit/core": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
- "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
- "license": "MIT",
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^5.1.0",
+ "@csstools/css-calc": "^2.1.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@dnd-kit/accessibility": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
+ "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@dnd-kit/core": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
+ "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
+ "license": "MIT",
"dependencies": {
"@dnd-kit/accessibility": "^3.1.1",
"@dnd-kit/utilities": "^3.2.2",
@@ -1773,10 +2150,33 @@
"react": ">=16.8.0"
}
},
+ "node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@emnapi/runtime": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz",
- "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==",
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
+ "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -1791,1905 +2191,1924 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
- "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
- "cpu": [
- "ppc64"
- ],
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
"engines": {
- "node": ">=18"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
- "node_modules/@esbuild/android-arm": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
- "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
"engines": {
- "node": ">=18"
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
- "node_modules/@esbuild/android-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
- "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz",
+ "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.5"
+ },
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@esbuild/android-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
- "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
"engines": {
- "node": ">=18"
+ "node": "*"
}
},
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
- "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
- "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
- "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.7.tgz",
+ "integrity": "sha512-F42g89Qd5oAWtp0k0nnSrjziAKza7w8SVT4mStc18LZMaRb4J1HQAHLCalEtDCxrTuksx7NU9qsmeLwpOfPqWw==",
+ "dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
+ "dependencies": {
+ "ajv": "^6.14.0",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.3.2",
+ "minimatch": "^3.1.5",
+ "strip-json-comments": "^3.1.1"
+ },
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
- "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@eslint/eslintrc/node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
"engines": {
- "node": ">=18"
+ "node": ">= 4"
}
},
- "node_modules/@esbuild/linux-arm": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
- "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
"engines": {
- "node": ">=18"
+ "node": "*"
}
},
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
- "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@eslint/js": {
+ "version": "9.39.5",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz",
+ "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==",
+ "dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
}
},
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
- "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
+ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
- "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
- "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
- "cpu": [
- "mips64el"
- ],
+ "node_modules/@floating-ui/core": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz",
+ "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.12"
}
},
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
- "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
- "cpu": [
- "ppc64"
- ],
+ "node_modules/@floating-ui/dom": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz",
+ "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
+ "dependencies": {
+ "@floating-ui/core": "^1.8.0",
+ "@floating-ui/utils": "^0.2.12"
}
},
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
- "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
- "cpu": [
- "riscv64"
- ],
+ "node_modules/@floating-ui/react-dom": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz",
+ "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==",
"license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@floating-ui/dom": "^1.8.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.12",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz",
+ "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==",
+ "license": "MIT"
+ },
+ "node_modules/@fontsource/caveat": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/caveat/-/caveat-5.3.0.tgz",
+ "integrity": "sha512-eHTfzQxFSW9ABERRLNruHoNJmKed2J7pqTUc5lp4a4POMgXGKpxmWj3d9Hz10kmAg6iuTTLe6UagbA4bnsmfQw==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource/inter": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.3.0.tgz",
+ "integrity": "sha512-RofMylZmjlJEfELXeNHFWBRcSs75rGU/6bV2S2jfnvv/3rPXPGe0LgUJTklcHZ9lM4OZmAVFhcJPnACfb91A3g==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource/jetbrains-mono": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/jetbrains-mono/-/jetbrains-mono-5.3.0.tgz",
+ "integrity": "sha512-fqDfB5I9f1p1TV486aUgB9t8zP84P0O1FtQR5Ol9vjwPy+S+EIGlVYm1cvj2W5shcZMTg2nZFdVMoH5wFu8a1A==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@fontsource/poppins": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource/poppins/-/poppins-5.3.0.tgz",
+ "integrity": "sha512-cms1nM7U6SN8epIV1WMVOV8VsA645aSm3wHfzIQnkk188U341ThbJGSl2Sv54V29gnDbT2arMPfLzvVIIVCceQ==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@gsap/react": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@gsap/react/-/react-2.1.2.tgz",
+ "integrity": "sha512-JqliybO1837UcgH2hVOM4VO+38APk3ECNrsuSM4MuXp+rbf+/2IG2K1YJiqfTcXQHH7XlA0m3ykniFYstfq0Iw==",
+ "license": "SEE LICENSE AT https://gsap.com/standard-license",
+ "peerDependencies": {
+ "gsap": "^3.12.5",
+ "react": ">=17"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
+ "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/types": "^0.15.0"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=18.18.0"
}
},
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
- "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
- "cpu": [
- "s390x"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "node_modules/@humanfs/node": {
+ "version": "0.16.8",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz",
+ "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.2",
+ "@humanfs/types": "^0.15.0",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=18.18.0"
}
},
- "node_modules/@esbuild/linux-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
- "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "node_modules/@humanfs/types": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz",
+ "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">=18"
+ "node": ">=18.18.0"
}
},
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
- "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@img/colour": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+ "dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
"engines": {
"node": ">=18"
}
},
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
- "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz",
+ "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==",
"cpu": [
- "x64"
+ "arm64"
],
- "license": "MIT",
+ "dev": true,
+ "license": "Apache-2.0",
"optional": true,
"os": [
- "netbsd"
+ "darwin"
],
"engines": {
- "node": ">=18"
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.3.3"
}
},
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
- "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz",
+ "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==",
"cpu": [
- "arm64"
+ "x64"
],
- "license": "MIT",
+ "dev": true,
+ "license": "Apache-2.0",
"optional": true,
"os": [
- "openbsd"
+ "darwin"
],
"engines": {
- "node": ">=18"
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.3.3"
}
},
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
- "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
+ "node_modules/@img/sharp-freebsd-wasm32": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz",
+ "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==",
+ "dev": true,
+ "license": "Apache-2.0",
"optional": true,
"os": [
- "openbsd"
+ "freebsd"
],
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.4"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
- "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz",
+ "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==",
"cpu": [
"arm64"
],
- "license": "MIT",
+ "dev": true,
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "openharmony"
+ "darwin"
],
- "engines": {
- "node": ">=18"
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
- "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz",
+ "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==",
"cpu": [
"x64"
],
- "license": "MIT",
+ "dev": true,
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "sunos"
+ "darwin"
],
- "engines": {
- "node": ">=18"
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
- "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz",
+ "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==",
"cpu": [
- "arm64"
+ "arm"
],
- "license": "MIT",
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "win32"
+ "linux"
],
- "engines": {
- "node": ">=18"
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
- "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz",
+ "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==",
"cpu": [
- "ia32"
+ "arm64"
],
- "license": "MIT",
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "win32"
+ "linux"
],
- "engines": {
- "node": ">=18"
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@esbuild/win32-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
- "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz",
+ "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==",
"cpu": [
- "x64"
+ "ppc64"
],
- "license": "MIT",
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
"optional": true,
"os": [
- "win32"
+ "linux"
],
- "engines": {
- "node": ">=18"
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
- "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz",
+ "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==",
+ "cpu": [
+ "riscv64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"funding": {
- "url": "https://opencollective.com/eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@eslint-community/regexpp": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
- "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz",
+ "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==",
+ "cpu": [
+ "s390x"
+ ],
"dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@eslint/config-array": {
- "version": "0.21.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz",
- "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==",
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz",
+ "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/object-schema": "^2.1.7",
- "debug": "^4.3.1",
- "minimatch": "^3.1.5"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@eslint/config-array/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/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz",
+ "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@eslint/config-array/node_modules/minimatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz",
+ "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@eslint/config-helpers": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
- "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz",
+ "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.3.3"
}
},
- "node_modules/@eslint/core": {
- "version": "0.17.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
- "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz",
+ "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.3.3"
}
},
- "node_modules/@eslint/eslintrc": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz",
- "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==",
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz",
+ "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==",
+ "cpu": [
+ "ppc64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.14.0",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.1",
- "minimatch": "^3.1.5",
- "strip-json-comments": "^3.1.1"
- },
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=20.9.0"
},
"funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/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"
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.3.3"
}
},
- "node_modules/@eslint/eslintrc/node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz",
+ "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==",
+ "cpu": [
+ "riscv64"
+ ],
"dev": true,
- "license": "MIT",
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">= 4"
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.3.3"
}
},
- "node_modules/@eslint/eslintrc/node_modules/minimatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz",
+ "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==",
+ "cpu": [
+ "s390x"
+ ],
"dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/@eslint/js": {
- "version": "9.39.4",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz",
- "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- }
- },
- "node_modules/@eslint/object-schema": {
- "version": "2.1.7",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
- "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/plugin-kit": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
- "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0",
- "levn": "^0.4.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@flo-audio/libflo-audio": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/@flo-audio/libflo-audio/-/libflo-audio-0.1.2.tgz",
- "integrity": "sha512-tMsyM1VX+MYPtpxgiS7mf8lI9YrkIv8CEn/1wEOXQIyPwVp+LM/Fgnlt4qz6cZX+3Cd0JvzYEr8d0RnFoxAZgA=="
- },
- "node_modules/@flo-audio/reflo": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/@flo-audio/reflo/-/reflo-0.1.2.tgz",
- "integrity": "sha512-drjhfovfuYFEh0Cc+2P/rnmHo0+AYpkCPyjanJjlHNpLlSJeTu1NiOWKA4RfxEitYip+3HiAgWygRkJnKTsCfQ=="
- },
- "node_modules/@floating-ui/core": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
- "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/utils": "^0.2.10"
- }
- },
- "node_modules/@floating-ui/dom": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
- "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/core": "^1.7.3",
- "@floating-ui/utils": "^0.2.10"
- }
- },
- "node_modules/@floating-ui/react-dom": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
- "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.7.4"
- },
- "peerDependencies": {
- "react": ">=16.8.0",
- "react-dom": ">=16.8.0"
- }
- },
- "node_modules/@floating-ui/utils": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
- "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
- "license": "MIT"
- },
- "node_modules/@fontsource/caveat": {
- "version": "5.2.8",
- "resolved": "https://registry.npmjs.org/@fontsource/caveat/-/caveat-5.2.8.tgz",
- "integrity": "sha512-9fUUfFE2IQFKbx+xOcaeQxxmh8iJguEb8z+j1PeueO4UUx+XfT4pRm/B04ZDvFA794/iRxY/IibmP8ZKtIf4rw==",
- "license": "OFL-1.1",
- "funding": {
- "url": "https://github.com/sponsors/ayuhito"
- }
- },
- "node_modules/@fontsource/inter": {
- "version": "5.2.8",
- "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.8.tgz",
- "integrity": "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==",
- "license": "OFL-1.1",
- "funding": {
- "url": "https://github.com/sponsors/ayuhito"
- }
- },
- "node_modules/@fontsource/jetbrains-mono": {
- "version": "5.2.8",
- "resolved": "https://registry.npmjs.org/@fontsource/jetbrains-mono/-/jetbrains-mono-5.2.8.tgz",
- "integrity": "sha512-6w8/SG4kqvIMu7xd7wt6x3idn1Qux3p9N62s6G3rfldOUYHpWcc2FKrqf+Vo44jRvqWj2oAtTHrZXEP23oSKwQ==",
- "license": "OFL-1.1",
- "funding": {
- "url": "https://github.com/sponsors/ayuhito"
- }
- },
- "node_modules/@fontsource/poppins": {
- "version": "5.2.7",
- "resolved": "https://registry.npmjs.org/@fontsource/poppins/-/poppins-5.2.7.tgz",
- "integrity": "sha512-6uQyPmseo4FgI97WIhA4yWRlNaoLk4vSDK/PyRwdqqZb5zAEuc+Kunt8JTMcsHYUEGYBtN15SNkMajMdqUSUmg==",
- "license": "OFL-1.1",
- "funding": {
- "url": "https://github.com/sponsors/ayuhito"
- }
- },
- "node_modules/@humanfs/core": {
- "version": "0.19.1",
- "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
- "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanfs/node": {
- "version": "0.16.7",
- "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
- "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanfs/core": "^0.19.1",
- "@humanwhocodes/retry": "^0.4.0"
- },
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/retry": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
- "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@img/sharp-darwin-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
- "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
- "cpu": [
- "arm64"
+ "libc": [
+ "glibc"
],
- "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
- "darwin"
+ "linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.0.4"
+ "@img/sharp-libvips-linux-s390x": "1.3.3"
}
},
- "node_modules/@img/sharp-darwin-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
- "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz",
+ "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==",
"cpu": [
"x64"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "Apache-2.0",
"optional": true,
"os": [
- "darwin"
+ "linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.0.4"
+ "@img/sharp-libvips-linux-x64": "1.3.3"
}
},
- "node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
- "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz",
+ "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==",
"cpu": [
"arm64"
],
"dev": true,
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
- "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
- "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
- "cpu": [
- "arm"
+ "libc": [
+ "musl"
],
- "dev": true,
- "license": "LGPL-3.0-or-later",
+ "license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
+ "engines": {
+ "node": ">=20.9.0"
+ },
"funding": {
"url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.3"
}
},
- "node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
- "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz",
+ "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==",
"cpu": [
- "arm64"
+ "x64"
],
"dev": true,
- "license": "LGPL-3.0-or-later",
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
+ "engines": {
+ "node": ">=20.9.0"
+ },
"funding": {
"url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.3"
}
},
- "node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
- "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
- "cpu": [
- "s390x"
- ],
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz",
+ "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==",
"dev": true,
- "license": "LGPL-3.0-or-later",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@emnapi/runtime": "^1.11.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
- "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
+ "node_modules/@img/sharp-webcontainers-wasm32": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz",
+ "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==",
"cpu": [
- "x64"
+ "wasm32"
],
"dev": true,
- "license": "LGPL-3.0-or-later",
+ "license": "Apache-2.0",
"optional": true,
- "os": [
- "linux"
- ],
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.4"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
- "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz",
+ "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==",
"cpu": [
"arm64"
],
"dev": true,
- "license": "LGPL-3.0-or-later",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
- "linux"
+ "win32"
],
+ "engines": {
+ "node": ">=20.9.0"
+ },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
- "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz",
+ "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==",
"cpu": [
- "x64"
+ "ia32"
],
"dev": true,
- "license": "LGPL-3.0-or-later",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
- "linux"
+ "win32"
],
+ "engines": {
+ "node": "^20.9.0"
+ },
"funding": {
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@img/sharp-linux-arm": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
- "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz",
+ "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==",
"cpu": [
- "arm"
+ "x64"
],
"dev": true,
- "license": "Apache-2.0",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
- "linux"
+ "win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.0.5"
}
},
- "node_modules/@img/sharp-linux-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
- "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
},
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.0.4"
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@img/sharp-linux-s390x": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
- "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
- "cpu": [
- "s390x"
- ],
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
"dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
},
- "optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.0.4"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/@img/sharp-linux-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
- "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.0.4"
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
}
},
- "node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
- "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
},
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
- "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.15.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz",
+ "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==",
"dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
},
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
},
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/@img/sharp-wasm32": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
- "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
- "cpu": [
- "wasm32"
- ],
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
- "optional": true,
+ "license": "MIT",
"dependencies": {
- "@emnapi/runtime": "^1.2.0"
+ "p-try": "^2.0.0"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=6"
},
"funding": {
- "url": "https://opencollective.com/libvips"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@img/sharp-win32-ia32": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
- "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
- "cpu": [
- "ia32"
- ],
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
},
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/@img/sharp-win32-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
- "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
+ "license": "MIT",
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
+ "node": ">=8"
}
},
- "node_modules/@isaacs/cliui": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
- "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
"dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^5.1.2",
- "string-width-cjs": "npm:string-width@^4.2.0",
- "strip-ansi": "^7.0.1",
- "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
- "wrap-ansi": "^8.1.0",
- "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
- },
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=8"
}
},
- "node_modules/@jest/diff-sequences": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz",
- "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==",
+ "node_modules/@jest/console": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.5.2.tgz",
+ "integrity": "sha512-e8sQC4pCMHPBrPX7Hk8TJr+DM5dkUnImSTNag8SEWFAFAF6xIz4AJvCKapnrdHnZxep4bxw4PhG+ZbimYBMyKw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "jest-message-util": "30.5.1",
+ "jest-util": "30.5.1",
+ "slash": "^3.0.0"
+ },
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jest/expect-utils": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz",
- "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==",
+ "node_modules/@jest/core": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.5.2.tgz",
+ "integrity": "sha512-/jqvFWoJF7LV1a6AUpYMbMm+2yIYsHJfR474H0SCzr9k8tnO/jl9wRg6zSG6lxgf6EozNlCG4amFzWsbZSvvZA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/get-type": "30.1.0"
+ "@jest/console": "30.5.2",
+ "@jest/pattern": "30.5.0",
+ "@jest/reporters": "30.5.2",
+ "@jest/test-result": "30.5.2",
+ "@jest/transform": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "exit-x": "^0.2.2",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.11",
+ "jest-changed-files": "30.5.1",
+ "jest-config": "30.5.2",
+ "jest-haste-map": "30.5.1",
+ "jest-message-util": "30.5.1",
+ "jest-regex-util": "30.5.0",
+ "jest-resolve": "30.5.1",
+ "jest-resolve-dependencies": "30.5.2",
+ "jest-runner": "30.5.2",
+ "jest-runtime": "30.5.2",
+ "jest-snapshot": "30.5.2",
+ "jest-util": "30.5.1",
+ "jest-validate": "30.5.1",
+ "jest-watcher": "30.5.2",
+ "pretty-format": "30.5.1",
+ "slash": "^3.0.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
}
},
- "node_modules/@jest/get-type": {
- "version": "30.1.0",
- "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz",
- "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==",
+ "node_modules/@jest/diff-sequences": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.5.0.tgz",
+ "integrity": "sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jest/pattern": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz",
- "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==",
+ "node_modules/@jest/environment": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.5.2.tgz",
+ "integrity": "sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg==",
"dev": true,
"license": "MIT",
"dependencies": {
+ "@jest/fake-timers": "30.5.2",
+ "@jest/types": "30.5.1",
"@types/node": "*",
- "jest-regex-util": "30.0.1"
+ "jest-mock": "30.5.2"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "node_modules/@jest/environment-jsdom-abstract": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.5.2.tgz",
+ "integrity": "sha512-8/P+8hKv7L4mhFoB6gpYLj/fuzXk8PWrde7TDHh8tJz5pE1ktlMbg0y6hDY/V8MfAnispFlPl/vPifowLy3JGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@sinclair/typebox": "^0.34.0"
+ "@jest/environment": "30.5.2",
+ "@jest/fake-timers": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "jest-mock": "30.5.2",
+ "jest-util": "30.5.1"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@types/jsdom": "*",
+ "canvas": "^3.0.0",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
}
},
- "node_modules/@jest/types": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
- "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
+ "node_modules/@jest/expect": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.5.2.tgz",
+ "integrity": "sha512-2E+1Pg6jJxbRjLNLpciC71iri/3qsKJL222/aXJEFwC0VdUSvfS+JZQQLEVjUYYc8t8pQu2MGE3cF2+bNTYRsg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/pattern": "30.0.1",
- "@jest/schemas": "30.0.5",
- "@types/istanbul-lib-coverage": "^2.0.6",
- "@types/istanbul-reports": "^3.0.4",
- "@types/node": "*",
- "@types/yargs": "^17.0.33",
- "chalk": "^4.1.2"
+ "expect": "30.5.2",
+ "jest-snapshot": "30.5.2"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "devOptional": true,
+ "node_modules/@jest/expect-utils": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.5.2.tgz",
+ "integrity": "sha512-d/HOLSrJUlBIl6n3LzOa7cjW3xdePm5H5gQw2lixZ/0h157l9sw3mLblzFqnPcTbhDzhRQdBOX3A3KcG73nm5Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "@jest/get-type": "30.5.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/@jest/fake-timers": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.5.2.tgz",
+ "integrity": "sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "@jest/types": "30.5.1",
+ "@sinonjs/fake-timers": "^15.4.0",
+ "@types/node": "*",
+ "jest-message-util": "30.5.1",
+ "jest-mock": "30.5.2",
+ "jest-util": "30.5.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "devOptional": true,
+ "node_modules/@jest/get-type": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.5.0.tgz",
+ "integrity": "sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/source-map": {
- "version": "0.3.11",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
- "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
- "devOptional": true,
+ "node_modules/@jest/globals": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.5.2.tgz",
+ "integrity": "sha512-62zfS+dL+M5aTNHXCNLyqD+j4oqxTIzDYrZbpqMP8Yn+gvlAGyzC6BSPNb1ZmFOakV1RtFYX/O3FCQXSWmQdgg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25"
+ "@jest/environment": "30.5.2",
+ "@jest/expect": "30.5.2",
+ "@jest/types": "30.5.1",
+ "jest-mock": "30.5.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "devOptional": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "devOptional": true,
+ "node_modules/@jest/pattern": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.5.0.tgz",
+ "integrity": "sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@nisoku/satori-log": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/@nisoku/satori-log/-/satori-log-0.1.2.tgz",
- "integrity": "sha512-VlhKOByqy0DnG6b1EVuTAYJFHtBf7brwFD++3So07RTc5AyH43djtDLr0XuaD/NFiy2nCF+QQCbRo4JrMimqpg==",
- "license": "MIT"
- },
- "node_modules/@quansync/fs": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-0.1.5.tgz",
- "integrity": "sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "quansync": "^0.2.11"
+ "@types/node": "*",
+ "jest-regex-util": "30.5.0"
},
- "funding": {
- "url": "https://github.com/sponsors/sxzz"
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/number": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
- "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
+ "node_modules/@jest/react-is-18": {
+ "name": "react-is",
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/@radix-ui/primitive": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
- "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
+ "node_modules/@jest/react-is-19": {
+ "name": "react-is",
+ "version": "19.3.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.3.0.tgz",
+ "integrity": "sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/@radix-ui/react-arrow": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
- "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==",
+ "node_modules/@jest/reporters": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.5.2.tgz",
+ "integrity": "sha512-ev6E9iG73twQcfAfoTnviuYkr3yOrYbzAtMFCimv2fxHXPIp9PBt2u1wNMt0aYWgl8FPwIcS8oqRJg6alnht4Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.1.3"
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "30.5.2",
+ "@jest/test-result": "30.5.2",
+ "@jest/transform": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@jridgewell/trace-mapping": "^0.3.31",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "collect-v8-coverage": "^1.0.2",
+ "exit-x": "^0.2.2",
+ "glob": "^13.0.6",
+ "graceful-fs": "^4.2.11",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^6.0.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^5.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "30.5.1",
+ "jest-util": "30.5.1",
+ "jest-worker": "30.5.1",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.2",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
},
"peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
+ "node-notifier": {
"optional": true
}
}
},
- "node_modules/@radix-ui/react-collapsible": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz",
- "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==",
- "license": "MIT",
+ "node_modules/@jest/reporters/node_modules/glob": {
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
},
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "engines": {
+ "node": "18 || 20 || >=22"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@radix-ui/react-collection": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
- "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "node_modules/@jest/reporters/node_modules/lru-cache": {
+ "version": "11.5.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz",
+ "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
}
},
- "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
- "license": "MIT",
+ "node_modules/@jest/reporters/node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
},
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "engines": {
+ "node": "18 || 20 || >=22"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
- "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "node_modules/@jest/schemas": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz",
+ "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/react-context": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
- "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "node_modules/@jest/snapshot-utils": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.5.1.tgz",
+ "integrity": "sha512-V3wnxNtiVmw5PPVg433Cn3VdXnsOeu/ofLw3KC04Bn2y1wIlU5kozXQn48rhrgj/02LrCVtntTEF1yBha0XSUw==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "dependencies": {
+ "@jest/types": "30.5.1",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "natural-compare": "^1.4.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/react-dialog": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
- "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-focus-guards": "1.1.3",
- "@radix-ui/react-focus-scope": "1.1.7",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "node_modules/@jest/source-map": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.5.2.tgz",
+ "integrity": "sha512-c5CehvkbfHX6yyNg7bMn2ylqlp9AHXuZ/3hPH/Lh5bxD/vefd/lV9HBjMqXef9yQNqkdwyZvkLSVSwB38hy8Qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.31",
+ "callsites": "^3.1.0",
+ "convert-source-map": "^2.0.0",
+ "graceful-fs": "^4.2.11"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@jest/test-result": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.5.2.tgz",
+ "integrity": "sha512-eO6YU5rsLfs60ne694e0IAmRgeBnoA8mu0nlxXDbl/1j5km0o2vO9/VbbUIKIH+WRKKEI+ELgwraRGn2Lhep8g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@jest/console": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "collect-v8-coverage": "^1.0.2"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/react-direction": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
- "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "node_modules/@jest/test-sequencer": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.5.2.tgz",
+ "integrity": "sha512-bmij8jZyYAC47ExT2GeP7PcrlwSNS+Bp3KeRuBH88gpcxqDv6fljN8PemS4J/lLZ79xb6mpaennQTTq0zUAVVg==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "dependencies": {
+ "@jest/test-result": "30.5.2",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.5.1",
+ "slash": "^3.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
- "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
+ "node_modules/@jest/transform": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz",
+ "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-escape-keydown": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@babel/core": "^7.27.4",
+ "@jest/types": "30.5.1",
+ "@jridgewell/trace-mapping": "^0.3.31",
+ "babel-plugin-istanbul": "^8.0.0",
+ "chalk": "^4.1.2",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.5.1",
+ "jest-regex-util": "30.5.0",
+ "jest-util": "30.5.1",
+ "pirates": "^4.0.7",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^5.0.1"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/react-dropdown-menu": {
- "version": "2.1.16",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz",
- "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==",
+ "node_modules/@jest/types": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz",
+ "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-menu": "2.1.16",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@jest/pattern": "30.5.0",
+ "@jest/schemas": "30.5.0",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@radix-ui/react-focus-guards": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
- "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "devOptional": true,
"license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
}
},
- "node_modules/@radix-ui/react-focus-scope": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
- "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "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": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
}
},
- "node_modules/@radix-ui/react-id": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
- "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "devOptional": true,
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu": {
- "version": "2.1.16",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz",
- "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-focus-guards": "1.1.3",
- "@radix-ui/react-focus-scope": "1.1.7",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-popper": "1.2.8",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-roving-focus": "1.1.11",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "devOptional": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
- "node_modules/@radix-ui/react-popper": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
- "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-use-rect": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1",
- "@radix-ui/rect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "devOptional": true,
+ "license": "MIT"
},
- "node_modules/@radix-ui/react-portal": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
- "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "devOptional": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@radix-ui/react-presence": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
- "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.4.tgz",
+ "integrity": "sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g==",
+ "dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@tybys/wasm-util": "^0.10.3"
},
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-primitive": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
- "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.2.3"
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
},
"peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
+ "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4"
}
},
- "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@nisoku/satori": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@nisoku/satori/-/satori-0.1.3.tgz",
+ "integrity": "sha512-OeaPHfmiX2CpFhMRi+4VKAi9+u5bkfwK8L1RMRAvzTaIW4uMLYh19W8iHCpLrFf3JJgUDpvS50jYmmbN6ryW+g==",
+ "license": "MIT"
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.150.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.150.0.tgz",
+ "integrity": "sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/oxc-project"
}
},
- "node_modules/@radix-ui/react-roving-focus": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
- "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
+ "node_modules/@parcel/watcher": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz",
+ "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==",
+ "dev": true,
+ "hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-controllable-state": "1.2.2"
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.4"
},
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-select": {
- "version": "2.2.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
- "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/number": "1.1.1",
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-focus-guards": "1.1.3",
- "@radix-ui/react-focus-scope": "1.1.7",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-popper": "1.2.8",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-visually-hidden": "1.2.3",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
},
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.6.0",
+ "@parcel/watcher-darwin-arm64": "2.6.0",
+ "@parcel/watcher-darwin-x64": "2.6.0",
+ "@parcel/watcher-freebsd-x64": "2.6.0",
+ "@parcel/watcher-linux-arm-glibc": "2.6.0",
+ "@parcel/watcher-linux-arm-musl": "2.6.0",
+ "@parcel/watcher-linux-arm64-glibc": "2.6.0",
+ "@parcel/watcher-linux-arm64-musl": "2.6.0",
+ "@parcel/watcher-linux-x64-glibc": "2.6.0",
+ "@parcel/watcher-linux-x64-musl": "2.6.0",
+ "@parcel/watcher-win32-arm64": "2.6.0",
+ "@parcel/watcher-win32-x64": "2.6.0"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz",
+ "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz",
+ "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
- "node_modules/@radix-ui/react-separator": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz",
- "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==",
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz",
+ "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.1.4"
- },
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz",
+ "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz",
+ "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz",
+ "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz",
+ "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz",
+ "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz",
+ "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz",
+ "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz",
+ "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz",
+ "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz",
+ "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
+ "node_modules/@quansync/fs": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-0.1.5.tgz",
+ "integrity": "sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quansync": "^0.2.11"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/@radix-ui/number": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.3.tgz",
+ "integrity": "sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/primitive": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.7.tgz",
+ "integrity": "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.15.tgz",
+ "integrity": "sha512-v4zggRcjadnI+ClKDuijlQEW4tw3NoaeHc/PwpKnLoLLKNUG4InLegkstooLcRIUWCs+8L22dGURCVuFfOKfnA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.10"
+ },
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
@@ -3705,13 +4124,20 @@
}
}
},
- "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz",
- "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==",
+ "node_modules/@radix-ui/react-collapsible": {
+ "version": "1.1.20",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.20.tgz",
+ "integrity": "sha512-mcGesGplBnzN2sbvJETzpCNfSMyPnb29q1GRLU+Ib7bJrpIG2ywmRoh2V5VbA2uNvKikKUlVbAPks7JDjz4A8Q==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-slot": "1.2.4"
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-presence": "1.1.10",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-controllable-state": "1.2.6",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
@@ -3728,23 +4154,16 @@
}
}
},
- "node_modules/@radix-ui/react-slider": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz",
- "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==",
+ "node_modules/@radix-ui/react-collection": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.15.tgz",
+ "integrity": "sha512-9W+B9NPF0NaaPh/1NJd3+KqsnlLqU9H7T2rvww+fp+T/evVXdNAyYcnfRQZFOjkR1ajQp3yORlqnI8soawLvNA==",
"license": "MIT",
"dependencies": {
- "@radix-ui/number": "1.1.1",
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1"
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-slot": "1.3.3"
},
"peerDependencies": {
"@types/react": "*",
@@ -3761,14 +4180,11 @@
}
}
},
- "node_modules/@radix-ui/react-slot": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
- "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz",
+ "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -3779,53 +4195,42 @@
}
}
},
- "node_modules/@radix-ui/react-switch": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz",
- "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==",
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.2.tgz",
+ "integrity": "sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1"
- },
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-tooltip": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz",
- "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-popper": "1.2.8",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-visually-hidden": "1.2.3"
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.23",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.23.tgz",
+ "integrity": "sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-dismissable-layer": "1.1.19",
+ "@radix-ui/react-focus-guards": "1.1.6",
+ "@radix-ui/react-focus-scope": "1.1.16",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-portal": "1.1.17",
+ "@radix-ui/react-presence": "1.1.10",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-slot": "1.3.3",
+ "@radix-ui/react-use-controllable-state": "1.2.6",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.7.2"
},
"peerDependencies": {
"@types/react": "*",
@@ -3842,14 +4247,11 @@
}
}
},
- "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.4.tgz",
+ "integrity": "sha512-5pzg4FGQNpExhnhT2zlrP1wZFaYCd1K0nYWoFAdcYoYK868IEigqMX3B3f8yIoRlAhAeDWciLI6ZdCKHF9P4Vg==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
- },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -3860,48 +4262,67 @@
}
}
},
- "node_modules/@radix-ui/react-use-callback-ref": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
- "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.19.tgz",
+ "integrity": "sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==",
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-callback-ref": "1.1.4",
+ "@radix-ui/react-use-effect-event": "0.0.5"
+ },
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-use-controllable-state": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
- "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "node_modules/@radix-ui/react-dropdown-menu": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.24.tgz",
+ "integrity": "sha512-geq8l2rJkxvkXsT9RMgtUE3P8pITFpTsvYpbySi1IH4fZEABD/Gp85myayFgxk0ktljGMJnCbeFkyTusvSvv7g==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-effect-event": "0.0.2",
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-menu": "2.1.24",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-controllable-state": "1.2.6"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-use-effect-event": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
- "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.6.tgz",
+ "integrity": "sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -3912,29 +4333,39 @@
}
}
},
- "node_modules/@radix-ui/react-use-escape-keydown": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
- "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.16.tgz",
+ "integrity": "sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-callback-ref": "1.1.1"
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-callback-ref": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-use-layout-effect": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
- "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz",
+ "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==",
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -3945,64 +4376,109 @@
}
}
},
- "node_modules/@radix-ui/react-use-previous": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
- "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
- "license": "MIT",
+ "node_modules/@radix-ui/react-menu": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.24.tgz",
+ "integrity": "sha512-uW7RVuU6Lp/ZtfeY4b3kL32zccgEWvPv1+cf17ubYzHa9cL8AHokmk36cG/XEiH/smbQvumnieXX9j/e9RqJWA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-collection": "1.1.15",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-direction": "1.1.4",
+ "@radix-ui/react-dismissable-layer": "1.1.19",
+ "@radix-ui/react-focus-guards": "1.1.6",
+ "@radix-ui/react-focus-scope": "1.1.16",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-popper": "1.3.7",
+ "@radix-ui/react-portal": "1.1.17",
+ "@radix-ui/react-presence": "1.1.10",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-roving-focus": "1.1.19",
+ "@radix-ui/react-slot": "1.3.3",
+ "@radix-ui/react-use-callback-ref": "1.1.4",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.7.2"
+ },
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-use-rect": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz",
- "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==",
+ "node_modules/@radix-ui/react-popper": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.7.tgz",
+ "integrity": "sha512-UsJrrd7w4wuKKTdvd/DNERVlwSlUcyXzjhyDwBk+3aPOsCjOY6ZSbxuw8E6lZTjjfP8Cpd0J8VVkrYUWyGYXyg==",
"license": "MIT",
"dependencies": {
- "@radix-ui/rect": "1.1.1"
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.15",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-callback-ref": "1.1.4",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-use-rect": "1.1.4",
+ "@radix-ui/react-use-size": "1.1.4",
+ "@radix-ui/rect": "1.1.3"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-use-size": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
- "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
+ "node_modules/@radix-ui/react-portal": {
+ "version": "1.1.17",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.17.tgz",
+ "integrity": "sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-visually-hidden": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz",
- "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==",
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.10.tgz",
+ "integrity": "sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.1.3"
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
@@ -4019,192 +4495,473 @@
}
}
},
- "node_modules/@radix-ui/rect": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz",
- "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
- "license": "MIT"
- },
- "node_modules/@reactour/mask": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@reactour/mask/-/mask-1.2.0.tgz",
- "integrity": "sha512-XLgBLWfKJybtZjNTSO5lt/SIvRlCZBadB6JfE/hO1ErqURRjYhnv+edC0Ki1haUCqMGFppWk3lwcPCjmK0xNog==",
+ "node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.10",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.10.tgz",
+ "integrity": "sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==",
+ "license": "MIT",
"dependencies": {
- "@reactour/utils": "*"
+ "@radix-ui/react-slot": "1.3.3"
},
"peerDependencies": {
- "react": "16.x || 17.x || 18.x || 19.x"
- }
- },
- "node_modules/@reactour/popover": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@reactour/popover/-/popover-1.3.0.tgz",
- "integrity": "sha512-YdyjSmHPvEeQEcJM4gcGFa5pI/Yf4nZGqwG4JnT+rK1SyUJBIPnm4Gkl/h7/+1g0KCFMkwNwagS3ZiXvZB7ThA==",
- "dependencies": {
- "@reactour/utils": "*"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
- "peerDependencies": {
- "react": "16.x || 17.x || 18.x || 19.x"
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@reactour/tour": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@reactour/tour/-/tour-3.8.0.tgz",
- "integrity": "sha512-KZTFi1pAvoTVKKRdBN5+XCYxXBp4k4Ql/acZcXyPvec8VU24fkMSEeV+v8krfYQpoVcewxIu3gM6xWZZLjxi7w==",
+ "node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.19.tgz",
+ "integrity": "sha512-V9jI6hDjT7l3jsCQD9bLNvDLM3tH/gdbOTp7Tefp3hbbgCGQoK7tUvrWiRlcoBHIZ809ElXwNQwVo0B98LuTXQ==",
+ "license": "MIT",
"dependencies": {
- "@reactour/mask": "*",
- "@reactour/popover": "*",
- "@reactour/utils": "*"
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-collection": "1.1.15",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-direction": "1.1.4",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-callback-ref": "1.1.4",
+ "@radix-ui/react-use-controllable-state": "1.2.6",
+ "@radix-ui/react-use-is-hydrated": "0.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
- "react": "16.x || 17.x || 18.x || 19.x"
- }
- },
- "node_modules/@reactour/utils": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@reactour/utils/-/utils-0.6.0.tgz",
- "integrity": "sha512-GqaLjQi7MJsgtAKjdiw2Eak1toFkADoLRnm1+HZpaD+yl+DkaHpC1N7JAl+kVOO5I17bWInPA+OFbXjO9Co8Qg==",
- "dependencies": {
- "@rooks/use-mutation-observer": "^4.11.2",
- "resize-observer-polyfill": "^1.5.1"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
- "peerDependencies": {
- "react": "16.x || 17.x || 18.x || 19.x"
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.3",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
- "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rollup/plugin-node-resolve": {
- "version": "15.3.1",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
- "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@rollup/pluginutils": "^5.0.1",
- "@types/resolve": "1.20.2",
- "deepmerge": "^4.2.2",
- "is-module": "^1.0.0",
- "resolve": "^1.22.1"
- },
- "engines": {
- "node": ">=14.0.0"
+ "node_modules/@radix-ui/react-select": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.3.7.tgz",
+ "integrity": "sha512-WFGImkmbzcfxeIwq/+4HvRN0pizBwbwQUED4I13ezQsDdfl38ZntN6TmR8XaSzPBqoCToe8rF75j6NPNDSzhbg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/number": "1.1.3",
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-collection": "1.1.15",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-direction": "1.1.4",
+ "@radix-ui/react-dismissable-layer": "1.1.19",
+ "@radix-ui/react-focus-guards": "1.1.6",
+ "@radix-ui/react-focus-scope": "1.1.16",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-popper": "1.3.7",
+ "@radix-ui/react-portal": "1.1.17",
+ "@radix-ui/react-presence": "1.1.10",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-slot": "1.3.3",
+ "@radix-ui/react-use-callback-ref": "1.1.4",
+ "@radix-ui/react-use-controllable-state": "1.2.6",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-use-previous": "1.1.4",
+ "@radix-ui/react-visually-hidden": "1.2.11",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.7.2"
},
"peerDependencies": {
- "rollup": "^2.78.0||^3.0.0||^4.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
- "rollup": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
"optional": true
}
}
},
- "node_modules/@rollup/plugin-node-resolve/node_modules/resolve": {
- "version": "1.22.11",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
- "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
- "dev": true,
+ "node_modules/@radix-ui/react-separator": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.15.tgz",
+ "integrity": "sha512-jOLO4lssEzWpoDu7G+Ze4VjwMRUBt291pnZD0gmalREZipnTX3wadQo7Fy48GCTfe14/YRN6rw/rOJqrE85Wxw==",
"license": "MIT",
"dependencies": {
- "is-core-module": "^2.16.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
+ "@radix-ui/react-primitive": "2.1.10"
},
- "engines": {
- "node": ">= 0.4"
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/@rollup/plugin-terser": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
- "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
- "dev": true,
+ "node_modules/@radix-ui/react-slider": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.4.7.tgz",
+ "integrity": "sha512-mTSLf1GC/C0moWjTbvCM6Qn/gBjvlFt1azuWF2v7MN5C3Zq2U2J2lN3ZEYkpujuOU5Ro7A28wkviSxaKnG0BYg==",
"license": "MIT",
"dependencies": {
- "serialize-javascript": "^6.0.1",
- "smob": "^1.0.0",
- "terser": "^5.17.4"
- },
- "engines": {
- "node": ">=14.0.0"
+ "@radix-ui/number": "1.1.3",
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-collection": "1.1.15",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-direction": "1.1.4",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-controllable-state": "1.2.6",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-use-previous": "1.1.4",
+ "@radix-ui/react-use-size": "1.1.4"
},
"peerDependencies": {
- "rollup": "^2.0.0||^3.0.0||^4.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
- "rollup": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
"optional": true
}
}
},
- "node_modules/@rollup/plugin-virtual": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz",
- "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==",
- "dev": true,
- "engines": {
- "node": ">=14.0.0"
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.3.tgz",
+ "integrity": "sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.5"
},
"peerDependencies": {
- "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
- "rollup": {
+ "@types/react": {
"optional": true
}
}
},
- "node_modules/@rollup/pluginutils": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
- "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
- "dev": true,
+ "node_modules/@radix-ui/react-switch": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.3.7.tgz",
+ "integrity": "sha512-48tB/4dn2UVLBCYhTu9AuR63IHl73l/qLbLgxd86noTUor4/K4LFDAcYjK+isP5313qxaFpjPVogE7+Y0/V3Kw==",
"license": "MIT",
"dependencies": {
- "@types/estree": "^1.0.0",
- "estree-walker": "^2.0.2",
- "picomatch": "^4.0.2"
- },
- "engines": {
- "node": ">=14.0.0"
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-use-controllable-state": "1.2.6",
+ "@radix-ui/react-use-size": "1.1.4"
},
"peerDependencies": {
- "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
- "rollup": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
"optional": true
}
}
},
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
- "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
+ "node_modules/@radix-ui/react-tooltip": {
+ "version": "1.2.16",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.16.tgz",
+ "integrity": "sha512-6EamKFRRnlpdadndbZ6LMwycfwkwPte1B42hs6QA0gYhjaOKqW4PZ4pjaW9UrlDX5eVt/OjncE7BFTPL5nmZhg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.2.2",
+ "@radix-ui/react-dismissable-layer": "1.1.19",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-popper": "1.3.7",
+ "@radix-ui/react-portal": "1.1.17",
+ "@radix-ui/react-presence": "1.1.10",
+ "@radix-ui/react-primitive": "2.1.10",
+ "@radix-ui/react-slot": "1.3.3",
+ "@radix-ui/react-use-controllable-state": "1.2.6",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-visually-hidden": "1.2.11"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.4.tgz",
+ "integrity": "sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.6.tgz",
+ "integrity": "sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.7",
+ "@radix-ui/react-use-effect-event": "0.0.5",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-effect-event": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz",
+ "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-is-hydrated": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz",
+ "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz",
+ "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-previous": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.4.tgz",
+ "integrity": "sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-rect": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz",
+ "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/rect": "1.1.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.4.tgz",
+ "integrity": "sha512-D3anSY15EJoxrihpsXI6SMrmmonnQtR2ni7arO+Lfdg3O95b9hNXxONk8jA5C8ANdF/h5HMAxejgs8PWJ6rlhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-visually-hidden": {
+ "version": "1.2.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.11.tgz",
+ "integrity": "sha512-NFS86RYYZb4/exihaESBGOpMJFz8MGLAfu3mOBSGByVnVPC9JPASfYubxd/8KbkQK0sYAv8lVQDEQukDX/qXvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/rect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz",
+ "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==",
+ "license": "MIT"
+ },
+ "node_modules/@reactour/mask": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@reactour/mask/-/mask-1.2.0.tgz",
+ "integrity": "sha512-XLgBLWfKJybtZjNTSO5lt/SIvRlCZBadB6JfE/hO1ErqURRjYhnv+edC0Ki1haUCqMGFppWk3lwcPCjmK0xNog==",
+ "dependencies": {
+ "@reactour/utils": "*"
+ },
+ "peerDependencies": {
+ "react": "16.x || 17.x || 18.x || 19.x"
+ }
+ },
+ "node_modules/@reactour/popover": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@reactour/popover/-/popover-1.3.0.tgz",
+ "integrity": "sha512-YdyjSmHPvEeQEcJM4gcGFa5pI/Yf4nZGqwG4JnT+rK1SyUJBIPnm4Gkl/h7/+1g0KCFMkwNwagS3ZiXvZB7ThA==",
+ "dependencies": {
+ "@reactour/utils": "*"
+ },
+ "peerDependencies": {
+ "react": "16.x || 17.x || 18.x || 19.x"
+ }
+ },
+ "node_modules/@reactour/tour": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@reactour/tour/-/tour-3.8.0.tgz",
+ "integrity": "sha512-KZTFi1pAvoTVKKRdBN5+XCYxXBp4k4Ql/acZcXyPvec8VU24fkMSEeV+v8krfYQpoVcewxIu3gM6xWZZLjxi7w==",
+ "dependencies": {
+ "@reactour/mask": "*",
+ "@reactour/popover": "*",
+ "@reactour/utils": "*"
+ },
+ "peerDependencies": {
+ "react": "16.x || 17.x || 18.x || 19.x"
+ }
+ },
+ "node_modules/@reactour/utils": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@reactour/utils/-/utils-0.6.0.tgz",
+ "integrity": "sha512-GqaLjQi7MJsgtAKjdiw2Eak1toFkADoLRnm1+HZpaD+yl+DkaHpC1N7JAl+kVOO5I17bWInPA+OFbXjO9Co8Qg==",
+ "dependencies": {
+ "@rooks/use-mutation-observer": "^4.11.2",
+ "resize-observer-polyfill": "^1.5.1"
+ },
+ "peerDependencies": {
+ "react": "16.x || 17.x || 18.x || 19.x"
+ }
+ },
+ "node_modules/@rolldown/binding-android-arm-eabi": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.9.tgz",
+ "integrity": "sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
"optional": true,
"os": [
"android"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
- "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.9.tgz",
+ "integrity": "sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg==",
"cpu": [
"arm64"
],
@@ -4212,12 +4969,15 @@
"optional": true,
"os": [
"android"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
- "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.9.tgz",
+ "integrity": "sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw==",
"cpu": [
"arm64"
],
@@ -4225,12 +4985,15 @@
"optional": true,
"os": [
"darwin"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
- "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.9.tgz",
+ "integrity": "sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw==",
"cpu": [
"x64"
],
@@ -4238,220 +5001,161 @@
"optional": true,
"os": [
"darwin"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
- "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.9.tgz",
+ "integrity": "sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g==",
"cpu": [
- "arm64"
+ "x64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
- "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.9.tgz",
+ "integrity": "sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw==",
"cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
- "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
- "cpu": [
- "arm"
+ "arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
- "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
- "cpu": [
- "arm"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
- "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.9.tgz",
+ "integrity": "sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw==",
"cpu": [
"arm64"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
- "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
- "cpu": [
- "arm64"
+ "libc": [
+ "glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
- "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
- "cpu": [
- "loong64"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
- "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.9.tgz",
+ "integrity": "sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA==",
"cpu": [
- "loong64"
+ "arm64"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
- "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
- "cpu": [
- "ppc64"
+ "libc": [
+ "musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
- "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.9.tgz",
+ "integrity": "sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw==",
"cpu": [
"ppc64"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
- "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
- "cpu": [
- "riscv64"
+ "libc": [
+ "glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
- "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
- "cpu": [
- "riscv64"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
- "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.9.tgz",
+ "integrity": "sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ==",
"cpu": [
"s390x"
],
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
- "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.9.tgz",
+ "integrity": "sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q==",
"cpu": [
"x64"
],
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
- "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.9.tgz",
+ "integrity": "sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ==",
"cpu": [
"x64"
],
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
"optional": true,
"os": [
"linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
- "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
- "cpu": [
- "x64"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
- "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.9.tgz",
+ "integrity": "sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg==",
"cpu": [
"arm64"
],
@@ -4459,12 +5163,15 @@
"optional": true,
"os": [
"openharmony"
- ]
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
- "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.9.tgz",
+ "integrity": "sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww==",
"cpu": [
"arm64"
],
@@ -4472,25 +5179,15 @@
"optional": true,
"os": [
"win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
- "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
- "cpu": [
- "ia32"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
- "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.9.tgz",
+ "integrity": "sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g==",
"cpu": [
"x64"
],
@@ -4498,1267 +5195,3418 @@
"optional": true,
"os": [
"win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
- "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
- "cpu": [
- "x64"
],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@rooks/use-mutation-observer": {
- "version": "4.11.2",
- "resolved": "https://registry.npmjs.org/@rooks/use-mutation-observer/-/use-mutation-observer-4.11.2.tgz",
- "integrity": "sha512-vpsdrZdr6TkB1zZJcHx+fR1YC/pHs2BaqcuYiEGjBVbwY5xcC49+h0hAUtQKHth3oJqXfIX/Ng8S7s5HFHdM/A==",
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
+ "license": "MIT"
+ },
+ "node_modules/@rollup/plugin-babel": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.1.0.tgz",
+ "integrity": "sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.18.6",
+ "@rollup/pluginutils": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
"peerDependencies": {
- "react": ">=16.8.0"
+ "@babel/core": "^7.0.0",
+ "@types/babel__core": "^7.1.9",
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/babel__core": {
+ "optional": true
+ },
+ "rollup": {
+ "optional": true
+ }
}
},
- "node_modules/@sinclair/typebox": {
- "version": "0.34.41",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz",
- "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==",
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "16.0.3",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz",
+ "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
},
- "node_modules/@surma/rollup-plugin-off-main-thread": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
- "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
+ "node_modules/@rollup/plugin-node-resolve/node_modules/resolve": {
+ "version": "1.22.12",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+ "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@rollup/plugin-replace": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.3.tgz",
+ "integrity": "sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "magic-string": "^0.30.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-terser": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-1.0.0.tgz",
+ "integrity": "sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "serialize-javascript": "^7.0.3",
+ "smob": "^1.0.0",
+ "terser": "^5.17.4"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz",
+ "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
+ "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
+ "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
+ "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
+ "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
+ "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
+ "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
+ "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
+ "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
+ "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
+ "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
+ "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
+ "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
+ "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
+ "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
+ "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
+ "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
+ "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
+ "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
+ "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
+ "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
+ "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
+ "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
+ "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
+ "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
+ "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rooks/use-mutation-observer": {
+ "version": "4.11.2",
+ "resolved": "https://registry.npmjs.org/@rooks/use-mutation-observer/-/use-mutation-observer-4.11.2.tgz",
+ "integrity": "sha512-vpsdrZdr6TkB1zZJcHx+fR1YC/pHs2BaqcuYiEGjBVbwY5xcC49+h0hAUtQKHth3oJqXfIX/Ng8S7s5HFHdM/A==",
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.34.52",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz",
+ "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "15.4.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz",
+ "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1"
+ }
+ },
+ "node_modules/@tauri-apps/api": {
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.11.1.tgz",
+ "integrity": "sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==",
+ "license": "Apache-2.0 OR MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/tauri"
+ }
+ },
+ "node_modules/@tauri-apps/cli": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.5.tgz",
+ "integrity": "sha512-YbeJ6tctNoo40purO4u3Eeo3RVqmsjJr0NoKQRu+4pvO4gMLzkjta7x0k96SxSLmx+rQ+8um1ThOlw+HLpgFug==",
+ "dev": true,
+ "license": "Apache-2.0 OR MIT",
+ "bin": {
+ "tauri": "tauri.js"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/tauri"
+ },
+ "optionalDependencies": {
+ "@tauri-apps/cli-darwin-arm64": "2.11.5",
+ "@tauri-apps/cli-darwin-x64": "2.11.5",
+ "@tauri-apps/cli-linux-arm-gnueabihf": "2.11.5",
+ "@tauri-apps/cli-linux-arm64-gnu": "2.11.5",
+ "@tauri-apps/cli-linux-arm64-musl": "2.11.5",
+ "@tauri-apps/cli-linux-riscv64-gnu": "2.11.5",
+ "@tauri-apps/cli-linux-x64-gnu": "2.11.5",
+ "@tauri-apps/cli-linux-x64-musl": "2.11.5",
+ "@tauri-apps/cli-win32-arm64-msvc": "2.11.5",
+ "@tauri-apps/cli-win32-ia32-msvc": "2.11.5",
+ "@tauri-apps/cli-win32-x64-msvc": "2.11.5"
+ }
+ },
+ "node_modules/@tauri-apps/cli-darwin-arm64": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.5.tgz",
+ "integrity": "sha512-tggOiVOohjIHdiElbjeBfB41s6cmfsq+ZQ0PX0fEtCdsDdZ9cCi54e5gNK7tdPbR6JbdDe7RA4kbQdyyBUUk/Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-darwin-x64": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.5.tgz",
+ "integrity": "sha512-SrO+KCbqvG1IvVPdlzQX4GEGZRQDISrmDY9bGcW68DLVFBCC06H+Loz6oyUZETUxsSMR6B4oDfvbQVgD4hxsqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.5.tgz",
+ "integrity": "sha512-qLrOaCa8hLD5QVPQRjAgOXvhlTFKXmTliVF773GgvADYcWZSdmncnF5zBFAkdu1uQK8KfQbDlBUwqQYZqBfBRQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-arm64-gnu": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.5.tgz",
+ "integrity": "sha512-Tq32xpQjiQEdIrvwDq7lwHhXemn070CXWdbCvr9rdi9rsv9NFTbQ6izVSIfNE+59QaerxuwtUtZ5IxDNWaoYBw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-arm64-musl": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.5.tgz",
+ "integrity": "sha512-+OdWKj5Aq+C8HXypQ4t926V8cpVnc0ZcJIdhTXWjVAJHkaNuo8EuQR6KRZKHWIbJJgKdMPCDosvwzIFaBBqHKQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.5.tgz",
+ "integrity": "sha512-Q0V2hjpllyDW8dWQZSsITuQDfcY9BpBZuhXkMa2T5AFLZAn+FJPXQSyvnxWNVxRowdQ59Xn0QVtGm6HEHNUEvw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-x64-gnu": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.5.tgz",
+ "integrity": "sha512-Xz1s87gFjZJZMQKAhLa77YeiCJM6yVog3f9OxDgVd/KxDIoB1dA5V2xOnMM+SRkOGk9juwIBqesVAjV0kUB0DA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-x64-musl": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.5.tgz",
+ "integrity": "sha512-6A88wqAZXZHgMaBrGiy/Bpa4GgUnftXM7uquKOeOXCuK78/XdBxEECicK/1oHgrT179XBFOaA6lQEHysjRmGig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-win32-arm64-msvc": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.5.tgz",
+ "integrity": "sha512-sRGgF/ObRfLcS3PtUdyTbJtkGq3E+PNZTknvAURwMNUtHw9DU/BF6S5si43y9lS5yEO9bWJCA+GGYvnn6cphQw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-win32-ia32-msvc": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.5.tgz",
+ "integrity": "sha512-bHOv/yxqfKpI7ioIFQi5wOfZ7jkbPzJD/UhXY52I/hrmE3qNh71cohIPyqZB5GQn3LZeJWdCUOqmIg/w6XX+Wg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-win32-x64-msvc": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.5.tgz",
+ "integrity": "sha512-vaaOmavqdCeS7oMib2banBZemgrC5v54tSkwoBV+bxrXQZhQZrOwE2EO2i4x+CHNtvQUM/6bSs3iymZMAsycWg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 OR MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/plugin-dialog": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.7.3.tgz",
+ "integrity": "sha512-CRgE+7TP4tvq9MjBU6f04NLTFIqVMLKHk3hAqlhil00ngK9ACTrXPH3oHpKMProxILodd3YjBoKbMwSI4IEcfA==",
+ "license": "MIT OR Apache-2.0",
+ "dependencies": {
+ "@tauri-apps/api": "^2.11.0"
+ }
+ },
+ "node_modules/@tauri-apps/plugin-fs": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.5.2.tgz",
+ "integrity": "sha512-XXvMSnFiob+G1H+YHCDf+bzWVumseQuEIhzpbOJzevUfL4k0U+sTApZWJHpoLiamggnVPJm5dJ5sDsniRyWxlg==",
+ "license": "MIT OR Apache-2.0",
+ "dependencies": {
+ "@tauri-apps/api": "^2.11.0"
+ }
+ },
+ "node_modules/@tauri-apps/plugin-notification": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.4.0.tgz",
+ "integrity": "sha512-xlJXMcUoKOjNupzDue5wrEsa1wytf+l/2gCAPhafHyP683Y3N7J/8clUWLZ3vpnwkpT2C1zcLMMQFjjecIG2xg==",
+ "license": "MIT OR Apache-2.0",
+ "dependencies": {
+ "@tauri-apps/api": "^2.11.0"
+ }
+ },
+ "node_modules/@tauri-apps/plugin-opener": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.5.tgz",
+ "integrity": "sha512-xvzGai5aQds8j8R8RsUK/lW6pGG50YgOYIPLzvkqmkwAj7dfySOD7sGtejRzvVdMmv1EQfKVEFh1MvmDp8QR0g==",
+ "license": "MIT OR Apache-2.0",
+ "dependencies": {
+ "@tauri-apps/api": "^2.11.0"
+ }
+ },
+ "node_modules/@tokenizer/inflate": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz",
+ "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "token-types": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/@tokenizer/token": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
+ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
+ "license": "MIT"
+ },
+ "node_modules/@transloadit/prettier-bytes": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-2.0.0.tgz",
+ "integrity": "sha512-GYzxSL3y9XlhwamBLkHT1y2jFrRsHkZZ1jNctn8NeMNyTtIbMK1Qf0f1koHkDdW+MwOUowCmpm8zP6ZpQ36G5w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=22"
+ }
+ },
+ "node_modules/@trickfilm400/rollup-plugin-off-main-thread": {
+ "version": "3.0.0-pre1",
+ "resolved": "https://registry.npmjs.org/@trickfilm400/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-3.0.0-pre1.tgz",
+ "integrity": "sha512-/67zpWDBLV+oYAEL682s1ktXL0HgqX76f6gaVGkGnVZlBbm1zd0v4Bz8MFF2GGhoX9rvfq3KSQHubFHwa6w6/Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "ejs": "^3.1.10",
+ "json5": "^2.2.3",
+ "magic-string": "^0.30.21",
+ "string.prototype.matchall": "^4.0.12"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz",
+ "integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "30.0.0",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz",
+ "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^30.0.0",
+ "pretty-format": "^30.0.0"
+ }
+ },
+ "node_modules/@types/jsdom": {
+ "version": "21.1.7",
+ "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
+ "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/tough-cookie": "*",
+ "parse5": "^7.0.0"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.2.tgz",
+ "integrity": "sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~8.9.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.3.0",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz",
+ "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.3.0",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz",
+ "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==",
+ "devOptional": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.3.0"
+ }
+ },
+ "node_modules/@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/retry": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz",
+ "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==",
+ "license": "MIT"
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/tough-cookie": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
+ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.33",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+ "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.1.tgz",
+ "integrity": "sha512-nDNrUQ/4ruSNYbu749TRY7cfrzPtoLHEXSNBI8aaNY32LlZCajixqRf3FqcKC4p5Cam4VOHYx/t+i5+nKXvrqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.12.2",
+ "@typescript-eslint/scope-manager": "8.70.1",
+ "@typescript-eslint/type-utils": "8.70.1",
+ "@typescript-eslint/utils": "8.70.1",
+ "@typescript-eslint/visitor-keys": "8.70.1",
+ "ignore": "^7.0.5",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.70.1",
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.1.tgz",
+ "integrity": "sha512-nO974WLllwhSFWQXnMLj6nDGa8f0khKEz1JzpPJ1u7Vm/4X1X6ZHajpoknU4bb41vJyMB0HHVyS2GqdhWfIXZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.70.1",
+ "@typescript-eslint/types": "8.70.1",
+ "@typescript-eslint/typescript-estree": "8.70.1",
+ "@typescript-eslint/visitor-keys": "8.70.1",
+ "debug": "^4.4.3"
+ },
+ "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 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.1.tgz",
+ "integrity": "sha512-62xOgboPfwc3/IgPSX/W6oQR3ZbF04194FPGUGH8HL8iLFHbt/456/8Ph1wLNUgVF+s94FlHoipBsz+v7+LMnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.70.1",
+ "@typescript-eslint/types": "^8.70.1",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.1.tgz",
+ "integrity": "sha512-Pa0EeSeAusQc1WbjQMac+YfenewYTBu0KjgYvkUKwhXaHUKbFog23Dm/rp0DX/6tyYOQ3Xl1a+3EcFNZynGHCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.70.1",
+ "@typescript-eslint/visitor-keys": "8.70.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.1.tgz",
+ "integrity": "sha512-jumze1fPI+sDOaM2TWGQdn39PDxTr7TZGeuyLkAbNyx2vtMT3uRnVKChN0hfht5V2TugphJzF6bYXvBcE09qqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.1.tgz",
+ "integrity": "sha512-7zKTnyvaVWqzLZHPFQtX1hVHqgkMC+WebPWakNCSyrQVbIP1AM0L0TlBZtACldIRb6PptI8Odk+jyZ5kP3B1VA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.70.1",
+ "@typescript-eslint/typescript-estree": "8.70.1",
+ "@typescript-eslint/utils": "8.70.1",
+ "debug": "^4.4.3",
+ "ts-api-utils": "^2.5.0"
+ },
+ "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 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.1.tgz",
+ "integrity": "sha512-Dm1ypdhhrGCTyyehxElhgJ6kgk8MVCv5qXdoOVqPr1uqk42jX8KjrZqhROvdShczA8qrDoYiOWn1ykWlx2k81Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.1.tgz",
+ "integrity": "sha512-TU8PwyGN0PQJUcE96mw8eCQ44SmxGdQlJmlWakHaHQ15eIuuvye5yNtmh/i6oS88jzXVQB71xdNkbkB/fMwL0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.70.1",
+ "@typescript-eslint/tsconfig-utils": "8.70.1",
+ "@typescript-eslint/types": "8.70.1",
+ "@typescript-eslint/visitor-keys": "8.70.1",
+ "debug": "^4.4.3",
+ "minimatch": "^10.2.2",
+ "semver": "^7.7.3",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.1.tgz",
+ "integrity": "sha512-Esgul8MsnKnRLdYU2Eb2cRV9bS5HJYtKj1ByJnOzzG2M58DGdSUQ1jUuILxipqcpB2h9WLrbD5GijIWUjX/Tqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.1",
+ "@typescript-eslint/scope-manager": "8.70.1",
+ "@typescript-eslint/types": "8.70.1",
+ "@typescript-eslint/typescript-estree": "8.70.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 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.70.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.1.tgz",
+ "integrity": "sha512-Vwj9lUIW5Xq3wQ9w6gv3R86g1hMK8f2zNOdGTAgeXUMMXFK78G9ruCjjqutHMNJc0+CH7LYRnHeUB9IT8wFmcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.70.1",
+ "eslint-visitor-keys": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
+ "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz",
+ "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@unrs/resolver-binding-android-arm-eabi": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz",
+ "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-android-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz",
+ "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz",
+ "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-x64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz",
+ "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-freebsd-x64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz",
+ "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz",
+ "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz",
+ "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz",
+ "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz",
+ "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-loong64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz",
+ "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-loong64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz",
+ "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz",
+ "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz",
+ "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz",
+ "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz",
+ "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz",
+ "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz",
+ "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-openharmony-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz",
+ "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz",
+ "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz",
+ "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz",
+ "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz",
+ "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@uppy/components": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@uppy/components/-/components-2.0.0.tgz",
+ "integrity": "sha512-wviwX37ISeJQEaHh5ijyfSW7wDb5Ctvy10dnkRjuN9hddJo59N7lx+dKe985cP4OBBSr+wAzAkrvP6I8MmMvMg==",
+ "license": "MIT",
+ "dependencies": {
+ "clsx": "^2.1.1",
+ "dequal": "^2.0.3",
+ "preact": "^10.29.2",
+ "pretty-bytes": "^7.1.0"
+ },
+ "peerDependencies": {
+ "@uppy/core": "^6.0.0",
+ "@uppy/google-drive-picker": "^2.0.0",
+ "@uppy/google-photos-picker": "^2.0.0",
+ "@uppy/image-editor": "^5.0.0",
+ "@uppy/screen-capture": "^6.0.0",
+ "@uppy/webcam": "^6.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@uppy/image-editor": {
+ "optional": true
+ },
+ "@uppy/screen-capture": {
+ "optional": true
+ },
+ "@uppy/webcam": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@uppy/components/node_modules/pretty-bytes": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-7.1.3.tgz",
+ "integrity": "sha512-U2KZ675nqba6XSBppSjU2pRgc9Ffx9+uUtd/RTWYmOawVkZuUbBYuwdtFZQmLv+yMgQ2TQxWWuOpyNje67J9tg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@uppy/core": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@uppy/core/-/core-6.0.1.tgz",
+ "integrity": "sha512-H+v4tOBPYY8Cf0JWoGa3+JPTl9Of8SBaVUH5TNwGgynncTWrQtuyGK91hv9wOjm0SFds3X5psPx1ArhngdSrBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@transloadit/prettier-bytes": "^2.0.0",
+ "classnames": "^2.5.1",
+ "lodash": "^4.18.1",
+ "mime-match": "^1.0.2",
+ "namespace-emitter": "^2.0.1",
+ "nanoid": "^5.1.11",
+ "p-queue": "^9.3.3",
+ "p-retry": "^6.1.0",
+ "preact": "^10.29.2"
+ }
+ },
+ "node_modules/@uppy/dashboard": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@uppy/dashboard/-/dashboard-6.0.0.tgz",
+ "integrity": "sha512-8ODlTuK4yTCSwTIXrt7kRmsJLpnZdOOJG8MaRMOQdr3VxsOxkvifnYFXNdjTgCnmq09KAtXP3Tssuwt6BpK5oQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@transloadit/prettier-bytes": "^2.0.0",
+ "@uppy/thumbnail-generator": "^6.0.0",
+ "classnames": "^2.5.1",
+ "lodash": "^4.18.1",
+ "nanoid": "^5.1.11",
+ "preact": "^10.29.2",
+ "shallow-equal": "^3.1.0"
+ },
+ "peerDependencies": {
+ "@uppy/core": "^6.0.0"
+ }
+ },
+ "node_modules/@uppy/google-drive-picker": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@uppy/google-drive-picker/-/google-drive-picker-2.0.0.tgz",
+ "integrity": "sha512-i3XPwEWPCZJtHM9bYRIQ89cjIrSx6dqm3C81bb63Z0H3bet9Yz8E5BJS7ofyppJiOiJg19Vec4evx5QOCZ45aQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "preact": "^10.29.2"
+ },
+ "peerDependencies": {
+ "@uppy/core": "^6.0.0"
+ }
+ },
+ "node_modules/@uppy/google-photos-picker": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@uppy/google-photos-picker/-/google-photos-picker-2.0.0.tgz",
+ "integrity": "sha512-mWad0IRAgZaAYCjIAytWS3t8MK3u3ZyAgXFgmeCqz15i3hXOXmrzlez/MEpMR9QJc9Hsju9yHShP/lKWF2tbIA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "preact": "^10.29.2"
+ },
+ "peerDependencies": {
+ "@uppy/core": "^6.0.0"
+ }
+ },
+ "node_modules/@uppy/react": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@uppy/react/-/react-6.0.0.tgz",
+ "integrity": "sha512-AgPeeEGCz4FFN2zblqrJs8zQzzDKPoToM4dkWsHXF/Ndm1BmI4uF8NkVjEvmzwjF4e2JPxRvk52baYTeSSKruQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@uppy/components": "^2.0.0",
+ "preact": "^10.29.2",
+ "use-sync-external-store": "^1.6.0"
+ },
+ "peerDependencies": {
+ "@uppy/core": "^6.0.0",
+ "@uppy/dashboard": "^6.0.0",
+ "@uppy/screen-capture": "^6.0.0",
+ "@uppy/status-bar": "^6.0.0",
+ "@uppy/webcam": "^6.0.0",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@uppy/dashboard": {
+ "optional": true
+ },
+ "@uppy/screen-capture": {
+ "optional": true
+ },
+ "@uppy/status-bar": {
+ "optional": true
+ },
+ "@uppy/webcam": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@uppy/thumbnail-generator": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@uppy/thumbnail-generator/-/thumbnail-generator-6.0.0.tgz",
+ "integrity": "sha512-7564MpbWL6MsvpAhSZ4or7uorp2KrJQneYsPbC7Wy+yuPozdieKJPNxWVqeBQcn6ZMF+1FUjLJrna+3h+teKbA==",
+ "license": "MIT",
+ "dependencies": {
+ "exifr": "^7.1.3"
+ },
+ "peerDependencies": {
+ "@uppy/core": "^6.0.0"
+ }
+ },
+ "node_modules/@vite-pwa/assets-generator": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-1.0.4.tgz",
+ "integrity": "sha512-LlYM5CEmFmdl7le4B0Pr9+NPipQgStFOslvfxEQ/1LW3wUquZ3s3ec2z132lzfVEYAiJAmfFhQ0EVs6ntO7RKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "colorette": "^2.0.20",
+ "consola": "^3.4.2",
+ "sharp": "^0.35.4",
+ "sharp-ico": "^0.1.5",
+ "unconfig": "^7.3.1"
+ },
+ "bin": {
+ "pwa-assets-generator": "bin/pwa-assets-generator.mjs"
+ },
+ "engines": {
+ "node": ">=16.14.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.1.tgz",
+ "integrity": "sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rolldown/pluginutils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "peerDependencies": {
+ "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "oxc-transform-react": "^0.145.0",
+ "vite": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rolldown/plugin-babel": {
+ "optional": true
+ },
+ "babel-plugin-react-compiler": {
+ "optional": true
+ },
+ "oxc-transform-react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@web-scrobbler/metadata-filter": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@web-scrobbler/metadata-filter/-/metadata-filter-3.2.0.tgz",
+ "integrity": "sha512-K2Wkq9AOJkgj4Hk9g0flKnNWYkJy1GTPpHTgpNLU5OXaXgqPKLyrtb62M1cIxMN3ESH6XGvPKM92VEl/Gc3Rog==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/@zag-js/anatomy": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-1.44.0.tgz",
+ "integrity": "sha512-gVN02k7cUqEDlEDDv3CcStMIqDQ32e7QCH8FVBwwXqbSH8D5KMuqPrmyfdE8irVZuPfY4PtKuZsNvJLYvXDpgA==",
+ "license": "MIT"
+ },
+ "node_modules/@zag-js/core": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-1.44.0.tgz",
+ "integrity": "sha512-tqDBJeDpDuLfjodk6NetSDZLMy7+r799RcC5oDtVivowfSxfPBSsfh4UxYT/+zXv9RZ0mYG3TzO4yFROPmniIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@zag-js/dom-query": "1.44.0",
+ "@zag-js/utils": "1.44.0"
+ }
+ },
+ "node_modules/@zag-js/dom-query": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-1.44.0.tgz",
+ "integrity": "sha512-BKdiKNjd9iTtaQjjU07YymGkgKVSO7vXu8ukZPyt+F8tOesAv9xW5wCn3fuEI6zNthzOpHD9ejj48YW0mljnpQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@zag-js/types": "1.44.0"
+ }
+ },
+ "node_modules/@zag-js/marquee": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/marquee/-/marquee-1.44.0.tgz",
+ "integrity": "sha512-PDD3C0GUjTNyAkEzMtjy0fyqg2S5gn/O3JsoUzLoPQcjFCeqllr5HR3jzUo7yPFXGT3+HtWDoAHMYgMrtpQFZg==",
+ "license": "MIT",
+ "dependencies": {
+ "@zag-js/anatomy": "1.44.0",
+ "@zag-js/core": "1.44.0",
+ "@zag-js/dom-query": "1.44.0",
+ "@zag-js/types": "1.44.0",
+ "@zag-js/utils": "1.44.0"
+ }
+ },
+ "node_modules/@zag-js/react": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-1.44.0.tgz",
+ "integrity": "sha512-qRO5LJLzKuul97it+qYj/IrriS+IX9KZ7OrhCxPbY1Xd2g7TJdOpuGRU5IsGwTJCUfW6vQBrBj/0Qhc1GMClog==",
+ "license": "MIT",
+ "dependencies": {
+ "@zag-js/core": "1.44.0",
+ "@zag-js/store": "1.44.0",
+ "@zag-js/types": "1.44.0",
+ "@zag-js/utils": "1.44.0"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@zag-js/store": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-1.44.0.tgz",
+ "integrity": "sha512-syjbybsc1e2zro50Eu+SaloeJbiXTY78wa+m8iUzswdmVzpts+7KSk3Oogso7jxZ7L91vNAQDhSqZR73Il3KOA==",
+ "license": "MIT",
+ "dependencies": {
+ "proxy-compare": "3.0.1"
+ }
+ },
+ "node_modules/@zag-js/types": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-1.44.0.tgz",
+ "integrity": "sha512-hVi+EekA3V2EDyJxhkSg1Znmk8Qhk3JRWH8atkwTvnGckpCXjQQ9YpKGsP6KSzD88ci7PgH/mYj7fU62E+GYqw==",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "3.2.3"
+ }
+ },
+ "node_modules/@zag-js/utils": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-1.44.0.tgz",
+ "integrity": "sha512-XO4UoPSRBE/CQ781eSqYELOzsc8Bch33340L6/iVEP+5rW8SL5yCyKewu9w0t0bG1Y+EETLlmvswDjI252t1Vw==",
+ "license": "MIT"
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "devOptional": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
+ "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/anymatch/node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/aria-hidden": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
+ "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "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",
+ "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/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/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": {
+ "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/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": {
+ "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.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": {
- "ejs": "^3.1.6",
- "json5": "^2.2.0",
- "magic-string": "^0.25.0",
- "string.prototype.matchall": "^4.0.6"
+ "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/@swc/core": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.8.tgz",
- "integrity": "sha512-T8keoJjXaSUoVBCIjgL6wAnhADIb09GOELzKg10CjNg+vLX48P93SME6jTfte9MZIm5m+Il57H3rTSk/0kzDUw==",
+ "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,
- "hasInstallScript": true,
+ "license": "MIT",
"dependencies": {
- "@swc/counter": "^0.1.3",
- "@swc/types": "^0.1.25"
+ "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": ">=10"
+ "node": ">= 0.4"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/swc"
- },
- "optionalDependencies": {
- "@swc/core-darwin-arm64": "1.15.8",
- "@swc/core-darwin-x64": "1.15.8",
- "@swc/core-linux-arm-gnueabihf": "1.15.8",
- "@swc/core-linux-arm64-gnu": "1.15.8",
- "@swc/core-linux-arm64-musl": "1.15.8",
- "@swc/core-linux-x64-gnu": "1.15.8",
- "@swc/core-linux-x64-musl": "1.15.8",
- "@swc/core-win32-arm64-msvc": "1.15.8",
- "@swc/core-win32-ia32-msvc": "1.15.8",
- "@swc/core-win32-x64-msvc": "1.15.8"
- },
- "peerDependencies": {
- "@swc/helpers": ">=0.5.17"
- },
- "peerDependenciesMeta": {
- "@swc/helpers": {
- "optional": true
- }
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@swc/core-darwin-arm64": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.8.tgz",
- "integrity": "sha512-M9cK5GwyWWRkRGwwCbREuj6r8jKdES/haCZ3Xckgkl8MUQJZA3XB7IXXK1IXRNeLjg6m7cnoMICpXv1v1hlJOg==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
+ "license": "MIT"
},
- "node_modules/@swc/core-darwin-x64": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.8.tgz",
- "integrity": "sha512-j47DasuOvXl80sKJHSi2X25l44CMc3VDhlJwA7oewC1nV1VsSzwX+KOwE5tLnfORvVJJyeiXgJORNYg4jeIjYQ==",
- "cpu": [
- "x64"
- ],
+ "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,
- "optional": true,
- "os": [
- "darwin"
- ],
+ "license": "MIT",
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
}
},
- "node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.8.tgz",
- "integrity": "sha512-siAzDENu2rUbwr9+fayWa26r5A9fol1iORG53HWxQL1J8ym4k7xt9eME0dMPXlYZDytK5r9sW8zEA10F2U3Xwg==",
- "cpu": [
- "arm"
- ],
+ "node_modules/at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "ISC",
"engines": {
- "node": ">=10"
+ "node": ">= 4.0.0"
}
},
- "node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.8.tgz",
- "integrity": "sha512-o+1y5u6k2FfPYbTRUPvurwzNt5qd0NTumCTFscCNuBksycloXY16J8L+SMW5QRX59n4Hp9EmFa3vpvNHRVv1+Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
+ "node_modules/automation-events": {
+ "version": "7.1.15",
+ "resolved": "https://registry.npmjs.org/automation-events/-/automation-events-7.1.15.tgz",
+ "integrity": "sha512-NsHJlve3twcgs8IyP4iEYph7Fzpnh6klN7G5LahwvypakBjFbsiGHJxrqTmeHKREdu/Tx6oZboqNI0tD4MnFlA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.28.6",
+ "tslib": "^2.8.1"
+ },
"engines": {
- "node": ">=10"
+ "node": ">=18.2.0"
}
},
- "node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.8.tgz",
- "integrity": "sha512-koiCqL09EwOP1S2RShCI7NbsQuG6r2brTqUYE7pV7kZm9O17wZ0LSz22m6gVibpwEnw8jI3IE1yYsQTVpluALw==",
- "cpu": [
- "arm64"
- ],
+ "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,
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.8.tgz",
- "integrity": "sha512-4p6lOMU3bC+Vd5ARtKJ/FxpIC5G8v3XLoPEZ5s7mLR8h7411HWC/LmTXDHcrSXRC55zvAVia1eldy6zDLz8iFQ==",
- "cpu": [
- "x64"
- ],
+ "node_modules/babel-jest": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.5.2.tgz",
+ "integrity": "sha512-ES8WeJ2fNWPEDunyAtUfJ12nHyaWUloCHdkfK2oW5uSoQSUmjNKdWiGaXJITJwvFEWoD/evHEg/QoCXAvLaQqQ==",
"dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "MIT",
+ "dependencies": {
+ "@jest/transform": "30.5.2",
+ "@types/babel__core": "^7.20.5",
+ "babel-plugin-istanbul": "^8.0.0",
+ "babel-preset-jest": "30.5.0",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "slash": "^3.0.0"
+ },
"engines": {
- "node": ">=10"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.11.0 || ^8.0.0-0"
}
},
- "node_modules/@swc/core-linux-x64-musl": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.8.tgz",
- "integrity": "sha512-z3XBnbrZAL+6xDGAhJoN4lOueIxC/8rGrJ9tg+fEaeqLEuAtHSW2QHDHxDwkxZMjuF/pZ6MUTjHjbp8wLbuRLA==",
- "cpu": [
- "x64"
- ],
+ "node_modules/babel-plugin-istanbul": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz",
+ "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==",
"dev": true,
- "optional": true,
- "os": [
- "linux"
+ "license": "BSD-3-Clause",
+ "workspaces": [
+ "test/babel-8"
],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-instrument": "^6.0.2",
+ "test-exclude": "^7.0.1"
+ },
"engines": {
- "node": ">=10"
+ "node": ">=18"
}
},
- "node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.8.tgz",
- "integrity": "sha512-djQPJ9Rh9vP8GTS/Df3hcc6XP6xnG5c8qsngWId/BLA9oX6C7UzCPAn74BG/wGb9a6j4w3RINuoaieJB3t+7iQ==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.5.0.tgz",
+ "integrity": "sha512-gtGo1B+u14jrZQv6TdSWIWkTqclboo7Qn+dFAGUOIuXLFuJKAdg3U5MIWzZnW4vfUb4dX9skmAMiby86e/SF4A==",
"dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/babel__core": "^7.20.5"
+ },
"engines": {
- "node": ">=10"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.8.tgz",
- "integrity": "sha512-/wfAgxORg2VBaUoFdytcVBVCgf1isWZIEXB9MZEUty4wwK93M/PxAkjifOho9RN3WrM3inPLabICRCEgdHpKKQ==",
- "cpu": [
- "ia32"
- ],
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz",
+ "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==",
"dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.27.7",
+ "@babel/helper-define-polyfill-provider": "^0.6.5",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.8.tgz",
- "integrity": "sha512-GpMePrh9Sl4d61o4KAHOOv5is5+zt6BEXCOCgs/H0FLGeii7j9bWDE8ExvKFy2GRRZVNR1ugsnzaGWHKM6kuzA==",
- "cpu": [
- "x64"
- ],
+ "node_modules/babel-plugin-polyfill-corejs2/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,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
}
},
- "node_modules/@swc/counter": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
- "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
- "dev": true
- },
- "node_modules/@swc/types": {
- "version": "0.1.25",
- "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
- "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz",
+ "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@swc/counter": "^0.1.3"
+ "@babel/helper-define-polyfill-provider": "^0.6.5",
+ "core-js-compat": "^3.43.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@swc/wasm": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.15.8.tgz",
- "integrity": "sha512-RG2BxGbbsjtddFCo1ghKH6A/BMXbY1eMBfpysV0lJMCpI4DZOjW1BNBnxvBt7YsYmlJtmy5UXIg9/4ekBTFFaQ==",
- "dev": true
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz",
+ "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
},
- "node_modules/@tauri-apps/api": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.10.1.tgz",
- "integrity": "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==",
- "license": "Apache-2.0 OR MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/tauri"
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
+ "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0 || ^8.0.0-0"
}
},
- "node_modules/@tauri-apps/cli": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.10.1.tgz",
- "integrity": "sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==",
+ "node_modules/babel-preset-jest": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.5.0.tgz",
+ "integrity": "sha512-ZGPn5ClP4lBDpuOK8W1yQIOy359HmbnZv3suucAlIe+SEE9yDsxV4S2PjSbH2Vc97U+WmzYD7vw3kr8NsQ/i6w==",
"dev": true,
- "license": "Apache-2.0 OR MIT",
- "bin": {
- "tauri": "tauri.js"
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-jest-hoist": "30.5.0",
+ "babel-preset-current-node-syntax": "^1.2.0"
},
"engines": {
- "node": ">= 10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/tauri"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
- "optionalDependencies": {
- "@tauri-apps/cli-darwin-arm64": "2.10.1",
- "@tauri-apps/cli-darwin-x64": "2.10.1",
- "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.1",
- "@tauri-apps/cli-linux-arm64-gnu": "2.10.1",
- "@tauri-apps/cli-linux-arm64-musl": "2.10.1",
- "@tauri-apps/cli-linux-riscv64-gnu": "2.10.1",
- "@tauri-apps/cli-linux-x64-gnu": "2.10.1",
- "@tauri-apps/cli-linux-x64-musl": "2.10.1",
- "@tauri-apps/cli-win32-arm64-msvc": "2.10.1",
- "@tauri-apps/cli-win32-ia32-msvc": "2.10.1",
- "@tauri-apps/cli-win32-x64-msvc": "2.10.1"
+ "peerDependencies": {
+ "@babel/core": "^7.11.0 || ^8.0.0-beta.1 || ^8.0.0"
}
},
- "node_modules/@tauri-apps/cli-darwin-arm64": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.10.1.tgz",
- "integrity": "sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==",
- "cpu": [
- "arm64"
- ],
+ "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": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.23",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.23.tgz",
+ "integrity": "sha512-le521dGVfxM7yRX0EikCoSz+rOK+hHzdDt/E7mG1jOJB/6WAAUuwVroLwaB7ApaUsz5Q0kFlDXLSA9MheUIfRQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
"engines": {
- "node": ">= 10"
+ "node": ">=6.0.0"
}
},
- "node_modules/@tauri-apps/cli-darwin-x64": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.10.1.tgz",
- "integrity": "sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==",
- "cpu": [
- "x64"
- ],
+ "node_modules/brace-expansion": {
+ "version": "1.1.18",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
"dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
},
- "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.10.1.tgz",
- "integrity": "sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "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": ">= 10"
+ "node": ">=8"
}
},
- "node_modules/@tauri-apps/cli-linux-arm64-gnu": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.10.1.tgz",
- "integrity": "sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/browserslist": {
+ "version": "4.28.9",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz",
+ "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==",
"dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.11.20",
+ "caniuse-lite": "^1.0.30001810",
+ "electron-to-chromium": "^1.5.420",
+ "node-releases": "^2.0.54",
+ "update-browserslist-db": "^1.3.2"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
"engines": {
- "node": ">= 10"
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
- "node_modules/@tauri-apps/cli-linux-arm64-musl": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.10.1.tgz",
- "integrity": "sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
"dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "MIT",
+ "dependencies": {
+ "fast-json-stable-stringify": "2.x"
+ },
"engines": {
- "node": ">= 10"
+ "node": ">= 6"
}
},
- "node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.10.1.tgz",
- "integrity": "sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==",
- "cpu": [
- "riscv64"
- ],
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
"dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
}
},
- "node_modules/@tauri-apps/cli-linux-x64-gnu": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.10.1.tgz",
- "integrity": "sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==",
- "cpu": [
- "x64"
- ],
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
"dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "license": "MIT",
"engines": {
- "node": ">= 10"
+ "node": ">=8"
}
},
- "node_modules/@tauri-apps/cli-linux-x64-musl": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.10.1.tgz",
- "integrity": "sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==",
- "cpu": [
- "x64"
- ],
+ "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": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "linux"
- ],
+ "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": ">= 10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@tauri-apps/cli-win32-arm64-msvc": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.10.1.tgz",
- "integrity": "sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==",
- "cpu": [
- "arm64"
- ],
+ "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": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "win32"
- ],
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
"engines": {
- "node": ">= 10"
+ "node": ">= 0.4"
}
},
- "node_modules/@tauri-apps/cli-win32-ia32-msvc": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.10.1.tgz",
- "integrity": "sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==",
- "cpu": [
- "ia32"
- ],
+ "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": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "win32"
- ],
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
"engines": {
- "node": ">= 10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@tauri-apps/cli-win32-x64-msvc": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.10.1.tgz",
- "integrity": "sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
- "license": "Apache-2.0 OR MIT",
- "optional": true,
- "os": [
- "win32"
- ],
+ "license": "MIT",
"engines": {
- "node": ">= 10"
+ "node": ">=6"
}
},
- "node_modules/@tauri-apps/plugin-dialog": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.6.0.tgz",
- "integrity": "sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==",
- "license": "MIT OR Apache-2.0",
- "dependencies": {
- "@tauri-apps/api": "^2.8.0"
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/@tauri-apps/plugin-fs": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.5.tgz",
- "integrity": "sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==",
- "license": "MIT OR Apache-2.0",
- "dependencies": {
- "@tauri-apps/api": "^2.8.0"
- }
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001810",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
+ "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
},
- "node_modules/@tauri-apps/plugin-notification": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.3.3.tgz",
- "integrity": "sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg==",
- "license": "MIT OR Apache-2.0",
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "@tauri-apps/api": "^2.8.0"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/@tauri-apps/plugin-opener": {
- "version": "2.5.3",
- "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz",
- "integrity": "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==",
- "license": "MIT OR Apache-2.0",
- "dependencies": {
- "@tauri-apps/api": "^2.8.0"
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/@tokenizer/inflate": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz",
- "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==",
+ "node_modules/ci-info": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz",
+ "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
"license": "MIT",
- "dependencies": {
- "debug": "^4.4.3",
- "token-types": "^6.1.1"
- },
"engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
+ "node": ">=8"
}
},
- "node_modules/@tokenizer/token": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
- "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
+ "node_modules/cjs-module-lexer": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.1.tgz",
+ "integrity": "sha512-Ca8swihM+/4yKecYHY52kgJd300hi2lADU/a1RxNTRe+RJ9jvqQlESpbz9DnG9mowez8qwXHB8qYdIUw9e+F5Q==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/@transloadit/prettier-bytes": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.3.5.tgz",
- "integrity": "sha512-xF4A3d/ZyX2LJWeQZREZQw+qFX4TGQ8bGVP97OLRt6sPO6T0TNHBFTuRHOJh7RNmYOBmQ9MHxpolD9bXihpuVA==",
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
"license": "MIT"
},
- "node_modules/@types/babel__core": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@types/babel__generator": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
- "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/types": "^7.0.0"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/@types/babel__template": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/@types/babel__traverse": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
- "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.28.2"
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/@types/estree": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "license": "MIT"
- },
- "node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
- "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
},
- "node_modules/@types/istanbul-lib-report": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
- "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "node_modules/cloc": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/cloc/-/cloc-2.11.0.tgz",
+ "integrity": "sha512-+mxuCHo7ESOQadlsyMjmPZ4hGBtvQzmNGHfLdBNvXKbnRhtmOTslU4XF2cyFSaOCHaaF26ba2CGjU6lpeIFB0w==",
"dev": true,
+ "license": "GPL-2.0",
+ "bin": {
+ "cloc": "lib/cloc"
+ }
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-coverage": "*"
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/@types/istanbul-reports": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
- "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-report": "*"
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
}
},
- "node_modules/@types/jasmine": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-6.0.0.tgz",
- "integrity": "sha512-18lgGsLmEh3VJk9eZ5wAjTISxdqzl6YOwu8UdMpolajN57QOCNbl+AbHUd+Yu9ItrsFdB+c8LSZSGNg8nHaguw==",
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz",
+ "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==",
"dev": true,
"license": "MIT"
},
- "node_modules/@types/jest": {
- "version": "30.0.0",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz",
- "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==",
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "expect": "^30.0.0",
- "pretty-format": "^30.0.0"
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
}
},
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
- "node_modules/@types/lodash": {
- "version": "4.17.24",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz",
- "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==",
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"dev": true,
"license": "MIT"
},
- "node_modules/@types/node": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz",
- "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==",
- "devOptional": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~7.18.0"
- }
- },
- "node_modules/@types/react": {
- "version": "19.2.14",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
- "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"devOptional": true,
- "license": "MIT",
- "dependencies": {
- "csstype": "^3.2.2"
- }
+ "license": "MIT"
},
- "node_modules/@types/react-dom": {
- "version": "19.2.3",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
- "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
- "devOptional": true,
+ "node_modules/common-tags": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@types/react": "^19.2.0"
+ "engines": {
+ "node": ">=4.0.0"
}
},
- "node_modules/@types/resolve": {
- "version": "1.20.2",
- "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
- "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT"
},
- "node_modules/@types/stack-utils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
- "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
"dev": true,
- "license": "MIT"
- },
- "node_modules/@types/trusted-types": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
- "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
- "devOptional": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
},
- "node_modules/@types/yargs": {
- "version": "17.0.33",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
- "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
- "dev": true,
+ "node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
"license": "MIT",
- "dependencies": {
- "@types/yargs-parser": "*"
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
- "node_modules/@types/yargs-parser": {
- "version": "21.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
- "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "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/@typescript-eslint/eslint-plugin": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz",
- "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==",
+ "node_modules/core-js-compat": {
+ "version": "3.47.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz",
+ "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@eslint-community/regexpp": "^4.12.2",
- "@typescript-eslint/scope-manager": "8.57.0",
- "@typescript-eslint/type-utils": "8.57.0",
- "@typescript-eslint/utils": "8.57.0",
- "@typescript-eslint/visitor-keys": "8.57.0",
- "ignore": "^7.0.5",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^2.4.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "browserslist": "^4.28.0"
},
"funding": {
"type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^8.57.0",
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "url": "https://opencollective.com/core-js"
}
},
- "node_modules/@typescript-eslint/parser": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.0.tgz",
- "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==",
+ "node_modules/cross-env": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
+ "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.57.0",
- "@typescript-eslint/types": "8.57.0",
- "@typescript-eslint/typescript-estree": "8.57.0",
- "@typescript-eslint/visitor-keys": "8.57.0",
- "debug": "^4.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "@epic-web/invariant": "^1.0.0",
+ "cross-spawn": "^7.0.6"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "bin": {
+ "cross-env": "dist/bin/cross-env.js",
+ "cross-env-shell": "dist/bin/cross-env-shell.js"
},
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "engines": {
+ "node": ">=20"
}
},
- "node_modules/@typescript-eslint/project-service": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz",
- "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==",
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.57.0",
- "@typescript-eslint/types": "^8.57.0",
- "debug": "^4.4.3"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "node": ">= 8"
}
},
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz",
- "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==",
+ "node_modules/crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cssstyle": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.57.0",
- "@typescript-eslint/visitor-keys": "8.57.0"
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "node": ">=18"
}
},
- "node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz",
- "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==",
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/data-urls": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "dependencies": {
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
},
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz",
- "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==",
+ "node_modules/data-urls/node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.57.0",
- "@typescript-eslint/typescript-estree": "8.57.0",
- "@typescript-eslint/utils": "8.57.0",
- "debug": "^4.4.3",
- "ts-api-utils": "^2.4.0"
+ "punycode": "^2.3.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 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "node": ">=18"
}
},
- "node_modules/@typescript-eslint/types": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.0.tgz",
- "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==",
+ "node_modules/data-urls/node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-2-Clause",
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "node": ">=12"
}
},
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz",
- "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==",
+ "node_modules/data-urls/node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/project-service": "8.57.0",
- "@typescript-eslint/tsconfig-utils": "8.57.0",
- "@typescript-eslint/types": "8.57.0",
- "@typescript-eslint/visitor-keys": "8.57.0",
- "debug": "^4.4.3",
- "minimatch": "^10.2.2",
- "semver": "^7.7.3",
- "tinyglobby": "^0.2.15",
- "ts-api-utils": "^2.4.0"
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "node": ">=18"
}
},
- "node_modules/@typescript-eslint/utils": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.0.tgz",
- "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==",
+ "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": {
- "@eslint-community/eslint-utils": "^4.9.1",
- "@typescript-eslint/scope-manager": "8.57.0",
- "@typescript-eslint/types": "8.57.0",
- "@typescript-eslint/typescript-estree": "8.57.0"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">= 0.4"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz",
- "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==",
+ "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": {
- "@typescript-eslint/types": "8.57.0",
- "eslint-visitor-keys": "^5.0.0"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">= 0.4"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "url": "https://github.com/sponsors/inspect-js"
}
},
- "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
- "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
+ "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": "Apache-2.0",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
"engines": {
- "node": "^20.19.0 || ^22.13.0 || >=24"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@uppy/components": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@uppy/components/-/components-1.2.0.tgz",
- "integrity": "sha512-rtIr+77Rw/q5Vw++xazF1dCg2d4A4zT9CV+ZyN8Rsx8xiIr2CxCR4TaHHBy+WeC0b7Mk6yNuJ0wUa34tFJ6pKg==",
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
- "clsx": "^2.1.1",
- "dequal": "^2.0.3",
- "preact": "^10.26.10",
- "pretty-bytes": "^6.1.1"
+ "ms": "^2.1.3"
},
- "peerDependencies": {
- "@uppy/core": "^5.2.0",
- "@uppy/image-editor": "^4.2.0",
- "@uppy/screen-capture": "^5.1.0",
- "@uppy/webcam": "^5.1.0"
+ "engines": {
+ "node": ">=6.0"
},
"peerDependenciesMeta": {
- "@uppy/image-editor": {
- "optional": true
- },
- "@uppy/screen-capture": {
- "optional": true
- },
- "@uppy/webcam": {
+ "supports-color": {
"optional": true
}
}
},
- "node_modules/@uppy/core": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@uppy/core/-/core-5.2.0.tgz",
- "integrity": "sha512-uvfNyz4cnaplt7LYJmEZHuqOuav0tKp4a9WKJIaH6iIj7XiqYvS2J5SEByexAlUFlzefOAyjzj4Ja2dd/8aMrw==",
- "license": "MIT",
- "dependencies": {
- "@transloadit/prettier-bytes": "^0.3.4",
- "@uppy/store-default": "^5.0.0",
- "@uppy/utils": "^7.1.4",
- "lodash": "^4.17.21",
- "mime-match": "^1.0.2",
- "namespace-emitter": "^2.0.1",
- "nanoid": "^5.0.9",
- "preact": "^10.5.13"
- }
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/@uppy/dashboard": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@uppy/dashboard/-/dashboard-5.1.1.tgz",
- "integrity": "sha512-6H/xVvhhdfwp1+FRMp2C+tudyaedqD5+LMDB8Iw20k9+QCL1eGzOh4wXm6MCqJtNfQ1tLaprGMG1jlo7yS/uyw==",
+ "node_modules/decode-bmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz",
+ "integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@transloadit/prettier-bytes": "^0.3.4",
- "@uppy/provider-views": "^5.2.2",
- "@uppy/thumbnail-generator": "^5.1.0",
- "@uppy/utils": "^7.1.5",
- "classnames": "^2.2.6",
- "lodash": "^4.17.23",
- "nanoid": "^5.0.9",
- "preact": "^10.26.10",
- "shallow-equal": "^3.0.0"
+ "@canvas/image-data": "^1.0.0",
+ "to-data-view": "^1.1.0"
},
- "peerDependencies": {
- "@uppy/core": "^5.2.0"
+ "engines": {
+ "node": ">=8.6.0"
}
},
- "node_modules/@uppy/provider-views": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/@uppy/provider-views/-/provider-views-5.2.2.tgz",
- "integrity": "sha512-NAazIJ5sjrAc6++CeJ/u9dB5gDaaAOLHrYeEmWs/HqLlftlIinRZOybnyzJRXwI8jWI/FK5moluzt2HXu6dPQQ==",
+ "node_modules/decode-ico": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz",
+ "integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@uppy/utils": "^7.1.5",
- "classnames": "^2.2.6",
- "lodash": "^4.17.21",
- "nanoid": "^5.0.9",
- "p-queue": "^8.0.0",
- "preact": "^10.5.13"
+ "@canvas/image-data": "^1.0.0",
+ "decode-bmp": "^0.2.0",
+ "to-data-view": "^1.1.0"
},
- "peerDependencies": {
- "@uppy/core": "^5.2.0"
+ "engines": {
+ "node": ">=8.6"
}
},
- "node_modules/@uppy/react": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@uppy/react/-/react-5.2.0.tgz",
- "integrity": "sha512-6lzPutg2XGavs7P6ALmqOBPitd/Jqi3r1jCJQD5nx8xtNlBRwvlBR6hrZgo8XOI9cR+OaNDrJ0vEFxXDWb04Ag==",
+ "node_modules/dedent": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz",
+ "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@uppy/components": "^1.2.0",
- "preact": "^10.26.10",
- "use-sync-external-store": "^1.3.0"
- },
"peerDependencies": {
- "@uppy/core": "^5.2.0",
- "@uppy/dashboard": "^5.1.1",
- "@uppy/screen-capture": "^5.1.0",
- "@uppy/status-bar": "^5.1.0",
- "@uppy/webcam": "^5.1.0",
- "react": "^18.0.0 || ^19.0.0",
- "react-dom": "^18.0.0 || ^19.0.0"
+ "babel-plugin-macros": "^3.1.0"
},
"peerDependenciesMeta": {
- "@uppy/dashboard": {
- "optional": true
- },
- "@uppy/screen-capture": {
- "optional": true
- },
- "@uppy/status-bar": {
- "optional": true
- },
- "@uppy/webcam": {
+ "babel-plugin-macros": {
"optional": true
}
}
},
- "node_modules/@uppy/store-default": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-5.0.0.tgz",
- "integrity": "sha512-hQtCSQ1yGiaval/wVYUWquYGDJ+bpQ7e4FhUUAsRQz1x1K+o7NBtjfp63O9I4Ks1WRoKunpkarZ+as09l02cPw==",
- "license": "MIT"
- },
- "node_modules/@uppy/thumbnail-generator": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@uppy/thumbnail-generator/-/thumbnail-generator-5.1.0.tgz",
- "integrity": "sha512-QAKJHHkMrD/30GOyUb5U9HyJ7Ie3jiMLp4pVdw27PoA4pNV7fDQz0tyDeRPj2H+BWPEB1NsTSSfHI2pjHNI+OQ==",
- "license": "MIT",
- "dependencies": {
- "@uppy/utils": "^7.1.4",
- "exifr": "^7.0.0"
- },
- "peerDependencies": {
- "@uppy/core": "^5.2.0"
- }
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/@uppy/utils": {
- "version": "7.1.5",
- "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-7.1.5.tgz",
- "integrity": "sha512-Vz4WGTjef6WebECGur4clWjpkET4o3bdvPMj1m2sD5cL+dTt69m+FIE5h5JD3HBMLEPTXPVkrXGMIFcbOYC12Q==",
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "lodash": "^4.17.21",
- "preact": "^10.5.13"
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "node_modules/@vite-pwa/assets-generator": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-1.0.2.tgz",
- "integrity": "sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==",
+ "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": {
- "cac": "^6.7.14",
- "colorette": "^2.0.20",
- "consola": "^3.4.2",
- "sharp": "^0.33.5",
- "sharp-ico": "^0.1.5",
- "unconfig": "^7.3.1"
- },
- "bin": {
- "pwa-assets-generator": "bin/pwa-assets-generator.mjs"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
},
"engines": {
- "node": ">=16.14.0"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/antfu"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@vitejs/plugin-react": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz",
- "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==",
+ "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": {
- "@babel/core": "^7.29.0",
- "@babel/plugin-transform-react-jsx-self": "^7.27.1",
- "@babel/plugin-transform-react-jsx-source": "^7.27.1",
- "@rolldown/pluginutils": "1.0.0-rc.3",
- "@types/babel__core": "^7.20.5",
- "react-refresh": "^0.18.0"
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
},
"engines": {
- "node": "^20.19.0 || >=22.12.0"
+ "node": ">= 0.4"
},
- "peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/@web-scrobbler/metadata-filter": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@web-scrobbler/metadata-filter/-/metadata-filter-3.2.0.tgz",
- "integrity": "sha512-K2Wkq9AOJkgj4Hk9g0flKnNWYkJy1GTPpHTgpNLU5OXaXgqPKLyrtb62M1cIxMN3ESH6XGvPKM92VEl/Gc3Rog==",
+ "node_modules/defu": {
+ "version": "6.1.7",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz",
+ "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"license": "MIT",
"engines": {
- "node": ">=10.0.0"
+ "node": ">=6"
}
},
- "node_modules/acorn": {
- "version": "8.15.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
- "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
- "devOptional": true,
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
"license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
"engines": {
- "node": ">=0.4.0"
+ "node": ">=8"
}
},
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
+ "license": "MIT"
+ },
+ "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/dompurify": {
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.15.tgz",
+ "integrity": "sha512-EUBjM+B+lkDE41iE82DDSCfkoPGfXx8IxFxPMjNzm/Uk4xDet77rTN9wqlxlVg71kK7XGuUMv6wUxJUwwv+Xyw==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
+ },
+ "node_modules/dsssp": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/dsssp/-/dsssp-0.8.0.tgz",
+ "integrity": "sha512-e3uQs0Tg4ZpLpt/y+HihJ3BTlork+6TUmXa/TO13YV+OINz0i2jzGIBuibf3R3SqxjwxIM2MMraVMmUbobK9hg==",
"license": "MIT",
+ "funding": {
+ "url": "https://github.com/numberonebot/dsssp?sponsor=1"
+ },
"peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "react": "^18.2.0 || ^19.0.0",
+ "react-dom": "^18.2.0 || ^19.0.0"
}
},
- "node_modules/ajv": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
- "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
+ "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": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
},
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "engines": {
+ "node": ">= 0.4"
}
},
- "node_modules/ansi-regex": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
- "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.427",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.427.tgz",
+ "integrity": "sha512-n14zb3FdsChZ2BNobqNHAJMcP3ifFv4paox2LvCrfVAQcqGiSURgbJl+PfMpHVCNFkStnNc+RRVtPBTVW5PDgw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
}
},
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
+ "license": "MIT"
+ },
+ "node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
"engines": {
- "node": ">=8"
+ "node": ">=0.12"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
"dev": true,
- "license": "Python-2.0"
- },
- "node_modules/aria-hidden": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
- "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
"license": "MIT",
"dependencies": {
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
+ "is-arrayish": "^0.2.1"
}
},
- "node_modules/array-buffer-byte-length": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
- "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "node_modules/es-abstract": {
+ "version": "1.24.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
+ "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.3",
- "is-array-buffer": "^3.0.5"
+ "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"
@@ -5767,162 +8615,113 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "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",
- "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/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==",
+ "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",
- "dependencies": {
- "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/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==",
+ "node_modules/es-iterator-helpers": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
+ "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
"define-properties": "^1.2.1",
- "es-abstract": "^1.23.5",
- "es-shim-unscopables": "^1.0.2"
+ "es-abstract": "^1.23.6",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.0.3",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.6",
+ "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.4",
+ "safe-array-concat": "^1.1.3"
},
"engines": {
"node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "node_modules/es-module-lexer": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz",
+ "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==",
"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"
- }
+ "license": "MIT"
},
- "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==",
+ "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": {
- "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"
+ "es-errors": "^1.3.0"
},
"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==",
+ "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": {
- "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"
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/async": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
- "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
- "dev": true,
- "license": "MIT"
- },
- "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==",
+ "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/at-least-node": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
- "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">= 4.0.0"
- }
- },
- "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==",
+ "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": {
- "possible-typed-array-names": "^1.0.0"
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
},
"engines": {
"node": ">= 0.4"
@@ -5931,890 +8730,724 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.14",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz",
- "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==",
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.27.7",
- "@babel/helper-define-polyfill-provider": "^0.6.5",
- "semver": "^6.3.1"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/babel-plugin-polyfill-corejs2/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"
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz",
- "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==",
+ "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",
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.5",
- "core-js-compat": "^3.43.0"
+ "engines": {
+ "node": ">=10"
},
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.6.5",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz",
- "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==",
+ "node_modules/eslint": {
+ "version": "9.39.5",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz",
+ "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.5"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "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.11",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
- "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==",
- "dev": true,
- "license": "Apache-2.0",
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.2",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.6",
+ "@eslint/js": "9.39.5",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.14.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.5",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
"bin": {
- "baseline-browser-mapping": "dist/cli.js"
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
}
},
- "node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "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": {
- "balanced-match": "^1.0.0"
- }
- },
- "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"
+ "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": ">=8"
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
}
},
- "node_modules/browserslist": {
- "version": "4.28.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
- "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "node_modules/eslint-plugin-react/node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "baseline-browser-mapping": "^2.9.0",
- "caniuse-lite": "^1.0.30001759",
- "electron-to-chromium": "^1.5.263",
- "node-releases": "^2.0.27",
- "update-browserslist-db": "^1.2.0"
- },
- "bin": {
- "browserslist": "cli.js"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ "node": "*"
}
},
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "devOptional": true,
- "license": "MIT"
- },
- "node_modules/cac": {
- "version": "6.7.14",
- "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
- "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "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": "MIT",
- "engines": {
- "node": ">=8"
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
}
},
- "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==",
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-2-Clause",
"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"
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://opencollective.com/eslint"
}
},
- "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==",
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
+ "license": "Apache-2.0",
"engines": {
- "node": ">= 0.4"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "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==",
+ "node_modules/eslint/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": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
+ "license": "Apache-2.0",
"engines": {
- "node": ">= 0.4"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "node_modules/eslint/node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=6"
+ "node": ">= 4"
}
},
- "node_modules/caniuse-lite": {
- "version": "1.0.30001762",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
- "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "node": "*"
}
},
- "node_modules/ci-info": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz",
- "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==",
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/classnames": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
- "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
- "license": "MIT"
- },
- "node_modules/cloc": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/cloc/-/cloc-2.11.0.tgz",
- "integrity": "sha512-+mxuCHo7ESOQadlsyMjmPZ4hGBtvQzmNGHfLdBNvXKbnRhtmOTslU4XF2cyFSaOCHaaF26ba2CGjU6lpeIFB0w==",
- "dev": true,
- "license": "GPL-2.0",
- "bin": {
- "cloc": "lib/cloc"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/clsx": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
- "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
- "license": "MIT",
+ "node_modules/espree/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": ">=6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/color": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
- "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1",
- "color-string": "^1.9.0"
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
},
"engines": {
- "node": ">=12.5.0"
+ "node": ">=4"
}
},
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-3-Clause",
"dependencies": {
- "color-name": "~1.1.4"
+ "estraverse": "^5.1.0"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">=0.10"
}
},
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/color-string": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
- "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-2-Clause",
"dependencies": {
- "color-name": "^1.0.0",
- "simple-swizzle": "^0.2.2"
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
}
},
- "node_modules/colorette": {
- "version": "2.0.20",
- "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
- "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "devOptional": true,
- "license": "MIT"
- },
- "node_modules/common-tags": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
- "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-2-Clause",
"engines": {
- "node": ">=4.0.0"
+ "node": ">=4.0"
}
},
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true,
"license": "MIT"
},
- "node_modules/consola": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
- "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-2-Clause",
"engines": {
- "node": "^14.18.0 || >=16.10.0"
+ "node": ">=0.10.0"
}
},
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "node_modules/eta": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/eta/-/eta-4.6.0.tgz",
+ "integrity": "sha512-lW6is4T1NFOYnmqGZIfvixqj7A7sSvScF+DN8EK6K58xI5MZ5UvYe0GjopxOXQtZvUn4eDdVuZ8XSoYWTMEKwA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.6"
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/bgub/eta?sponsor=1"
}
},
- "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,
+ "node_modules/eventemitter3": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
+ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
"license": "MIT"
},
- "node_modules/core-js-compat": {
- "version": "3.47.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz",
- "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==",
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "browserslist": "^4.28.0"
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/cross-env": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
- "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
+ "node_modules/execa/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@epic-web/invariant": "^1.0.0",
- "cross-spawn": "^7.0.6"
- },
- "bin": {
- "cross-env": "dist/bin/cross-env.js",
- "cross-env-shell": "dist/bin/cross-env-shell.js"
- },
- "engines": {
- "node": ">=20"
- }
+ "license": "ISC"
},
- "node_modules/cross-fetch": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
- "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
+ "node_modules/exifr": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.3.tgz",
+ "integrity": "sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==",
+ "license": "MIT"
+ },
+ "node_modules/exit-x": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz",
+ "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "node-fetch": "^2.6.12"
+ "engines": {
+ "node": ">= 0.8.0"
}
},
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "node_modules/expect": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-30.5.2.tgz",
+ "integrity": "sha512-0LNuMvs8/5mRYhnCR4k+lGV7fqPMs6Bnksda4S3zsCUmdxBpAn4zU4NNzXdq1pMKe/H4W5t/zVIDSJ/H3e0vDA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
+ "@jest/expect-utils": "30.5.2",
+ "@jest/get-type": "30.5.0",
+ "jest-matcher-utils": "30.5.2",
+ "jest-message-util": "30.5.1",
+ "jest-mock": "30.5.2",
+ "jest-util": "30.5.1"
},
"engines": {
- "node": ">= 8"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/crypto-random-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
- "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
+ "license": "MIT"
},
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "devOptional": true,
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
"license": "MIT"
},
- "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==",
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"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"
- }
+ "license": "MIT"
},
- "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==",
+ "node_modules/fast-uri": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz",
+ "integrity": "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==",
"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"
- }
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
},
- "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==",
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
"dev": true,
- "license": "MIT",
+ "license": "Apache-2.0",
"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"
+ "bser": "2.1.1"
}
},
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
"engines": {
- "node": ">=6.0"
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
- "supports-color": {
+ "picomatch": {
"optional": true
}
}
},
- "node_modules/decode-bmp": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz",
- "integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==",
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@canvas/image-data": "^1.0.0",
- "to-data-view": "^1.1.0"
+ "flat-cache": "^4.0.0"
},
"engines": {
- "node": ">=8.6.0"
+ "node": ">=16.0.0"
}
},
- "node_modules/decode-ico": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz",
- "integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==",
- "dev": true,
+ "node_modules/file-type": {
+ "version": "21.3.4",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz",
+ "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==",
"license": "MIT",
"dependencies": {
- "@canvas/image-data": "^1.0.0",
- "decode-bmp": "^0.2.0",
- "to-data-view": "^1.1.0"
+ "@tokenizer/inflate": "^0.4.1",
+ "strtok3": "^10.3.4",
+ "token-types": "^6.1.1",
+ "uint8array-extras": "^1.4.0"
},
"engines": {
- "node": ">=8.6"
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/file-type?sponsor=1"
}
},
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "node_modules/filelist": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz",
+ "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
}
},
- "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==",
+ "node_modules/filelist/node_modules/brace-expansion": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz",
+ "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==",
"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"
+ "balanced-match": "^1.0.0"
}
},
- "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==",
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
+ "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "define-data-property": "^1.0.1",
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=10"
}
},
- "node_modules/defu": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
- "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/detect-libc": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.1.tgz",
- "integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==",
- "dev": true,
- "license": "Apache-2.0",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
"engines": {
"node": ">=8"
}
},
- "node_modules/detect-node-es": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
- "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
- "license": "MIT"
- },
- "node_modules/doctrine": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
- "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
"dependencies": {
- "esutils": "^2.0.2"
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/dompurify": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz",
- "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==",
- "license": "(MPL-2.0 OR Apache-2.0)",
- "optionalDependencies": {
- "@types/trusted-types": "^2.0.7"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "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==",
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=16"
}
},
- "node_modules/eastasianwidth": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
- "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "node_modules/flatted": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
"dev": true,
- "license": "MIT"
+ "license": "ISC"
},
- "node_modules/ejs": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
- "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "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": "Apache-2.0",
+ "license": "MIT",
"dependencies": {
- "jake": "^10.8.5"
- },
- "bin": {
- "ejs": "bin/cli.js"
+ "is-callable": "^1.2.7"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/electron-to-chromium": {
- "version": "1.5.267",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
- "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/emoji-regex": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/es-abstract": {
- "version": "1.24.0",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
- "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==",
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"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"
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=14"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "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==",
+ "node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">=10"
}
},
- "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,
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": ">= 0.4"
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
- "node_modules/es-iterator-helpers": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
- "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "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",
- "es-abstract": "^1.23.6",
- "es-errors": "^1.3.0",
- "es-set-tostringtag": "^2.0.3",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.6",
- "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.4",
- "safe-array-concat": "^1.1.3"
+ "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/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==",
+ "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",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "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",
- "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==",
+ "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",
- "dependencies": {
- "hasown": "^2.0.2"
- },
"engines": {
- "node": ">= 0.4"
+ "node": ">=6.9.0"
}
},
- "node_modules/es-to-primitive": {
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
"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==",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "is-callable": "^1.2.7",
- "is-date-object": "^1.0.5",
- "is-symbol": "^1.0.4"
+ "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"
@@ -6823,555 +9456,538 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/esbuild": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
- "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
- "hasInstallScript": true,
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
"license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
"engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.2",
- "@esbuild/android-arm": "0.27.2",
- "@esbuild/android-arm64": "0.27.2",
- "@esbuild/android-x64": "0.27.2",
- "@esbuild/darwin-arm64": "0.27.2",
- "@esbuild/darwin-x64": "0.27.2",
- "@esbuild/freebsd-arm64": "0.27.2",
- "@esbuild/freebsd-x64": "0.27.2",
- "@esbuild/linux-arm": "0.27.2",
- "@esbuild/linux-arm64": "0.27.2",
- "@esbuild/linux-ia32": "0.27.2",
- "@esbuild/linux-loong64": "0.27.2",
- "@esbuild/linux-mips64el": "0.27.2",
- "@esbuild/linux-ppc64": "0.27.2",
- "@esbuild/linux-riscv64": "0.27.2",
- "@esbuild/linux-s390x": "0.27.2",
- "@esbuild/linux-x64": "0.27.2",
- "@esbuild/netbsd-arm64": "0.27.2",
- "@esbuild/netbsd-x64": "0.27.2",
- "@esbuild/openbsd-arm64": "0.27.2",
- "@esbuild/openbsd-x64": "0.27.2",
- "@esbuild/openharmony-arm64": "0.27.2",
- "@esbuild/sunos-x64": "0.27.2",
- "@esbuild/win32-arm64": "0.27.2",
- "@esbuild/win32-ia32": "0.27.2",
- "@esbuild/win32-x64": "0.27.2"
+ "node": ">=6"
}
},
- "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/get-own-enumerable-property-symbols": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
+ "license": "ISC"
},
- "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/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=8.0.0"
}
},
- "node_modules/eslint": {
- "version": "9.39.4",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz",
- "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
+ "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": {
- "@eslint-community/eslint-utils": "^4.8.0",
- "@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.21.2",
- "@eslint/config-helpers": "^0.4.2",
- "@eslint/core": "^0.17.0",
- "@eslint/eslintrc": "^3.3.5",
- "@eslint/js": "9.39.4",
- "@eslint/plugin-kit": "^0.4.1",
- "@humanfs/node": "^0.16.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.4.2",
- "@types/estree": "^1.0.6",
- "ajv": "^6.14.0",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.6",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.4.0",
- "eslint-visitor-keys": "^4.2.1",
- "espree": "^10.4.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.5",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3"
- },
- "bin": {
- "eslint": "bin/eslint.js"
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
+ "node": ">= 0.4"
}
},
- "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"
- },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=4"
+ "node": ">=10"
},
- "peerDependencies": {
- "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint-plugin-react/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/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": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "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/eslint-plugin-react/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "node_modules/glob": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
+ "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
"dev": true,
- "license": "ISC",
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "foreground-child": "^3.3.1",
+ "jackspeak": "^4.1.1",
+ "minimatch": "^10.1.1",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": "*"
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "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==",
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
}
},
- "node_modules/eslint-scope": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
- "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "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": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "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": "Apache-2.0",
+ "license": "MIT",
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/eslint/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/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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/gsap": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.15.0.tgz",
+ "integrity": "sha512-dMW4CWBTUK1AEEDeZc1g4xpPGIrSf9fJF960qbTZmN/QwZIWY5wgliS6JWl9/25fpTGJrMRtSjGtOmPnfjZB+A==",
+ "license": "Standard 'no charge' license: https://gsap.com/standard-license."
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.9",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz",
+ "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
}
},
- "node_modules/eslint/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==",
+ "node_modules/handlebars/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "BSD-3-Clause",
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=0.10.0"
+ }
+ },
+ "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://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/eslint/node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 4"
+ "node": ">=8"
}
},
- "node_modules/eslint/node_modules/minimatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "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": "ISC",
+ "license": "MIT",
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "es-define-property": "^1.0.0"
},
- "engines": {
- "node": "*"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/espree": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
- "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "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": "BSD-2-Clause",
+ "license": "MIT",
"dependencies": {
- "acorn": "^8.15.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.1"
+ "dunder-proto": "^1.0.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/espree/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==",
+ "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": "Apache-2.0",
+ "license": "MIT",
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/esquery": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
- "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "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": "BSD-3-Clause",
+ "license": "MIT",
"dependencies": {
- "estraverse": "^5.1.0"
+ "has-symbols": "^1.0.3"
},
"engines": {
- "node": ">=0.10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
"dependencies": {
- "estraverse": "^5.2.0"
+ "function-bind": "^1.1.2"
},
"engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
+ "node": ">= 0.4"
}
},
- "node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "node_modules/html-encoding-sniffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^3.1.1"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=18"
}
},
- "node_modules/eventemitter3": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
- "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/exifr": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.3.tgz",
- "integrity": "sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==",
- "license": "MIT"
+ "node_modules/html-parse-stringify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-4.0.1.tgz",
+ "integrity": "sha512-0zHsZJrK7S3K2aucXWL6ycoYJ/iNtIcFHC/nYQgFklPtrv5LpJctIiSCroWZWeuoXvuyFdzp6KzjJQ+OT5MfFw==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://locize.com"
+ }
},
- "node_modules/expect": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz",
- "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==",
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/expect-utils": "30.2.0",
- "@jest/get-type": "30.1.0",
- "jest-matcher-utils": "30.2.0",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
},
"engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ "node": ">= 14"
}
},
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
},
- "node_modules/fast-json-stable-stringify": {
+ "node_modules/human-signals": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
- "license": "MIT"
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
},
- "node_modules/fast-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
- "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
- "dev": true,
+ "node_modules/i18next": {
+ "version": "26.4.2",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.4.2.tgz",
+ "integrity": "sha512-RX+R0VLg13IbvRuJSxnqykUFS9vQZTl8wYpWPCIUDWVrSGjsQywB5Y+pjzrkboxGAuYfJZVH1InFTdgBdxq6ug==",
"funding": [
{
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
+ "type": "individual",
+ "url": "https://www.locize.com/i18next"
},
{
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.locize.com"
}
],
- "license": "BSD-3-Clause"
- },
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
"peerDependencies": {
- "picomatch": "^3 || ^4"
+ "typescript": "^5 || ^6 || ^7"
},
"peerDependenciesMeta": {
- "picomatch": {
+ "typescript": {
"optional": true
}
}
},
- "node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
- "dev": true,
+ "node_modules/i18next-browser-languagedetector": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.1.tgz",
+ "integrity": "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==",
"license": "MIT",
"dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
+ "@babel/runtime": "^7.23.2"
}
},
- "node_modules/file-type": {
- "version": "21.3.2",
- "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.2.tgz",
- "integrity": "sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==",
+ "node_modules/i18next-http-backend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-4.0.2.tgz",
+ "integrity": "sha512-oay62dIB2kL7+WHzoUXBjWfL3+mwijD3pQkQkIEaRLhy6kjXxUhrRenV0gInwlCASAaJaDy94+XvYizK+cAGdA==",
"license": "MIT",
- "dependencies": {
- "@tokenizer/inflate": "^0.4.1",
- "strtok3": "^10.3.4",
- "token-types": "^6.1.1",
- "uint8array-extras": "^1.4.0"
- },
"engines": {
- "node": ">=20"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/file-type?sponsor=1"
+ "node": ">=18"
}
},
- "node_modules/filelist": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
- "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "node_modules/ico-endec": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz",
+ "integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==",
"dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "minimatch": "^5.0.1"
- }
+ "license": "MPL-2.0"
},
- "node_modules/filelist/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=0.10.0"
}
},
- "node_modules/fill-range": {
+ "node_modules/idb": {
"version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
+ "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
"engines": {
- "node": ">=8"
+ "node": ">= 4"
}
},
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "node_modules/import-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
},
"engines": {
- "node": ">=16"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/flatted": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
- "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
- "license": "ISC"
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
},
- "node_modules/for-each": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
- "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "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": {
- "is-callable": "^1.2.7"
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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"
@@ -7380,76 +9996,87 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/foreground-child": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
- "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true,
- "license": "ISC",
+ "license": "MIT"
+ },
+ "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": {
- "cross-spawn": "^7.0.6",
- "signal-exit": "^4.0.1"
+ "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": ">=14"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "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": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
+ "has-bigints": "^1.0.2"
},
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
+ "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",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
"engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ "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",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "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/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==",
+ "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==",
"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"
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -7458,53 +10085,59 @@
"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==",
+ "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/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==",
+ "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/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==",
+ "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": ">=6.9.0"
+ "node": ">=0.10.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==",
+ "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-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"
+ "call-bound": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -7513,46 +10146,38 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/get-nonce": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
- "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=6"
+ "node": ">=8"
}
},
- "node_modules/get-own-enumerable-property-symbols": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
- "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
- "dev": true,
- "license": "ISC"
- },
- "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==",
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
"engines": {
- "node": ">= 0.4"
+ "node": ">=6"
}
},
- "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==",
+ "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.3",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6"
+ "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"
@@ -7561,65 +10186,82 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/glob": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
- "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
+ "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": "BlueOak-1.0.0",
+ "license": "MIT",
"dependencies": {
- "foreground-child": "^3.3.1",
- "jackspeak": "^4.1.1",
- "minimatch": "^10.1.1",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^2.0.0"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
+ "is-extglob": "^2.1.1"
},
"engines": {
- "node": "20 || >=22"
+ "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/isaacs"
+ "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",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
"dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
+ "license": "MIT"
+ },
+ "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": ">=10.13.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
- "dev": true,
+ "node_modules/is-network-error": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz",
+ "integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==",
"license": "MIT",
"engines": {
- "node": ">=18"
+ "node": ">=16"
},
"funding": {
"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==",
+ "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": {
- "define-properties": "^1.2.1",
- "gopd": "^1.0.1"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -7628,32 +10270,35 @@
"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==",
+ "node_modules/is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=0.10.0"
}
},
- "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==",
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
"dev": true,
- "license": "ISC"
+ "license": "MIT"
},
- "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==",
+ "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"
},
@@ -7661,37 +10306,37 @@
"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",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "node_modules/is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">=0.10.0"
}
},
- "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==",
+ "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",
- "dependencies": {
- "es-define-property": "^1.0.0"
+ "engines": {
+ "node": ">= 0.4"
},
"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==",
+ "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": {
- "dunder-proto": "^1.0.0"
+ "call-bound": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -7700,27 +10345,28 @@
"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==",
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.4"
+ "node": ">=8"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "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==",
+ "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": {
- "has-symbols": "^1.0.3"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -7729,171 +10375,76 @@
"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==",
+ "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": {
- "function-bind": "^1.1.2"
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
- }
- },
- "node_modules/html-parse-stringify": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
- "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
- "license": "MIT",
- "dependencies": {
- "void-elements": "3.1.0"
- }
- },
- "node_modules/i18next": {
- "version": "25.8.18",
- "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.8.18.tgz",
- "integrity": "sha512-lzY5X83BiL5AP77+9DydbrqkQHFN9hUzWGjqjLpPcp5ZOzuu1aSoKaU3xbBLSjWx9dAzW431y+d+aogxOZaKRA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://locize.com"
- },
- {
- "type": "individual",
- "url": "https://locize.com/i18next.html"
- },
- {
- "type": "individual",
- "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.28.6"
},
- "peerDependencies": {
- "typescript": "^5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/i18next-browser-languagedetector": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.1.tgz",
- "integrity": "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.23.2"
- }
- },
- "node_modules/i18next-http-backend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.2.tgz",
- "integrity": "sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==",
- "license": "MIT",
- "dependencies": {
- "cross-fetch": "4.0.0"
- }
- },
- "node_modules/ico-endec": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz",
- "integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==",
- "dev": true,
- "license": "MPL-2.0"
- },
- "node_modules/idb": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
- "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/ignore": {
- "version": "7.0.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
- "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/import-fresh": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
- "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "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": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
+ "which-typed-array": "^1.1.16"
},
"engines": {
- "node": ">=6"
+ "node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "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.8.19"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "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": {
- "es-errors": "^1.3.0",
- "hasown": "^2.0.2",
- "side-channel": "^1.1.0"
+ "call-bound": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.8",
"call-bound": "^1.0.3",
"get-intrinsic": "^1.2.6"
},
@@ -7904,596 +10455,817 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-arrayish": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
- "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
+ "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/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==",
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
"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"
- },
+ "license": "BSD-3-Clause",
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=8"
}
},
- "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==",
+ "node_modules/istanbul-lib-instrument": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-3-Clause",
"dependencies": {
- "has-bigints": "^1.0.2"
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=10"
}
},
- "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==",
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-3-Clause",
"dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=10"
}
},
- "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==",
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=10"
}
},
- "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/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
"dev": true,
- "license": "MIT",
+ "license": "BSD-3-Clause",
"dependencies": {
- "hasown": "^2.0.2"
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=8"
}
},
- "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==",
+ "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": {
- "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
"get-intrinsic": "^1.2.6",
- "is-typed-array": "^1.1.13"
+ "get-proto": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "set-function-name": "^2.0.2"
},
"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==",
+ "node_modules/jackspeak": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
+ "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
"dev": true,
- "license": "MIT",
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "call-bound": "^1.0.2",
- "has-tostringtag": "^1.0.2"
+ "@isaacs/cliui": "^8.0.2"
},
"engines": {
- "node": ">= 0.4"
+ "node": "20 || >=22"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "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/jake": {
+ "version": "10.9.4",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
+ "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
"dev": true,
- "license": "MIT",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.6",
+ "filelist": "^1.0.4",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=10"
}
},
- "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==",
+ "node_modules/jest": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-30.5.2.tgz",
+ "integrity": "sha512-3gnpdBIza8ijCl3iMV9ChE3hSt1+46865qqod863gQtJr1DixOkAU5DoGbi3u+XlRcw++BhZQMu/y4xBdHBvSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.3"
+ "@jest/core": "30.5.2",
+ "@jest/types": "30.5.1",
+ "import-local": "^3.2.0",
+ "jest-cli": "30.5.2"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
}
},
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "node_modules/jest-changed-files": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.5.1.tgz",
+ "integrity": "sha512-0+bvMM/ENhDI29Z8q1r4HxiDIi4G5tnBmSw4esfPQoj9q8Nik7KIyuxHkTVnnniJQf05SxpGaKDQ+4h28ynGPg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "execa": "^5.1.1",
+ "jest-util": "30.5.1",
+ "p-limit": "^3.1.0"
+ },
"engines": {
- "node": ">=8"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/jest-circus": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.5.2.tgz",
+ "integrity": "sha512-vffFgjs5JSJ9q4ds1vNW3klKYPJfYfIY61LT/zaZgvTeASJOWZUt8LBfHgIcV4rwxlPBLl/ePBGccHEclS4PlQ==",
"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"
+ "@jest/environment": "30.5.2",
+ "@jest/expect": "30.5.2",
+ "@jest/test-result": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "co": "^4.6.0",
+ "dedent": "^1.6.0",
+ "is-generator-fn": "^2.1.0",
+ "jest-each": "30.5.2",
+ "jest-matcher-utils": "30.5.2",
+ "jest-message-util": "30.5.1",
+ "jest-runtime": "30.5.2",
+ "jest-snapshot": "30.5.2",
+ "jest-util": "30.5.1",
+ "p-limit": "^3.1.0",
+ "pretty-format": "30.5.1",
+ "pure-rand": "^7.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.6"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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/jest-cli": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.5.2.tgz",
+ "integrity": "sha512-YYYxUUVjFgPvgEleKNKMaYGIFgR3l3832Cl0kRL/oCiDZ03v7wImUtquHl2OOBCCNgprjZgBN5bczS/JklPBDg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "is-extglob": "^2.1.1"
+ "@jest/core": "30.5.2",
+ "@jest/test-result": "30.5.2",
+ "@jest/types": "30.5.1",
+ "chalk": "^4.1.2",
+ "exit-x": "^0.2.2",
+ "import-local": "^3.2.0",
+ "jest-config": "30.5.2",
+ "jest-util": "30.5.1",
+ "jest-validate": "30.5.1",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
},
"engines": {
- "node": ">=0.10.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
}
},
- "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==",
+ "node_modules/jest-config": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.5.2.tgz",
+ "integrity": "sha512-U6221OZekabePvGcGPf4raIBKMvYQWFHvhobDJRojOYaFMj2HaGytAdknjDhYc6JTz2fdHW9+6k0wWUDaNeOFQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@jest/get-type": "30.5.0",
+ "@jest/pattern": "30.5.0",
+ "@jest/test-sequencer": "30.5.2",
+ "@jest/types": "30.5.1",
+ "babel-jest": "30.5.2",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "deepmerge": "^4.3.1",
+ "glob": "^13.0.6",
+ "graceful-fs": "^4.2.11",
+ "jest-circus": "30.5.2",
+ "jest-docblock": "30.5.0",
+ "jest-environment-node": "30.5.2",
+ "jest-regex-util": "30.5.0",
+ "jest-resolve": "30.5.1",
+ "jest-runner": "30.5.2",
+ "jest-util": "30.5.1",
+ "jest-validate": "30.5.1",
+ "parse-json": "^5.2.0",
+ "pretty-format": "30.5.1",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "peerDependencies": {
+ "@types/node": "*",
+ "esbuild-register": ">=3.4.0",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "esbuild-register": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
}
},
- "node_modules/is-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
- "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
- "dev": true,
- "license": "MIT"
- },
- "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==",
+ "node_modules/jest-config/node_modules/glob": {
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
- "license": "MIT",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": "18 || 20 || >=22"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "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",
+ "node_modules/jest-config/node_modules/lru-cache": {
+ "version": "11.5.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz",
+ "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"engines": {
- "node": ">=0.12.0"
+ "node": "20 || >=22"
}
},
- "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==",
+ "node_modules/jest-config/node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
- "license": "MIT",
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
},
"engines": {
- "node": ">= 0.4"
+ "node": "18 || 20 || >=22"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/isaacs"
}
- },
- "node_modules/is-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
- "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
+ },
+ "node_modules/jest-diff": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.5.2.tgz",
+ "integrity": "sha512-rBtHnI6BWTiWj3lM7fOLVfChx7R9B0u9VV3PRHawKs79x6ZjW1QoSrKenaigNGWlvhtoi2BqvDbABDie+Os3xQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@jest/diff-sequences": "30.5.0",
+ "@jest/get-type": "30.5.0",
+ "chalk": "^4.1.2",
+ "pretty-format": "30.5.1"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.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==",
+ "node_modules/jest-docblock": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.5.0.tgz",
+ "integrity": "sha512-NwDqcxtoZi33RhuW+zJS/RVA3rmheQ8BnwpYZuc/Eruaz6seQb7+aoCeDZu/3X7W2XmD8DbSo9Pn72DbKsBFYw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.2",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
+ "detect-newline": "^3.1.0"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/is-regexp": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
- "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
+ "node_modules/jest-each": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.5.2.tgz",
+ "integrity": "sha512-GRrW+7fmmgmkvyfEBqc1QFdWnF1Ex5yG6Y6AWL4TTxnkWlKIT98dsKh3P3UuWm6v4XsQwVE6DEzXIPMzWJ3ZbA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.5.0",
+ "@jest/types": "30.5.1",
+ "chalk": "^4.1.2",
+ "jest-regex-util": "30.5.0",
+ "jest-util": "30.5.1",
+ "pretty-format": "30.5.1"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/jest-environment-jsdom": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.5.2.tgz",
+ "integrity": "sha512-6NOZjEP+WNi4WXjbxb/1ROnfaMxn6Dhqu6uSC22o0H28z+uppejs/jZ9KCVoLepqqoCjcNZujtzQqC9jSV15jg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.5.2",
+ "@jest/environment-jsdom-abstract": "30.5.2",
+ "@types/jsdom": "^21.1.7",
+ "jsdom": "^26.1.0"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "peerDependencies": {
+ "canvas": "^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
}
},
- "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==",
+ "node_modules/jest-environment-node": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.5.2.tgz",
+ "integrity": "sha512-Ciz4KgTGIbojxSKpuFImgWJj5EyqfE8xMq9NxWmOXnQywHHS03H9Mv+vaCB29J5pr3JBrY27WbRV18rBdjh8Dg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.3"
+ "@jest/environment": "30.5.2",
+ "@jest/fake-timers": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "jest-mock": "30.5.2",
+ "jest-util": "30.5.1",
+ "jest-validate": "30.5.1"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "node_modules/jest-haste-map": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz",
+ "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">=8"
+ "dependencies": {
+ "@jest/types": "30.5.1",
+ "@parcel/watcher": "^2.6.0",
+ "@types/node": "*",
+ "anymatch": "^3.1.3",
+ "fb-watchman": "^2.0.2",
+ "fdir": "^6.5.0",
+ "graceful-fs": "^4.2.11",
+ "jest-regex-util": "30.5.0",
+ "jest-util": "30.5.1",
+ "jest-worker": "30.5.1",
+ "picomatch": "^4.0.3"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/jest-leak-detector": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.5.1.tgz",
+ "integrity": "sha512-gt4GT2aWgEoCNTcBe4rqS74xTIUJxi+UD9SNSu9aOk5LmTEd6fS5KSTmAKAfitCCktQHNN+upUuL6EkBfFbMDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
+ "@jest/get-type": "30.5.0",
+ "pretty-format": "30.5.1"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/jest-matcher-utils": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.5.2.tgz",
+ "integrity": "sha512-lFkB365PTIHOhPzwrb9T6gvlDnPpOZ7/c3ewOKKB7bzztqjVrtlyRL2MkyfJXpyY2u2SKw001JKrTx14fBUFcQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.2",
- "has-symbols": "^1.1.0",
- "safe-regex-test": "^1.1.0"
+ "@jest/get-type": "30.5.0",
+ "chalk": "^4.1.2",
+ "jest-diff": "30.5.2",
+ "pretty-format": "30.5.1"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/jest-message-util": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz",
+ "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "which-typed-array": "^1.1.16"
+ "@babel/code-frame": "^7.27.1",
+ "@jest/types": "30.5.1",
+ "@types/stack-utils": "^2.0.3",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "jest-util": "30.5.1",
+ "picomatch": "^4.0.3",
+ "pretty-format": "30.5.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.6"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-mock": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz",
+ "integrity": "sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/expect-utils": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "jest-util": "30.5.1"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/jest-regex-util": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz",
+ "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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==",
+ "node_modules/jest-resolve": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.5.1.tgz",
+ "integrity": "sha512-wprhLejRtwN6h8ZgaqC0eYjGJ1uMdGPT/+b3eFncbG4NWuuP9QL+vWwRinu9waw7hkOLcpMJGVJAMgBwsPssMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.3"
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.5.1",
+ "jest-util": "30.5.1",
+ "jest-validate": "30.5.1",
+ "slash": "^3.0.0",
+ "unrs-resolver": "^1.12.1"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/is-weakset": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
- "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "node_modules/jest-resolve-dependencies": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.5.2.tgz",
+ "integrity": "sha512-GMI0DP5enX9Z2qW2zFy1bOkrCfWAOPRJQ7qHt0pdfrxBPsgWxglMPrRSK2TX/wRWYxcPRSLFg3Z88qPOzHx7FQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
+ "jest-regex-util": "30.5.0",
+ "jest-snapshot": "30.5.2"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "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",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "node_modules/jest-runner": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.5.2.tgz",
+ "integrity": "sha512-/B6px7hiiNhVSRwuv9AGn0nawYvwsHeQZ3ItTd5Gp2diFd0EOKaWVeWqcbw3L88vx1GfpCKjQkxWItZCTl11Rw==",
"dev": true,
- "license": "ISC"
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "30.5.2",
+ "@jest/environment": "30.5.2",
+ "@jest/source-map": "30.5.2",
+ "@jest/test-result": "30.5.2",
+ "@jest/transform": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "emittery": "^0.13.1",
+ "exit-x": "^0.2.2",
+ "graceful-fs": "^4.2.11",
+ "jest-docblock": "30.5.0",
+ "jest-environment-node": "30.5.2",
+ "jest-haste-map": "30.5.1",
+ "jest-leak-detector": "30.5.1",
+ "jest-message-util": "30.5.1",
+ "jest-resolve": "30.5.1",
+ "jest-runtime": "30.5.2",
+ "jest-util": "30.5.1",
+ "jest-watcher": "30.5.2",
+ "jest-worker": "30.5.1",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.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==",
+ "node_modules/jest-runtime": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.5.2.tgz",
+ "integrity": "sha512-0paUAHBlheai10A3XSy9Xh+YBG0IROy+/qzcDPzQ/nbbXrznQzeWy5qniICWK6d3W3scaRQCVAbXdcK0ibBq4w==",
"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"
+ "@jest/environment": "30.5.2",
+ "@jest/fake-timers": "30.5.2",
+ "@jest/globals": "30.5.2",
+ "@jest/source-map": "30.5.2",
+ "@jest/test-result": "30.5.2",
+ "@jest/transform": "30.5.2",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "cjs-module-lexer": "^2.2.0",
+ "collect-v8-coverage": "^1.0.2",
+ "es-module-lexer": "^2.1.0",
+ "glob": "^13.0.6",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.5.1",
+ "jest-message-util": "30.5.1",
+ "jest-mock": "30.5.2",
+ "jest-regex-util": "30.5.0",
+ "jest-resolve": "30.5.1",
+ "jest-snapshot": "30.5.2",
+ "jest-util": "30.5.1",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jackspeak": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
- "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
+ "node_modules/jest-runtime/node_modules/glob": {
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "@isaacs/cliui": "^8.0.2"
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
},
"engines": {
- "node": "20 || >=22"
+ "node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jake": {
- "version": "10.9.4",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
- "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
+ "node_modules/jest-runtime/node_modules/lru-cache": {
+ "version": "11.5.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz",
+ "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/jest-runtime/node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "async": "^3.2.6",
- "filelist": "^1.0.4",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "jake": "bin/cli.js"
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
},
"engines": {
- "node": ">=10"
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-diff": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz",
- "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==",
+ "node_modules/jest-snapshot": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.5.2.tgz",
+ "integrity": "sha512-jKIdes25AnAH73dOCi2qE6J6vHJ6L2vyBS11M89kT50DVJcLTf2AOjvcc+2vVaN8lUbY5v2R83aqXo3Ro9fqYA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/diff-sequences": "30.0.1",
- "@jest/get-type": "30.1.0",
+ "@babel/core": "^7.27.4",
+ "@babel/generator": "^7.27.5",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.27.1",
+ "@babel/types": "^7.27.3",
+ "@jest/expect-utils": "30.5.2",
+ "@jest/get-type": "30.5.0",
+ "@jest/snapshot-utils": "30.5.1",
+ "@jest/transform": "30.5.2",
+ "@jest/types": "30.5.1",
+ "babel-preset-current-node-syntax": "^1.2.0",
"chalk": "^4.1.2",
- "pretty-format": "30.2.0"
+ "expect": "30.5.2",
+ "graceful-fs": "^4.2.11",
+ "jest-diff": "30.5.2",
+ "jest-matcher-utils": "30.5.2",
+ "jest-message-util": "30.5.1",
+ "jest-util": "30.5.1",
+ "pretty-format": "30.5.1",
+ "semver": "^7.7.2",
+ "synckit": "^0.11.8"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-matcher-utils": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz",
- "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==",
+ "node_modules/jest-util": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz",
+ "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/get-type": "30.1.0",
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
"chalk": "^4.1.2",
- "jest-diff": "30.2.0",
- "pretty-format": "30.2.0"
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.3"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-message-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
- "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
+ "node_modules/jest-validate": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.5.1.tgz",
+ "integrity": "sha512-i/buJ56wTpxihE93hQYNMfdOThS87+HGvLZzZJmU4xggPcdTYQq051iwALLCHp3q+SkCGH+EFejQZz5EbBSkkg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.27.1",
- "@jest/types": "30.2.0",
- "@types/stack-utils": "^2.0.3",
+ "@jest/get-type": "30.5.0",
+ "@jest/types": "30.5.1",
+ "camelcase": "^6.3.0",
"chalk": "^4.1.2",
- "graceful-fs": "^4.2.11",
- "micromatch": "^4.0.8",
- "pretty-format": "30.2.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.6"
+ "leven": "^3.1.0",
+ "pretty-format": "30.5.1"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-mock": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
- "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-watcher": {
+ "version": "30.5.2",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.5.2.tgz",
+ "integrity": "sha512-rqRgg4R11GA9m1UsEZwQeixHsgZReCn6TOHAHtIH33yXrIvoX0OGPA20Yzzjkz7X40fZvcRSxEpQppYPcWzmcQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
+ "@jest/test-result": "30.5.2",
+ "@jest/types": "30.5.1",
"@types/node": "*",
- "jest-util": "30.2.0"
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
+ "emittery": "^0.13.1",
+ "jest-util": "30.5.1",
+ "string-length": "^4.0.2"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-regex-util": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
- "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==",
+ "node_modules/jest-worker": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.5.1.tgz",
+ "integrity": "sha512-Cbxh5v7AoLuFRmFJSM4/aHdQ68rjXvUWr716EE0Dh3I7T+T/3FgFKhOERGXHcU2Meftq9+9zxPM3TSNyI9D+HA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@ungap/structured-clone": "^1.3.0",
+ "jest-util": "30.5.1",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.1.1"
+ },
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
- "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "chalk": "^4.1.2",
- "ci-info": "^4.2.0",
- "graceful-fs": "^4.2.11",
- "picomatch": "^4.0.2"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/jiti": {
@@ -8514,10 +11286,20 @@
"license": "MIT"
},
"node_modules/js-yaml": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
- "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
+ "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -8526,6 +11308,83 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/jsdom": {
+ "version": "26.1.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssstyle": "^4.2.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.5.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.6",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.16",
+ "parse5": "^7.2.1",
+ "rrweb-cssom": "^0.8.0",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^5.1.1",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.1.1",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jsdom/node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/jsdom/node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/jsdom/node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -8546,6 +11405,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
@@ -8653,6 +11519,274 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lightningcss": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
+ "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.33.0",
+ "lightningcss-darwin-arm64": "1.33.0",
+ "lightningcss-darwin-x64": "1.33.0",
+ "lightningcss-freebsd-x64": "1.33.0",
+ "lightningcss-linux-arm-gnueabihf": "1.33.0",
+ "lightningcss-linux-arm64-gnu": "1.33.0",
+ "lightningcss-linux-arm64-musl": "1.33.0",
+ "lightningcss-linux-x64-gnu": "1.33.0",
+ "lightningcss-linux-x64-musl": "1.33.0",
+ "lightningcss-win32-arm64-msvc": "1.33.0",
+ "lightningcss-win32-x64-msvc": "1.33.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz",
+ "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz",
+ "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz",
+ "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz",
+ "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz",
+ "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz",
+ "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz",
+ "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz",
+ "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz",
+ "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz",
+ "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz",
+ "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -8670,9 +11804,10 @@
}
},
"node_modules/lodash": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
- "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
@@ -8681,6 +11816,13 @@
"dev": true,
"license": "MIT"
},
+ "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",
@@ -8727,16 +11869,45 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
+ "node_modules/m3u-parser-generator": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/m3u-parser-generator/-/m3u-parser-generator-5.0.2.tgz",
+ "integrity": "sha512-ifPLvWajdf475gO5oP+t3oGuXGlehOpL7H912bPUI+QpyAMUusV87l5azXTT7cPLXOWqeQkbo5C+OomCeTFX9A==",
+ "license": "MIT"
+ },
"node_modules/magic-string": {
- "version": "0.25.9",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
- "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "sourcemap-codec": "^1.4.8"
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -8748,14 +11919,25 @@
}
},
"node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-2.0.0.tgz",
+ "integrity": "sha512-kOy3OxT2HH39N70UnKgu4NWDZjLOz8W/mfyvniHjRH/DrL3f2pOfvWQ4p60offbbtDAnXWp0v9LfMIqMec269Q==",
"license": "MIT",
"engines": {
- "node": ">= 0.8"
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -8770,9 +11952,9 @@
}
},
"node_modules/micromatch/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -8790,6 +11972,16 @@
"wildcard": "^1.1.0"
}
},
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/minimatch": {
"version": "10.2.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
@@ -8817,24 +12009,34 @@
}
},
"node_modules/minimatch/node_modules/brace-expansion": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
- "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
- "node": "18 || 20 || >=22"
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
"dev": true,
- "license": "ISC",
+ "license": "BlueOak-1.0.0",
"engines": {
"node": ">=16 || 14 >=14.17"
}
@@ -8846,9 +12048,9 @@
"license": "MIT"
},
"node_modules/music-metadata": {
- "version": "11.12.3",
- "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-11.12.3.tgz",
- "integrity": "sha512-n6hSTZkuD59qWgHh6IP5dtDlDZQXoxk/bcA85Jywg8Z1iFrlNgl2+GTFgjZyn52W5UgQpV42V4XqrQZZAMbZTQ==",
+ "version": "11.16.0",
+ "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-11.16.0.tgz",
+ "integrity": "sha512-D5zZHjQUbfR+JhHjnwdbgeB4qj7zVJtisCB1I0GAI5sjSPGqPLoY14WMIzMeR8iA+4nSFswVLpO4crksZUybBg==",
"funding": [
{
"type": "github",
@@ -8863,11 +12065,11 @@
"dependencies": {
"@borewit/text-codec": "^0.2.2",
"@tokenizer/token": "^0.3.0",
- "content-type": "^1.0.5",
+ "content-type": "^2.1.0",
"debug": "^4.4.3",
- "file-type": "^21.3.1",
- "media-typer": "^1.1.0",
- "strtok3": "^10.3.4",
+ "file-type": "^21.3.4",
+ "media-typer": "^2.0.0",
+ "strtok3": "^10.3.5",
"token-types": "^6.1.2",
"uint8array-extras": "^1.5.0",
"win-guid": "^0.2.1"
@@ -8883,9 +12085,9 @@
"license": "MIT"
},
"node_modules/nanoid": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz",
- "integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==",
+ "version": "5.1.16",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.16.tgz",
+ "integrity": "sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==",
"funding": [
{
"type": "github",
@@ -8900,6 +12102,22 @@
"node": "^18 || >=20"
}
},
+ "node_modules/napi-postinstall": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz",
+ "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "napi-postinstall": "lib/cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/napi-postinstall"
+ }
+ },
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -8907,32 +12125,46 @@
"dev": true,
"license": "MIT"
},
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.55",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.55.tgz",
+ "integrity": "sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
"engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
+ "node": ">=18"
}
},
- "node_modules/node-releases": {
- "version": "2.0.27",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
- "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
"node_modules/npm-check-updates": {
"version": "19.6.3",
@@ -8949,6 +12181,26 @@
"npm": ">=8.12.1"
}
},
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.28",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.28.tgz",
+ "integrity": "sha512-IlVB7OS7qrOsVYlpnFIkETjMwT9jwvmocJmmM+GZU/PAB3uGi9Ezd7vcWhWBUnSc0ya4ppmQITOyP1ez9gg8cg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -9057,6 +12309,22 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -9126,33 +12394,60 @@
}
},
"node_modules/p-queue": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz",
- "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==",
+ "version": "9.3.3",
+ "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.3.3.tgz",
+ "integrity": "sha512-NXAOdnEe5FsZJfT4oK84lE1Y5cFFdWlRuOo5tww8DyNMxyRXwn39fIkUtNLKppcPC+UYU/bXujNCUGDv01y7CA==",
"license": "MIT",
"dependencies": {
- "eventemitter3": "^5.0.1",
- "p-timeout": "^6.1.2"
+ "eventemitter3": "^5.0.4",
+ "p-timeout": "^7.0.0"
},
"engines": {
- "node": ">=18"
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-retry": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz",
+ "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/retry": "0.12.2",
+ "is-network-error": "^1.0.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=16.17"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-timeout": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz",
- "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.2.tgz",
+ "integrity": "sha512-prbX4Z3YszrFNgH+MW5Zoeq3baXrMtP/MQnFeET90UB/GtGcGDQ5Usg9OCy6ETjTTntOw1SL2z9fMPUppN3Guw==",
"license": "MIT",
"engines": {
- "node": ">=14.16"
+ "node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
@@ -9173,6 +12468,38 @@
"node": ">=6"
}
},
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -9234,9 +12561,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -9245,6 +12572,85 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "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",
@@ -9256,9 +12662,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
- "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "version": "8.5.28",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
+ "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
"funding": [
{
"type": "opencollective",
@@ -9275,7 +12681,7 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.11",
+ "nanoid": "^3.3.18",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -9284,9 +12690,9 @@
}
},
"node_modules/postcss/node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "version": "3.3.19",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz",
+ "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==",
"funding": [
{
"type": "github",
@@ -9302,12 +12708,21 @@
}
},
"node_modules/preact": {
- "version": "10.28.2",
- "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.2.tgz",
- "integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==",
+ "version": "10.29.8",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.8.tgz",
+ "integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==",
+ "license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
+ },
+ "peerDependencies": {
+ "preact-render-to-string": ">=5"
+ },
+ "peerDependenciesMeta": {
+ "preact-render-to-string": {
+ "optional": true
+ }
}
},
"node_modules/prelude-ls": {
@@ -9321,9 +12736,9 @@
}
},
"node_modules/prettier": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz",
- "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
+ "version": "3.9.8",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.8.tgz",
+ "integrity": "sha512-WRFq3Wn3WId7LLROfMLdH7xaFr2jR62wU8nLO6rQUOLOxNZUviyJQs1M0iIhLexSFy+L+w0ch66wtoO2jRjG0A==",
"dev": true,
"license": "MIT",
"bin": {
@@ -9340,6 +12755,7 @@
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
"integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": "^14.13.1 || >=16.0.0"
@@ -9349,15 +12765,16 @@
}
},
"node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz",
+ "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
+ "@jest/react-is-18": "npm:react-is@^18.3.1",
+ "@jest/react-is-19": "npm:react-is@^19.2.5",
+ "@jest/schemas": "30.5.0",
+ "ansi-styles": "^5.2.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -9395,6 +12812,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/proxy-compare": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz",
+ "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==",
+ "license": "MIT"
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -9405,6 +12828,23 @@
"node": ">=6"
}
},
+ "node_modules/pure-rand": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz",
+ "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/quansync": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
@@ -9422,51 +12862,41 @@
],
"license": "MIT"
},
- "node_modules/randombytes": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "^5.1.0"
- }
- },
"node_modules/react": {
- "version": "19.2.4",
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
- "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
+ "version": "19.3.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz",
+ "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
- "version": "19.2.4",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
- "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
+ "version": "19.3.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz",
+ "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==",
"license": "MIT",
"dependencies": {
- "scheduler": "^0.27.0"
+ "scheduler": "^0.28.0"
},
"peerDependencies": {
- "react": "^19.2.4"
+ "react": "^19.3.0"
}
},
"node_modules/react-i18next": {
- "version": "16.5.8",
- "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.5.8.tgz",
- "integrity": "sha512-2ABeHHlakxVY+LSirD+OiERxFL6+zip0PaHo979bgwzeHg27Sqc82xxXWIrSFmfWX0ZkrvXMHwhsi/NGUf5VQg==",
+ "version": "17.0.15",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.15.tgz",
+ "integrity": "sha512-7uYpx/oBkesLto7cOzOmfITlUBaXHCAcFahmgETMfWr8nbbWRRnVGvz8wsH/xpbNcyoH+NpCcnOQEqWPMO6/hw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.28.4",
- "html-parse-stringify": "^3.0.1",
+ "@babel/runtime": "^7.29.7",
+ "html-parse-stringify": "^4.0.1",
"use-sync-external-store": "^1.6.0"
},
"peerDependencies": {
- "i18next": ">= 25.6.2",
+ "i18next": ">= 26.2.0",
"react": ">= 16.8.0",
- "typescript": "^5"
+ "typescript": "^5 || ^6 || ^7"
},
"peerDependenciesMeta": {
"react-dom": {
@@ -9481,35 +12911,18 @@
}
},
"node_modules/react-icons": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz",
- "integrity": "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==",
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.7.0.tgz",
+ "integrity": "sha512-LBLy340Rzqy6+/yVhZKT3B/QpP1BZaesGqasf09HPOBzRarcDIFH0WwXlXQfE7q7ipxK4MSiC5DIBWURCny6fw==",
"license": "MIT",
"peerDependencies": {
"react": "*"
}
},
- "node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/react-refresh": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
- "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/react-remove-scroll": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
- "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
+ "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",
"license": "MIT",
"dependencies": {
"react-remove-scroll-bar": "^2.3.7",
@@ -9677,6 +13090,16 @@
"regjsparser": "bin/parser"
}
},
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -9710,6 +13133,29 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-cwd/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -9717,13 +13163,56 @@
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=4"
+ "node": ">=4"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/rolldown": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.9.tgz",
+ "integrity": "sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==",
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.150.0",
+ "@rolldown/pluginutils": "^1.0.0"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm-eabi": "1.2.9",
+ "@rolldown/binding-android-arm64": "1.2.9",
+ "@rolldown/binding-darwin-arm64": "1.2.9",
+ "@rolldown/binding-darwin-x64": "1.2.9",
+ "@rolldown/binding-freebsd-x64": "1.2.9",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.2.9",
+ "@rolldown/binding-linux-arm64-gnu": "1.2.9",
+ "@rolldown/binding-linux-arm64-musl": "1.2.9",
+ "@rolldown/binding-linux-ppc64-gnu": "1.2.9",
+ "@rolldown/binding-linux-s390x-gnu": "1.2.9",
+ "@rolldown/binding-linux-x64-gnu": "1.2.9",
+ "@rolldown/binding-linux-x64-musl": "1.2.9",
+ "@rolldown/binding-openharmony-arm64": "1.2.9",
+ "@rolldown/binding-win32-arm64-msvc": "1.2.9",
+ "@rolldown/binding-win32-x64-msvc": "1.2.9"
}
},
"node_modules/rollup": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
@@ -9764,6 +13253,13 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/safe-array-concat": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
@@ -9784,27 +13280,6 @@
"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",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "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",
@@ -9840,16 +13315,36 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
"node_modules/scheduler": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz",
+ "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==",
"license": "MIT"
},
"node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -9860,13 +13355,13 @@
}
},
"node_modules/serialize-javascript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
- "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.1.tgz",
+ "integrity": "sha512-k3CMsaIvvdSwm8oLB4MXSl0wH2/cwlH7xGcnRd2DaeRmBkbzYmyT8j0tsX60DwD1eRwHTpNpH8ljKu9oUT1MeQ==",
"dev": true,
"license": "BSD-3-Clause",
- "dependencies": {
- "randombytes": "^2.1.0"
+ "engines": {
+ "node": ">=20.0.0"
}
},
"node_modules/set-function-length": {
@@ -9925,43 +13420,53 @@
"license": "MIT"
},
"node_modules/sharp": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
- "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
+ "version": "0.35.4",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz",
+ "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==",
"dev": true,
- "hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
- "color": "^4.2.3",
- "detect-libc": "^2.0.3",
- "semver": "^7.6.3"
+ "@img/colour": "^1.1.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.8.5"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.33.5",
- "@img/sharp-darwin-x64": "0.33.5",
- "@img/sharp-libvips-darwin-arm64": "1.0.4",
- "@img/sharp-libvips-darwin-x64": "1.0.4",
- "@img/sharp-libvips-linux-arm": "1.0.5",
- "@img/sharp-libvips-linux-arm64": "1.0.4",
- "@img/sharp-libvips-linux-s390x": "1.0.4",
- "@img/sharp-libvips-linux-x64": "1.0.4",
- "@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
- "@img/sharp-libvips-linuxmusl-x64": "1.0.4",
- "@img/sharp-linux-arm": "0.33.5",
- "@img/sharp-linux-arm64": "0.33.5",
- "@img/sharp-linux-s390x": "0.33.5",
- "@img/sharp-linux-x64": "0.33.5",
- "@img/sharp-linuxmusl-arm64": "0.33.5",
- "@img/sharp-linuxmusl-x64": "0.33.5",
- "@img/sharp-wasm32": "0.33.5",
- "@img/sharp-win32-ia32": "0.33.5",
- "@img/sharp-win32-x64": "0.33.5"
+ "@img/sharp-darwin-arm64": "0.35.4",
+ "@img/sharp-darwin-x64": "0.35.4",
+ "@img/sharp-freebsd-wasm32": "0.35.4",
+ "@img/sharp-libvips-darwin-arm64": "1.3.3",
+ "@img/sharp-libvips-darwin-x64": "1.3.3",
+ "@img/sharp-libvips-linux-arm": "1.3.3",
+ "@img/sharp-libvips-linux-arm64": "1.3.3",
+ "@img/sharp-libvips-linux-ppc64": "1.3.3",
+ "@img/sharp-libvips-linux-riscv64": "1.3.3",
+ "@img/sharp-libvips-linux-s390x": "1.3.3",
+ "@img/sharp-libvips-linux-x64": "1.3.3",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.3",
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.3",
+ "@img/sharp-linux-arm": "0.35.4",
+ "@img/sharp-linux-arm64": "0.35.4",
+ "@img/sharp-linux-ppc64": "0.35.4",
+ "@img/sharp-linux-riscv64": "0.35.4",
+ "@img/sharp-linux-s390x": "0.35.4",
+ "@img/sharp-linux-x64": "0.35.4",
+ "@img/sharp-linuxmusl-arm64": "0.35.4",
+ "@img/sharp-linuxmusl-x64": "0.35.4",
+ "@img/sharp-webcontainers-wasm32": "0.35.4",
+ "@img/sharp-win32-arm64": "0.35.4",
+ "@img/sharp-win32-ia32": "0.35.4",
+ "@img/sharp-win32-x64": "0.35.4"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
}
},
"node_modules/sharp-ico": {
@@ -10088,16 +13593,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/simple-swizzle": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
- "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-arrayish": "^0.3.1"
- }
- },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -10109,20 +13604,29 @@
}
},
"node_modules/smob": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
- "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz",
+ "integrity": "sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.0.0"
+ }
},
"node_modules/sonner": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz",
- "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.8.tgz",
+ "integrity": "sha512-UM/ByIoFra8yzV75n1o0Puu0bw5U/9UNnDacrJNspekBewIfsQ3D6ez1nvlWpt7aTsO6rujQtifBpycwIivqlg==",
"license": "MIT",
"peerDependencies": {
+ "@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc",
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
}
},
"node_modules/source-map": {
@@ -10198,13 +13702,12 @@
"webidl-conversions": "^4.0.2"
}
},
- "node_modules/sourcemap-codec": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
- "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
- "deprecated": "Please use @jridgewell/sourcemap-codec instead",
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true,
- "license": "MIT"
+ "license": "BSD-3-Clause"
},
"node_modules/stack-utils": {
"version": "2.0.6",
@@ -10229,6 +13732,17 @@
"node": ">=8"
}
},
+ "node_modules/standardized-audio-context": {
+ "version": "25.3.77",
+ "resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.77.tgz",
+ "integrity": "sha512-Ki9zNz6pKcC5Pi+QPjPyVsD9GwJIJWgryji0XL9cAJXMGyn+dPOf6Qik1AHei0+UNVcc4BOCa0hWLBzlwqsW/A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.25.6",
+ "automation-events": "^7.0.9",
+ "tslib": "^2.7.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",
@@ -10243,6 +13757,43 @@
"node": ">= 0.4"
}
},
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-length/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-length/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -10460,6 +14011,16 @@
"node": ">=8"
}
},
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/strip-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
@@ -10470,6 +14031,16 @@
"node": ">=10"
}
},
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -10484,9 +14055,9 @@
}
},
"node_modules/strtok3": {
- "version": "10.3.4",
- "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz",
- "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz",
+ "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==",
"license": "MIT",
"dependencies": {
"@tokenizer/token": "^0.3.0"
@@ -10525,6 +14096,29 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/synckit": {
+ "version": "0.11.13",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz",
+ "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.3.6"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
"node_modules/temp-dir": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
@@ -10573,14 +14167,117 @@
"node": ">=10"
}
},
+ "node_modules/test-exclude": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz",
+ "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^10.2.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/test-exclude/node_modules/brace-expansion": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz",
+ "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/test-exclude/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/test-exclude/node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
- "picomatch": "^4.0.3"
+ "picomatch": "^4.0.4"
},
"engines": {
"node": ">=12.0.0"
@@ -10589,6 +14286,26 @@
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/to-data-view": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz",
@@ -10626,23 +14343,106 @@
"url": "https://github.com/sponsors/Borewit"
}
},
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
- "node_modules/ts-api-utils": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
- "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
+ "node_modules/tone": {
+ "version": "15.1.22",
+ "resolved": "https://registry.npmjs.org/tone/-/tone-15.1.22.tgz",
+ "integrity": "sha512-TCScAGD4sLsama5DjvTUXlLDXSqPealhL64nsdV1hhr6frPWve0DeSo63AKnSJwgfg55fhvxj0iPPRwPN5o0ag==",
+ "license": "MIT",
+ "dependencies": {
+ "standardized-audio-context": "^25.3.70",
+ "tslib": "^2.3.1"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
+ "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/ts-jest": {
+ "version": "29.4.12",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz",
+ "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bs-logger": "^0.2.6",
+ "fast-json-stable-stringify": "^2.1.0",
+ "handlebars": "^4.7.9",
+ "json5": "^2.2.3",
+ "lodash.memoize": "^4.1.2",
+ "make-error": "^1.3.6",
+ "semver": "^7.8.5",
+ "type-fest": "^4.41.0",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "ts-jest": "cli.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7.0.0-beta.0 <8",
+ "@jest/transform": "^29.0.0 || ^30.0.0",
+ "@jest/types": "^29.0.0 || ^30.0.0",
+ "babel-jest": "^29.0.0 || ^30.0.0",
+ "jest": "^29.0.0 || ^30.0.0",
+ "jest-util": "^29.0.0 || ^30.0.0",
+ "typescript": ">=4.3 <7"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@jest/transform": {
+ "optional": true
+ },
+ "@jest/types": {
+ "optional": true
+ },
+ "babel-jest": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jest-util": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-jest/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
"dev": true,
- "license": "MIT",
+ "license": "(MIT OR CC0-1.0)",
"engines": {
- "node": ">=18.12"
+ "node": ">=16"
},
- "peerDependencies": {
- "typescript": ">=4.8.4"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/tslib": {
@@ -10664,6 +14464,16 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/type-fest": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
@@ -10770,6 +14580,20 @@
"node": ">=14.17"
}
},
+ "node_modules/uglify-js": {
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
+ "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/uint8array-extras": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
@@ -10818,9 +14642,9 @@
}
},
"node_modules/undici-types": {
- "version": "7.18.2",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
- "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
+ "version": "8.9.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz",
+ "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
"devOptional": true,
"license": "MIT"
},
@@ -10891,6 +14715,44 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/unrs-resolver": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz",
+ "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "napi-postinstall": "^0.3.4"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unrs-resolver"
+ },
+ "optionalDependencies": {
+ "@unrs/resolver-binding-android-arm-eabi": "1.12.2",
+ "@unrs/resolver-binding-android-arm64": "1.12.2",
+ "@unrs/resolver-binding-darwin-arm64": "1.12.2",
+ "@unrs/resolver-binding-darwin-x64": "1.12.2",
+ "@unrs/resolver-binding-freebsd-x64": "1.12.2",
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2",
+ "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2",
+ "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-arm64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-loong64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-x64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-x64-musl": "1.12.2",
+ "@unrs/resolver-binding-openharmony-arm64": "1.12.2",
+ "@unrs/resolver-binding-wasm32-wasi": "1.12.2",
+ "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2",
+ "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2",
+ "@unrs/resolver-binding-win32-x64-msvc": "1.12.2"
+ }
+ },
"node_modules/upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
@@ -10903,9 +14765,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz",
+ "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==",
"dev": true,
"funding": [
{
@@ -10995,31 +14857,32 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
- "node_modules/uuid": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
- "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
"dev": true,
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "bin": {
- "uuid": "dist/bin/uuid"
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
}
},
"node_modules/vite": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
- "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.0.tgz",
+ "integrity": "sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==",
"license": "MIT",
"dependencies": {
- "esbuild": "^0.27.0",
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3",
- "postcss": "^8.5.6",
- "rollup": "^4.43.0",
- "tinyglobby": "^0.2.15"
+ "lightningcss": "^1.33.0",
+ "picomatch": "^4.0.7",
+ "postcss": "^8.5.28",
+ "rolldown": "~1.2.6",
+ "tinyglobby": "^0.2.17"
},
"bin": {
"vite": "bin/vite.js"
@@ -11035,9 +14898,10 @@
},
"peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0",
+ "@vitejs/devtools": "^0.7.1",
+ "esbuild": "^0.27.0 || ^0.28.0",
"jiti": ">=1.21.0",
"less": "^4.0.0",
- "lightningcss": "^1.21.0",
"sass": "^1.70.0",
"sass-embedded": "^1.70.0",
"stylus": ">=0.54.8",
@@ -11050,13 +14914,16 @@
"@types/node": {
"optional": true
},
- "jiti": {
+ "@vitejs/devtools": {
"optional": true
},
- "less": {
+ "esbuild": {
+ "optional": true
+ },
+ "jiti": {
"optional": true
},
- "lightningcss": {
+ "less": {
"optional": true
},
"sass": {
@@ -11083,17 +14950,17 @@
}
},
"node_modules/vite-plugin-pwa": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz",
- "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.3.0.tgz",
+ "integrity": "sha512-c5kMgN+ITrOtHXp8PAtk2uOIEea6XjP/unCGxOWWBzQ6qa65qj/awHg0wf+QF9E/2u9vh86LqxPwzEPNbM2r5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.6",
"pretty-bytes": "^6.1.1",
"tinyglobby": "^0.2.10",
- "workbox-build": "^7.4.0",
- "workbox-window": "^7.4.0"
+ "workbox-build": "^7.4.1",
+ "workbox-window": "^7.4.1"
},
"engines": {
"node": ">=16.0.0"
@@ -11103,9 +14970,9 @@
},
"peerDependencies": {
"@vite-pwa/assets-generator": "^1.0.0",
- "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
- "workbox-build": "^7.4.0",
- "workbox-window": "^7.4.0"
+ "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+ "workbox-build": "^7.4.1",
+ "workbox-window": "^7.4.1"
},
"peerDependenciesMeta": {
"@vite-pwa/assets-generator": {
@@ -11114,9 +14981,9 @@
}
},
"node_modules/vite-plugin-singlefile": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/vite-plugin-singlefile/-/vite-plugin-singlefile-2.3.2.tgz",
- "integrity": "sha512-b8SxCi/gG7K298oJDcKOuZeU6gf6wIcCJAaEqUmmZXdjfuONlkyNyWZC3tEbN6QockRCNUd3it9eGTtpHGoYmg==",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/vite-plugin-singlefile/-/vite-plugin-singlefile-2.3.3.tgz",
+ "integrity": "sha512-XVnGH0QzbOa8fxRSsHdCarVN1BSBXNi7uLMQYlrGRN5apdHkk62XQWRJhVever0lnfuyBkwn+kvVChdm/OoOUg==",
"license": "MIT",
"dependencies": {
"micromatch": "^4.0.8"
@@ -11126,22 +14993,12 @@
},
"peerDependencies": {
"rollup": "^4.59.0",
- "vite": "^5.4.11 || ^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/vite-plugin-top-level-await": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.6.0.tgz",
- "integrity": "sha512-bNhUreLamTIkoulCR9aDXbTbhLk6n1YE8NJUTTxl5RYskNRtzOR0ASzSjBVRtNdjIfngDXo11qOsybGLNsrdww==",
- "dev": true,
- "dependencies": {
- "@rollup/plugin-virtual": "^3.0.2",
- "@swc/core": "^1.12.14",
- "@swc/wasm": "^1.12.14",
- "uuid": "10.0.0"
+ "vite": "^5.4.21 || ^6.0.0 || ^7.0.0 || ^8.0.0"
},
- "peerDependencies": {
- "vite": ">=2.8"
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
}
},
"node_modules/vite-plugin-wasm": {
@@ -11154,29 +15011,41 @@
"vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7 || ^8"
}
},
- "node_modules/void-elements": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
- "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=18"
}
},
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/which": {
@@ -11306,31 +15175,38 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/workbox-background-sync": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz",
- "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.1.tgz",
+ "integrity": "sha512-HhT7KE8tOWDm02wRNshXUnUPofMlhenF2DBdUnDPOubhizzPeItkYTmAB6td1Z2cjYPa98vzEiPLEuzn5hN66g==",
"dev": true,
"license": "MIT",
"dependencies": {
"idb": "^7.0.1",
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-broadcast-update": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz",
- "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.1.tgz",
+ "integrity": "sha512-uAlgslKLvbQY+suirIdnBCSYrcgBhjp81Nj4l1lj/Jmj0MJO2CJERnCJjT0GFVwmReV0N+zs78K6gqd5gr9/+A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-build": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.0.tgz",
- "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.1.tgz",
+ "integrity": "sha512-SDhxIvEAde9Gy/5w4Yo1Jh/M49Z0qE3q0oteyE8zGq0DScxFqVBcCtIXFuLtmtxRQZCMbf0prco4VyEu3KBQuw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11338,39 +15214,39 @@
"@babel/core": "^7.24.4",
"@babel/preset-env": "^7.11.0",
"@babel/runtime": "^7.11.2",
- "@rollup/plugin-babel": "^5.2.0",
- "@rollup/plugin-node-resolve": "^15.2.3",
- "@rollup/plugin-replace": "^2.4.1",
- "@rollup/plugin-terser": "^0.4.3",
- "@surma/rollup-plugin-off-main-thread": "^2.2.3",
+ "@rollup/plugin-babel": "^6.1.0",
+ "@rollup/plugin-node-resolve": "^16.0.3",
+ "@rollup/plugin-replace": "^6.0.3",
+ "@rollup/plugin-terser": "^1.0.0",
+ "@trickfilm400/rollup-plugin-off-main-thread": "^3.0.0-pre1",
"ajv": "^8.6.0",
"common-tags": "^1.8.0",
+ "eta": "^4.5.1",
"fast-json-stable-stringify": "^2.1.0",
"fs-extra": "^9.0.1",
"glob": "^11.0.1",
- "lodash": "^4.17.20",
"pretty-bytes": "^5.3.0",
- "rollup": "^2.79.2",
+ "rollup": "^4.53.3",
"source-map": "^0.8.0-beta.0",
"stringify-object": "^3.3.0",
"strip-comments": "^2.0.1",
"tempy": "^0.6.0",
"upath": "^1.2.0",
- "workbox-background-sync": "7.4.0",
- "workbox-broadcast-update": "7.4.0",
- "workbox-cacheable-response": "7.4.0",
- "workbox-core": "7.4.0",
- "workbox-expiration": "7.4.0",
- "workbox-google-analytics": "7.4.0",
- "workbox-navigation-preload": "7.4.0",
- "workbox-precaching": "7.4.0",
- "workbox-range-requests": "7.4.0",
- "workbox-recipes": "7.4.0",
- "workbox-routing": "7.4.0",
- "workbox-strategies": "7.4.0",
- "workbox-streams": "7.4.0",
- "workbox-sw": "7.4.0",
- "workbox-window": "7.4.0"
+ "workbox-background-sync": "7.4.1",
+ "workbox-broadcast-update": "7.4.1",
+ "workbox-cacheable-response": "7.4.1",
+ "workbox-core": "7.4.1",
+ "workbox-expiration": "7.4.1",
+ "workbox-google-analytics": "7.4.1",
+ "workbox-navigation-preload": "7.4.1",
+ "workbox-precaching": "7.4.1",
+ "workbox-range-requests": "7.4.1",
+ "workbox-recipes": "7.4.1",
+ "workbox-routing": "7.4.1",
+ "workbox-strategies": "7.4.1",
+ "workbox-streams": "7.4.1",
+ "workbox-sw": "7.4.1",
+ "workbox-window": "7.4.1"
},
"engines": {
"node": ">=20.0.0"
@@ -11394,73 +15270,10 @@
"ajv": ">=8"
}
},
- "node_modules/workbox-build/node_modules/@rollup/plugin-babel": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
- "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.10.4",
- "@rollup/pluginutils": "^3.1.0"
- },
- "engines": {
- "node": ">= 10.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0",
- "@types/babel__core": "^7.1.9",
- "rollup": "^1.20.0||^2.0.0"
- },
- "peerDependenciesMeta": {
- "@types/babel__core": {
- "optional": true
- }
- }
- },
- "node_modules/workbox-build/node_modules/@rollup/plugin-replace": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
- "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@rollup/pluginutils": "^3.1.0",
- "magic-string": "^0.25.7"
- },
- "peerDependencies": {
- "rollup": "^1.20.0 || ^2.0.0"
- }
- },
- "node_modules/workbox-build/node_modules/@rollup/pluginutils": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
- "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "0.0.39",
- "estree-walker": "^1.0.1",
- "picomatch": "^2.2.2"
- },
- "engines": {
- "node": ">= 8.0.0"
- },
- "peerDependencies": {
- "rollup": "^1.20.0||^2.0.0"
- }
- },
- "node_modules/workbox-build/node_modules/@types/estree": {
- "version": "0.0.39",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
- "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/workbox-build/node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11474,13 +15287,6 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/workbox-build/node_modules/estree-walker": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
- "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/workbox-build/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
@@ -11488,19 +15294,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/workbox-build/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"node_modules/workbox-build/node_modules/pretty-bytes": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
@@ -11514,157 +15307,141 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/workbox-build/node_modules/rollup": {
- "version": "2.79.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
- "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=10.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
"node_modules/workbox-cacheable-response": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz",
- "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.1.tgz",
+ "integrity": "sha512-8xaFoJdDc2OjrlbbL3gEeBO1WKcMwRqwLRupgqahYXu75yXajPLuwrbXMrIGZuWYXrQwk0xDjOxZ/ujCy/oJYw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-core": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.0.tgz",
- "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.1.tgz",
+ "integrity": "sha512-DT+vu46eh/2vRsSHTY4Xmc32Z1rr9PRlQUXr1Dx30ZuXRWwOsvZgGgcwxcasubQLQmbTNYZjv44LkBAQ4tT5tQ==",
"dev": true,
"license": "MIT"
},
"node_modules/workbox-expiration": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.0.tgz",
- "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.1.tgz",
+ "integrity": "sha512-lRKUF7b+OGbeXkQk1s6MHXOa3d7Xxf7Of31W6c6hCfipfIyrtdWZ89stq21AHZMaoG7VNFoHply4Ox+rU31TWg==",
"dev": true,
"license": "MIT",
"dependencies": {
"idb": "^7.0.1",
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-google-analytics": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz",
- "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.1.tgz",
+ "integrity": "sha512-Mks1JwLEt++ZAkF6sS1OpSh9RtAMIsiDgRpK+codiHGIPXeaUOgi4cPc3GFadUl8V5QPeypEk8Oxgl3HlwVzHw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-background-sync": "7.4.0",
- "workbox-core": "7.4.0",
- "workbox-routing": "7.4.0",
- "workbox-strategies": "7.4.0"
+ "workbox-background-sync": "7.4.1",
+ "workbox-core": "7.4.1",
+ "workbox-routing": "7.4.1",
+ "workbox-strategies": "7.4.1"
}
},
"node_modules/workbox-navigation-preload": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz",
- "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.1.tgz",
+ "integrity": "sha512-C4KVsjPcYKJOhr631AxR9XoG2rLF3QiTk5aMv36MXOjtWvm8axwNFAtKUPGsWUwLXXAMgYM1En7fsvndaXeXRQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-precaching": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.0.tgz",
- "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.1.tgz",
+ "integrity": "sha512-cdr/9qByww7yzEp7zg/qI4ukUrrNjQLgN+ONQRpjy/VqGQXwkgHwr00KksGJK8v0VifwDXBb8a4cWNZH71jn3Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0",
- "workbox-routing": "7.4.0",
- "workbox-strategies": "7.4.0"
+ "workbox-core": "7.4.1",
+ "workbox-routing": "7.4.1",
+ "workbox-strategies": "7.4.1"
}
},
"node_modules/workbox-range-requests": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz",
- "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.1.tgz",
+ "integrity": "sha512-7i2oxAUE82gHdAJBCAQ04JzNOdRPqzuOzGfoUyJpFSmeqBNYGPrAH8GPoPjUQTfp+NycwrD2H68VtuF8qxv0vQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-recipes": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.0.tgz",
- "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.1.tgz",
+ "integrity": "sha512-gnbVfmV4/TtmQaM4x9AtuXhcdstJsep3XMVeztOrQVPT+R6+6DeBjGTCQ7fFCXm+4GEHUA5VEBTyi5+4gWGeog==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-cacheable-response": "7.4.0",
- "workbox-core": "7.4.0",
- "workbox-expiration": "7.4.0",
- "workbox-precaching": "7.4.0",
- "workbox-routing": "7.4.0",
- "workbox-strategies": "7.4.0"
+ "workbox-cacheable-response": "7.4.1",
+ "workbox-core": "7.4.1",
+ "workbox-expiration": "7.4.1",
+ "workbox-precaching": "7.4.1",
+ "workbox-routing": "7.4.1",
+ "workbox-strategies": "7.4.1"
}
},
"node_modules/workbox-routing": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.0.tgz",
- "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.1.tgz",
+ "integrity": "sha512-yubJGErZOusuidAenaL5ypfhQOa7urxP/f8E0ws7FPb4039RiWXUWBAyUkmUoOL/BcQGen3h0J8872d51IYxtA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-strategies": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.0.tgz",
- "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.1.tgz",
+ "integrity": "sha512-GZxpaw9NbmOelj7667uZ2kpk5BFpOGbO4X0qjwh5ls8XQ8C+Lha5LQchTiUzsTFSS+NlUpftYAyOVXvQUrcqOQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/workbox-streams": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.0.tgz",
- "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.1.tgz",
+ "integrity": "sha512-HWWtraKUbJknd9kgqGcpQ3G114HOPYvqs8HaJMDs2ebLNAimDkVDaWfAXE6Ybl+m8U6KsCE6pWyLYuigWmnAXw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "workbox-core": "7.4.0",
- "workbox-routing": "7.4.0"
+ "workbox-core": "7.4.1",
+ "workbox-routing": "7.4.1"
}
},
"node_modules/workbox-sw": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.0.tgz",
- "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.1.tgz",
+ "integrity": "sha512-fez5f2DUlDJWTFYkCWQpY10N8gtztd849NswCbVFk0QlcSM4HT5A8x4g4ii650yem4I8tHY0R7JZahwp3ltIPw==",
"dev": true,
"license": "MIT"
},
"node_modules/workbox-window": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.0.tgz",
- "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.1.tgz",
+ "integrity": "sha512-notZDH2u8VXaqyuD7xaqIfEFi6SRM4SUSd7ewe9PDsVqADuepxX2ZMY3uvuZGxzY5ZOsGC/vD3A/3smFtJt4/A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/trusted-types": "^2.0.2",
- "workbox-core": "7.4.0"
+ "workbox-core": "7.4.1"
}
},
"node_modules/wrap-ansi": {
@@ -11762,6 +15539,69 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/write-file-atomic": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
+ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.21.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
+ "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -11769,6 +15609,80 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/yargs": {
+ "version": "17.7.3",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",
+ "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@@ -11783,9 +15697,9 @@
}
},
"node_modules/zustand": {
- "version": "5.0.12",
- "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz",
- "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==",
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.15.tgz",
+ "integrity": "sha512-MpSEjRiBkA9crSYeOUH32rJC7SVqAbm0Fqcqge/bUi2PPoLcBWKOsG+C8mevmpr8TwXHBVkChbbJiyvkE+i/3A==",
"license": "MIT",
"engines": {
"node": ">=12.20.0"
diff --git a/Build/package.json b/Build/package.json
index 25b3bf4..4575d52 100644
--- a/Build/package.json
+++ b/Build/package.json
@@ -14,82 +14,92 @@
"tauri": "tauri",
"start": "cd dist && python3 -m http.server 8000",
"preview": "vite preview",
- "test": "react-scripts test",
+ "test": "jest",
+ "test:run": "jest --passWithNoTests",
+ "test:e2e": "node tests/e2e/flo/flo_wasm_e2e.ts && node tests/e2e/symphonia/symphonia_e2e.ts",
+ "build:wasm": "wasm-pack build ../crates/symphonia-wasm --target web --out-dir ../../Build/src/platform/audio/wasm/symphonia --out-name symphonia --release",
+ "test:watch": "jest --watch",
"lint": "eslint 'src/**/*.ts' 'src/**/*.tsx'",
- "eject": "react-scripts eject",
"make-pretty": "prettier --write 'src/**/*.{ts,tsx,js,jsx,json,css,scss,md,html,cjs}'",
"count-lines": "cloc . --exclude-dir=node_modules,build,dist --exclude-ext=lock,json",
"i18n-check": "node i18n-izer.cjs --ignore-console",
+ "generate:visualizers": "node scripts/gen-visualizer-registry.cjs",
"update": "npm-check-updates -i"
},
"dependencies": {
+ "@audiflo/libflo": "^0.1.3",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
- "@dnd-kit/utilities": "^3.2.2",
- "@flo-audio/libflo-audio": "^0.1.2",
- "@flo-audio/reflo": "^0.1.2",
- "@fontsource/caveat": "^5.2.8",
- "@fontsource/inter": "^5.2.8",
- "@fontsource/jetbrains-mono": "^5.2.8",
- "@fontsource/poppins": "^5.2.7",
- "@nisoku/satori-log": "^0.1.2",
- "@radix-ui/react-collapsible": "^1.1.12",
- "@radix-ui/react-dialog": "^1.1.15",
- "@radix-ui/react-dropdown-menu": "^2.1.16",
- "@radix-ui/react-select": "^2.2.6",
- "@radix-ui/react-separator": "^1.1.8",
- "@radix-ui/react-slider": "^1.3.6",
- "@radix-ui/react-slot": "^1.2.4",
- "@radix-ui/react-switch": "^1.2.6",
- "@radix-ui/react-tooltip": "^1.2.8",
+ "@fontsource/caveat": "^5.3.0",
+ "@fontsource/inter": "^5.3.0",
+ "@fontsource/jetbrains-mono": "^5.3.0",
+ "@fontsource/poppins": "^5.3.0",
+ "@gsap/react": "^2.1.2",
+ "@nisoku/satori": "^0.1.3",
+ "@radix-ui/react-collapsible": "^1.1.20",
+ "@radix-ui/react-dialog": "^1.1.23",
+ "@radix-ui/react-dropdown-menu": "^2.1.24",
+ "@radix-ui/react-select": "^2.3.7",
+ "@radix-ui/react-separator": "^1.1.15",
+ "@radix-ui/react-slider": "^1.4.7",
+ "@radix-ui/react-slot": "^1.3.3",
+ "@radix-ui/react-switch": "^1.3.7",
+ "@radix-ui/react-tooltip": "^1.2.16",
"@reactour/tour": "^3.8.0",
- "@tauri-apps/api": "^2.10.1",
- "@tauri-apps/plugin-dialog": "^2.6.0",
- "@tauri-apps/plugin-fs": "^2.4.5",
- "@tauri-apps/plugin-notification": "^2.3.3",
- "@tauri-apps/plugin-opener": "^2.5.3",
- "@uppy/core": "^5.2.0",
- "@uppy/dashboard": "^5.1.1",
- "@uppy/react": "^5.2.0",
+ "@tauri-apps/api": "^2.11.1",
+ "@tauri-apps/plugin-dialog": "^2.7.3",
+ "@tauri-apps/plugin-fs": "^2.5.2",
+ "@tauri-apps/plugin-notification": "^2.4.0",
+ "@tauri-apps/plugin-opener": "^2.5.5",
+ "@uppy/core": "^6.0.1",
+ "@uppy/dashboard": "^6.0.0",
+ "@uppy/react": "^6.0.0",
"@web-scrobbler/metadata-filter": "^3.2.0",
- "dompurify": "^3.3.3",
- "i18next": "^25.8.18",
+ "@zag-js/marquee": "^1.44.0",
+ "@zag-js/react": "^1.44.0",
+ "dompurify": "^3.4.15",
+ "dsssp": "^0.8.0",
+ "gsap": "^3.15.0",
+ "i18next": "^26.4.2",
"i18next-browser-languagedetector": "^8.2.1",
- "i18next-http-backend": "^3.0.2",
- "lodash": "^4.17.23",
+ "i18next-http-backend": "^4.0.2",
"lucide-react": "^0.577.0",
- "music-metadata": "^11.12.3",
- "react": "^19.2.4",
- "react-dom": "^19.2.4",
- "react-i18next": "^16.5.8",
- "react-icons": "^5.6.0",
- "sonner": "^2.0.7",
- "vite-plugin-singlefile": "^2.3.2",
- "zustand": "^5.0.12"
+ "m3u-parser-generator": "^5.0.2",
+ "music-metadata": "^11.16.0",
+ "react": "^19.3.0",
+ "react-dom": "^19.3.0",
+ "react-i18next": "^17.0.15",
+ "react-icons": "^5.7.0",
+ "sonner": "^2.0.8",
+ "tone": "^15.1.22",
+ "vite-plugin-singlefile": "^2.3.3",
+ "zustand": "^5.0.15"
},
"devDependencies": {
- "@tauri-apps/cli": "^2.10.1",
- "@types/jasmine": "^6.0.0",
+ "@babel/plugin-transform-runtime": "^7.29.0",
+ "@tauri-apps/cli": "^2.11.5",
"@types/jest": "^30.0.0",
- "@types/lodash": "^4.17.24",
- "@types/node": "^25.5.0",
- "@types/react": "^19.2.14",
- "@types/react-dom": "^19.2.3",
- "@typescript-eslint/eslint-plugin": "^8.57.0",
- "@typescript-eslint/parser": "^8.57.0",
- "@vite-pwa/assets-generator": "^1.0.2",
- "@vitejs/plugin-react": "^5.2.0",
+ "@types/node": "^26.6.2",
+ "@types/react": "^19.3.0",
+ "@types/react-dom": "^19.3.0",
+ "@typescript-eslint/eslint-plugin": "^8.70.1",
+ "@typescript-eslint/parser": "^8.70.1",
+ "@vite-pwa/assets-generator": "^1.0.4",
+ "@vitejs/plugin-react": "^6.1.1",
"cloc": "^2.11.0",
"cross-env": "^10.1.0",
- "eslint": "^9.39.4",
+ "eslint": "^9.39.5",
"eslint-plugin-react": "^7.37.5",
+ "jest": "^30.5.2",
+ "jest-environment-jsdom": "^30.5.2",
"npm-check-updates": "^19.6.3",
- "prettier": "^3.8.1",
- "vite": "^7.3.1",
- "vite-plugin-pwa": "^1.2.0",
- "vite-plugin-top-level-await": "^1.6.0",
+ "prettier": "^3.9.8",
+ "ts-jest": "^29.4.12",
+ "vite": "^8.3.0",
+ "vite-plugin-pwa": "^1.3.0",
"vite-plugin-wasm": "^3.6.0",
- "workbox-window": "^7.4.0"
+ "workbox-precaching": "^7.4.1",
+ "workbox-routing": "^7.4.1"
},
"eslintConfig": {
"extends": [
diff --git a/Build/privacy.html b/Build/privacy.html
new file mode 100644
index 0000000..374f09c
--- /dev/null
+++ b/Build/privacy.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+ HTMLPlayer Privacy Policy
+
+
+
+
+
+
+
+
+
+
diff --git a/Build/public/privacy.html b/Build/public/privacy.html
deleted file mode 100644
index 1181ae2..0000000
--- a/Build/public/privacy.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
- HTMLPlayer Privacy Policy
-
-
-
- HTMLPlayer Privacy Policy
- Effective Date: 9/23/2025
-
- 1. Introduction
-
- HTMLPlayer respects your privacy. Since the App is primarily client-side,
- we do not collect personal data unless you interact with external services
- (e.g., Discord integration).
-
-
- 2. Data Collection
-
- The App does not collect personal information by default.
-
- Optional Discord integration may send limited information (username,
- current activity) to Discord's servers for the purpose of updating your
- music activity.
-
-
-
- 3. Cookies and Tracking
-
- HTMLPlayer does not use cookies or trackers for analytics or advertising.
-
-
- 4. Third-Party Services
-
- Discord integration is managed via OAuth; your authorization is handled by
- Discord directly. HTMLPlayer does not store Discord credentials or share
- data outside the Discord API.
-
-
- 5. Security
-
- All client-side operations run in your browser; no server-side storage of
- music or personal data occurs. We take no responsibility for security
- vulnerabilities in your browser or Discord.
-
-
- 6. Data Sharing
-
- HTMLPlayer does not sell, trade, or share personal information with third
- parties, except through authorized use of Discord features.
-
-
- 7. Updates to Privacy Policy
-
- We may update this Privacy Policy as HTMLPlayer evolves. Continued use
- indicates acceptance of the latest policy.
-
-
- 8. Contact
-
- For privacy questions, contact:
- nellowtcs@gmail.com
-
-
-
diff --git a/Build/public/tos.html b/Build/public/tos.html
deleted file mode 100644
index a3c61b6..0000000
--- a/Build/public/tos.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
- HTMLPlayer Terms of Service
-
-
-
- HTMLPlayer Terms of Service (TOS)
- Effective Date: 9/23/2025
-
- 1. Acceptance of Terms
-
- By using HTMLPlayer (the "App"), you agree to these Terms of Service. If
- you do not agree, do not use the App.
-
-
- 2. Use of the App
-
- HTMLPlayer is a free, open-source music player.
-
- All core functionality runs client-side in your browser; we do not
- collect usage data except when explicitly interacting with external
- services like Discord.
-
- You may use the App for personal, non-commercial purposes.
-
-
- 3. Intellectual Property
-
- HTMLPlayer and its source code are licensed under the
- MIT License . You may copy, modify, or redistribute the App according to the MIT
- License terms.
-
-
- 4. Discord Integration
-
- The App may optionally integrate with Discord to display music activity.
- Access to Discord features requires you to authorize HTMLPlayer via
- Discord OAuth. HTMLPlayer does not store your Discord credentials.
-
-
- 5. Beta Disclaimer
-
- HTMLPlayer is currently in beta. Features may be unstable or incomplete.
- Use at your own risk.
-
-
- 6. No Warranty
-
- The App is provided "as-is" without warranty of any kind, either express
- or implied. The developers are not liable for any damages arising from the
- use or inability to use HTMLPlayer.
-
-
- 7. Limitation of Liability
-
- You use HTMLPlayer entirely at your own risk. Developers are not
- responsible for any loss, data corruption, or other issues resulting from
- your use of the App.
-
-
- 8. Modifications to Terms
-
- We may update these Terms at any time. Continued use constitutes
- acceptance of the updated Terms.
-
-
- 9. Contact
-
- For questions about these Terms, contact:
- nellowtcs@gmail.com
-
-
-
diff --git a/Build/scripts/gen-visualizer-registry.cjs b/Build/scripts/gen-visualizer-registry.cjs
new file mode 100644
index 0000000..024f7da
--- /dev/null
+++ b/Build/scripts/gen-visualizer-registry.cjs
@@ -0,0 +1,87 @@
+const fs = require("fs");
+const path = require("path");
+
+const visualizersDir = path.resolve(
+ __dirname,
+ "..",
+ "src",
+ "ui",
+ "resources",
+ "visualizers",
+);
+const outFile = path.join(visualizersDir, "_registry.ts");
+
+const entries = fs
+ .readdirSync(visualizersDir)
+ .filter((name) => /\.visualizer\.tsx$/.test(name))
+ .sort();
+
+if (entries.length === 0) {
+ console.error("no visualizer files found");
+ process.exit(1);
+}
+
+const NAME_PATTERN = /^\s*name:\s*"([^"]*)"/m;
+
+const displayNames = new Map();
+for (const name of entries) {
+ const source = fs.readFileSync(path.join(visualizersDir, name), "utf8");
+ const match = NAME_PATTERN.exec(source);
+ if (!match) {
+ console.error(`no display name found in ${name}`);
+ process.exit(1);
+ }
+ displayNames.set(name.replace(/\.visualizer\.tsx$/, ""), match[1]);
+}
+
+const lines = [
+ "/* GENERATED by scripts/gen-visualizer-registry.cjs - do not edit by hand. */",
+ "/* Regenerate with: npm run generate:visualizers */",
+ 'import type { VisualizerType } from "../../../platform/visualizers/visualizerLoader";',
+ "",
+ "/*",
+ " * Explicit dynamic imports per visualizer. Do not replace with",
+ " * import.meta.glob: Vite 8 (rolldown) tree-shakes the glob output as pure",
+ " * (https://github.com/vitejs/vite/issues/21876), silently emptying the",
+ " * module map. An in-source literal survives because every member is",
+ " * reachable through dynamic keys.",
+ " */",
+ "const visualizerModules = {",
+];
+
+for (const name of entries) {
+ const moduleName = name.replace(/\.visualizer\.tsx$/, "");
+ const key = `../visualizers/${moduleName}.visualizer.tsx`;
+ lines.push(
+ ` [${JSON.stringify(key)}]: () =>`,
+ ` import(${JSON.stringify(`./${moduleName}.visualizer`)}).then((m) => m.default as VisualizerType),`,
+ );
+}
+
+lines.push(
+ "} as Record Promise>;",
+ "",
+ "const visualizerDisplayNames: Record = {",
+);
+for (const [key, label] of displayNames) {
+ lines.push(` ${JSON.stringify(key)}: ${JSON.stringify(label)},`);
+}
+lines.push(
+ "};",
+ "",
+ "export function visualizerModuleLoaders(): Record Promise> {",
+ " return visualizerModules;",
+ "}",
+ "",
+ "export function visualizerModuleNames(): string[] {",
+ " return Object.keys(visualizerModules);",
+ "}",
+ "",
+ "export function visualizerDisplayName(key: string): string | undefined {",
+ " return visualizerDisplayNames[key];",
+ "}",
+ "",
+);
+
+fs.writeFileSync(outFile, lines.join("\n"));
+console.log(`wrote ${outFile} (${entries.length} visualizers)`);
diff --git a/Build/src-tauri/Cargo.toml b/Build/src-tauri/Cargo.toml
index 79519ab..f60fa05 100644
--- a/Build/src-tauri/Cargo.toml
+++ b/Build/src-tauri/Cargo.toml
@@ -5,12 +5,8 @@ description = "A React Local Music App"
authors = ["NellowTCS"]
edition = "2021"
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
-# The `_lib` suffix may seem redundant but it is necessary
-# to make the lib name unique and wouldn't conflict with the bin name.
-# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "htmlplayer_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
diff --git a/Build/src-tauri/src/lib.rs b/Build/src-tauri/src/lib.rs
index 8414c66..f99d40a 100644
--- a/Build/src-tauri/src/lib.rs
+++ b/Build/src-tauri/src/lib.rs
@@ -1,4 +1,3 @@
-// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
use discord_rich_presence::{activity::Activity, DiscordIpc, DiscordIpcClient};
@@ -47,7 +46,6 @@ fn is_discord_running() -> bool {
return false;
}
- // Ignore errors when clearing activity; we only care whether the IPC is reachable.
let _ = client.clear_activity();
true
}
diff --git a/Build/src-tauri/src/main.rs b/Build/src-tauri/src/main.rs
index 0253c15..5d9d465 100644
--- a/Build/src-tauri/src/main.rs
+++ b/Build/src-tauri/src/main.rs
@@ -1,4 +1,3 @@
-// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
diff --git a/Build/src/components/Checkbox.tsx b/Build/src/components/Checkbox.tsx
deleted file mode 100644
index 9696d95..0000000
--- a/Build/src/components/Checkbox.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { InputHTMLAttributes, forwardRef } from "react";
-import styles from "./Checkbox.module.css";
-import { Icon } from "./Icon";
-export type CheckboxProps = Omit, "type">;
-
-export const Checkbox = forwardRef(
- ({ className, ...props }, ref) => {
- return (
-
-
-
-
- );
- },
-);
-
-Checkbox.displayName = "Checkbox";
diff --git a/Build/src/components/MainContent.tsx b/Build/src/components/MainContent.tsx
deleted file mode 100644
index 6ea8bc8..0000000
--- a/Build/src/components/MainContent.tsx
+++ /dev/null
@@ -1,819 +0,0 @@
-import React, { useState } from "react";
-import {
- DraggableItem,
- DropZone,
- DragHandle,
- DragHandleProps,
-} from "./Draggable";
-import { SongActionsDropdown } from "./SongActionsDropdown";
-import { Checkbox } from "./Checkbox";
-import { useRightClickMenu } from "./DropdownMenu";
-import { pickAudioFiles } from "../helpers/filePickerHelper";
-import { toast } from "sonner";
-import { Button } from "./Button";
-import { Input } from "./Input";
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
- DialogDescription,
- DialogFooter,
-} from "./Dialog";
-import styles from "./MainContent.module.css";
-import PersistentDropdownMenu, {
- PersistentDropdownMenuRef,
-} from "./PersistentDropdownMenu";
-import { AddToPopover } from "./AddToPopover";
-import { useTranslation } from "react-i18next";
-import { Icon } from "./Icon";
-import { musicIndexedDbHelper } from "../helpers/musicIndexedDbHelper";
-import { importAudioFiles } from "../helpers/importAudioFiles";
-import { Home } from "./Home";
-import { useAlbumArt } from "../hooks/useAlbumArt";
-
-interface SortableSongItemProps {
- song: Song;
- isCurrent: boolean;
- isSelected: boolean;
- onClick: () => void;
- onCheckboxChange: (e: React.ChangeEvent) => void;
- isSelectActive: boolean;
- ratings: Record;
- onRatingChange: (rating: "thumbs-up" | "thumbs-down") => void;
- onFavoriteToggle: (e: React.MouseEvent) => void;
- isFavorited: boolean;
- formatDuration: (seconds: number) => string;
- styles: any;
- SongActionsDropdown: any;
- library: MusicLibrary;
- createPlaylist: (name: string) => void;
- addToPlaylist: (playlistId: string, songId: string) => void;
- playSong: (song: Song, playlist?: Playlist) => void;
- removeSong: (songId: string) => void;
- isInPlaylist: boolean; // New prop to determine drag behavior
-}
-const SortableSongItem = React.memo(function SortableSongItem({
- song,
- isCurrent,
- isSelected,
- onClick,
- onCheckboxChange,
- isSelectActive,
- ratings,
- onRatingChange,
- onFavoriteToggle,
- isFavorited,
- formatDuration,
- styles,
- SongActionsDropdown,
- library,
- createPlaylist,
- addToPlaylist,
- playSong,
- removeSong,
- isInPlaylist,
-}: SortableSongItemProps) {
- const { t } = useTranslation();
- const { open, setOpen, containerRef } = useRightClickMenu(true);
-
- // Lazy load album art - only loads when component is rendered
- // Use song.albumArt if already loaded (for newly imported songs), otherwise lazy load
- const lazyAlbumArt = useAlbumArt(
- song.id,
- song.hasAlbumArt || !!song.albumArt,
- );
- const albumArt = song.albumArt || lazyAlbumArt;
-
- // Use DraggableItem for clean drag functionality, and DropZone if in playlist for reordering
- const songContent = (dragHandleProps?: DragHandleProps) => (
-
-
- {dragHandleProps && (
-
-
-
- )}
- {isSelectActive && (
-
- )}
-
- {albumArt && (
-
- )}
-
-
-
{song.title}
-
-
- {t("common.album")}:{" "}
-
- {song.album || t("common.unknownAlbum")}
-
- {" "}
- {t("common.duration")}: {formatDuration(song.duration)}
-
-
-
- {t("common.artist")}:
- {song.artist}
-
-
-
-
- {song.artist}
-
-
- {
- e.stopPropagation();
- onFavoriteToggle(e);
- }}
- >
-
-
- {
- e.stopPropagation();
- onRatingChange("thumbs-up");
- }}
- >
-
-
- {
- e.stopPropagation();
- onRatingChange("thumbs-down");
- }}
- >
-
-
-
-
-
- );
-
- return (
-
- {(dragHandleProps) =>
- isInPlaylist ? (
-
- {songContent(dragHandleProps)}
-
- ) : (
- songContent(dragHandleProps)
- )
- }
-
- );
-});
-
-interface MainContentProps {
- musicPlayerHook: ReturnType<
- typeof import("../hooks/musicPlayerHook").useMusicPlayer
- >;
- onMobileMenuClick?: () => void;
-}
-
-export const MainContent = ({
- musicPlayerHook,
- onMobileMenuClick,
-}: MainContentProps) => {
- const { t } = useTranslation();
-
- const [songSearchQuery, setSongSearchQuery] = useState("");
- const [sortBy, setSortBy] = useState<
- "name" | "artist" | "album" | "rating" | null
- >(null);
- const [sortOrder, setSortOrder] = useState<"asc" | "desc">("asc");
- const [ratings, setRatings] = useState<
- Record
- >({});
- const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
- const [songToDelete, setSongToDelete] = useState(null);
-
- const [selectedSongs, setSelectedSongs] = useState([]);
- const [isSelectSongsActive, setIsSelectSongsActive] = useState(false);
- const [showPlaylistDialog, setShowPlaylistDialog] = useState(false);
- const sortDropdownRef = React.useRef(null);
-
- const {
- playerState,
- library,
- playSong,
- addSong,
- removeSong,
- toggleFavorite,
- isFavorited,
- createPlaylist,
- addToPlaylist,
- navigateToArtist,
- navigateToAlbum,
- navigateToSongs,
- navigateToHome,
- } = musicPlayerHook;
-
- // Navigation listener
- React.useEffect(() => {
- const handleNavigate = (
- e: CustomEvent<{ view: "artist" | "album"; value: string }>,
- ) => {
- if (e.detail.view === "artist") navigateToArtist(e.detail.value);
- else if (e.detail.view === "album") navigateToAlbum(e.detail.value);
- };
- window.addEventListener("navigate", handleNavigate);
- return () => window.removeEventListener("navigate", handleNavigate);
- }, [navigateToArtist, navigateToAlbum]);
-
- // Clear sorting when entering playlist view
- React.useEffect(() => {
- if (playerState.currentPlaylist) {
- setSortBy(null);
- setSortOrder("asc");
- }
- }, [playerState.currentPlaylist]);
-
- const songsToDisplay = React.useMemo(() => {
- if (playerState.view === "artist" && playerState.currentArtist) {
- return library.songs.filter(
- (song) => song.artist === playerState.currentArtist,
- );
- } else if (playerState.view === "album" && playerState.currentAlbum) {
- return library.songs.filter(
- (song) => song.album === playerState.currentAlbum,
- );
- } else if (playerState.currentPlaylist) {
- return playerState.currentPlaylist.songs;
- } else {
- return library.songs;
- }
- }, [
- playerState.view,
- playerState.currentArtist,
- playerState.currentAlbum,
- playerState.currentPlaylist,
- library.songs,
- ]);
-
- const filteredSongs = React.useMemo(() => {
- const query = songSearchQuery.toLowerCase();
- if (!query) return songsToDisplay;
- return songsToDisplay.filter(
- (song: Song) =>
- song.title.toLowerCase().includes(query) ||
- song.artist.toLowerCase().includes(query),
- );
- }, [songsToDisplay, songSearchQuery]);
-
- const sortedSongs = React.useMemo(() => {
- let sorted = [...filteredSongs];
- if (sortBy) {
- sorted.sort((a, b) => {
- let aVal: string | number;
- let bVal: string | number;
- switch (sortBy) {
- case "name":
- aVal = a.title.toLowerCase();
- bVal = b.title.toLowerCase();
- break;
- case "artist":
- aVal = a.artist.toLowerCase();
- bVal = b.artist.toLowerCase();
- break;
- case "album":
- aVal = a.album?.toLowerCase() || "";
- bVal = b.album?.toLowerCase() || "";
- break;
- case "rating":
- aVal =
- ratings[a.id] === "thumbs-up"
- ? 1
- : ratings[a.id] === "thumbs-down"
- ? -1
- : 0;
- bVal =
- ratings[b.id] === "thumbs-up"
- ? 1
- : ratings[b.id] === "thumbs-down"
- ? -1
- : 0;
- break;
- default:
- return 0;
- }
- if (aVal < bVal) return sortOrder === "asc" ? -1 : 1;
- if (aVal > bVal) return sortOrder === "asc" ? 1 : -1;
- return 0;
- });
- }
- return sorted;
- }, [filteredSongs, sortBy, sortOrder, ratings]);
-
- const handleSongSearch = (query: string) => setSongSearchQuery(query);
-
- const handleSongClick = (song: Song) => {
- playSong(song, playerState.currentPlaylist || undefined);
- };
-
- const handleRating = (
- songId: string,
- rating: "thumbs-up" | "thumbs-down",
- ) => {
- const currentRating = ratings[songId];
- const newRating = currentRating === rating ? "none" : rating;
- setRatings((prev) => ({ ...prev, [songId]: newRating }));
- };
-
- const handleToggleFavorite = (
- e: React.MouseEvent,
- songId: string,
- ) => {
- e.stopPropagation();
- const wasAdded = toggleFavorite(songId);
- const song = library.songs.find((s) => s.id === songId);
- if (song) {
- toast.success(
- wasAdded
- ? t("favorites.added", { title: song.title })
- : t("favorites.removed", { title: song.title }),
- );
- }
- };
-
- const handleDeleteSong = async () => {
- if (filteredSongs.length === 0) {
- toast.error(t("delete.noSongs"));
- return;
- }
-
- // Check if user has chosen not to show delete confirmation
- const shouldShow = await musicIndexedDbHelper.shouldShowDialog(
- "delete-song-confirmation",
- );
- if (!shouldShow) {
- // Delete directly without showing dialog
- const songToDelete = filteredSongs[0];
- removeSong(songToDelete.id);
- toast.success(t("deletedFromLibrary", { song: songToDelete.title }));
- return;
- }
-
- // Show confirmation dialog
- setSongToDelete(filteredSongs[0]);
- setShowDeleteConfirm(true);
- };
-
- const handleDeleteConfirm = () => {
- if (songToDelete) {
- removeSong(songToDelete.id);
- toast.success(t("deletedFromLibrary", { song: songToDelete.title }));
- setShowDeleteConfirm(false);
- setSongToDelete(null);
- }
- };
-
- const handleDeleteCancel = () => {
- setShowDeleteConfirm(false);
- setSongToDelete(null);
- };
-
- // Helper to import audio files (used for both manual and share target)
- const handleImportAudioFiles = async (
- audioFiles: Array<{ file: File } | File>,
- ) => {
- await importAudioFiles(audioFiles, addSong, t);
- };
-
- // Manual add music (Uppy)
- const handleAddMusic = async () => {
- try {
- toast.info(t("filePicker.selectFiles"));
- const audioFiles = await pickAudioFiles();
- await handleImportAudioFiles(audioFiles);
- } catch {
- toast.dismiss();
- toast.error(t("filePicker.failedOpen"));
- }
- };
-
- const formatDuration = (seconds: number) => {
- const mins = Math.floor(seconds / 60);
- const secs = Math.round(seconds % 60);
- return `${mins}:${secs.toString().padStart(2, "0")}`;
- };
-
- const handleSelectSongsToggle = () => {
- setIsSelectSongsActive((prev) => !prev);
- setSelectedSongs([]);
- };
-
- const handleSelectAll = () => {
- if (selectedSongs.length === sortedSongs.length) setSelectedSongs([]);
- else setSelectedSongs(sortedSongs.map((song) => song.id));
- };
-
- const handleAddToPlaylist = () => setShowPlaylistDialog(true);
-
- const handleDeleteSelectedSongs = () => {
- selectedSongs.forEach((songId) => removeSong(songId));
- toast.success(t("deletedFromLibrary", { song: selectedSongs.length }));
- setSelectedSongs([]);
- };
-
- const isHomeView = playerState.view === "home";
- const isLibraryContext = playerState.view !== "home";
-
- const viewSwitcher = (
-
-
-
- {t("home.title")}
-
-
-
- {t("allSongs")}
-
-
- );
-
- return (
-
- {/* Header */}
-
-
-
-
-
- {playerState.view === "home" ? (
-
HTMLPlayer
- ) : playerState.view === "songs" ? (
-
HTMLPlayer
- ) : playerState.view === "artist" ? (
- <>
-
- {t("actions.back")}
-
-
{`${t("common.artist")}: ${playerState.currentArtist}`}
- >
- ) : playerState.view === "album" ? (
- <>
-
- {t("actions.back")}
-
-
{`${t("common.album")}: ${playerState.currentAlbum}`}
- >
- ) : null}
-
- {viewSwitcher}
-
-
- {isHomeView && (
-
- {viewSwitcher}
-
- )}
- {!isHomeView && (
-
-
-
- handleSongSearch(e.target.value)}
- data-tour="search"
- />
-
-
-
-
-
-
-
-
- }
- onClose={() => {}}
- >
- setSortBy("name")}
- className="w-full justify-start text-sm"
- >
-
- {t("sort.name")}
- {sortBy === "name" && • }
-
- setSortBy("artist")}
- className="w-full justify-start text-sm"
- >
-
- {t("sort.artist")}
- {sortBy === "artist" && • }
-
- setSortBy("album")}
- className="w-full justify-start text-sm"
- >
-
- {t("sort.album")}
- {sortBy === "album" && • }
-
- setSortBy("rating")}
- className="w-full justify-start text-sm"
- >
-
- {t("sort.rating")}
- {sortBy === "rating" && • }
-
-
-
- setSortOrder(sortOrder === "asc" ? "desc" : "asc")
- }
- className="w-full justify-start text-sm"
- >
- {sortOrder === "asc" ? (
-
- ) : (
-
- )}
- {sortOrder === "asc"
- ? t("sort.ascending")
- : t("sort.descending")}
-
-
- {
- setSortBy(null);
- sortDropdownRef.current?.close();
- }}
- className="w-full justify-start text-sm"
- >
-
- {t("sort.clear")}
-
-
-
-
-
- }
- onClose={() => handleSelectSongsToggle()}
- >
-
-
- {selectedSongs.length === sortedSongs.length
- ? t("actions.deselectAll")
- : t("actions.selectAll")}
-
-
-
- {t("playlist.addTo")}
-
-
-
- {t("common.delete")}
-
-
-
-
-
-
{viewSwitcher}
-
-
- )}
-
-
- {/* Main content */}
- {isHomeView ? (
-
-
-
- ) : (
-
-
-
- {t("songInfo.title")}
-
- {t("common.artist")}
-
- {t("actions.addTo")}
-
- {sortedSongs.map((song: Song) => (
-
handleSongClick(song)}
- onCheckboxChange={(e) => {
- e.stopPropagation();
- setSelectedSongs((prev) =>
- prev.includes(song.id)
- ? prev.filter((id) => id !== song.id)
- : [...prev, song.id],
- );
- }}
- isSelectActive={isSelectSongsActive}
- ratings={ratings}
- onRatingChange={(rating) => handleRating(song.id, rating)}
- onFavoriteToggle={(e) => handleToggleFavorite(e, song.id)}
- isFavorited={isFavorited(song.id)}
- formatDuration={formatDuration}
- styles={styles}
- SongActionsDropdown={SongActionsDropdown}
- library={library}
- createPlaylist={createPlaylist}
- addToPlaylist={addToPlaylist}
- playSong={playSong}
- isInPlaylist={!!playerState.currentPlaylist}
- removeSong={removeSong}
- />
- ))}
- {sortedSongs.length === 0 && (
-
- {songSearchQuery
- ? t("noResults.search")
- : t("noResults.playlist")}
-
- )}
-
-
- )}
-
- {/* Delete Modal */}
-
-
-
- {t("delete.songTitle")}
-
- {t("delete.confirm", { title: songToDelete?.title })}
-
-
-
-
- {t("common.cancel")}
-
-
- {t("common.delete")}
-
-
-
-
-
- {/* Add To Popover */}
-
library.songs.find((s) => s.id === id))
- .filter((s): s is Song => s !== undefined)}
- library={library}
- onCreatePlaylist={createPlaylist}
- onAddToPlaylist={addToPlaylist}
- open={showPlaylistDialog}
- onOpenChange={setShowPlaylistDialog}
- />
-
- );
-};
diff --git a/Build/src/components/Miniplayer.tsx b/Build/src/components/Miniplayer.tsx
deleted file mode 100644
index 7c32827..0000000
--- a/Build/src/components/Miniplayer.tsx
+++ /dev/null
@@ -1,462 +0,0 @@
-import { createRoot } from "react-dom/client";
-import { useTranslation } from "react-i18next";
-import { Button } from "./Button";
-import { Icon } from "./Icon";
-import { getCurrentThemeCSS } from "../helpers/themeMode";
-import styles from "./Miniplayer.module.css";
-import { useAudioStore } from "../contexts/audioStore";
-import { IconRegistryProvider } from "../helpers/iconLoader";
-
-interface MiniplayerControls {
- togglePlayPause: () => void;
- playNext: () => void;
- playPrevious: () => void;
- playerState: {
- currentSong: PlayerState["currentSong"];
- isPlaying: boolean;
- };
-}
-
-let pipWindow: Window | null = null;
-
-/**
- * Enhanced stylesheet copying with better CSS modules support
- */
-function copyAllStyles(pipWindow: Window) {
- // Method 1: Copy all link elements
- document.querySelectorAll('link[rel="stylesheet"]').forEach((link) => {
- const newLink = pipWindow.document.createElement("link");
- newLink.rel = "stylesheet";
- newLink.href = (link as HTMLLinkElement).href;
- newLink.type = "text/css";
- pipWindow.document.head.appendChild(newLink);
- });
-
- // Method 2: Copy all style elements (including CSS modules)
- document.querySelectorAll("style").forEach((style) => {
- const newStyle = pipWindow.document.createElement("style");
- newStyle.textContent = style.textContent;
-
- // Copy any attributes that might be important
- Array.from(style.attributes).forEach((attr) => {
- newStyle.setAttribute(attr.name, attr.value);
- });
-
- pipWindow.document.head.appendChild(newStyle);
- });
-
- // Method 3: Copy CSS rules from accessible stylesheets
- let copiedRulesCount = 0;
- try {
- [...document.styleSheets].forEach((styleSheet) => {
- try {
- const cssRules = [...styleSheet.cssRules]
- .map((rule) => rule.cssText)
- .join("");
- if (cssRules) {
- const style = pipWindow.document.createElement("style");
- style.textContent = cssRules;
- pipWindow.document.head.appendChild(style);
- copiedRulesCount += styleSheet.cssRules.length;
- }
- } catch (e) {
- // Skip inaccessible stylesheets (CORS/cross-origin)
- console.warn("Could not access stylesheet:", styleSheet.href, e);
- }
- });
- } catch (e) {
- console.warn("Could not copy some stylesheets:", e);
- }
-
- console.log(`Copied ${copiedRulesCount} CSS rules to PiP window`);
-}
-
-/**
- * Check if Document Picture-in-Picture API is supported
- */
-export const isMiniplayerSupported = (): boolean => {
- return (
- "documentPictureInPicture" in window && !!window.documentPictureInPicture
- );
-};
-
-/**
- * Toggle Picture-in-Picture miniplayer
- */
-export const toggleMiniplayer = async (controls: MiniplayerControls) => {
- if (!controls.playerState.currentSong) {
- console.error("No song is currently playing");
- return;
- }
-
- try {
- if (pipWindow) {
- pipWindow.close();
- pipWindow = null;
- return;
- }
-
- // Check if Document Picture-in-Picture API is supported
- if (
- !("documentPictureInPicture" in window) ||
- !window.documentPictureInPicture
- ) {
- console.error("Document Picture-in-Picture not supported");
- return;
- }
-
- const newPipWindow = await window.documentPictureInPicture.requestWindow({
- width: 400,
- height: 70,
- });
- pipWindow = newPipWindow;
-
- console.log("PiP window opened successfully");
-
- // Copy theme class
- if (document.documentElement.classList.contains("dark")) {
- newPipWindow.document.documentElement.classList.add("dark");
- }
-
- // Copy all styles
- copyAllStyles(newPipWindow);
-
- // Wait for theme application to complete
- await new Promise((resolve) => setTimeout(resolve, 300));
-
- // Re-fetch theme CSS after delay
- const themeCSS = getCurrentThemeCSS();
- if (themeCSS && themeCSS.trim() !== ":root {\n \n}") {
- const themeStyle = newPipWindow.document.createElement("style");
- themeStyle.textContent = themeCSS;
- themeStyle.setAttribute("data-theme-variables", "true");
- newPipWindow.document.head.appendChild(themeStyle);
- console.log("Applied theme CSS variables to PiP window");
- } else {
- // Fallback: manually extract and apply theme variables
- const rootStyle = getComputedStyle(document.documentElement);
- const fallbackVariables: string[] = [];
- const themeVars = [
- "--themecolor",
- "--themecolor2",
- "--themecolor3",
- "--themecolor4",
- "--themegradient",
- "--themecolor-transparent",
- "--themecolor2-transparent",
- "--themecolor3-transparent",
- "--foreground",
- "--foreground-strong",
- "--foreground-stronger",
- "--foreground-muted",
- "--foreground-subtle",
- "--background",
- "--surface",
- "--surface-foreground",
- "--surface-transparent-05",
- "--surface-transparent-1",
- "--surface-transparent-2",
- "--primary",
- "--primary-foreground",
- "--primary-transparent",
- "--primary-border",
- "--primary-border-strong",
- "--secondary",
- "--secondary-foreground",
- "--menu-background",
- "--spacing-1",
- "--spacing-2",
- "--spacing-3",
- "--spacing-4",
- "--radius",
- "--radius-lg",
- ];
-
- themeVars.forEach((varName) => {
- const value = rootStyle.getPropertyValue(varName).trim();
- if (value) {
- fallbackVariables.push(`${varName}: ${value};`);
- }
- });
-
- if (fallbackVariables.length > 0) {
- const fallbackStyle = newPipWindow.document.createElement("style");
- fallbackStyle.textContent = `:root {\n ${fallbackVariables.join("\n ")}\n}`;
- fallbackStyle.setAttribute("data-fallback-theme-variables", "true");
- newPipWindow.document.head.appendChild(fallbackStyle);
- console.log("Applied fallback theme variables");
- }
- }
-
- // Set up the body
- newPipWindow.document.body.style.margin = "0";
- newPipWindow.document.body.style.padding = "0";
- newPipWindow.document.body.style.overflow = "hidden";
-
- // Create React root and render
- const rootElement = createRoot(newPipWindow.document.body);
- rootElement.render( );
-
- // Handle window close
- newPipWindow.addEventListener("pagehide", () => {
- rootElement.unmount();
- pipThemeChannel.close(); // Clean up the BroadcastChannel
- pipWindow = null;
- });
-
- // Create a new BroadcastChannel specifically for the PiP window
- const pipThemeChannel = new BroadcastChannel("theme-updates");
-
- // Listen for theme updates in the PiP window
- pipThemeChannel.onmessage = (event) => {
- if (event.data.type === "theme-css") {
- console.log("PiP window received theme update");
-
- // Apply dark mode class based on broadcast data
- if (event.data.darkMode) {
- newPipWindow.document.documentElement.classList.add("dark");
- } else {
- newPipWindow.document.documentElement.classList.remove("dark");
- }
-
- // Remove any existing theme styles
- const existingThemeStyles = newPipWindow.document.querySelectorAll(
- 'style[data-theme-variables], style[data-fallback-theme-variables], style[id^="theme-stylesheet"]',
- );
- existingThemeStyles.forEach((style) => style.remove());
-
- // Apply new theme CSS
- const styleElement = newPipWindow.document.createElement("style");
- styleElement.textContent = event.data.css;
- styleElement.setAttribute("data-theme-variables", "true");
- if (event.data.fallback) {
- styleElement.setAttribute("data-fallback-theme-variables", "true");
- }
- newPipWindow.document.head.appendChild(styleElement);
-
- // Force reflow to apply styles immediately
- newPipWindow.document.body.offsetHeight;
- }
- };
- } catch (err) {
- console.error("PiP failed:", err);
- pipWindow = null;
- }
-};
-
-interface MiniplayerProps {
- controls: MiniplayerControls;
-}
-
-const MiniplayerContent: React.FC = () => {
- const { t } = useTranslation();
- const { currentSong, isPlaying, play, pause, next, previous } =
- useAudioStore();
-
- const handlePlayPause = () => {
- if (isPlaying) {
- pause("pip");
- } else {
- play("pip");
- }
- };
-
- const handlePrevious = () => {
- previous("pip");
- };
-
- const handleNext = () => {
- next("pip");
- };
-
- if (!currentSong) {
- return {t("player.noSongPlaying")}
;
- }
-
- return (
-
-
- {currentSong.albumArt && (
-
- )}
-
-
{currentSong.title}
-
{currentSong.artist}
-
-
-
-
-
-
- {isPlaying ? (
-
- ) : (
-
- )}
-
-
-
-
-
-
-
- );
-};
-
-// Standalone miniplayer component
-const Miniplayer = ({ controls }: MiniplayerProps) => {
- const { t } = useTranslation();
- const { playerState, togglePlayPause, playNext, playPrevious } = controls;
- const { currentSong, isPlaying } = playerState;
-
- if (!currentSong) {
- return {t("player.noSongPlaying")}
;
- }
-
- return (
-
-
-
-
{currentSong.title}
-
{currentSong.artist}
-
-
- {t("player.previousTrack")}
-
- {isPlaying ? t("player.pause") : t("player.play")}
-
- {t("player.nextTrack")}
-
-
- );
-};
-
-export const spawnMiniplayer = (controls: MiniplayerControls) => {
- const container = document.createElement("div");
- document.body.appendChild(container);
-
- const root = createRoot(container);
- root.render( );
-
- return () => {
- root.unmount();
- document.body.removeChild(container);
- };
-};
-
-// Create a BroadcastChannel for IPC
-const themeChannel = new BroadcastChannel("theme-updates");
-
-// Send theme CSS updates
-export function broadcastThemeCSS() {
- const themeCSS = getCurrentThemeCSS();
- const isDarkMode = document.documentElement.classList.contains("dark");
-
- if (themeCSS && themeCSS.trim() !== ":root {\n \n}") {
- themeChannel.postMessage({
- type: "theme-css",
- css: themeCSS,
- darkMode: isDarkMode,
- timestamp: Date.now(),
- });
- } else {
- // Fallback: Extract specific theme variables
- const rootStyle = getComputedStyle(document.documentElement);
- const fallbackVariables: string[] = [];
- const themeVars = [
- "--themecolor",
- "--themecolor2",
- "--themecolor3",
- "--themecolor4",
- "--themegradient",
- "--themecolor-transparent",
- "--themecolor2-transparent",
- "--themecolor3-transparent",
- "--foreground",
- "--foreground-strong",
- "--foreground-stronger",
- "--foreground-muted",
- "--foreground-subtle",
- "--background",
- "--surface",
- "--surface-foreground",
- "--surface-transparent-05",
- "--surface-transparent-1",
- "--surface-transparent-2",
- "--primary",
- "--primary-foreground",
- "--primary-transparent",
- "--primary-border",
- "--primary-border-strong",
- "--secondary",
- "--secondary-foreground",
- "--menu-background",
- "--spacing-1",
- "--spacing-2",
- "--spacing-3",
- "--spacing-4",
- "--radius",
- "--radius-lg",
- ];
-
- themeVars.forEach((varName) => {
- const value = rootStyle.getPropertyValue(varName).trim();
- if (value) {
- fallbackVariables.push(`${varName}: ${value};`);
- }
- });
-
- if (fallbackVariables.length > 0) {
- const fallbackCSS = `:root {\n ${fallbackVariables.join("\n ")}\n}`;
- themeChannel.postMessage({
- type: "theme-css",
- css: fallbackCSS,
- darkMode: isDarkMode,
- timestamp: Date.now(),
- fallback: true,
- });
- }
- }
-}
-
-// Listen for theme updates in the main document
-if (typeof window !== "undefined") {
- themeChannel.onmessage = (event) => {
- if (event.data.type === "theme-css") {
- // Theme update received - main window can handle if needed
- }
- };
-}
-
-// Extend the Window interface to include documentPictureInPicture
-declare global {
- interface Window {
- documentPictureInPicture?: {
- requestWindow: (options: {
- width: number;
- height: number;
- }) => Promise void }>;
- };
- }
-}
diff --git a/Build/src/components/Player.tsx b/Build/src/components/Player.tsx
deleted file mode 100644
index a01ab83..0000000
--- a/Build/src/components/Player.tsx
+++ /dev/null
@@ -1,552 +0,0 @@
-import React, {
- useEffect,
- useRef,
- useState,
- useCallback,
- useImperativeHandle,
- forwardRef,
-} from "react";
-import { Button } from "./Button";
-import { Visualizer } from "./Visualizer";
-import { Lyrics } from "./Lyrics";
-import styles from "./Player.module.css";
-import { SongActionsDropdown } from "./SongActionsDropdown";
-import { useTranslation } from "react-i18next";
-import { toggleMiniplayer, isMiniplayerSupported } from "./Miniplayer";
-import { useAudioSync } from "../hooks/useAudioSync";
-import { ScrollText } from "./ScrollText";
-import { isSafari } from "../helpers/safariHelper";
-import { Icon } from "./Icon";
-import { useAlbumArt } from "../hooks/useAlbumArt";
-
-interface PlayerProps {
- musicPlayerHook: ReturnType<
- typeof import("../hooks/musicPlayerHook").useMusicPlayer
- >;
- settings: PlayerSettings;
-}
-
-export interface PlayerRef {
- toggleVisualizer: () => void;
- toggleLyrics: () => void;
-}
-
-export const Player = forwardRef(
- ({ musicPlayerHook, settings }, ref) => {
- const { t } = useTranslation();
-
- // Initialize audio sync for cross-window communication
- useAudioSync({ musicPlayerHook, isMiniplayer: false });
-
- const progressRef = useRef(null);
- const volumeRef = useRef(null);
-
- const {
- playerState,
- library,
- togglePlayPause,
- playNext,
- playPrevious,
- setVolume,
- seekTo,
- addToFavorites,
- removeFromFavorites,
- isFavorited,
- toggleShuffle,
- toggleRepeat,
- createPlaylist,
- addToPlaylist,
- playSong,
- removeSong,
- } = musicPlayerHook;
-
- const {
- currentSong,
- isPlaying,
- currentTime,
- volume,
- shuffle,
- repeat,
- analyserNode,
- } = playerState;
- // Lazy load album art for current song
- const lazyAlbumArt = useAlbumArt(
- currentSong?.id,
- currentSong?.hasAlbumArt || !!currentSong?.albumArt,
- );
- const currentAlbumArt = currentSong?.albumArt || lazyAlbumArt;
-
- const [showVisualizer, setShowVisualizer] = useState(false);
- const [showLyrics, setShowLyrics] = useState(false);
- const [isVisualizerClosing, setIsVisualizerClosing] = useState(false);
- const [isLyricsClosing, setIsLyricsClosing] = useState(false);
- const [hasVisualizerAnimatedIn, setHasVisualizerAnimatedIn] =
- useState(false);
- const [isDraggingProgress, setIsDraggingProgress] = useState(false);
- const [isDraggingVolume, setIsDraggingVolume] = useState(false);
-
- // Track when visualizer open animation completes
- useEffect(() => {
- if (showVisualizer && !isVisualizerClosing && !hasVisualizerAnimatedIn) {
- const timer = setTimeout(() => setHasVisualizerAnimatedIn(true), 250);
- return () => clearTimeout(timer);
- }
- if (!showVisualizer) {
- setHasVisualizerAnimatedIn(false);
- }
- }, [showVisualizer, isVisualizerClosing, hasVisualizerAnimatedIn]);
-
- const formatTime = (seconds: number) => {
- const totalSeconds = Math.round(seconds);
- const shouldShowHours = currentSong && currentSong.duration >= 3600;
-
- if (shouldShowHours) {
- const hours = Math.floor(totalSeconds / 3600);
- const mins = Math.floor((totalSeconds % 3600) / 60);
- const secs = totalSeconds % 60;
- return `${hours}:${mins.toString().padStart(2, "0")}:${secs
- .toString()
- .padStart(2, "0")}`;
- } else {
- const mins = Math.floor(totalSeconds / 60);
- const secs = totalSeconds % 60;
- return `${mins}:${secs.toString().padStart(2, "0")}`;
- }
- };
-
- const updateProgress = useCallback(
- (clientX: number) => {
- if (!progressRef.current || !currentSong) return;
- const rect = progressRef.current.getBoundingClientRect();
- const clickX = clientX - rect.left;
- const percentage = Math.max(0, Math.min(1, clickX / rect.width));
- const newTime = percentage * currentSong.duration;
- seekTo(newTime);
- },
- [currentSong, seekTo],
- );
-
- const updateVolume = useCallback(
- (clientX: number) => {
- if (!volumeRef.current) return;
- const rect = volumeRef.current.getBoundingClientRect();
- const clickX = clientX - rect.left;
- const percentage = Math.max(0, Math.min(1, clickX / rect.width));
- setVolume(percentage);
- },
- [setVolume],
- );
-
- const handleProgressClick = (e: React.MouseEvent) => {
- if (isDraggingProgress) return;
- updateProgress(e.clientX);
- };
-
- const handleVolumeClick = (e: React.MouseEvent) => {
- if (isDraggingVolume) return;
- updateVolume(e.clientX);
- };
-
- const handleProgressMouseDown = (e: React.MouseEvent) => {
- setIsDraggingProgress(true);
- updateProgress(e.clientX);
- };
-
- const handleProgressTouchStart = (e: React.TouchEvent) => {
- setIsDraggingProgress(true);
- updateProgress(e.touches[0].clientX);
- };
-
- const handleVolumeMouseDown = (e: React.MouseEvent) => {
- setIsDraggingVolume(true);
- updateVolume(e.clientX);
- };
-
- const handleVolumeTouchStart = (e: React.TouchEvent) => {
- setIsDraggingVolume(true);
- updateVolume(e.touches[0].clientX);
- };
-
- useEffect(() => {
- const handleMouseMove = (e: MouseEvent) => {
- if (isDraggingProgress) updateProgress(e.clientX);
- else if (isDraggingVolume) updateVolume(e.clientX);
- };
-
- const handleTouchMove = (e: TouchEvent) => {
- if (isDraggingProgress) {
- e.preventDefault();
- updateProgress(e.touches[0].clientX);
- } else if (isDraggingVolume) {
- e.preventDefault();
- updateVolume(e.touches[0].clientX);
- }
- };
-
- const handleMouseUp = () => {
- setIsDraggingProgress(false);
- setIsDraggingVolume(false);
- };
-
- const handleTouchEnd = () => {
- setIsDraggingProgress(false);
- setIsDraggingVolume(false);
- };
-
- if (isDraggingProgress || isDraggingVolume) {
- document.addEventListener("mousemove", handleMouseMove);
- document.addEventListener("mouseup", handleMouseUp);
- document.addEventListener("touchmove", handleTouchMove, {
- passive: false,
- });
- document.addEventListener("touchend", handleTouchEnd);
- }
-
- return () => {
- document.removeEventListener("mousemove", handleMouseMove);
- document.removeEventListener("mouseup", handleMouseUp);
- document.removeEventListener("touchmove", handleTouchMove);
- document.removeEventListener("touchend", handleTouchEnd);
- };
- }, [isDraggingProgress, isDraggingVolume, updateProgress, updateVolume]);
-
- const handleVolumeToggle = () => {
- setVolume(volume === 0 ? 0.7 : 0);
- };
-
- const handleFavorite = () => {
- if (!currentSong) return;
- const isFavorite = library.favorites.includes(currentSong.id);
- if (isFavorite) removeFromFavorites(currentSong.id);
- else addToFavorites(currentSong.id);
- };
-
- const handleVisualizerToggle = useCallback(() => {
- if (showVisualizer || isVisualizerClosing) {
- // Close with animation
- setIsVisualizerClosing(true);
- setTimeout(() => {
- setIsVisualizerClosing(false);
- setShowVisualizer(false);
- }, 250); // Match animation duration
- } else {
- setShowVisualizer(true);
- }
- }, [showVisualizer, isVisualizerClosing]);
-
- const handleLyricsToggle = useCallback(() => {
- if (showLyrics || isLyricsClosing) {
- // Close with animation
- setIsLyricsClosing(true);
- setTimeout(() => {
- setIsLyricsClosing(false);
- setShowLyrics(false);
- }, 250); // Match animation duration
- } else {
- setShowLyrics(true);
- }
- }, [showLyrics, isLyricsClosing]);
-
- // Expose toggle methods via ref for keyboard shortcuts
- useImperativeHandle(
- ref,
- () => ({
- toggleVisualizer: handleVisualizerToggle,
- toggleLyrics: handleLyricsToggle,
- }),
- [handleVisualizerToggle, handleLyricsToggle],
- );
-
- const getVolumeIcon = () => {
- if (volume === 0) return ;
- if (volume < 0.3) return ;
- if (volume < 0.7) return ;
- return ;
- };
-
- const getRepeatTitle = () => {
- switch (repeat) {
- case "one":
- return t("player.repeatTrack");
- case "all":
- return t("player.repeatAll");
- default:
- return t("player.repeatOff");
- }
- };
-
- useEffect(() => {
- if (currentSong && settings?.showLyrics) setShowLyrics(true);
- }, [currentSong, settings?.showLyrics]);
-
- // Check if running on Safari
- const isOnSafari = isSafari();
-
- const progressPercentage = currentSong
- ? (currentTime / currentSong.duration) * 100
- : 0;
- const volumePercentage = volume * 100;
- const isHomeView = playerState.view === "home";
-
- if (!currentSong) {
- return (
-
-
- {t("player.selectSong")}
-
-
- );
- }
-
- const isFavorite = library.favorites.includes(currentSong.id);
-
- // Determine visualizer data-state: closing, open (initial animation), or visible (no animation)
- const visualizerDataState = isVisualizerClosing
- ? "closing"
- : hasVisualizerAnimatedIn
- ? "visible"
- : "open";
-
- return (
- <>
- {(showVisualizer || isVisualizerClosing) && (
-
-
-
- )}
-
-
-
- {currentAlbumArt && (
-
- )}
-
-
-
-
-
-
{currentSong.artist}
-
-
-
-
-
-
-
-
-
-
-
-
- {isPlaying ? (
-
- ) : (
-
- )}
-
-
-
-
-
-
-
-
-
-
-
- {formatTime(currentTime)}
-
-
-
- {formatTime(currentSong.duration)}
-
-
-
-
-
-
-
- {getVolumeIcon()}
-
-
-
-
-
-
-
-
- {!isOnSafari && (
-
-
-
- )}
-
-
-
- {isMiniplayerSupported() && (
- {
- toggleMiniplayer({
- playerState: {
- currentSong,
- isPlaying,
- },
- togglePlayPause,
- playNext,
- playPrevious,
- });
- }}
- title="Picture-in-Picture"
- >
-
-
- )}
-
-
-
-
-
- {(showLyrics || isLyricsClosing) && currentSong && (
-
- )}
-
- >
- );
- },
-);
-
-Player.displayName = "Player";
diff --git a/Build/src/components/Playlist.tsx b/Build/src/components/Playlist.tsx
deleted file mode 100644
index 5abfd98..0000000
--- a/Build/src/components/Playlist.tsx
+++ /dev/null
@@ -1,1070 +0,0 @@
-import {
- useState,
- useEffect,
- JSX,
- memo,
- useCallback,
- useMemo,
- useRef,
-} from "react";
-import { useTranslation } from "react-i18next";
-import { toast } from "sonner";
-import { DropZone, DraggableItem } from "./Draggable";
-import styles from "./Playlist.module.css";
-import { generatePlaylistImage } from "../helpers/playlistImageHelper";
-import modalStyles from "./Dialog.module.css";
-import { Button } from "./Button";
-import { Input } from "./Input";
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
- DialogDescription,
- DialogFooter,
-} from "./Dialog";
-import {
- Collapsible,
- CollapsibleTrigger,
- CollapsibleContent,
-} from "./Collapsible";
-import {
- DropdownMenu,
- DropdownMenuTrigger,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuSeparator,
- useRightClickMenu,
-} from "./DropdownMenu";
-import { ScrollText } from "./ScrollText";
-import { Icon } from "./Icon";
-import { musicIndexedDbHelper } from "../helpers/musicIndexedDbHelper";
-
-interface PlaylistProps {
- musicPlayerHook: ReturnType<
- typeof import("../hooks/musicPlayerHook").useMusicPlayer
- >;
-}
-
-export const PlaylistComponent = ({ musicPlayerHook }: PlaylistProps) => {
- const { t } = useTranslation();
- const [playlistSearchQuery, setPlaylistSearchQuery] = useState("");
- const [showCreatePlaylist, setShowCreatePlaylist] = useState(false);
- const [newPlaylistName, setNewPlaylistName] = useState("");
- const [playlistImages, setPlaylistImages] = useState>(
- {},
- );
- const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
- const [playlistToDelete, setPlaylistToDelete] = useState<
- Playlist | PlaylistFolder | null
- >(null);
- const [openFolders, setOpenFolders] = useState>(new Set());
-
- const toggleFolder = useCallback((folderId: string) => {
- setOpenFolders((prev) => {
- const newSet = new Set(prev);
- if (newSet.has(folderId)) {
- newSet.delete(folderId);
- } else {
- newSet.add(folderId);
- }
- return newSet;
- });
- }, []);
-
- const [showMoveDialog, setShowMoveDialog] = useState(false);
- const [itemToMove, setItemToMove] = useState<
- Playlist | PlaylistFolder | null
- >(null);
- const [availableFolders, setAvailableFolders] = useState<
- { folder: PlaylistFolder; path: string[] }[]
- >([]);
- const [showRenameDialog, setShowRenameDialog] = useState(false);
- const [itemToRename, setItemToRename] = useState<
- Playlist | PlaylistFolder | null
- >(null);
- const [renameValue, setRenameValue] = useState("");
-
- const [showCreateFolderDialog, setShowCreateFolderDialog] = useState(false);
- const [newFolderName, setNewFolderName] = useState("");
-
- const {
- library,
- playSong,
- createPlaylist,
- createFolder,
- removePlaylist,
- moveToFolder,
- exportPlaylist,
- importPlaylist,
- navigateToSongs,
- } = musicPlayerHook;
-
- // Debounced and batched playlist image generation to prevent RAM spikes
- useEffect(() => {
- let isCancelled = false;
-
- const updatePlaylistImages = async () => {
- const newImages: Record = {};
-
- // Recursive function to find all playlists in the tree
- const findAllPlaylists = (
- items: (Playlist | PlaylistFolder)[],
- ): Playlist[] => {
- const result: Playlist[] = [];
- for (const item of items) {
- if ("children" in item) {
- // This is a folder, recurse into children
- result.push(...findAllPlaylists(item.children));
- } else if ("songs" in item) {
- // This is a playlist
- result.push(item);
- }
- }
- return result;
- };
-
- const allPlaylists = findAllPlaylists(library.playlists);
-
- // Process playlist images in batches to prevent RAM spikes
- const BATCH_SIZE = 5;
- const BATCH_DELAY = 50; // ms between batches
-
- for (let i = 0; i < allPlaylists.length; i += BATCH_SIZE) {
- if (isCancelled) return;
-
- const batch = allPlaylists.slice(i, i + BATCH_SIZE);
-
- // Process batch in parallel but limited
- await Promise.all(
- batch.map(async (playlist) => {
- if (playlist.id !== "all-songs") {
- try {
- const image = await generatePlaylistImage(playlist.songs);
- if (image && !isCancelled) {
- newImages[playlist.id] = image;
- }
- } catch (error) {
- console.warn(
- `Failed to generate image for playlist ${playlist.id}:`,
- error,
- );
- }
- }
- }),
- );
-
- // Update state incrementally to show progress and yield to main thread
- if (!isCancelled) {
- setPlaylistImages((prev) => ({ ...prev, ...newImages }));
- }
-
- // Yield to main thread between batches
- if (i + BATCH_SIZE < allPlaylists.length) {
- await new Promise((resolve) => setTimeout(resolve, BATCH_DELAY));
- }
- }
- };
-
- // Delay initial image generation to let the UI render first
- const timeoutId = setTimeout(updatePlaylistImages, 100);
-
- return () => {
- isCancelled = true;
- clearTimeout(timeoutId);
- };
- }, [library.playlists, library.songs]);
-
- const getAllPlaylists = useCallback(
- (items: (Playlist | PlaylistFolder)[]): (Playlist | PlaylistFolder)[] => {
- const result: (Playlist | PlaylistFolder)[] = [];
- for (const item of items) {
- result.push(item);
- if ("children" in item) {
- result.push(...getAllPlaylists(item.children));
- }
- }
- return result;
- },
- [],
- );
-
- const filteredPlaylists = useMemo(
- () =>
- library.playlists.filter(
- (item) =>
- item.id !== "all-songs" &&
- item.name.toLowerCase().includes(playlistSearchQuery.toLowerCase()),
- ),
- [library.playlists, playlistSearchQuery],
- );
-
- const handlePlaylistSearch = (query: string) => setPlaylistSearchQuery(query);
-
- const handlePlaylistSelect = useCallback(
- (playlist: Playlist) => {
- if (playlist.songs.length > 0) playSong(playlist.songs[0], playlist);
- },
- [playSong],
- );
-
- const handleAllSongsClick = useCallback(() => {
- const existingAllSongs = library.playlists.find(
- (p) => p.id === "all-songs",
- );
- if (
- existingAllSongs &&
- "songs" in existingAllSongs &&
- existingAllSongs.songs.length > 0
- ) {
- playSong(existingAllSongs.songs[0], existingAllSongs);
- navigateToSongs();
- } else if (library.songs.length > 0) {
- const allSongsPlaylist: Playlist = {
- id: "all-songs",
- name: t("allSongs"),
- songs: library.songs,
- };
- playSong(allSongsPlaylist.songs[0], allSongsPlaylist);
- navigateToSongs();
- }
- }, [library.playlists, library.songs, playSong, navigateToSongs]);
-
- const handleAddPlaylist = () => {
- setShowCreatePlaylist(true);
- setNewPlaylistName("");
- };
-
- const handleCreatePlaylistConfirm = useCallback(() => {
- if (!newPlaylistName.trim()) return;
-
- createPlaylist(newPlaylistName.trim());
- toast.success(
- t("playlist.playlistCreated", { name: newPlaylistName.trim() }),
- );
-
- setShowCreatePlaylist(false);
- setNewPlaylistName("");
- }, [newPlaylistName, createPlaylist]);
-
- const handleCreatePlaylistCancel = () => {
- setShowCreatePlaylist(false);
- setNewPlaylistName("");
- };
-
- const handleDeletePlaylist = async (playlist: Playlist) => {
- // Check if user has chosen not to show delete confirmation
- const shouldShow = await musicIndexedDbHelper.shouldShowDialog(
- "delete-playlist-confirmation",
- );
- if (!shouldShow) {
- // Delete directly without showing dialog
- removePlaylist(playlist.id);
- toast.success(t("playlist.playlistDeleted", { name: playlist.name }));
- return;
- }
-
- // Show confirmation dialog
- setPlaylistToDelete(playlist);
- setIsDeleteDialogOpen(true);
- };
-
- const handleDeleteConfirm = useCallback(() => {
- if (!playlistToDelete) return;
- removePlaylist(playlistToDelete.id);
- toast.success(
- t("playlist.playlistDeleted", { name: playlistToDelete.name }),
- );
- setIsDeleteDialogOpen(false);
- setPlaylistToDelete(null);
- }, [playlistToDelete, removePlaylist]);
-
- const handleSharePlaylist = useCallback((playlist: Playlist) => {
- // Share just the playlist info, not the URL
- const shareData = {
- title: t("playlist.playlistShareTitle", { name: playlist.name }),
- text: t("playlist.playlistShareText", {
- name: playlist.name,
- count: playlist.songs.length,
- }),
- };
-
- try {
- if (
- navigator.share &&
- navigator.canShare &&
- navigator.canShare(shareData)
- ) {
- navigator.share(shareData);
- toast.success(t("playlist.playlistShared"));
- } else {
- navigator.clipboard.writeText(`${shareData.title}\n${shareData.text}`);
- toast.success(t("playlist.playlistCopied"));
- }
- } catch {
- toast.error(t("playlist.playlistShareFailed"));
- }
- }, []);
-
- const handleExportPlaylist = useCallback(
- (playlist: Playlist, format: "json" | "m3u" = "json") => {
- exportPlaylist(playlist, format);
- },
- [exportPlaylist],
- );
-
- const getPlaylistIcon = useCallback((playlistName: string) => {
- if (playlistName.toLowerCase().includes("favorite")) {
- return ;
- }
- if (playlistName.toLowerCase().includes("made")) {
- return ;
- }
- return ;
- }, []);
-
- const handleImportPlaylist = () => {
- const input = document.createElement("input");
- input.type = "file";
- input.accept = ".json,.m3u,.m3u8";
- input.onchange = async (e) => {
- const file = (e.target as HTMLInputElement).files?.[0];
- if (file) {
- try {
- await importPlaylist(file);
- } catch (error) {
- // Error handling is done in the importPlaylist function
- error && setIsDeleteDialogOpen(false); // Dummy usage to avoid lint error
- }
- }
- };
- input.click();
- };
-
- const handleMoveToFolder = useCallback(
- (item: Playlist | PlaylistFolder) => {
- // Recursive function to get all folders
- const getAllFolders = (
- items: (Playlist | PlaylistFolder)[],
- path: string[] = [],
- ): { folder: PlaylistFolder; path: string[] }[] => {
- const folders: { folder: PlaylistFolder; path: string[] }[] = [];
- for (const item of items) {
- if ("children" in item) {
- folders.push({ folder: item, path: [...path] });
- folders.push(...getAllFolders(item.children, [...path, item.name]));
- }
- }
- return folders;
- };
-
- const allFolders = getAllFolders(library.playlists);
- // Always allow moving even if no folders, can move to root
- setAvailableFolders(allFolders);
- setItemToMove(item);
- setShowMoveDialog(true);
- },
- [library.playlists],
- );
-
- const handleRenameItem = useCallback((item: Playlist | PlaylistFolder) => {
- setItemToRename(item);
- setRenameValue(item.name);
- setShowRenameDialog(true);
- }, []);
-
- const playlistListRef = useRef(null);
-
- const renderPlaylistItem = (item: Playlist | PlaylistFolder, depth = 0) => {
- if ("songs" in item) {
- return ;
- } else {
- return (
-
- );
- }
- };
-
- const PlaylistItem = memo(
- ({ item, depth }: { item: Playlist; depth: number }) => {
- const { open, setOpen, containerRef } = useRightClickMenu(true);
-
- return (
-
-
-
-
- handlePlaylistSelect(item)}
- >
- {playlistImages[item.id] ? (
-
-
-
- ) : (
- getPlaylistIcon(item.name)
- )}
-
-
-
- {item.songs.length}
-
-
-
-
-
-
-
-
-
-
-
-
- handleRenameItem(item)}>
-
- {t("playlist.renamePlaylist")}
-
- handleSharePlaylist(item)}>
-
- {t("playlist.sharePlaylist")}
-
-
- handleMoveToFolder(item)}>
-
- {t("playlist.moveToFolder")}
-
- {
- moveToFolder(item.id, null); // Move to root
- toast.success(t("playlist.movedToRoot", { item: item.name }));
- }}
- >
-
- {t("playlist.moveToRoot")}
-
-
- handleExportPlaylist(item, "json")}
- >
-
- {t("playlist.exportJSON")}
-
- handleExportPlaylist(item, "m3u")}
- >
-
- {t("playlist.exportM3U")}
-
-
- handleDeletePlaylist(item)}
- className={styles.deleteMenuItem}
- >
-
- {t("playlist.deletePlaylist")}
-
-
-
-
- );
- },
- );
-
- const FolderItem = memo(
- ({
- item,
- depth,
- renderPlaylistItem,
- }: {
- item: PlaylistFolder;
- depth: number;
- renderPlaylistItem: (
- item: Playlist | PlaylistFolder,
- depth: number,
- ) => JSX.Element;
- }) => {
- const isOpen = openFolders.has(item.id);
- const { open, setOpen, containerRef } = useRightClickMenu(true);
-
- return (
- toggleFolder(item.id)}
- >
-
- {/* Folder header */}
-
-
-
-
-
-
-
-
-
-
-
- {item.children.length}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- handleRenameItem(item)}>
-
- {t("playlist.renameFolder")}
-
-
- handleMoveToFolder(item)}>
-
- {t("playlist.moveToFolder")}
-
- {
- moveToFolder(item.id, null); // Move to root
- toast.success(
- t("playlist.movedToRoot", { item: item.name }),
- );
- }}
- >
-
- {t("playlist.moveToRoot")}
-
-
- {
- // Check if user has chosen not to show delete confirmation
- const shouldShow =
- await musicIndexedDbHelper.shouldShowDialog(
- "delete-playlist-confirmation",
- );
- if (!shouldShow) {
- // Delete directly without showing dialog
- removePlaylist(item.id);
- toast.success(
- t("playlist.folderDeleted", { name: item.name }),
- );
- return;
- }
-
- // Show confirmation dialog
- setPlaylistToDelete(item);
- setIsDeleteDialogOpen(true);
- }}
- className={styles.deleteMenuItem}
- >
-
- {t("playlist.deleteFolder")}
-
-
-
-
-
-
- {item.children.map((child) =>
- renderPlaylistItem(child, depth + 1),
- )}
- {/* Empty folder, centered with i18n */}
- {item.children.length === 0 && (
-
- {t("playlist.emptyFolder")}
-
- )}
-
-
-
- );
- },
- );
-
- return (
-
-
-
-
-
-
-
handlePlaylistSearch(e.target.value)}
- />
-
-
-
-
-
-
-
-
-
-
- {t("playlist.addPlaylist")}
-
- setShowCreateFolderDialog(true)}>
-
- {t("playlist.addFolder")}
-
-
-
-
- {t("playlist.importPlaylist")}
-
-
-
-
-
-
- {/* All Songs */}
-
-
- {t("allSongs")}
- {library.songs.length}
-
-
- {/* Favorites */}
-
- handlePlaylistSelect({
- id: "favorites",
- name: t("favorites.favorites"),
- songs: library.songs.filter((s) =>
- library.favorites.includes(s.id),
- ),
- })
- }
- >
-
- {t("favorites.favorites")}
- {library.favorites.length}
-
-
- {/* User playlists and folders */}
- {filteredPlaylists.map((item) => renderPlaylistItem(item))}
-
- {filteredPlaylists.length === 0 && playlistSearchQuery && (
-
{t("noPlaylistsFound")}
- )}
-
-
- {/* Create Playlist Modal */}
-
-
-
- {t("playlist.createPlaylist")}
-
- {t("playlist.enterPlaylistName")}
-
-
-
- setNewPlaylistName(e.target.value)}
- onKeyDown={(e: any) => {
- if (e.key === "Enter") handleCreatePlaylistConfirm();
- }}
- autoFocus
- />
-
-
-
- {t("common.cancel")}
-
-
- {t("common.create")}
-
-
-
-
-
- {/* Move to Folder Dialog */}
-
-
-
- {t("playlist.moveToFolder")}
-
- {t("playlist.selectFolderToMove", { item: itemToMove?.name })}
-
-
-
- {/* Move to Root option */}
- {
- if (itemToMove) {
- moveToFolder(itemToMove.id, null);
- toast.success(
- t("playlist.movedToRoot", { item: itemToMove?.name }),
- );
- }
- setShowMoveDialog(false);
- setItemToMove(null);
- }}
- >
- 📁 {t("playlist.moveToRoot")}
-
- {availableFolders.map(({ folder, path }) => (
- {
- if (itemToMove) moveToFolder(itemToMove.id, folder.id);
- toast.success(
- t("playlist.movedToFolder", {
- item: itemToMove?.name,
- folder: folder.name,
- }),
- );
- setShowMoveDialog(false);
- setItemToMove(null);
- }}
- >
- {path.length > 0
- ? `${path.join(" / ")} / ${folder.name}`
- : folder.name}
-
- ))}
-
-
- setShowMoveDialog(false)}>
- {t("common.cancel")}
-
-
-
-
-
- {/* Rename Dialog */}
-
-
-
-
- {itemToRename && "songs" in itemToRename
- ? t("playlist.renamePlaylist")
- : t("playlist.renameFolder")}
-
- {t("playlist.enterNewName")}
-
-
- setRenameValue(e.target.value)}
- />
-
-
- setShowRenameDialog(false)}
- >
- {t("common.cancel")}
-
- {
- if (itemToRename && renameValue.trim()) {
- itemToRename.name = renameValue.trim();
- toast.success(
- itemToRename && "songs" in itemToRename
- ? t("playlist.playlistRenamed", {
- name: renameValue.trim(),
- })
- : t("playlist.folderRenamed", {
- name: renameValue.trim(),
- }),
- );
- setShowRenameDialog(false);
- setItemToRename(null);
- setRenameValue("");
- }
- }}
- >
- {t("common.save")}
-
-
-
-
-
- {/* Delete Confirmation */}
-
-
-
-
- {playlistToDelete && "songs" in playlistToDelete
- ? t("playlist.deletePlaylist")
- : t("playlist.deleteFolder")}
-
-
- {playlistToDelete
- ? "songs" in playlistToDelete
- ? t("playlist.deletePlaylistConfirmation", {
- name: playlistToDelete.name,
- })
- : t("playlist.deleteFolderConfirmation", {
- name: playlistToDelete.name,
- })
- : ""}
-
-
-
- setIsDeleteDialogOpen(false)}
- >
- {t("common.cancel")}
-
-
- {t("common.delete")}
-
-
-
-
-
- {/* Create Folder Dialog */}
-
-
-
- {t("playlist.createFolder")}
-
- {t("playlist.enterFolderName")}
-
-
-
- setNewFolderName(e.target.value)}
- />
-
-
- {
- setShowCreateFolderDialog(false);
- setNewFolderName("");
- }}
- >
- {t("common.cancel")}
-
- {
- if (newFolderName.trim()) {
- createFolder(newFolderName.trim());
- toast.success(
- t("playlist.folderCreated", { name: newFolderName.trim() }),
- );
- setShowCreateFolderDialog(false);
- setNewFolderName("");
- }
- }}
- >
- {t("common.create")}
-
-
-
-
-
- );
-};
-
-export default memo(PlaylistComponent, (prevProps, nextProps) => {
- // Only re-render if the library playlists or songs have actually changed
- return (
- prevProps.musicPlayerHook.library.playlists ===
- nextProps.musicPlayerHook.library.playlists &&
- prevProps.musicPlayerHook.library.songs ===
- nextProps.musicPlayerHook.library.songs &&
- prevProps.musicPlayerHook.library.favorites ===
- nextProps.musicPlayerHook.library.favorites
- );
-});
diff --git a/Build/src/components/ScrollText.module.css b/Build/src/components/ScrollText.module.css
deleted file mode 100644
index 7b9ee91..0000000
--- a/Build/src/components/ScrollText.module.css
+++ /dev/null
@@ -1,36 +0,0 @@
-.wrapper {
- position: relative;
- overflow: hidden;
- width: 100%;
- min-width: 0;
-}
-
-.inner {
- display: inline-flex;
- align-items: center;
- white-space: nowrap;
- transform: translateX(0);
- will-change: transform;
-}
-
-.scrolling {
- animation: scrollText var(--scroll-duration, 15s) linear infinite;
-}
-
-.pauseOnHover:hover .scrolling {
- animation-play-state: paused;
-}
-
-.text {
- display: inline-block;
- white-space: nowrap;
-}
-
-@keyframes scrollText {
- 0% {
- transform: translateX(0);
- }
- 100% {
- transform: translateX(calc(-1 * var(--scroll-distance, 0px)));
- }
-}
diff --git a/Build/src/components/ScrollText.tsx b/Build/src/components/ScrollText.tsx
deleted file mode 100644
index 9bf1efc..0000000
--- a/Build/src/components/ScrollText.tsx
+++ /dev/null
@@ -1,232 +0,0 @@
-import {
- useMemo,
- useRef,
- useState,
- useCallback,
- useLayoutEffect,
- useEffect,
- type CSSProperties,
- type HTMLAttributes,
-} from "react";
-import DOMPurify from "dompurify";
-import { useTranslation } from "react-i18next";
-import styles from "./ScrollText.module.css";
-
-interface ScrollTextProps extends HTMLAttributes {
- text: string;
- textClassName?: string;
- textStyle?: CSSProperties;
- speed?: number;
- gap?: number;
- minDuration?: number;
- pauseOnHover?: boolean;
- allowHTML?: boolean;
- containerClassName?: string;
- wrapperStyle?: CSSProperties;
-}
-
-export const ScrollText = ({
- text,
- className,
- textClassName,
- textStyle,
- speed = 30,
- gap = 24,
- minDuration = 10,
- pauseOnHover = true,
- allowHTML = true,
- containerClassName,
- wrapperStyle,
- ...rest
-}: ScrollTextProps) => {
- const { t } = useTranslation();
- const wrapperRef = useRef(null);
- const innerRef = useRef(null);
- const resizeObserverRef = useRef(null);
- const rafRef = useRef(null);
-
- // Combined state for better performance
- const [scrollState, setScrollState] = useState({
- shouldScroll: false,
- distance: 0,
- duration: minDuration,
- });
-
- const safeText = useMemo(
- () => (allowHTML ? DOMPurify.sanitize(text) : text),
- [text, allowHTML],
- );
-
- // Memoize the span props to avoid recreating on every render
- const spanProps = useMemo(() => {
- const baseProps = {
- className: styles.text,
- style: scrollState.shouldScroll ? { marginRight: `${gap}px` } : undefined,
- };
-
- return allowHTML
- ? { ...baseProps, dangerouslySetInnerHTML: { __html: safeText } }
- : { ...baseProps, children: text };
- }, [allowHTML, safeText, text, gap, scrollState.shouldScroll]);
-
- // Optimized measure function with debouncing
- const measure = useCallback(() => {
- const wrapper = wrapperRef.current;
- const inner = innerRef.current;
- if (!wrapper || !inner) return;
-
- const base = inner.querySelector(
- "[data-scroll-text='primary']",
- ) as HTMLElement | null;
- if (!base) return;
-
- const contentWidth = base.scrollWidth;
- const wrapperWidth = wrapper.clientWidth;
-
- if (wrapperWidth <= 0) {
- if (typeof window !== "undefined") {
- if (rafRef.current) window.cancelAnimationFrame(rafRef.current);
- rafRef.current = window.requestAnimationFrame(() => {
- rafRef.current = null;
- measure();
- });
- }
- return;
- }
-
- const overflow = contentWidth - wrapperWidth;
- const startThreshold = 14;
- const stopThreshold = 6;
-
- setScrollState((prev) => {
- const shouldScroll = prev.shouldScroll
- ? overflow > stopThreshold
- : overflow > startThreshold;
-
- if (shouldScroll) {
- const loopDistance = contentWidth + gap;
- const derivedDuration = Math.max(minDuration, loopDistance / speed);
-
- if (
- prev.shouldScroll &&
- Math.abs(prev.distance - loopDistance) < 1 &&
- Math.abs(prev.duration - derivedDuration) < 0.1
- ) {
- return prev;
- }
-
- return {
- shouldScroll: true,
- distance: loopDistance,
- duration: derivedDuration,
- };
- }
-
- if (!prev.shouldScroll && Math.abs(prev.distance - contentWidth) < 1) {
- return prev;
- }
-
- return {
- shouldScroll: false,
- distance: contentWidth,
- duration: minDuration,
- };
- });
- }, [gap, minDuration, speed]);
-
- // Initialize resize observer once
- useEffect(() => {
- if (typeof ResizeObserver === "undefined") return;
-
- resizeObserverRef.current = new ResizeObserver(() => measure());
-
- return () => {
- resizeObserverRef.current?.disconnect();
- };
- }, [measure]);
-
- // Observe both elements with the same observer
- useLayoutEffect(() => {
- if (!resizeObserverRef.current) return;
-
- const wrapper = wrapperRef.current;
- const inner = innerRef.current;
-
- if (wrapper) resizeObserverRef.current.observe(wrapper);
- if (inner) resizeObserverRef.current.observe(inner);
- measure();
-
- return () => {
- if (wrapper) resizeObserverRef.current?.unobserve(wrapper);
- if (inner) resizeObserverRef.current?.unobserve(inner);
- };
- }, [measure, safeText]);
-
- useEffect(() => {
- return () => {
- if (rafRef.current && typeof window !== "undefined") {
- window.cancelAnimationFrame(rafRef.current);
- }
- };
- }, []);
-
- // Memoize class names to avoid recalculating on every render
- const wrapperClasses = useMemo(
- () =>
- [
- styles.wrapper,
- pauseOnHover && scrollState.shouldScroll ? styles.pauseOnHover : "",
- className,
- containerClassName,
- ]
- .filter(Boolean)
- .join(" "),
- [className, containerClassName, pauseOnHover, scrollState.shouldScroll],
- );
-
- const innerClasses = useMemo(
- () =>
- [
- styles.inner,
- textClassName,
- scrollState.shouldScroll ? styles.scrolling : "",
- ]
- .filter(Boolean)
- .join(" "),
- [textClassName, scrollState.shouldScroll],
- );
-
- // Memoize combined text style
- const combinedTextStyle = useMemo(
- () =>
- ({
- ...(scrollState.shouldScroll
- ? {
- "--scroll-distance": `${scrollState.distance}px`,
- "--scroll-duration": `${scrollState.duration}s`,
- "--scroll-gap": `${gap}px`,
- }
- : {}),
- ...textStyle,
- }) as CSSProperties,
- [scrollState, gap, textStyle],
- );
-
- return (
-
-
-
- {scrollState.shouldScroll && (
-
- )}
-
-
- );
-};
diff --git a/Build/src/components/Settings.tsx b/Build/src/components/Settings.tsx
deleted file mode 100644
index 46c8578..0000000
--- a/Build/src/components/Settings.tsx
+++ /dev/null
@@ -1,1107 +0,0 @@
-import {
- Sheet,
- SheetContent,
- SheetDescription,
- SheetFooter,
- SheetHeader,
- SheetTitle,
-} from "./Sheet";
-import { Button } from "./Button";
-import { Switch } from "./Switch";
-import { Slider } from "./Slider";
-import { Input } from "./Input";
-import {
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "./Select";
-import { ThemeModeSwitch } from "./ThemeModeSwitch";
-import { ShortcutConfig } from "./ShortcutConfig";
-import styles from "./Settings.module.css";
-import { useThemeLoader } from "../helpers/themeLoader";
-import { useIconRegistry } from "../helpers/iconLoader";
-import { useWallpaperLoader } from "../helpers/wallpaperLoader";
-import { toast } from "sonner";
-import { useRef, useState, useEffect, JSX } from "react";
-import { useTranslation } from "react-i18next";
-import { languageNames } from "../types/supportedLanguages";
-import { isSafari } from "../helpers/safariHelper";
-import { Icon } from "./Icon";
-import { isTauri } from "@tauri-apps/api/core";
-
-import { resetAllDialogPreferences } from "../helpers/musicIndexedDbHelper";
-import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogTitle,
-} from "./Dialog";
-
-export interface SettingsProps {
- className?: string;
- open?: boolean;
- onOpenChange?: (open: boolean) => void;
- settings: PlayerSettings;
- onSettingsChange: (settings: Partial) => void;
- onShortcutsChanged?: () => void;
-}
-
-type SettingsCategory = "playback" | "interface" | "shortcuts" | "experimental";
-
-export const Settings = ({
- className,
- open,
- onOpenChange,
- settings,
- onSettingsChange,
- onShortcutsChanged,
-}: SettingsProps) => {
- const { t, i18n } = useTranslation();
-
- // State for dialog reset button
- const [dialogResetOpen, setDialogResetOpen] = useState(false);
- const [dialogResetLoading, setDialogResetLoading] = useState(false);
- const [activeCategory, setActiveCategory] =
- useState("playback");
-
- const handleDialogResetClose = () => setDialogResetOpen(false);
-
- // Use the persisted crossfadeBeforeGapless value, fallback to current crossfade
- const previousCrossfadeRef = useRef(
- settings.crossfadeBeforeGapless ?? settings.crossfade,
- );
-
- const { themes, currentTheme, setTheme } = useThemeLoader();
- const { iconSets, currentSet, setIconSet } = useIconRegistry();
- const { wallpapers, setWallpaper } = useWallpaperLoader();
-
- // Check if running on Safari
- const isOnSafari = isSafari();
-
- // Initialize Eruda if it was previously enabled
- useEffect(() => {
- if (settings.erudaEnabled && !(window as any).eruda) {
- loadEruda().catch(console.error);
- }
- }, [settings.erudaEnabled]);
-
- const handleResetSettings = async () => {
- const defaultThemeName = "Blue";
- try {
- await setTheme(defaultThemeName);
- onSettingsChange({
- volume: 0.75,
- crossfade: 3,
- crossfadeBeforeGapless: undefined,
- defaultShuffle: false,
- defaultRepeat: "off",
- autoPlayNext: true,
- compactMode: false,
- showAlbumArt: true,
- showLyrics: false,
- sessionRestore: true,
- gaplessPlayback: false,
- smartShuffle: true,
- colorTheme: defaultThemeName,
- wallpaper: "None",
- language: "English",
- tempo: 1,
- pitch: 0,
- discordEnabled: false,
- discordUserId: undefined,
- erudaEnabled: false,
- });
- } catch {
- toast.error(t("settings.resetError"));
- }
- };
-
- const handleVolumeChange = (newVolume: number[]) => {
- onSettingsChange({ volume: newVolume[0] / 100 });
- };
-
- const handleCrossfadeChange = (newCrossfade: number[]) => {
- // Prevent crossfade changes when gapless playback is enabled
- if (settings.gaplessPlayback) {
- return;
- }
- const newValue = newCrossfade[0];
- previousCrossfadeRef.current = newValue; // Update stored value
- onSettingsChange({
- crossfade: newValue,
- crossfadeBeforeGapless: undefined, // Clear stored value when manually changed
- });
- };
-
- // Get supported languages dynamically from i18next config
- let languages: string[] = [];
-
- // Only use filter if supportedLngs is an array
- if (Array.isArray(i18n.options.supportedLngs)) {
- languages = i18n.options.supportedLngs.filter((l) => l !== "cimode");
- }
-
- const handleLanguageChange = (lang: string) => {
- i18n.changeLanguage(lang);
- toast.success(
- t("settings.interface.languageSet", {
- language: languageNames[lang] || lang,
- }),
- );
- };
-
- const handleClearCache = async () => {
- try {
- // Clear all cache storage (service worker caches)
- if ("caches" in window) {
- const cacheNames = await caches.keys();
- await Promise.all(
- cacheNames.map((cacheName) => caches.delete(cacheName)),
- );
- }
-
- // Clear i18n resource cache
- if (i18n.services.resourceStore) {
- Object.keys(i18n.services.resourceStore.data).forEach((lang) => {
- i18n.services.resourceStore.data[lang] = {};
- });
- }
-
- // Reload i18n resources
- await i18n.reloadResources();
-
- toast.success(t("settings.cacheClearedSuccess"));
- } catch (error) {
- console.error("Failed to clear cache:", error);
- toast.error(t("settings.cacheClearedError"));
- }
- };
-
- const [discordRpcStatus, setDiscordRpcStatus] = useState<
- "unknown" | "available" | "unavailable" | "unsupported"
- >("unknown");
-
- const isTauriEnv = isTauri();
-
- const checkDiscordRpcStatus = async () => {
- if (!isTauriEnv) {
- setDiscordRpcStatus("unsupported");
- return;
- }
-
- try {
- const { invoke } = await import("@tauri-apps/api/core");
- const available = await invoke("is_discord_running");
- setDiscordRpcStatus(available ? "available" : "unavailable");
- } catch (error) {
- console.error("Failed to check Discord RPC status:", error);
- setDiscordRpcStatus("unavailable");
- }
- };
-
- useEffect(() => {
- if (settings.discordEnabled) {
- checkDiscordRpcStatus();
- } else {
- setDiscordRpcStatus("unknown");
- }
- }, [settings.discordEnabled]);
-
- // Dynamic Eruda loading/unloading functions
- const loadEruda = () => {
- return new Promise((resolve, reject) => {
- if ((window as any).eruda) {
- // Already loaded
- (window as any).eruda.init();
- resolve();
- return;
- }
-
- const script = document.createElement("script");
- script.src = "https://cdn.jsdelivr.net/npm/eruda";
- script.integrity =
- "sha384-F7xQBvh3l6dG/mMD6QPIeVmXtzWT4Ce3ZDu8ysPuzMWMx9bFOIMGnRPUhLuQipss";
- script.crossOrigin = "anonymous";
- script.onload = () => {
- try {
- (window as any).eruda.init();
- resolve();
- } catch (error) {
- reject(error);
- }
- };
- script.onerror = reject;
- document.head.appendChild(script);
- });
- };
-
- const unloadEruda = () => {
- if ((window as any).eruda) {
- try {
- (window as any).eruda.destroy();
- // Remove the script element
- const erudaScript = document.querySelector('script[src*="eruda"]');
- if (erudaScript) {
- erudaScript.remove();
- }
- // Clean up global reference
- delete (window as any).eruda;
- } catch (error) {
- console.warn("Failed to unload Eruda:", error);
- }
- }
- };
-
- // TODO: i18n-ize
- const handleErudaToggle = async (enabled: boolean) => {
- try {
- if (enabled) {
- await loadEruda();
- toast.success("Eruda debug console enabled");
- } else {
- unloadEruda();
- toast.success("Eruda debug console disabled");
- }
- onSettingsChange({ erudaEnabled: enabled });
- } catch (error) {
- console.error("Failed to toggle Eruda:", error);
- toast.error("Failed to toggle Eruda debug console");
- }
- };
-
- const audioSection = (
-
-
-
-
{t("settings.audio.title")}
-
-
-
-
- {t("settings.playback.tempo")}
-
- {Math.round(settings.tempo * 100)}%
-
-
-
{
- let newVal = val[0];
-
- if (Math.abs(newVal - 100) <= 3) {
- newVal = 100;
- }
-
- onSettingsChange({ tempo: newVal / 100 });
- }}
- min={50}
- max={150}
- step={1}
- className={styles.slider}
- />
-
-
-
-
- {t("settings.playback.pitch")}
-
- {(settings.pitch ?? 0) === 0
- ? "0"
- : (settings.pitch ?? 0) > 0
- ? `+${settings.pitch ?? 0}`
- : (settings.pitch ?? 0)}
-
-
-
{
- let newVal = val[0];
-
- if (Math.abs(newVal) <= 0.5) {
- newVal = 0;
- }
-
- onSettingsChange({ pitch: newVal });
- }}
- min={-48}
- max={48}
- step={1}
- className={styles.slider}
- />
-
-
-
-
- {t("player.volume")}
-
- {Math.round(settings.volume * 100)}%
-
-
-
-
-
- {!isOnSafari && (
-
-
-
- {t("settings.audio.crossfade")}
- {settings.gaplessPlayback && (
-
- {" "}
- ({t("settings.audio.crossfadeDisabled")})
-
- )}
-
-
- {settings.gaplessPlayback ? "0s" : `${settings.crossfade}s`}
-
-
-
-
- )}
-
- {!isOnSafari && (
-
-
-
- {t("settings.playback.gapless")}
-
-
- {t("settings.playback.gaplessDesc")}
-
-
-
{
- if (val) {
- const currentCrossfade = settings.crossfade;
- previousCrossfadeRef.current = currentCrossfade;
- onSettingsChange({
- gaplessPlayback: val,
- crossfade: 0,
- crossfadeBeforeGapless: currentCrossfade,
- });
- } else {
- const restoreValue =
- settings.crossfadeBeforeGapless ??
- previousCrossfadeRef.current;
- onSettingsChange({
- gaplessPlayback: val,
- crossfade: restoreValue,
- crossfadeBeforeGapless: undefined,
- });
- }
- }}
- />
-
- )}
-
- );
-
- const playbackSection = (
-
-
-
-
{t("settings.playback.title")}
-
-
-
-
-
- {t("settings.playback.shuffle")}
-
-
- {t("settings.playback.shuffleDesc")}
-
-
-
onSettingsChange({ defaultShuffle: val })}
- />
-
-
-
-
-
- {t("settings.playback.smartShuffle")}
-
-
- {t("settings.playback.smartShuffleDesc")}
-
-
-
onSettingsChange({ smartShuffle: val })}
- />
-
-
-
-
-
- {t("settings.playback.repeat")}
-
-
-
- onSettingsChange({
- defaultRepeat: val as PlayerSettings["defaultRepeat"],
- })
- }
- >
-
-
-
-
- {t("player.repeatOff")}
- {t("player.repeatTrack")}
- {t("player.repeatAll")}
-
-
-
-
-
-
-
- {t("settings.playback.autoPlay")}
-
-
- {t("settings.playback.autoPlayDesc")}
-
-
-
onSettingsChange({ autoPlayNext: val })}
- />
-
-
-
-
-
- {t("settings.playback.sessionRestore")}
-
-
- {t("settings.playback.sessionRestoreDesc")}
-
-
-
onSettingsChange({ sessionRestore: val })}
- />
-
-
- );
-
- const interfaceSection = (
-
-
-
-
{t("settings.interface.title")}
-
-
-
-
-
- {t("settings.interface.colorTheme")}
-
-
-
{
- try {
- await setTheme(val);
- onSettingsChange({ colorTheme: val });
- } catch {
- toast.error(t("settings.themeError"));
- }
- }}
- >
-
-
-
-
- {themes.map((theme) => (
-
- {theme.name}
-
- ))}
-
-
-
-
-
-
-
{t("settings.interface.iconSet")}
-
- {t("settings.interface.iconSetDesc")}
-
-
-
{
- try {
- setIconSet(val);
- toast.success(t("settings.interface.iconSetChanged"));
- } catch {
- toast.error(t("settings.interface.iconSetError"));
- }
- }}
- >
-
-
-
-
- {iconSets.map((iconSet) => (
-
- {iconSet.label}
-
- ))}
-
-
-
-
-
-
-
{t("settings.interface.wallpaper")}
-
- {t("settings.interface.wallpaperDesc")}
-
-
-
{
- try {
- if (val === "None") {
- await setWallpaper(val);
- onSettingsChange({ wallpaper: "None" });
- } else {
- await setWallpaper(val);
- onSettingsChange({ wallpaper: val });
- }
- } catch {
- toast.error(t("settings.interface.wallpaperError"));
- }
- }}
- >
-
-
-
-
-
- {t("settings.interface.wallpaperNone", "None")}
-
- {wallpapers?.map((wallpaper) => (
-
- {wallpaper.name}
-
- ))}
-
-
-
-
-
-
-
{t("settings.interface.themeMode")}
-
- {t("settings.interface.themeModeDesc")}
-
-
-
- onSettingsChange({
- themeMode: val as PlayerSettings["themeMode"],
- })
- }
- />
-
-
-
-
-
- {t("settings.interface.compact")}
-
-
- {t("settings.interface.compactDesc")}
-
-
-
onSettingsChange({ compactMode: val })}
- />
-
-
-
-
-
- {t("settings.interface.albumArt")}
-
-
- {t("settings.interface.albumArtDesc")}
-
-
-
onSettingsChange({ showAlbumArt: val })}
- />
-
-
-
-
-
{t("settings.interface.lyrics")}
-
- {t("settings.interface.lyricsDesc")}
-
-
-
onSettingsChange({ showLyrics: val })}
- />
-
-
-
-
-
- {t("settings.interface.language")}
-
-
- {t("settings.interface.languageDescription")}
-
-
-
-
-
- {languageNames[i18n.language] || i18n.language.toUpperCase()}
-
-
-
- {languages.map((lang) => (
-
- {languageNames[lang] || lang.toUpperCase()}
-
- ))}
-
-
-
-
-
-
-
{t("settings.interface.clearCache")}
-
- {t("settings.interface.clearCacheDesc")}
-
-
-
-
- {t("settings.interface.clearCacheButton")}
-
-
-
-
-
{t("settings.resetDialogs")}
-
- {t("settings.resetDialogsDescription")}
-
-
-
setDialogResetOpen(true)}
- >
-
- {t("settings.resetDialogsButton")}
-
-
-
-
- {t("settings.resetDialogsTitle")}
-
- {t("settings.resetDialogsDescription")}
-
-
-
-
- {t("common.cancel")}
-
- {
- setDialogResetLoading(true);
- try {
- await resetAllDialogPreferences();
- toast.success(t("settings.resetDialogsSuccess"));
- setDialogResetOpen(false);
- } catch (e: any) {
- toast.error(e?.message || t("settings.resetError"));
- } finally {
- setDialogResetLoading(false);
- }
- }}
- disabled={dialogResetLoading}
- variant="destructive"
- >
- {dialogResetLoading ? t("common.loading") : t("common.reset")}
-
-
-
-
-
-
- );
-
- const shortcutsSection = (
-
-
-
-
{t("settings.shortcuts.title")}
-
-
-
-
-
{t("settings.shortcuts.enabled")}
-
- {t("settings.shortcuts.enabledDesc")}
-
-
-
{}}
- />
-
-
-
-
- );
-
- const experimentalSection = (
-
-
-
-
Beta
-
-
-
-
-
- Enable Discord Integration (Broken Beta)
-
-
- Note: Discord's RPC API requires special approval. Currently
- logs track info for testing.
-
-
-
onSettingsChange({ discordEnabled: val })}
- />
-
-
- {settings.discordEnabled && (
- <>
-
-
-
{t("discord.connection")}
-
- {settings.discordUserId
- ? t("discord.connected", {
- userId: settings.discordUserId,
- })
- : t("discord.notConnected")}
-
-
-
{
- if (settings.discordUserId) {
- onSettingsChange({ discordUserId: undefined });
- toast.success(t("discord.disconnected"));
- } else {
- const discordOAuthUrl =
- "https://discord.com/oauth2/authorize?client_id=1419480226970341476&response_type=code&redirect_uri=https%3A%2F%2Fhtmlplayer-backend.onrender.com%2Foauth%2Fcallback&scope=identify";
- window.open(discordOAuthUrl, "_blank");
- toast.info(t("discord.completeAuth"));
- }
- }}
- >
- {settings.discordUserId
- ? t("discord.disconnect")
- : t("discord.connect")}
-
-
-
- {!settings.discordUserId && (
-
-
-
- {t("discord.manualUserId")}
-
-
- {t("discord.manualUserIdDescription")}
-
-
-
- {
- if (e.key === "Enter") {
- const input = e.target as HTMLInputElement;
- if (input.value.trim()) {
- onSettingsChange({
- discordUserId: input.value.trim(),
- });
- toast.success(t("discord.userIdSaved"));
- input.value = "";
- }
- }
- }}
- />
- {
- const input = (e.target as HTMLElement)
- .previousElementSibling as HTMLInputElement;
- if (input && input.value.trim()) {
- onSettingsChange({
- discordUserId: input.value.trim(),
- });
- toast.success(t("discord.userIdSaved"));
- input.value = "";
- }
- }}
- >
- {t("common.save")}
-
-
-
- )}
-
-
-
-
{t("discord.status")}
-
- {discordRpcStatus === "unknown" && t("discord.statusUnknown")}
- {discordRpcStatus === "unsupported" &&
- t("discord.statusUnsupported")}
- {discordRpcStatus === "available" &&
- t("discord.statusAvailable")}
- {discordRpcStatus === "unavailable" &&
- t("discord.statusUnavailable")}
-
-
-
- {t("discord.refreshStatus")}
-
-
- >
- )}
-
-
-
-
Enable Eruda Debug Console
-
- Eruda is a debug console for mobile browsers. Takes effect
- immediately.
-
-
-
-
-
- );
-
- const categoryPanels: Record = {
- playback: (
- <>
- {audioSection}
- {playbackSection}
- >
- ),
- interface: interfaceSection,
- shortcuts: shortcutsSection,
- experimental: experimentalSection,
- };
-
- const categoryList: Array<{
- id: SettingsCategory;
- label: string;
- description: string;
- icon: string;
- }> = [
- {
- id: "playback",
- label: t("settings.category.playback", "Playback"),
- description: t(
- "settings.category.playbackDescription",
- "Audio and playback behavior",
- ),
- icon: "music",
- },
- {
- id: "interface",
- label: t("settings.category.interface", "Interface"),
- description: t(
- "settings.category.interfaceDescription",
- "Themes, language, and appearance",
- ),
- icon: "palette",
- },
- {
- id: "shortcuts",
- label: t("settings.category.shortcuts", "Shortcuts"),
- description: t(
- "settings.category.shortcutsDescription",
- "Keyboard shortcut preferences",
- ),
- icon: "keyboard",
- },
- {
- id: "experimental",
- label: t("settings.category.experimental", "Beta"),
- description: t(
- "settings.category.experimentalDescription",
- "Early and experimental features",
- ),
- icon: "messageCircle",
- },
- ];
-
- return (
-
-
-
-
- {t("settings.title")}
- {t("settings.description")}
-
-
-
-
-
-
- {categoryList.map((category) => {
- const isActive = activeCategory === category.id;
- return (
- setActiveCategory(category.id)}
- aria-current={isActive ? "page" : undefined}
- >
-
-
-
- {category.label}
-
-
- {category.description}
-
-
-
- );
- })}
-
-
-
- {categoryPanels[activeCategory]}
-
-
-
-
-
-
-
- {t("settings.reset")}
-
-
-
-
-
- );
-};
diff --git a/Build/src/components/Sidebar.tsx b/Build/src/components/Sidebar.tsx
deleted file mode 100644
index a71f20f..0000000
--- a/Build/src/components/Sidebar.tsx
+++ /dev/null
@@ -1,286 +0,0 @@
-import { useState, memo, useEffect, useLayoutEffect } from "react";
-import { useTranslation } from "react-i18next";
-import { Button } from "./Button";
-import { Separator } from "./Separator";
-import { Settings as SettingsComponent } from "./Settings";
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
- DialogDescription,
- DialogFooter,
-} from "./Dialog";
-import { PlaylistComponent } from "./Playlist";
-import styles from "./Sidebar.module.css";
-import { Icon } from "./Icon";
-import { HelpGuideButton } from "./HelpGuide";
-
-interface SidebarProps {
- musicPlayerHook: ReturnType<
- typeof import("../hooks/musicPlayerHook").useMusicPlayer
- >;
- onCollapseChange?: (isCollapsed: boolean) => void;
- onShortcutsChanged?: () => void;
- settingsOpen?: boolean;
- onSettingsOpenChange?: (open: boolean) => void;
- isMobileOpen?: boolean;
- onMobileOpenChange?: (open: boolean) => void;
-}
-
-const COLLAPSED_WIDTH = "40px";
-const EXPANDED_WIDTH = "250px";
-
-export const Sidebar = memo(
- ({
- musicPlayerHook,
- onCollapseChange,
- onShortcutsChanged,
- settingsOpen,
- onSettingsOpenChange,
- isMobileOpen,
- onMobileOpenChange,
- }: SidebarProps) => {
- const { t } = useTranslation();
-
- const [showAbout, setShowAbout] = useState(false);
- const [isCollapsed, setIsCollapsed] = useState(false);
- const [isMobile, setIsMobile] = useState(false);
-
- const { settings, updateSettings } = musicPlayerHook;
-
- // Detect mobile viewport
- useEffect(() => {
- const checkMobile = () => {
- setIsMobile(window.innerWidth <= 768);
- };
-
- checkMobile();
- window.addEventListener("resize", checkMobile);
-
- return () => window.removeEventListener("resize", checkMobile);
- }, []);
-
- // Update CSS custom property when collapsed state changes
- useLayoutEffect(() => {
- document.documentElement.style.setProperty(
- "--sidebar-width",
- isCollapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH,
- );
- }, [isCollapsed]);
-
- // Use external settings state if provided, otherwise use internal state
- const isSettingsOpen = settingsOpen !== undefined ? settingsOpen : false;
- const setSettingsOpen = onSettingsOpenChange || (() => {});
-
- const handleAbout = () => {
- setShowAbout(true);
- };
-
- const handleSettings = () => {
- setSettingsOpen(!isSettingsOpen);
- };
-
- const handleMenuClick = () => {
- if (isMobile) {
- // On mobile, close the sidebar overlay
- onMobileOpenChange?.(false);
- } else {
- // On desktop, toggle collapse
- const newCollapsedState = !isCollapsed;
- setIsCollapsed(newCollapsedState);
- onCollapseChange?.(newCollapsedState);
- }
- };
-
- const handleSliverClick = () => {
- setIsCollapsed(false);
- onCollapseChange?.(false);
- };
-
- const handleBackdropClick = () => {
- if (isMobile) {
- onMobileOpenChange?.(false);
- }
- };
-
- // On desktop, show collapsed sliver
- if (isCollapsed && !isMobile) {
- return (
-
-
-
-
-
- );
- }
-
- return (
- <>
- {/* Backdrop for mobile overlay */}
- {isMobile && isMobileOpen && (
-
- )}
-
-
-
-
-
-
-
{t("playlists")}
-
-
-
-
-
-
-
-
- {t("aboutMenu")}
-
-
-
-
- {t("settings.title")}
-
-
-
-
- {/* About Modal */}
-
-
-
- {t("aboutHTMLPlayer")}
-
- {t("aboutHTMLPlayerDesc")}
-
-
-
-
-
- {t("about.version")}
-
- 2.0.0
-
-
-
- window.open(
- "https://github.com/user/HTMLPlayer",
- "_blank",
- )
- }
- >
-
- GitHub
-
- window.open("/privacy.html", "_blank")}
- >
- {t("about.privacy")}
-
- window.open("/tos.html", "_blank")}
- >
- {t("about.terms")}
-
-
-
- {t("about.madeWith")}
-
-
-
- setShowAbout(false)}>
- {t("common.close")}
-
-
-
-
-
- >
- );
- },
- (prevProps, nextProps) => {
- // Only re-render if the library playlists or songs have actually changed
- return (
- prevProps.musicPlayerHook.library.playlists ===
- nextProps.musicPlayerHook.library.playlists &&
- prevProps.musicPlayerHook.library.songs ===
- nextProps.musicPlayerHook.library.songs &&
- prevProps.musicPlayerHook.library.favorites ===
- nextProps.musicPlayerHook.library.favorites &&
- prevProps.musicPlayerHook.settings ===
- nextProps.musicPlayerHook.settings &&
- prevProps.settingsOpen === nextProps.settingsOpen &&
- prevProps.isMobileOpen === nextProps.isMobileOpen
- );
- },
-);
diff --git a/Build/src/components/Visualizer.tsx b/Build/src/components/Visualizer.tsx
deleted file mode 100644
index 83dc68d..0000000
--- a/Build/src/components/Visualizer.tsx
+++ /dev/null
@@ -1,267 +0,0 @@
-import { useRef, useEffect, useState, useCallback } from "react";
-import { useTranslation } from "react-i18next";
-import {
- getVisualizer,
- getAvailableVisualizers,
- VisualizerType,
- clearVisualizerState,
-} from "../helpers/visualizerLoader";
-import { Button } from "./Button";
-import { Icon } from "./Icon";
-import {
- DropdownMenu,
- DropdownMenuTrigger,
- DropdownMenuContent,
- DropdownMenuRadioGroup,
- DropdownMenuRadioItem,
-} from "./DropdownMenu";
-import styles from "./Visualizer.module.css";
-
-interface VisualizerProps {
- analyserNode: AnalyserNode | null;
- isPlaying: boolean;
- className?: string;
-}
-
-export const Visualizer = ({
- analyserNode,
- isPlaying,
- className,
-}: VisualizerProps) => {
- const { t } = useTranslation();
-
- const DEFAULT_VISUALIZER_KEY = "oceanwaves";
-
- const canvasRef = useRef(null);
- const animationFrameId = useRef(null);
- const [availableVisualizers, setAvailableVisualizers] = useState(
- [],
- );
- const [loadedVisualizerNames, setLoadedVisualizerNames] = useState<
- Map
- >(new Map());
- const [selectedVisualizerKey, setSelectedVisualizerKey] =
- useState("");
- const [selectedVisualizer, setSelectedVisualizer] =
- useState(null);
- const [visualizerSettings, setVisualizerSettings] = useState<
- Record
- >({});
- const [showSettings, setShowSettings] = useState(false);
- const [isLoadingVisualizer, setIsLoadingVisualizer] = useState(false);
-
- // Initialize available visualizers and load their names
- useEffect(() => {
- const visualizers = getAvailableVisualizers();
- setAvailableVisualizers(visualizers);
-
- // Load all visualizer names for the dropdown
- Promise.all(
- visualizers.map(async (key) => {
- const visualizer = await getVisualizer(key);
- return { key, name: visualizer?.name || key };
- }),
- ).then((results) => {
- const namesMap = new Map(results.map(({ key, name }) => [key, name]));
- setLoadedVisualizerNames(namesMap);
- });
-
- if (visualizers.length > 0 && !selectedVisualizerKey) {
- setSelectedVisualizerKey(
- visualizers.includes(DEFAULT_VISUALIZER_KEY)
- ? DEFAULT_VISUALIZER_KEY
- : visualizers[0],
- );
- }
- }, [selectedVisualizerKey]);
-
- // Load selected visualizer
- useEffect(() => {
- if (!selectedVisualizerKey) return;
-
- setIsLoadingVisualizer(true);
- getVisualizer(selectedVisualizerKey)
- .then((visualizer) => {
- setSelectedVisualizer(visualizer);
- setIsLoadingVisualizer(false);
-
- // Initialize settings with defaults
- if (visualizer?.settingsConfig) {
- setVisualizerSettings(
- Object.entries(visualizer.settingsConfig).reduce(
- (acc, [key, config]) => {
- acc[key] = config.default;
- return acc;
- },
- {} as Record,
- ),
- );
- }
- })
- .catch((error) => {
- console.error("Failed to load visualizer:", error);
- setIsLoadingVisualizer(false);
- });
- }, [selectedVisualizerKey]);
-
- // Cleanup visualizer state when component unmounts
- useEffect(() => {
- return () => {
- // Clean up all visualizer states when unmounting
- clearVisualizerState();
- };
- }, []);
-
- const handleSettingChange = (key: string, value: any) => {
- setVisualizerSettings((prev) => ({
- ...prev,
- [key]: value,
- }));
- };
-
- // Reuse data array to prevent allocation on every frame
- const dataArrayRef = useRef(null);
-
- const draw = useCallback(() => {
- if (!analyserNode || !canvasRef.current || !selectedVisualizer) return;
- const canvas = canvasRef.current;
- const ctx = canvas.getContext("2d");
- if (!ctx) return;
-
- const bufferLength = analyserNode.frequencyBinCount;
-
- // Reuse or create the data array only when buffer size changes
- if (!dataArrayRef.current || dataArrayRef.current.length !== bufferLength) {
- dataArrayRef.current = new Uint8Array(bufferLength);
- }
-
- selectedVisualizer.draw(
- analyserNode,
- canvas,
- ctx,
- bufferLength,
- dataArrayRef.current,
- selectedVisualizer.dataType,
- visualizerSettings,
- );
-
- animationFrameId.current = requestAnimationFrame(draw);
- }, [analyserNode, selectedVisualizer, visualizerSettings]);
-
- useEffect(() => {
- if (isPlaying && analyserNode && selectedVisualizer) {
- animationFrameId.current = requestAnimationFrame(draw);
- } else {
- if (animationFrameId.current)
- cancelAnimationFrame(animationFrameId.current);
- }
- return () => {
- if (animationFrameId.current)
- cancelAnimationFrame(animationFrameId.current);
- };
- }, [isPlaying, analyserNode, selectedVisualizer, draw]);
-
- useEffect(() => {
- const canvas = canvasRef.current;
- if (!canvas) return;
- const resizeObserver = new ResizeObserver(() => {
- const { width, height } = canvas.getBoundingClientRect();
- canvas.width = width;
- canvas.height = height;
- });
- resizeObserver.observe(canvas);
- return () => resizeObserver.disconnect();
- }, []);
-
- const handleVisualizerChange = async (newKey: string) => {
- setSelectedVisualizerKey(newKey);
- };
-
- return (
-
-
-
-
-
-
-
-
- {isLoadingVisualizer
- ? t("common.loading")
- : selectedVisualizer?.name ||
- t("visualizer.selectVisualizer")}
-
-
-
-
-
- {availableVisualizers.map((key) => (
-
- {loadedVisualizerNames.get(key) || key}
-
- ))}
-
-
-
- {selectedVisualizer?.settingsConfig && (
- setShowSettings(!showSettings)}
- >
-
-
- )}
-
- {showSettings && selectedVisualizer?.settingsConfig && (
-
- )}
-
- );
-};
diff --git a/Build/src/constants/pip.ts b/Build/src/constants/pip.ts
new file mode 100644
index 0000000..564bc86
--- /dev/null
+++ b/Build/src/constants/pip.ts
@@ -0,0 +1,39 @@
+export const PIP_WINDOW_WIDTH = 400;
+export const PIP_WINDOW_HEIGHT = 70;
+export const PIP_STYLE_DELAY_MS = 300;
+
+export const PIP_THEME_VARIABLES = [
+ "--themecolor",
+ "--themecolor2",
+ "--themecolor3",
+ "--themecolor4",
+ "--themegradient",
+ "--themecolor-transparent",
+ "--themecolor2-transparent",
+ "--themecolor3-transparent",
+ "--foreground",
+ "--foreground-strong",
+ "--foreground-stronger",
+ "--foreground-muted",
+ "--foreground-subtle",
+ "--background",
+ "--surface",
+ "--surface-foreground",
+ "--surface-transparent-05",
+ "--surface-transparent-1",
+ "--surface-transparent-2",
+ "--primary",
+ "--primary-foreground",
+ "--primary-transparent",
+ "--primary-border",
+ "--primary-border-strong",
+ "--secondary",
+ "--secondary-foreground",
+ "--menu-background",
+ "--spacing-1",
+ "--spacing-2",
+ "--spacing-3",
+ "--spacing-4",
+ "--radius",
+ "--radius-lg",
+] as const;
diff --git a/Build/src/contexts/audioStore.ts b/Build/src/contexts/audioStore.ts
deleted file mode 100644
index d9212e4..0000000
--- a/Build/src/contexts/audioStore.ts
+++ /dev/null
@@ -1,303 +0,0 @@
-import { create } from "zustand";
-import { subscribeWithSelector } from "zustand/middleware";
-import { useEffect, useRef } from "react";
-import { SafariAudioManager } from "../helpers/safariHelper";
-
-export interface AudioEvent {
- type:
- | "play"
- | "pause"
- | "seek"
- | "volume"
- | "next"
- | "previous"
- | "timeUpdate"
- | "songChange";
- payload?: any;
- timestamp: number;
- source: "main" | "pip";
-}
-
-interface AudioState {
- // Current audio state
- isPlaying: boolean;
- currentTime: number;
- duration: number;
- volume: number;
- currentSong: Song | null;
-
- // Event handling
- lastEvent: AudioEvent | null;
-
- // Actions for state updates (internal use)
- setPlaying: (playing: boolean, source?: "main" | "pip") => void;
- setCurrentTime: (time: number, source?: "main" | "pip") => void;
- setVolume: (volume: number, source?: "main" | "pip") => void;
- setCurrentSong: (song: Song | null, source?: "main" | "pip") => void;
- setDuration: (duration: number, source?: "main" | "pip") => void;
-
- // Control actions that emit events
- play: (source?: "main" | "pip") => void;
- pause: (source?: "main" | "pip") => void;
- seek: (time: number, source?: "main" | "pip") => void;
- next: (source?: "main" | "pip") => void;
- previous: (source?: "main" | "pip") => void;
- updateTime: (time: number, source?: "main" | "pip") => void;
- changeVolume: (volume: number, source?: "main" | "pip") => void;
-}
-
-// Create BroadcastChannel for cross-window communication
-const audioChannel = new BroadcastChannel("audio-events");
-
-// Initialize Safari audio manager (only activates on Safari)
-const safariAudio = new SafariAudioManager();
-
-export const useAudioStore = create()(
- subscribeWithSelector((set, get) => ({
- // Initial state
- isPlaying: false,
- currentTime: 0,
- duration: 0,
- volume: 0.75,
- currentSong: null,
- lastEvent: null,
-
- // State setters (for internal sync, don't broadcast)
- setPlaying: (playing: boolean, _source: "main" | "pip" = "main") => {
- set({ isPlaying: playing });
- },
-
- setCurrentTime: (time: number, _source: "main" | "pip" = "main") => {
- set({ currentTime: time });
- },
-
- setVolume: (volume: number, _source: "main" | "pip" = "main") => {
- set({ volume });
- },
-
- setCurrentSong: (song: Song | null, source: "main" | "pip" = "main") => {
- set({ currentSong: song });
- // Broadcast song changes
- const event: AudioEvent = {
- type: "songChange",
- payload: { song },
- timestamp: Date.now(),
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
-
- // NOTE: Don't set Safari audio source here - it will be set in playSong()
- // after the song is cached and we have a valid blob URL
- },
-
- setDuration: (duration: number, _source: "main" | "pip" = "main") => {
- set({ duration });
- },
-
- // Control actions (these broadcast events)
- play: (source: "main" | "pip" = "main") => {
- const event: AudioEvent = {
- type: "play",
- timestamp: Date.now(),
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
-
- // Sync Safari audio element
- if (safariAudio.isActive()) {
- safariAudio.play();
- }
- },
-
- pause: (source: "main" | "pip" = "main") => {
- const event: AudioEvent = {
- type: "pause",
- timestamp: Date.now(),
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
-
- // Sync Safari audio element
- if (safariAudio.isActive()) {
- safariAudio.pause();
- }
- },
-
- seek: (time: number, source: "main" | "pip" = "main") => {
- const event: AudioEvent = {
- type: "seek",
- payload: { time },
- timestamp: Date.now(),
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
-
- // Sync Safari audio element
- if (safariAudio.isActive()) {
- safariAudio.seek(time);
- }
- },
-
- next: (source: "main" | "pip" = "main") => {
- const event: AudioEvent = {
- type: "next",
- timestamp: Date.now(),
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
- },
-
- previous: (source: "main" | "pip" = "main") => {
- const event: AudioEvent = {
- type: "previous",
- timestamp: Date.now(),
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
- },
-
- updateTime: (time: number, source: "main" | "pip" = "main") => {
- set({ currentTime: time });
- // Only broadcast time updates every 500ms to avoid spam
- const now = Date.now();
- const lastEvent = get().lastEvent;
- if (
- !lastEvent ||
- lastEvent.type !== "timeUpdate" ||
- now - lastEvent.timestamp > 500
- ) {
- const event: AudioEvent = {
- type: "timeUpdate",
- payload: { time },
- timestamp: now,
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
- }
- },
-
- changeVolume: (volume: number, source: "main" | "pip" = "main") => {
- set({ volume });
- const event: AudioEvent = {
- type: "volume",
- payload: { volume },
- timestamp: Date.now(),
- source,
- };
- set({ lastEvent: event });
- audioChannel.postMessage(event);
-
- // Sync Safari audio element
- if (safariAudio.isActive()) {
- safariAudio.setVolume(volume);
- }
- },
- })),
-);
-
-// Listen for events from other windows/tabs
-audioChannel.onmessage = (event) => {
- const audioEvent: AudioEvent = event.data;
- const store = useAudioStore.getState();
-
- // Determine if this is the main window or PiP window
- const isMainWindow =
- typeof window !== "undefined" && window.parent === window;
- const currentSource = isMainWindow ? "main" : "pip";
-
- // Prevent infinite loops by checking source
- if (audioEvent.source === currentSource) {
- return;
- }
-
- console.log(
- `[${currentSource}] Received audio event:`,
- audioEvent.type,
- "from",
- audioEvent.source,
- );
-
- // Handle incoming events (update state without broadcasting)
- switch (audioEvent.type) {
- case "play":
- store.setPlaying(true, audioEvent.source);
- break;
- case "pause":
- store.setPlaying(false, audioEvent.source);
- break;
- case "volume":
- store.setVolume(audioEvent.payload.volume, audioEvent.source);
- break;
- case "seek":
- store.setCurrentTime(audioEvent.payload.time, audioEvent.source);
- break;
- case "timeUpdate":
- store.setCurrentTime(audioEvent.payload.time, audioEvent.source);
- break;
- case "songChange":
- store.setCurrentSong(audioEvent.payload.song, audioEvent.source);
- break;
- // next/previous are handled by the audio sync hook
- }
-};
-
-// Hook for subscribing to specific events
-export const useAudioEvents = (
- eventType: AudioEvent["type"],
- callback: (event: AudioEvent) => void,
-) => {
- const lastEvent = useAudioStore((state) => state.lastEvent);
- const lastProcessedEventRef = useRef(0);
-
- useEffect(() => {
- if (
- lastEvent &&
- lastEvent.type === eventType &&
- lastEvent.timestamp !== lastProcessedEventRef.current
- ) {
- // Simple deduplication: only process events that are recent (less than 1000ms old)
- const now = Date.now();
- if (now - lastEvent.timestamp < 1000) {
- lastProcessedEventRef.current = lastEvent.timestamp;
- callback(lastEvent);
- }
- }
- }, [lastEvent, eventType]); // Remove callback from dependencies to prevent infinite loops
-};
-
-// Hook for audio controls
-export const useAudioControls = () => {
- const { play, pause, seek, next, previous, changeVolume } = useAudioStore();
- const isPlaying = useAudioStore((state) => state.isPlaying);
-
- return {
- play,
- pause,
- seek,
- next,
- previous,
- setVolume: changeVolume,
- togglePlayPause: () => (isPlaying ? pause() : play()),
- };
-};
-
-// Hook for audio state
-export const useAudioState = () => {
- return useAudioStore((state) => ({
- isPlaying: state.isPlaying,
- currentTime: state.currentTime,
- duration: state.duration,
- volume: state.volume,
- currentSong: state.currentSong,
- }));
-};
-
-// Export Safari audio manager for direct access if needed
-export const getSafariAudioManager = () => safariAudio;
diff --git a/Build/src/core/engine/asyncOp.ts b/Build/src/core/engine/asyncOp.ts
new file mode 100644
index 0000000..7065668
--- /dev/null
+++ b/Build/src/core/engine/asyncOp.ts
@@ -0,0 +1,19 @@
+export class AsyncOp {
+ private generation = 0;
+
+ next(): number {
+ return ++this.generation;
+ }
+
+ isCurrent(generation: number): boolean {
+ return generation === this.generation;
+ }
+
+ peek(): number {
+ return this.generation;
+ }
+
+ invalidate(): void {
+ this.generation++;
+ }
+}
diff --git a/Build/src/core/engine/engine.ts b/Build/src/core/engine/engine.ts
new file mode 100644
index 0000000..3017beb
--- /dev/null
+++ b/Build/src/core/engine/engine.ts
@@ -0,0 +1,801 @@
+import type {
+ Track,
+ Playlist,
+ EngineSettings,
+ EngineState,
+ PlayerState,
+ EngineEventMap,
+ EngineError,
+ RepeatMode,
+} from "./types";
+import { KomorebiEvents } from "./events";
+import { StateMachine } from "./state";
+import {
+ QueueManager,
+ type WeightedRandomizer,
+ type ShuffleMode,
+} from "./queue";
+import { Scheduler } from "./scheduler";
+import { AsyncOp } from "./asyncOp";
+import { assertNever } from "./invariants";
+import type { IAudioBackend } from "../../platform/audio";
+import type { PreloadManager } from "../../platform/audio/preloader";
+import { clampRate, clampVolume } from "../../platform/audio/clamp";
+
+export interface IAudioEngineConfig {
+ crossfade: {
+ enabled: boolean;
+ duration: number;
+ shape: "none" | "linear" | "equalpower";
+ };
+ gapless: {
+ enabled: boolean;
+ };
+ smartShuffle: boolean;
+ autoPlayNext: boolean;
+ trackResolver?: (track: Track) => Promise;
+ preloadManager?: PreloadManager;
+}
+
+export const DEFAULT_ENGINE_SETTINGS: EngineSettings = {
+ volume: 1,
+ crossfade: 0,
+ crossfadeBeforeGapless: 3000,
+ autoPlayNext: true,
+ tempo: 1,
+ pitch: 0,
+ gaplessPlayback: true,
+ smartShuffle: true,
+ repeat: "off",
+ defaultShuffle: false,
+ defaultRepeat: "off",
+};
+
+export class KomorebiEngine {
+ private events = new KomorebiEvents();
+ private stateMachine = new StateMachine();
+ private queue = new QueueManager();
+ private scheduler = new Scheduler();
+
+ private backend: IAudioBackend;
+ private settings: EngineSettings = { ...DEFAULT_ENGINE_SETTINGS };
+ private currentTime = 0;
+ private duration = 0;
+ private currentError: EngineError | null = null;
+ private currentPlaylist: Playlist | null = null;
+
+ private timeUpdateInterval: number | null = null;
+ private scheduledTransitionId: number | null = null;
+
+ private readonly loadOp = new AsyncOp();
+ private readonly trackResolver:
+ ((track: Track) => Promise) | undefined;
+ private readonly preloadManager: PreloadManager | null;
+ private prefetchSentinel = false;
+
+ constructor(backend: IAudioBackend, config?: Partial) {
+ this.backend = backend;
+ this.trackResolver = config?.trackResolver;
+ this.preloadManager = config?.preloadManager ?? null;
+ this.backend.onTimeUpdate((time) => {
+ this.handleTimeUpdate(time);
+ });
+ this.backend.onEnded(() => {
+ this.handleTrackEnded();
+ });
+ this.backend.onError((error) => {
+ this.handleError(error);
+ });
+
+ if (config?.crossfade) {
+ this.scheduler.setCrossfadeConfig({
+ enabled: config.crossfade.enabled,
+ duration: config.crossfade.duration,
+ shape: config.crossfade.shape,
+ });
+ this.settings.crossfade = config.crossfade.duration;
+ }
+
+ if (config?.gapless) {
+ this.scheduler.setGaplessConfig({ enabled: config.gapless.enabled });
+ this.settings.gaplessPlayback = config.gapless.enabled;
+ }
+
+ if (config?.smartShuffle !== undefined) {
+ this.settings.smartShuffle = config.smartShuffle;
+ }
+
+ if (config?.autoPlayNext !== undefined) {
+ this.settings.autoPlayNext = config.autoPlayNext;
+ }
+ }
+
+ setWeightedRandomizer(randomizer: WeightedRandomizer | null): void {
+ this.queue.setWeightedRandomizer(randomizer);
+ if (this.settings.smartShuffle) {
+ this.queue.setShuffleMode("smart");
+ }
+ }
+
+ setShuffleMode(mode: ShuffleMode): void {
+ this.queue.setShuffleMode(mode);
+ this.settings.smartShuffle = mode === "smart";
+ this.events.emit("settingschange", {
+ settings: { smartShuffle: this.settings.smartShuffle },
+ });
+ }
+
+ getShuffleMode(): ShuffleMode {
+ return this.queue.getShuffleMode();
+ }
+
+ async load(track: Track, playlist?: Playlist): Promise {
+ if (playlist) {
+ this.queue.setPlaylist(playlist);
+ this.currentPlaylist = playlist;
+ } else if (this.queue.getTracks().findIndex((t) => t.id === track.id) < 0) {
+ const solo: Playlist = {
+ id: `solo:${track.id}`,
+ name: track.title,
+ songs: [track],
+ };
+ this.queue.setPlaylist(solo);
+ this.currentPlaylist = solo;
+ }
+
+ const previousTrack = this.queue.getCurrentTrack();
+
+ const trackIndex = this.queue
+ .getTracks()
+ .findIndex((t) => t.id === track.id);
+ this.queue.jumpToIndex(trackIndex >= 0 ? trackIndex : null);
+ this.emitTrackChange(previousTrack, track);
+
+ this.cancelScheduledTransition();
+ this.stateMachine.transition("loading");
+ this.currentError = null;
+ this.events.emit("loading", { track });
+
+ const generation = this.loadOp.next();
+
+ let target: Track;
+ try {
+ target = await this.resolveSource(track);
+ } catch (error) {
+ if (this.loadOp.isCurrent(generation)) {
+ this.emitError(
+ "LOAD_SOURCE_ERROR",
+ `resolve source: ${String(error)}`,
+ track,
+ );
+ }
+ return;
+ }
+
+ return new Promise((resolve) => {
+ if (!this.loadOp.isCurrent(generation)) {
+ resolve();
+ return;
+ }
+
+ if (typeof target.url !== "string" || target.url.length === 0) {
+ this.emitError(
+ "LOAD_SOURCE_ERROR",
+ `no playable source (url=${String(target.url)})`,
+ track,
+ );
+ resolve();
+ return;
+ }
+
+ this.backend
+ .load(target.url, target)
+ .then(() => {
+ if (!this.loadOp.isCurrent(generation)) {
+ resolve();
+ return;
+ }
+ this.prefetchSentinel = false;
+ this.backend.setReplayGain?.(this.replayGainForTrack(target));
+ this.duration = this.backend.getDuration() ?? track.duration;
+ this.stateMachine.transition("ready");
+ this.events.emit("durationchange", { duration: this.duration });
+ this.events.emit("ready", { track });
+ this.emitStateChange();
+ this.prefetchUpcoming(target);
+ resolve();
+ })
+ .catch((error) => {
+ if (!this.loadOp.isCurrent(generation)) {
+ resolve();
+ return;
+ }
+ this.prefetchSentinel = false;
+ this.emitError("LOAD_ERROR", error.message, track);
+ resolve();
+ });
+ });
+ }
+
+ async play(): Promise {
+ try {
+ const state = this.stateMachine.getState();
+
+ if (state === "idle" || state === "error") {
+ const current = this.queue.getCurrentTrack();
+ if (!current) return;
+
+ this.load(current);
+ const generation = this.loadOp.peek();
+ await this.waitForState("ready");
+ if (!this.loadOp.isCurrent(generation)) return;
+ await this.play();
+ return;
+ }
+
+ if (state !== "ready" && state !== "paused") return;
+
+ const generation = this.loadOp.peek();
+ await this.backend.play();
+ if (!this.loadOp.isCurrent(generation)) return;
+
+ this.stateMachine.transition("playing");
+ this.startTimeUpdates();
+ this.emitStateChange();
+
+ const track = this.queue.getCurrentTrack();
+ if (track) {
+ this.queue.updateHistory(track.id);
+ }
+ } catch (error) {
+ this.emitError("PLAY_ERROR", (error as Error).message);
+ }
+ }
+
+ pause(): void {
+ if (this.stateMachine.isPlaying()) {
+ this.backend.pause();
+ this.stateMachine.transition("paused");
+ this.stopTimeUpdates();
+ this.emitStateChange();
+ }
+ }
+
+ stop(): void {
+ if (this.stateMachine.isIdle()) return;
+ this.loadOp.invalidate();
+ this.backend.stop();
+ this.backend.setReplayGain?.(null);
+ this.prefetchSentinel = false;
+ this.cancelScheduledTransition();
+ this.stateMachine.transition("idle");
+ this.currentTime = 0;
+ this.currentError = null;
+ this.stopTimeUpdates();
+ this.emitStateChange();
+ }
+
+ async next(): Promise {
+ this.cancelScheduledTransition();
+
+ const nextCursor = this.queue.peekNextCursor(this.settings.smartShuffle);
+
+ switch (nextCursor.kind) {
+ case "empty":
+ break;
+ case "active": {
+ const nextTrack = this.queue.getTracks()[nextCursor.index];
+ if (nextTrack === undefined) break;
+
+ try {
+ if (this.stateMachine.isPlaying()) {
+ await this.loadAndPlay(nextTrack);
+ } else {
+ await this.load(nextTrack);
+ }
+ } catch (error) {
+ this.emitError("NEXT_ERROR", (error as Error).message, nextTrack);
+ }
+ break;
+ }
+ default:
+ assertNever(nextCursor);
+ }
+ }
+
+ async previous(): Promise {
+ this.cancelScheduledTransition();
+
+ if (this.currentTime > 3) {
+ this.seek(0);
+ return;
+ }
+
+ const prevCursor = this.queue.peekPreviousCursor(
+ this.settings.smartShuffle,
+ );
+
+ switch (prevCursor.kind) {
+ case "empty":
+ break;
+ case "active": {
+ const prevTrack = this.queue.getTracks()[prevCursor.index];
+ if (prevTrack === undefined) break;
+
+ try {
+ if (this.stateMachine.isPlaying()) {
+ await this.loadAndPlay(prevTrack);
+ } else {
+ await this.load(prevTrack);
+ }
+ } catch (error) {
+ this.emitError("PREV_ERROR", (error as Error).message, prevTrack);
+ }
+ break;
+ }
+ default:
+ assertNever(prevCursor);
+ }
+ }
+
+ seek(time: number): void {
+ const clampedTime = Math.max(0, Math.min(time, this.duration));
+ this.backend.seek(clampedTime);
+ this.currentTime = clampedTime;
+ this.emitTimeUpdate();
+ }
+
+ setVolume(volume: number): void {
+ const clamped = clampVolume(volume);
+ this.settings.volume = clamped;
+
+ this.backend.setVolume(clamped);
+
+ this.events.emit("volumechange", { volume: clamped });
+ }
+
+ setTempo(tempo: number): void {
+ const clamped = clampRate(tempo);
+ this.settings.tempo = clamped;
+
+ this.backend.setPlaybackRate(clamped);
+
+ this.events.emit("settingschange", { settings: { tempo: clamped } });
+ }
+
+ setPitch(semitones: number): void {
+ this.settings.pitch = semitones;
+ this.events.emit("settingschange", { settings: { pitch: semitones } });
+
+ void this.backend.setPitch?.(semitones);
+ }
+
+ toggleShuffle(): void {
+ if (this.queue.isShuffled()) {
+ this.queue.unshuffle();
+ } else {
+ this.queue.shuffle(true);
+ }
+
+ this.settings.defaultShuffle = this.queue.isShuffled();
+ this.events.emit("queuechange", { queue: this.queue.getState() });
+ }
+
+ setShuffle(shuffled: boolean): void {
+ if (shuffled && !this.queue.isShuffled()) {
+ this.queue.shuffle(true);
+ } else if (!shuffled && this.queue.isShuffled()) {
+ this.queue.unshuffle();
+ }
+
+ this.settings.defaultShuffle = shuffled;
+ this.events.emit("queuechange", { queue: this.queue.getState() });
+ }
+
+ setRepeat(mode: RepeatMode): void {
+ this.settings.repeat = mode;
+ this.events.emit("settingschange", {
+ settings: { repeat: mode },
+ });
+ }
+
+ setAutoPlayNext(enabled: boolean): void {
+ this.settings.autoPlayNext = enabled;
+ this.events.emit("settingschange", {
+ settings: { autoPlayNext: enabled },
+ });
+ }
+
+ toggleRepeat(): void {
+ const current = this.settings.repeat;
+ this.settings.repeat =
+ current === "off" ? "all" : current === "all" ? "one" : "off";
+ this.events.emit("settingschange", {
+ settings: { repeat: this.settings.repeat },
+ });
+ }
+
+ setCrossfade(duration: number): void {
+ this.settings.crossfade = duration;
+ this.scheduler.setCrossfadeConfig({ enabled: duration > 0, duration });
+ this.events.emit("settingschange", { settings: { crossfade: duration } });
+ }
+
+ setGapless(enabled: boolean): void {
+ this.settings.gaplessPlayback = enabled;
+ this.scheduler.setGaplessConfig({ enabled });
+ this.events.emit("settingschange", {
+ settings: { gaplessPlayback: enabled },
+ });
+ }
+
+ updateSettings(newSettings: Partial): void {
+ Object.assign(this.settings, newSettings);
+
+ if (newSettings.volume !== undefined) {
+ this.setVolume(newSettings.volume);
+ }
+ if (newSettings.tempo !== undefined) {
+ this.setTempo(newSettings.tempo);
+ }
+ if (newSettings.crossfade !== undefined) {
+ this.setCrossfade(newSettings.crossfade);
+ }
+ if (newSettings.gaplessPlayback !== undefined) {
+ this.setGapless(newSettings.gaplessPlayback);
+ }
+ if (newSettings.pitch !== undefined) {
+ this.setPitch(newSettings.pitch);
+ }
+ if (newSettings.smartShuffle !== undefined) {
+ this.setShuffleMode(newSettings.smartShuffle ? "smart" : "random");
+ }
+ if (newSettings.repeat !== undefined) {
+ this.setRepeat(newSettings.repeat);
+ }
+
+ this.events.emit("settingschange", { settings: newSettings });
+ }
+
+ setPlaylist(playlist: Playlist): void {
+ this.queue.setPlaylist(playlist, false);
+ this.currentPlaylist = playlist;
+ this.events.emit("queuechange", { queue: this.queue.getState() });
+ }
+
+ getState(): EngineState {
+ return {
+ state: this.stateMachine.getState(),
+ currentTrack: this.queue.getCurrentTrack(),
+ currentPlaylist: this.currentPlaylist,
+ queue: this.queue.getState(),
+ settings: { ...this.settings },
+ currentTime: this.currentTime,
+ duration: this.duration,
+ volume: this.settings.volume,
+ playHistory: this.queue.getAllHistory(),
+ error: this.currentError,
+ };
+ }
+
+ getCurrentTrack(): Track | null {
+ return this.queue.getCurrentTrack();
+ }
+
+ getQueue(): QueueManager {
+ return this.queue;
+ }
+
+ getAnalyser(): AnalyserNode | null {
+ return this.backend.getAnalyser?.() ?? null;
+ }
+
+ getScheduler(): Scheduler {
+ return this.scheduler;
+ }
+
+ on(
+ event: E,
+ callback: (data: EngineEventMap[E]) => void,
+ ): void {
+ this.events.on(event, callback);
+ }
+
+ off(
+ event: E,
+ callback: (data: EngineEventMap[E]) => void,
+ ): void {
+ this.events.off(event, callback);
+ }
+
+ dispose(): void {
+ this.stopTimeUpdates();
+ this.cancelScheduledTransition();
+ this.backend.dispose();
+ this.events.removeAllListeners();
+ this.stateMachine.reset();
+ }
+
+ private async loadAndPlay(track: Track): Promise {
+ await this.load(track);
+ await this.play();
+ }
+
+ private async waitForState(
+ targetState: PlayerState,
+ timeout = 5000,
+ ): Promise {
+ return new Promise((resolve, reject) => {
+ let settled = false;
+ const timeoutId = setTimeout(() => {
+ if (settled) return;
+ settled = true;
+ this.events.off("statechange", onStateChange);
+ reject(new Error(`Timeout waiting for state: ${targetState}`));
+ }, timeout);
+
+ const onStateChange = () => {
+ if (settled) return;
+ if (this.stateMachine.getState() === targetState) {
+ settled = true;
+ clearTimeout(timeoutId);
+ this.events.off("statechange", onStateChange);
+ resolve();
+ } else if (this.stateMachine.hasError()) {
+ settled = true;
+ clearTimeout(timeoutId);
+ this.events.off("statechange", onStateChange);
+ const reason = this.currentError
+ ? `Engine entered error state: ${this.currentError.code}`
+ : "Engine entered error state";
+ reject(new Error(reason));
+ }
+ };
+
+ if (this.stateMachine.getState() === targetState) {
+ onStateChange();
+ return;
+ }
+ if (this.stateMachine.hasError()) {
+ onStateChange();
+ return;
+ }
+
+ this.events.on("statechange", onStateChange);
+ });
+ }
+
+ private handleTimeUpdate(time: number): void {
+ this.currentTime = time;
+
+ if (this.stateMachine.isPlaying()) {
+ this.checkScheduledTransition(time);
+ this.maybePrefetchDuringPlayback();
+ }
+
+ this.emitTimeUpdate();
+ }
+
+ private maybePrefetchDuringPlayback(): void {
+ if (this.prefetchSentinel || !this.preloadManager) return;
+ if (!this.scheduler.shouldPreload(this.currentTime, this.duration)) return;
+
+ this.prefetchSentinel = true;
+ const track = this.queue.getCurrentTrack();
+ if (track) {
+ this.prefetchUpcoming(track);
+ }
+ }
+
+ private prefetchUpcoming(track: Track): void {
+ const preloadManager = this.preloadManager;
+ if (!preloadManager) return;
+
+ const tracks = this.queue.getTracks();
+ const index = tracks.findIndex((candidate) => candidate.id === track.id);
+ if (index < 0) return;
+
+ preloadManager.preloadNext(tracks, index);
+ }
+
+ private async resolveSource(track: Track): Promise {
+ const preloadedUrl = this.preloadManager?.getUrl(track.id);
+ if (preloadedUrl) {
+ return { ...track, url: preloadedUrl };
+ }
+ return this.trackResolver ? await this.trackResolver(track) : track;
+ }
+
+ private replayGainForTrack(track: Track): number | null {
+ const replayGain = track.replayGain;
+ if (!replayGain) return null;
+
+ const gainDb = replayGain.trackGain ?? replayGain.albumGain;
+ return typeof gainDb === "number" && Number.isFinite(gainDb)
+ ? gainDb
+ : null;
+ }
+
+ private checkScheduledTransition(currentTime: number): void {
+ const track = this.queue.getCurrentTrack();
+ if (!track) return;
+
+ if (this.scheduler.shouldTriggerTransition(currentTime, track)) {
+ this.scheduleTransition(track);
+ }
+ }
+
+ private scheduleTransition(_track: Track): void {
+ if (this.scheduledTransitionId !== null) return;
+
+ this.stateMachine.transition("transitioning");
+
+ const nextTrack = this.queue.getNextTrack(this.settings.smartShuffle);
+ if (!nextTrack) {
+ if (this.stateMachine.canTransition("ready")) {
+ this.stateMachine.transition("ready");
+ }
+ return;
+ }
+
+ const mode = this.scheduler.getMode();
+ const isCrossfade = mode === "crossfade" && this.settings.crossfade > 0;
+ const delay = isCrossfade
+ ? 0
+ : mode === "gapless"
+ ? 100
+ : this.settings.crossfade;
+
+ this.scheduledTransitionId = window.setTimeout(() => {
+ this.scheduledTransitionId = null;
+ void this.executeTransition(nextTrack);
+ }, delay);
+ }
+
+ private async executeTransition(nextTrack: Track): Promise {
+ const currentTrack = this.queue.getCurrentTrack();
+ const isCrossfade =
+ this.scheduler.getMode() === "crossfade" &&
+ this.settings.crossfade > 0 &&
+ this.backend.beginCrossfade !== undefined;
+
+ if (isCrossfade) {
+ const crossfaded = await this.tryCrossfade(nextTrack);
+ if (crossfaded) {
+ if (currentTrack) {
+ this.events.emit("ended", { track: currentTrack });
+ }
+ if (this.stateMachine.canTransition("playing")) {
+ this.stateMachine.transition("playing");
+ this.emitStateChange();
+ }
+ return;
+ }
+ }
+
+ await this.loadAndPlay(nextTrack);
+
+ if (currentTrack) {
+ this.events.emit("ended", { track: currentTrack });
+ }
+
+ if (this.stateMachine.canTransition("playing")) {
+ this.stateMachine.transition("playing");
+ }
+ }
+
+ private async tryCrossfade(nextTrack: Track): Promise {
+ let url: string;
+ try {
+ const target = await this.resolveSource(nextTrack);
+ url = target.url;
+ if (typeof url !== "string" || url.length === 0) return false;
+ } catch {
+ return false;
+ }
+
+ const ok = await this.backend.beginCrossfade?.(url, nextTrack, {
+ durationMs: this.settings.crossfade,
+ shape: this.scheduler.getCrossfade().getCurve(),
+ });
+
+ if (!ok) return false;
+
+ const previousTrack = this.queue.getCurrentTrack();
+ const trackIndex = this.queue
+ .getTracks()
+ .findIndex((candidate) => candidate.id === nextTrack.id);
+ this.queue.jumpToIndex(trackIndex >= 0 ? trackIndex : null);
+ this.emitTrackChange(previousTrack, nextTrack);
+ this.prefetchSentinel = false;
+ this.duration = this.backend.getDuration() ?? nextTrack.duration;
+ this.events.emit("durationchange", { duration: this.duration });
+ this.prefetchUpcoming(nextTrack);
+ return true;
+ }
+
+ private cancelScheduledTransition(): void {
+ if (this.scheduledTransitionId !== null) {
+ clearTimeout(this.scheduledTransitionId);
+ this.scheduledTransitionId = null;
+ }
+
+ if (this.stateMachine.isTransitioning()) {
+ this.stateMachine.transition("ready");
+ }
+ }
+
+ private handleTrackEnded(): void {
+ if (this.stateMachine.isTransitioning()) {
+ return;
+ }
+
+ const track = this.queue.getCurrentTrack();
+ if (track) {
+ this.events.emit("ended", { track: track });
+ }
+
+ if (this.settings.repeat === "one") {
+ this.seek(0);
+ this.play();
+ return;
+ }
+
+ if (this.settings.autoPlayNext) {
+ this.next();
+ } else if (this.stateMachine.canTransition("ready")) {
+ this.stateMachine.transition("ready");
+ this.emitStateChange();
+ }
+ }
+
+ private handleError(error: Error): void {
+ this.emitError("BACKEND_ERROR", error.message);
+ }
+
+ private startTimeUpdates(): void {
+ if (this.timeUpdateInterval) return;
+
+ this.timeUpdateInterval = window.setInterval(() => {
+ if (this.stateMachine.isPlaying()) {
+ this.handleTimeUpdate(this.backend.getCurrentTime());
+ }
+ }, 100);
+ }
+
+ private stopTimeUpdates(): void {
+ if (this.timeUpdateInterval !== null) {
+ clearInterval(this.timeUpdateInterval);
+ this.timeUpdateInterval = null;
+ }
+ }
+
+ private emitStateChange(): void {
+ const prevState = this.stateMachine.getPreviousState();
+ const newState = this.stateMachine.getState();
+ this.events.emit("statechange", {
+ oldState: prevState ?? "idle",
+ newState,
+ });
+ }
+
+ private emitTrackChange(from: Track | null, to: Track | null): void {
+ this.events.emit("trackchange", { from, to });
+ }
+
+ private emitTimeUpdate(): void {
+ this.events.emit("timeupdate", {
+ currentTime: this.currentTime,
+ duration: this.duration,
+ });
+ }
+
+ private emitError(code: string, message: string, track?: Track): void {
+ this.currentError = { code, message, track };
+ if (this.stateMachine.canTransition("error")) {
+ this.stateMachine.transition("error");
+ }
+ this.events.emit("error", { error: this.currentError });
+ this.emitStateChange();
+ }
+}
diff --git a/Build/src/core/engine/events.ts b/Build/src/core/engine/events.ts
new file mode 100644
index 0000000..ebdba7e
--- /dev/null
+++ b/Build/src/core/engine/events.ts
@@ -0,0 +1,73 @@
+import type { EngineEvent, EngineEventMap } from "./types";
+
+type EventCallback = (data: T) => void;
+
+type ListenerErrorHandler = (event: EngineEvent, error: unknown) => void;
+
+const defaultErrorHandler: ListenerErrorHandler = (event, error) => {
+ console.error(`[events] listener for "${event}" threw:`, error);
+};
+
+export class KomorebiEvents {
+ private listeners: Map>> = new Map();
+ private readonly onListenerError: ListenerErrorHandler;
+
+ constructor(onListenerError: ListenerErrorHandler = defaultErrorHandler) {
+ this.onListenerError = onListenerError;
+ }
+
+ on(
+ event: E,
+ callback: EventCallback,
+ ): void {
+ if (!this.listeners.has(event)) {
+ this.listeners.set(event, new Set());
+ }
+ this.listeners.get(event)!.add(callback as EventCallback);
+ }
+
+ off(
+ event: E,
+ callback: EventCallback,
+ ): void {
+ const callbacks = this.listeners.get(event);
+ if (callbacks) {
+ callbacks.delete(callback as EventCallback);
+ }
+ }
+
+ emit(event: E, data: EngineEventMap[E]): void {
+ const callbacks = this.listeners.get(event);
+ if (!callbacks) return;
+ callbacks.forEach((cb) => {
+ try {
+ cb(data);
+ } catch (error) {
+ this.onListenerError(event, error);
+ }
+ });
+ }
+
+ once(
+ event: E,
+ callback: EventCallback,
+ ): void {
+ const wrapper: EventCallback = (data) => {
+ this.off(event, wrapper);
+ callback(data);
+ };
+ this.on(event, wrapper);
+ }
+
+ removeAllListeners(event?: EngineEvent): void {
+ if (event) {
+ this.listeners.delete(event);
+ } else {
+ this.listeners.clear();
+ }
+ }
+
+ listenerCount(event: EngineEvent): number {
+ return this.listeners.get(event)?.size ?? 0;
+ }
+}
diff --git a/Build/src/core/engine/invariants.ts b/Build/src/core/engine/invariants.ts
new file mode 100644
index 0000000..ba0867a
--- /dev/null
+++ b/Build/src/core/engine/invariants.ts
@@ -0,0 +1,12 @@
+export function assertInvariant(
+ condition: boolean,
+ message: string,
+): asserts condition {
+ if (!condition) {
+ throw new Error(`Invariant violation: ${message}`);
+ }
+}
+
+export function assertNever(value: never): never {
+ throw new Error(`Invariant violation: unexpected value ${String(value)}`);
+}
diff --git a/Build/src/core/engine/queue/index.ts b/Build/src/core/engine/queue/index.ts
new file mode 100644
index 0000000..76ff7be
--- /dev/null
+++ b/Build/src/core/engine/queue/index.ts
@@ -0,0 +1,428 @@
+import type {
+ Track,
+ Playlist,
+ QueueState,
+ QueueCursor,
+ PlayHistory,
+} from "../types";
+import { assertInvariant, assertNever } from "../invariants";
+
+export type ShuffleMode = "random" | "smart";
+
+export interface WeightedRandomizer {
+ getWeightedRandomTrack(trackIds: string[]): string | null;
+}
+
+type Direction = "next" | "previous";
+
+export class QueueManager {
+ private state: QueueState = {
+ tracks: [],
+ cursor: { kind: "empty" },
+ shuffled: false,
+ shuffleOrder: [],
+ };
+
+ private history: Map = new Map();
+ private maxHistorySize = 1000;
+ private weightedRandomizer: WeightedRandomizer | null = null;
+ private shuffleMode: ShuffleMode = "random";
+
+ setWeightedRandomizer(randomizer: WeightedRandomizer | null): void {
+ this.weightedRandomizer = randomizer;
+ }
+
+ getShuffleMode(): ShuffleMode {
+ return this.shuffleMode;
+ }
+
+ setShuffleMode(mode: ShuffleMode): void {
+ this.shuffleMode = mode;
+ }
+
+ setPlaylist(playlist: Playlist | null, preserveCurrent = true): void {
+ if (!playlist) {
+ this.state = {
+ tracks: [],
+ cursor: { kind: "empty" },
+ shuffled: this.state.shuffled,
+ shuffleOrder: [],
+ };
+ return;
+ }
+
+ const tracks = [...playlist.songs];
+ const currentTrack = preserveCurrent ? this.getCurrentTrack() : null;
+ const newIndex = currentTrack
+ ? tracks.findIndex((t) => t.id === currentTrack.id)
+ : -1;
+
+ this.state.tracks = tracks;
+ this.state.shuffleOrder = this.generateShuffleOrder(
+ tracks.length,
+ newIndex >= 0 ? newIndex : null,
+ );
+ this.setCursor(
+ newIndex >= 0 ? { kind: "active", index: newIndex } : { kind: "empty" },
+ );
+ }
+
+ getCursor(): QueueCursor {
+ return this.state.cursor;
+ }
+
+ setCursor(cursor: QueueCursor): void {
+ switch (cursor.kind) {
+ case "empty":
+ this.state.cursor = { kind: "empty" };
+ break;
+ case "active":
+ if (cursor.index >= 0 && cursor.index < this.state.tracks.length) {
+ this.state.cursor = { kind: "active", index: cursor.index };
+ } else {
+ this.state.cursor = { kind: "empty" };
+ }
+ break;
+ default:
+ assertNever(cursor);
+ }
+ }
+
+ jumpToIndex(index: number | null): void {
+ this.setCursor(
+ index === null ? { kind: "empty" } : { kind: "active", index },
+ );
+ }
+
+ peekNextCursor(_smartShuffle: boolean): QueueCursor {
+ return this.peekAdjacentCursor("next");
+ }
+
+ peekPreviousCursor(_smartShuffle: boolean): QueueCursor {
+ return this.peekAdjacentCursor("previous");
+ }
+
+ getCurrentTrack(): Track | null {
+ const cursor = this.state.cursor;
+ switch (cursor.kind) {
+ case "empty":
+ return null;
+ case "active":
+ return this.state.tracks[cursor.index] ?? null;
+ default:
+ return assertNever(cursor);
+ }
+ }
+
+ getCurrentIndex(): number | null {
+ const cursor = this.state.cursor;
+ switch (cursor.kind) {
+ case "empty":
+ return null;
+ case "active":
+ return cursor.index;
+ default:
+ return assertNever(cursor);
+ }
+ }
+
+ getNextIndex(smartShuffle: boolean): number | null {
+ const cursor = this.peekNextCursor(smartShuffle);
+ return cursor.kind === "active" ? cursor.index : null;
+ }
+
+ getPreviousIndex(smartShuffle: boolean): number | null {
+ const cursor = this.peekPreviousCursor(smartShuffle);
+ return cursor.kind === "active" ? cursor.index : null;
+ }
+
+ getTracks(): Track[] {
+ return [...this.state.tracks];
+ }
+
+ getPlayOrder(): number[] {
+ if (!this.state.shuffled) {
+ return this.state.tracks.map((_, i) => i);
+ }
+ return [...this.state.shuffleOrder];
+ }
+
+ getNextTrack(smartShuffle: boolean): Track | null {
+ return this.trackForCursor(this.peekNextCursor(smartShuffle));
+ }
+
+ getPreviousTrack(smartShuffle: boolean): Track | null {
+ return this.trackForCursor(this.peekPreviousCursor(smartShuffle));
+ }
+
+ shuffle(preserveCurrent = true): void {
+ this.state.shuffled = true;
+ const preserveIndex =
+ preserveCurrent && this.state.cursor.kind === "active"
+ ? this.state.cursor.index
+ : null;
+
+ if (this.shuffleMode === "smart" && this.weightedRandomizer) {
+ this.state.shuffleOrder = this.generateSmartShuffleOrder(
+ this.state.tracks.length,
+ preserveIndex,
+ );
+ } else {
+ this.state.shuffleOrder = this.generateShuffleOrder(
+ this.state.tracks.length,
+ preserveIndex,
+ );
+ }
+ }
+
+ private generateSmartShuffleOrder(
+ length: number,
+ preserveIndex: number | null,
+ ): number[] {
+ if (length === 0) return [];
+
+ const randomizer = this.weightedRandomizer;
+ if (!randomizer) {
+ return this.generateShuffleOrder(length, preserveIndex);
+ }
+
+ const trackIds = this.state.tracks.map((t) => t.id);
+ const selectedIds: string[] = [];
+ const availableIndices = Array.from({ length }, (_, i) => i);
+
+ while (availableIndices.length > 0) {
+ const availableTrackIds = availableIndices
+ .map((i) => trackIds[i])
+ .filter((id): id is string => id !== undefined);
+ const selectedId = randomizer.getWeightedRandomTrack(availableTrackIds);
+
+ if (!selectedId) break;
+
+ const selectedIndex = trackIds.indexOf(selectedId);
+ if (selectedIndex === -1) break;
+
+ const actualIndex = availableIndices.indexOf(selectedIndex);
+ if (actualIndex === -1) break;
+
+ selectedIds.push(selectedId);
+ availableIndices.splice(actualIndex, 1);
+ }
+
+ if (preserveIndex !== null && preserveIndex < length) {
+ const preserveId = trackIds[preserveIndex];
+ if (preserveId !== undefined) {
+ const idxInSelected = selectedIds.indexOf(preserveId);
+ if (idxInSelected > 0) {
+ selectedIds.splice(idxInSelected, 1);
+ selectedIds.unshift(preserveId);
+ }
+ }
+ }
+
+ return selectedIds.map((id) => trackIds.indexOf(id)).filter((i) => i >= 0);
+ }
+
+ unshuffle(): void {
+ this.state.shuffled = false;
+ this.state.shuffleOrder = [];
+ }
+
+ isShuffled(): boolean {
+ return this.state.shuffled;
+ }
+
+ private generateShuffleOrder(
+ length: number,
+ preserveIndex: number | null,
+ ): number[] {
+ if (length === 0) return [];
+
+ const indices = Array.from({ length }, (_, i) => i);
+
+ for (let i = indices.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ const valueAtI = indices[i];
+ const valueAtJ = indices[j];
+ if (valueAtI === undefined || valueAtJ === undefined) continue;
+ indices[i] = valueAtJ;
+ indices[j] = valueAtI;
+ }
+
+ if (preserveIndex !== null && preserveIndex < length) {
+ const currentInShuffle = indices.indexOf(preserveIndex);
+ if (currentInShuffle > 0) {
+ const first = indices[0];
+ const atPos = indices[currentInShuffle];
+ if (first !== undefined && atPos !== undefined) {
+ indices[0] = atPos;
+ indices[currentInShuffle] = first;
+ }
+ }
+ }
+
+ return indices;
+ }
+
+ updateHistory(trackId: string): void {
+ const existing = this.history.get(trackId);
+ if (existing) {
+ existing.lastPlayed = Date.now();
+ existing.playCount += 1;
+ } else {
+ this.history.set(trackId, {
+ trackId,
+ lastPlayed: Date.now(),
+ playCount: 1,
+ });
+ }
+
+ if (this.history.size > this.maxHistorySize) {
+ const sorted = Array.from(this.history.values()).sort(
+ (a, b) => a.lastPlayed - b.lastPlayed,
+ );
+ const toRemove = sorted.slice(0, this.history.size - this.maxHistorySize);
+ toRemove.forEach((h) => this.history.delete(h.trackId));
+ }
+ }
+
+ getPlayHistory(trackId: string): PlayHistory | undefined {
+ return this.history.get(trackId);
+ }
+
+ getAllHistory(): Map {
+ return new Map(this.history);
+ }
+
+ getState(): QueueState {
+ return { ...this.state, tracks: [...this.state.tracks] };
+ }
+
+ setState(state: Partial): void {
+ const { cursor, tracks, ...rest } = state;
+ if (tracks !== undefined) {
+ this.state.tracks = [...tracks];
+ }
+ if (cursor !== undefined) {
+ this.setCursor(cursor);
+ }
+ Object.assign(this.state, rest);
+ }
+
+ addTrack(track: Track): void {
+ this.state.tracks.push(track);
+ if (this.state.shuffled) {
+ this.mergeNewTrackIntoShuffleOrder();
+ }
+ }
+
+ private mergeNewTrackIntoShuffleOrder(): void {
+ const newIndex = this.state.tracks.length - 1;
+ this.state.shuffleOrder.push(newIndex);
+
+ if (this.state.shuffleOrder.length > 1) {
+ const swapPos = Math.floor(
+ Math.random() * (this.state.shuffleOrder.length - 1),
+ );
+ const atSwap = this.state.shuffleOrder[swapPos];
+ const atEnd = this.state.shuffleOrder[this.state.shuffleOrder.length - 1];
+ if (atSwap === undefined || atEnd === undefined) return;
+ this.state.shuffleOrder[swapPos] = atEnd;
+ this.state.shuffleOrder[this.state.shuffleOrder.length - 1] = atSwap;
+ }
+ }
+
+ removeTrack(trackId: string): void {
+ const index = this.state.tracks.findIndex((t) => t.id === trackId);
+ if (index === -1) return;
+
+ this.state.tracks.splice(index, 1);
+
+ switch (this.state.cursor.kind) {
+ case "empty":
+ break;
+ case "active": {
+ const { index: cursorIndex } = this.state.cursor;
+ if (cursorIndex > index) {
+ this.state.cursor = { kind: "active", index: cursorIndex - 1 };
+ } else if (cursorIndex === index) {
+ if (cursorIndex >= this.state.tracks.length) {
+ this.state.cursor = { kind: "empty" };
+ }
+ }
+ break;
+ }
+ default:
+ assertNever(this.state.cursor);
+ }
+
+ if (this.state.shuffled) {
+ this.state.shuffleOrder = this.state.shuffleOrder
+ .filter((i) => i !== index)
+ .map((i) => (i > index ? i - 1 : i));
+ }
+ }
+
+ clear(): void {
+ this.state.tracks = [];
+ this.state.cursor = { kind: "empty" };
+ this.state.shuffleOrder = [];
+ }
+
+ private trackForCursor(cursor: QueueCursor): Track | null {
+ switch (cursor.kind) {
+ case "empty":
+ return null;
+ case "active":
+ return this.state.tracks[cursor.index] ?? null;
+ default:
+ return assertNever(cursor);
+ }
+ }
+
+ private peekAdjacentCursor(direction: Direction): QueueCursor {
+ const order = this.getPlayOrder();
+ if (order.length === 0) return { kind: "empty" };
+
+ const last = order.length - 1;
+
+ switch (this.state.cursor.kind) {
+ case "empty": {
+ const first = order[0];
+ const lastIndex = order[last];
+ assertInvariant(
+ first !== undefined && lastIndex !== undefined,
+ "non-empty play order must yield both bounds",
+ );
+ return direction === "next"
+ ? { kind: "active", index: first }
+ : { kind: "active", index: lastIndex };
+ }
+ case "active": {
+ const currentPos = order.indexOf(this.state.cursor.index);
+ if (currentPos === -1) {
+ const first = order[0];
+ const lastIndex = order[last];
+ assertInvariant(
+ first !== undefined && lastIndex !== undefined,
+ "non-empty play order must yield both bounds",
+ );
+ return direction === "next"
+ ? { kind: "active", index: first }
+ : { kind: "active", index: lastIndex };
+ }
+ const adjacentPos =
+ direction === "next" ? currentPos + 1 : currentPos - 1;
+ const wrappedPos =
+ adjacentPos < 0 ? last : adjacentPos > last ? 0 : adjacentPos;
+ const wrapped = order[wrappedPos];
+ assertInvariant(
+ wrapped !== undefined,
+ "wrapped peek position must fall within the play order",
+ );
+ return { kind: "active", index: wrapped };
+ }
+ default:
+ return assertNever(this.state.cursor);
+ }
+ }
+}
diff --git a/Build/src/core/engine/scheduler/index.ts b/Build/src/core/engine/scheduler/index.ts
new file mode 100644
index 0000000..30c92d4
--- /dev/null
+++ b/Build/src/core/engine/scheduler/index.ts
@@ -0,0 +1,262 @@
+import type { CrossfadeConfig, GaplessConfig, Track } from "../types";
+
+export interface ScheduledTransition {
+ type: "crossfade" | "gapless";
+ fromTrack: Track;
+ toTrack: Track;
+ triggerTime: number;
+ duration: number;
+}
+
+export type TransitionCurve = "linear" | "equalpower";
+
+export class CrossfadeScheduler {
+ private config: CrossfadeConfig = {
+ enabled: false,
+ duration: 3000,
+ shape: "equalpower",
+ };
+
+ private activeTransition: ScheduledTransition | null = null;
+
+ setConfig(config: Partial): void {
+ this.config = { ...this.config, ...config };
+ }
+
+ getConfig(): CrossfadeConfig {
+ return { ...this.config };
+ }
+
+ isEnabled(): boolean {
+ return this.config.enabled && this.config.duration > 0;
+ }
+
+ calculateTriggerTime(
+ trackDuration: number,
+ currentTime: number,
+ ): number | null {
+ if (!this.isEnabled()) return null;
+
+ const durationSeconds = this.config.duration / 1000;
+ if (trackDuration <= durationSeconds) return null;
+
+ const triggerTime = trackDuration - durationSeconds;
+ if (currentTime >= triggerTime) {
+ return triggerTime;
+ }
+ return triggerTime;
+ }
+
+ shouldTrigger(currentTime: number, duration: number): boolean {
+ if (!this.isEnabled()) return false;
+
+ const triggerPoint = duration - this.config.duration;
+ return currentTime >= triggerPoint;
+ }
+
+ getCurve(): TransitionCurve {
+ return this.config.shape === "none" ? "linear" : this.config.shape;
+ }
+
+ calculateVolumes(progress: number): { fromVolume: number; toVolume: number } {
+ const { shape } = this.config;
+ const p = progress;
+
+ let fromVolume: number;
+ let toVolume: number;
+
+ switch (shape) {
+ case "equalpower":
+ fromVolume = Math.cos((p * Math.PI) / 2);
+ toVolume = Math.sin((p * Math.PI) / 2);
+ break;
+ case "linear":
+ fromVolume = 1 - p;
+ toVolume = p;
+ break;
+ default:
+ fromVolume = 1;
+ toVolume = 1;
+ }
+
+ return { fromVolume, toVolume };
+ }
+
+ createTransition(
+ fromTrack: Track,
+ toTrack: Track,
+ duration: number,
+ ): ScheduledTransition {
+ return {
+ type: "crossfade",
+ fromTrack,
+ toTrack,
+ triggerTime: Date.now(),
+ duration,
+ };
+ }
+
+ setActiveTransition(transition: ScheduledTransition | null): void {
+ this.activeTransition = transition;
+ }
+
+ getActiveTransition(): ScheduledTransition | null {
+ return this.activeTransition;
+ }
+
+ clearActiveTransition(): void {
+ this.activeTransition = null;
+ }
+}
+
+export class GaplessScheduler {
+ private config: GaplessConfig = {
+ enabled: true,
+ startOffset: 0,
+ endOffset: 0,
+ };
+
+ setConfig(config: Partial): void {
+ this.config = { ...this.config, ...config };
+ }
+
+ getConfig(): GaplessConfig {
+ return { ...this.config };
+ }
+
+ isEnabled(): boolean {
+ return this.config.enabled;
+ }
+
+ private samplesToSeconds(
+ samples: number | undefined,
+ fallback: number,
+ sampleRate: number | undefined,
+ ): number {
+ if (typeof samples !== "number" || !Number.isFinite(samples)) {
+ return fallback;
+ }
+ if (
+ typeof sampleRate !== "number" ||
+ !Number.isFinite(sampleRate) ||
+ sampleRate <= 0
+ ) {
+ return fallback;
+ }
+ return samples / sampleRate;
+ }
+
+ getStartOffset(track: Track): number {
+ return this.samplesToSeconds(
+ track.gapless?.encoderDelay,
+ this.config.startOffset,
+ track.encoding?.sampleRate,
+ );
+ }
+
+ getEndOffset(track: Track): number {
+ return this.samplesToSeconds(
+ track.gapless?.encoderPadding,
+ this.config.endOffset,
+ track.encoding?.sampleRate,
+ );
+ }
+
+ shouldPreload(currentTime: number, duration: number): boolean {
+ const preloadTime = 10;
+ return duration - currentTime <= preloadTime;
+ }
+
+ calculatePlayEnd(track: Track): number {
+ const offset = this.getEndOffset(track);
+ return track.duration - offset;
+ }
+
+ shouldTransition(currentTime: number, track: Track): boolean {
+ const playEnd = this.calculatePlayEnd(track);
+ const threshold = 0.1;
+ return currentTime >= playEnd - threshold;
+ }
+}
+
+export class Scheduler {
+ private crossfade: CrossfadeScheduler;
+ private gapless: GaplessScheduler;
+ private currentMode: "crossfade" | "gapless" | "none" = "none";
+
+ constructor() {
+ this.crossfade = new CrossfadeScheduler();
+ this.gapless = new GaplessScheduler();
+ }
+
+ setCrossfadeConfig(config: Partial): void {
+ this.crossfade.setConfig(config);
+ this.updateMode();
+ }
+
+ setGaplessConfig(config: Partial): void {
+ this.gapless.setConfig(config);
+ this.updateMode();
+ }
+
+ private updateMode(): void {
+ if (this.crossfade.isEnabled()) {
+ this.currentMode = "crossfade";
+ } else if (this.gapless.isEnabled() && this.gapless.getConfig().enabled) {
+ this.currentMode = "gapless";
+ } else {
+ this.currentMode = "none";
+ }
+ }
+
+ getMode(): "crossfade" | "gapless" | "none" {
+ return this.currentMode;
+ }
+
+ shouldPreload(currentTime: number, duration: number): boolean {
+ return this.gapless.shouldPreload(currentTime, duration);
+ }
+
+ shouldTriggerTransition(currentTime: number, track: Track): boolean {
+ switch (this.currentMode) {
+ case "crossfade":
+ return this.crossfade.shouldTrigger(currentTime, track.duration);
+ case "gapless":
+ return this.gapless.shouldTransition(currentTime, track);
+ default:
+ return false;
+ }
+ }
+
+ getTransitionParams(
+ currentTime: number,
+ track: Track,
+ ): {
+ triggerTime: number;
+ duration: number;
+ } | null {
+ switch (this.currentMode) {
+ case "crossfade":
+ const triggerTime = this.crossfade.calculateTriggerTime(
+ track.duration,
+ currentTime,
+ );
+ return triggerTime !== null
+ ? { triggerTime, duration: this.crossfade.getConfig().duration }
+ : null;
+ case "gapless":
+ const playEnd = this.gapless.calculatePlayEnd(track);
+ return { triggerTime: playEnd - 10, duration: 0 };
+ default:
+ return null;
+ }
+ }
+
+ getCrossfade(): CrossfadeScheduler {
+ return this.crossfade;
+ }
+
+ getGapless(): GaplessScheduler {
+ return this.gapless;
+ }
+}
diff --git a/Build/src/core/engine/state/index.ts b/Build/src/core/engine/state/index.ts
new file mode 100644
index 0000000..ae8a50f
--- /dev/null
+++ b/Build/src/core/engine/state/index.ts
@@ -0,0 +1,91 @@
+import type { PlayerState } from "../types";
+
+const VALID_TRANSITIONS: Record = {
+ idle: ["loading", "ready", "error"],
+ loading: ["ready", "error", "loading", "idle"],
+ ready: ["playing", "paused", "loading", "error", "idle"],
+ playing: ["paused", "transitioning", "ready", "error", "loading", "idle"],
+ paused: ["playing", "ready", "loading", "error", "idle"],
+ transitioning: ["playing", "paused", "ready", "idle", "error", "loading"],
+ error: ["loading", "ready", "idle"],
+};
+
+export class InvalidStateTransitionError extends Error {
+ readonly from: PlayerState;
+ readonly to: PlayerState;
+
+ constructor(from: PlayerState, to: PlayerState) {
+ super(`Transition from ${from} to ${to} is not allowed`);
+ this.name = "InvalidStateTransitionError";
+ this.from = from;
+ this.to = to;
+ }
+}
+
+export class StateMachine {
+ private state: PlayerState = "idle";
+ private history: PlayerState[] = [];
+
+ getState(): PlayerState {
+ return this.state;
+ }
+
+ canTransition(to: PlayerState): boolean {
+ return VALID_TRANSITIONS[this.state]?.includes(to) ?? false;
+ }
+
+ transition(to: PlayerState, force = false): boolean {
+ if (!force && !this.canTransition(to)) {
+ throw new InvalidStateTransitionError(this.state, to);
+ }
+ this.history.push(this.state);
+ if (this.history.length > 20) {
+ this.history.shift();
+ }
+ this.state = to;
+ return true;
+ }
+
+ isPlaying(): boolean {
+ return this.state === "playing";
+ }
+
+ isPaused(): boolean {
+ return this.state === "paused";
+ }
+
+ isIdle(): boolean {
+ return this.state === "idle";
+ }
+
+ isLoading(): boolean {
+ return this.state === "loading";
+ }
+
+ isReady(): boolean {
+ return this.state === "ready";
+ }
+
+ isTransitioning(): boolean {
+ return this.state === "transitioning";
+ }
+
+ hasError(): boolean {
+ return this.state === "error";
+ }
+
+ getPreviousState(): PlayerState | null {
+ return this.history.length > 0
+ ? (this.history[this.history.length - 1] ?? null)
+ : null;
+ }
+
+ getHistory(): PlayerState[] {
+ return [...this.history];
+ }
+
+ reset(): void {
+ this.state = "idle";
+ this.history = [];
+ }
+}
diff --git a/Build/src/core/engine/types.ts b/Build/src/core/engine/types.ts
new file mode 100644
index 0000000..5360fd6
--- /dev/null
+++ b/Build/src/core/engine/types.ts
@@ -0,0 +1,185 @@
+export type TrackSourceKind = "opfs" | "folderHandle";
+
+export interface Track {
+ id: string;
+ title: string;
+ artist: string;
+ album: string;
+ duration: number;
+ url: string;
+ mimeType?: string;
+ hasStoredAudio?: boolean;
+ sourceKind?: TrackSourceKind;
+ sourceId?: string;
+ path?: string;
+ albumArt?: string;
+ hasAlbumArt?: boolean;
+ embeddedLyrics?: EmbeddedLyrics[];
+ encoding?: EncodingDetails;
+ gapless?: GaplessInfo;
+ replayGain?: ReplayGainInfo;
+}
+
+export interface EmbeddedLyrics {
+ synced: boolean;
+ language?: string;
+ description?: string;
+ text?: string;
+ lines?: LyricLine[];
+}
+
+export interface LyricLine {
+ text: string;
+ timestamp: number;
+}
+
+export interface EncodingDetails {
+ bitrate?: number;
+ codec?: string;
+ sampleRate?: number;
+ channels?: number;
+ bitsPerSample?: number;
+ container?: string;
+ lossless?: boolean;
+ profile?: string;
+}
+
+export interface GaplessInfo {
+ encoderDelay?: number;
+ encoderPadding?: number;
+}
+
+export interface ReplayGainInfo {
+ trackGain?: number;
+ trackPeak?: number;
+ albumGain?: number;
+ albumPeak?: number;
+ referenceLoudness?: number;
+}
+
+export interface Playlist {
+ id: string;
+ name: string;
+ songs: Track[];
+}
+
+export interface PlaylistFolder {
+ id: string;
+ name: string;
+ children: (Playlist | PlaylistFolder)[];
+}
+
+export type PlaylistItem = Playlist | PlaylistFolder;
+
+export type QueueCursor = { kind: "empty" } | { kind: "active"; index: number };
+
+export interface QueueState {
+ tracks: Track[];
+ cursor: QueueCursor;
+ shuffled: boolean;
+ shuffleOrder: number[];
+}
+
+export interface PlayHistory {
+ trackId: string;
+ lastPlayed: number;
+ playCount: number;
+}
+
+export {
+ isQueueCursorEmpty,
+ isQueueCursorActive,
+ isQueueState,
+ isTrack,
+ isPlaylist,
+ isPlaylistItem,
+ isPlayHistory,
+ isRepeatMode,
+ isEngineSettings,
+ isPlainObject,
+} from "./validators";
+
+export interface EngineSettings {
+ volume: number;
+ crossfade: number;
+ crossfadeBeforeGapless: number;
+ autoPlayNext: boolean;
+ tempo: number;
+ pitch: number;
+ gaplessPlayback: boolean;
+ smartShuffle: boolean;
+ repeat: RepeatMode;
+ defaultShuffle: boolean;
+ defaultRepeat: RepeatMode;
+}
+
+export type RepeatMode = "off" | "one" | "all";
+
+export type PlayerState =
+ | "idle"
+ | "loading"
+ | "ready"
+ | "playing"
+ | "paused"
+ | "transitioning"
+ | "error";
+
+export interface EngineState {
+ state: PlayerState;
+ currentTrack: Track | null;
+ currentPlaylist: Playlist | null;
+ queue: QueueState;
+ settings: EngineSettings;
+ currentTime: number;
+ duration: number;
+ volume: number;
+ playHistory: Map;
+ error: EngineError | null;
+}
+
+export interface EngineError {
+ code: string;
+ message: string;
+ track?: Track;
+}
+
+export type EngineEvent =
+ | "statechange"
+ | "trackchange"
+ | "timeupdate"
+ | "durationchange"
+ | "volumechange"
+ | "queuechange"
+ | "settingschange"
+ | "ended"
+ | "loading"
+ | "ready"
+ | "error";
+
+export interface EngineEventMap {
+ statechange: { oldState: PlayerState; newState: PlayerState };
+ trackchange: { from: Track | null; to: Track | null };
+ timeupdate: { currentTime: number; duration: number };
+ durationchange: { duration: number };
+ volumechange: { volume: number };
+ queuechange: { queue: QueueState };
+ settingschange: { settings: Partial };
+ ended: { track: Track };
+ loading: { track: Track };
+ ready: { track: Track };
+ error: { error: EngineError };
+}
+
+export interface CrossfadeConfig {
+ enabled: boolean;
+ duration: number;
+ shape: CrossfadeShape;
+}
+
+export type CrossfadeShape = "none" | "linear" | "equalpower";
+
+export interface GaplessConfig {
+ enabled: boolean;
+ startOffset: number;
+ endOffset: number;
+}
diff --git a/Build/src/core/engine/validators.ts b/Build/src/core/engine/validators.ts
new file mode 100644
index 0000000..5d15341
--- /dev/null
+++ b/Build/src/core/engine/validators.ts
@@ -0,0 +1,127 @@
+import type {
+ EngineSettings,
+ Playlist,
+ PlaylistItem,
+ PlayHistory,
+ QueueCursor,
+ QueueState,
+ RepeatMode,
+ Track,
+} from "./types";
+
+export function isPlainObject(
+ value: unknown,
+): value is Record {
+ return typeof value === "object" && value !== null && !Array.isArray(value);
+}
+
+export function isQueueCursorEmpty(
+ cursor: QueueCursor,
+): cursor is { kind: "empty" } {
+ return cursor.kind === "empty";
+}
+
+export function isQueueCursorActive(
+ cursor: QueueCursor,
+): cursor is { kind: "active"; index: number } {
+ return (
+ cursor.kind === "active" &&
+ typeof cursor.index === "number" &&
+ Number.isInteger(cursor.index) &&
+ cursor.index >= 0
+ );
+}
+
+export function isQueueState(value: unknown): value is QueueState {
+ if (!isPlainObject(value)) return false;
+ if (!Array.isArray(value.tracks) || !value.tracks.every(isTrack)) {
+ return false;
+ }
+ if (typeof value.shuffled !== "boolean") return false;
+ if (
+ !Array.isArray(value.shuffleOrder) ||
+ !value.shuffleOrder.every((n) => typeof n === "number")
+ ) {
+ return false;
+ }
+
+ if (!isPlainObject(value.cursor)) return false;
+ switch (value.cursor.kind) {
+ case "empty":
+ return true;
+ case "active":
+ return (
+ typeof value.cursor.index === "number" &&
+ value.cursor.index >= 0 &&
+ value.cursor.index < value.tracks.length
+ );
+ default:
+ return false;
+ }
+}
+
+export function isTrack(value: unknown): value is Track {
+ if (!isPlainObject(value)) return false;
+ return (
+ typeof value.id === "string" &&
+ typeof value.title === "string" &&
+ typeof value.artist === "string" &&
+ typeof value.album === "string" &&
+ typeof value.duration === "number" &&
+ typeof value.url === "string"
+ );
+}
+
+export function isPlaylist(value: unknown): value is Playlist {
+ if (!isPlainObject(value)) return false;
+ return (
+ typeof value.id === "string" &&
+ typeof value.name === "string" &&
+ Array.isArray(value.songs) &&
+ value.songs.every(isTrack)
+ );
+}
+
+export function isPlaylistItem(value: unknown): value is PlaylistItem {
+ if (isPlaylist(value)) return true;
+ if (!isPlainObject(value)) return false;
+ if (typeof value.id !== "string" || typeof value.name !== "string") {
+ return false;
+ }
+ return Array.isArray(value.children) && value.children.every(isPlaylistItem);
+}
+
+export function isPlayHistory(value: unknown): value is PlayHistory {
+ if (!isPlainObject(value)) return false;
+ return (
+ typeof value.trackId === "string" &&
+ typeof value.lastPlayed === "number" &&
+ typeof value.playCount === "number"
+ );
+}
+
+const REPEAT_MODES: readonly RepeatMode[] = ["off", "one", "all"];
+
+export function isRepeatMode(value: unknown): value is RepeatMode {
+ return (
+ typeof value === "string" &&
+ (REPEAT_MODES as readonly string[]).includes(value)
+ );
+}
+
+export function isEngineSettings(value: unknown): value is EngineSettings {
+ if (!isPlainObject(value)) return false;
+ return (
+ typeof value.volume === "number" &&
+ typeof value.crossfade === "number" &&
+ typeof value.crossfadeBeforeGapless === "number" &&
+ typeof value.autoPlayNext === "boolean" &&
+ typeof value.tempo === "number" &&
+ typeof value.pitch === "number" &&
+ typeof value.gaplessPlayback === "boolean" &&
+ typeof value.smartShuffle === "boolean" &&
+ isRepeatMode(value.repeat) &&
+ typeof value.defaultShuffle === "boolean" &&
+ isRepeatMode(value.defaultRepeat)
+ );
+}
diff --git a/Build/src/data/legal.ts b/Build/src/data/legal.ts
new file mode 100644
index 0000000..34aa52f
--- /dev/null
+++ b/Build/src/data/legal.ts
@@ -0,0 +1,120 @@
+export interface LegalSection {
+ heading: string;
+ content: string | string[];
+}
+
+export interface LegalDocument {
+ title: string;
+ effectiveDate: string;
+ sections: LegalSection[];
+ contact: string;
+}
+
+export const privacyPolicy: LegalDocument = {
+ title: "HTMLPlayer Privacy Policy",
+ effectiveDate: "9/23/2025",
+ sections: [
+ {
+ heading: "1. Introduction",
+ content: `HTMLPlayer respects your privacy. Since the App is primarily client-side,
+we do not collect personal data unless you interact with external services
+(e.g., Discord integration).`,
+ },
+ {
+ heading: "2. Data Collection",
+ content: [
+ "The App does not collect personal information by default.",
+ "Optional Discord integration may send limited information (username, current activity) to Discord's servers for the purpose of updating your music activity.",
+ ],
+ },
+ {
+ heading: "3. Cookies and Tracking",
+ content:
+ "HTMLPlayer does not use cookies or trackers for analytics or advertising.",
+ },
+ {
+ heading: "4. Third-Party Services",
+ content: `Discord integration is managed via OAuth; your authorization is handled by
+Discord directly. HTMLPlayer does not store Discord credentials or share
+data outside the Discord API.`,
+ },
+ {
+ heading: "5. Security",
+ content: `All client-side operations run in your browser; no server-side storage of
+music or personal data occurs. We take no responsibility for security
+vulnerabilities in your browser or Discord.`,
+ },
+ {
+ heading: "6. Data Sharing",
+ content:
+ "HTMLPlayer does not sell, trade, or share personal information with third parties, except through authorized use of Discord features.",
+ },
+ {
+ heading: "7. Updates to Privacy Policy",
+ content:
+ "We may update this Privacy Policy as HTMLPlayer evolves. Continued use indicates acceptance of the latest policy.",
+ },
+ {
+ heading: "8. Contact",
+ content: "For privacy questions, contact: nellowtcs@gmail.com",
+ },
+ ],
+ contact: "nellowtcs@gmail.com",
+};
+
+export const termsOfService: LegalDocument = {
+ title: "HTMLPlayer Terms of Service (TOS)",
+ effectiveDate: "9/23/2025",
+ sections: [
+ {
+ heading: "1. Acceptance of Terms",
+ content:
+ 'By using HTMLPlayer (the "App"), you agree to these Terms of Service. If you do not agree, do not use the App.',
+ },
+ {
+ heading: "2. Use of the App",
+ content: [
+ "HTMLPlayer is a free, open-source music player.",
+ "All core functionality runs client-side in your browser; we do not collect usage data except when explicitly interacting with external services like Discord.",
+ "You may use the App for personal, non-commercial purposes.",
+ ],
+ },
+ {
+ heading: "3. Intellectual Property",
+ content: `HTMLPlayer and its source code are licensed under the
+MIT License. You may copy, modify, or redistribute the App according to the MIT License terms.`,
+ },
+ {
+ heading: "4. Discord Integration",
+ content: `The App may optionally integrate with Discord to display music activity.
+Access to Discord features requires you to authorize HTMLPlayer via
+Discord OAuth. HTMLPlayer does not store your Discord credentials.`,
+ },
+ {
+ heading: "5. Beta Disclaimer",
+ content:
+ "HTMLPlayer is currently in beta. Features may be unstable or incomplete. Use at your own risk.",
+ },
+ {
+ heading: "6. No Warranty",
+ content: `The App is provided "as-is" without warranty of any kind, either express
+or implied. The developers are not liable for any damages arising from the
+use or inability to use HTMLPlayer.`,
+ },
+ {
+ heading: "7. Limitation of Liability",
+ content:
+ "You use HTMLPlayer entirely at your own risk. Developers are not responsible for any loss, data corruption, or other issues resulting from your use of the App.",
+ },
+ {
+ heading: "8. Modifications to Terms",
+ content:
+ "We may update these Terms at any time. Continued use constitutes acceptance of the updated Terms.",
+ },
+ {
+ heading: "9. Contact",
+ content: "For questions about these Terms, contact: nellowtcs@gmail.com",
+ },
+ ],
+ contact: "nellowtcs@gmail.com",
+};
diff --git a/Build/src/global.css b/Build/src/global.css
index e4278a0..6236fbc 100644
--- a/Build/src/global.css
+++ b/Build/src/global.css
@@ -2,34 +2,20 @@
@import "@fontsource/poppins";
@import "@fontsource/jetbrains-mono";
@import "@fontsource/caveat";
+@import "./ui/theming/base-theme.css";
-/* This root block is kept separate as these values do not change between light and dark mode */
/* prettier-ignore */
:root {
- /* Layers */
- /* Content */
- /* Low content */
--z-content-low: 10;
- /* Standard content */
--z-content: 20;
- /* High standard content (has high standards :P) */
--z-content-high: 30;
- /* Navigation */
- /* Low navigation */
--z-nav-low: 100;
- /* Primary navigation */
--z-nav: 200;
- /* Sticky navigation */
--z-nav-sticky: 300;
- /* Dialogs, Dropdowns, etc. */
--z-overlay: 400;
- /* Tutorials, Guides */
--z-spotlight: 1000;
- /* Other */
- /* Critical stuff */
--z-critical: 2000;
- /* Fonts */
--font-family-base: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
--font-family-heading: "Poppins", -apple-system, BlinkMacSystemFont,
@@ -39,19 +25,16 @@
"Liberation Mono", Menlo, monospace;
--font-family-cursive: "Caveat", cursive;
- /* Radii */
--radius-sm: 0.25rem;
--radius: 0.5rem;
--radius-md: 0.75rem;
--radius-lg: 1rem;
--radius-full: 9999px;
- /* Animation */
--animation-duration-fast: 150ms;
--animation-duration-normal: 250ms;
--animation-duration-slow: 350ms;
- /* Spacing */
--spacing-1: 0.25rem;
--spacing-2: 0.5rem;
--spacing-3: 0.75rem;
@@ -61,9 +44,15 @@
--spacing-12: 3rem;
--spacing-16: 4rem;
- /* Miscellaneous */
+ --spacing-layout: 15px;
+ --player-art-size: 115px;
--sidebar-width: 250px;
--sidebar-collapsed-width: 40px;
+ --miniplayer-control-size: 2rem;
+ --miniplayer-main-control-size: 2.25rem;
+ --settings-sheet-max-width: 860px;
+ --settings-sidebar-min-width: 230px;
+ --settings-sidebar-max-width: 240px;
}
@@ -71,21 +60,19 @@ body {
font-family: var(--font-family-base);
margin: 0;
padding: 0;
- /* background: var(--themegradient); */
overflow: hidden;
}
-/* html {
+html {
+ overflow-y: auto;
background: var(--themegradient);
-} */
+ background-attachment: fixed;
+}
#root {
min-height: 100vh;
- /* background: var(--themegradient); */
}
-/* Loading screen is global for now */
-/* Loading Screen */
.loadingScreen {
position: fixed;
inset: 0;
@@ -143,10 +130,103 @@ body {
margin: 0;
}
-/* Mobile-specific CSS variable overrides */
@media (max-width: 768px) {
:root {
--sidebar-width: 0px;
- /* Sidebar is overlay on mobile, doesn't affect layout */
+ }
+}
+
+::view-transition-old(root),
+::view-transition-new(root) {
+ background: var(--themegradient);
+}
+
+html[data-vt-direction="forward"]::view-transition-old(root) {
+ --vt-slide-offset: -60px;
+ animation:
+ var(--animation-duration-fast) ease-in both vtFade reverse,
+ var(--animation-duration-normal) ease-in-out both vtSlide reverse;
+}
+
+html[data-vt-direction="forward"]::view-transition-new(root) {
+ --vt-slide-offset: 60px;
+ animation:
+ var(--animation-duration-fast) ease-out both vtFade,
+ var(--animation-duration-normal) ease-in-out both vtSlide;
+}
+
+html[data-vt-direction="back"]::view-transition-old(root) {
+ --vt-slide-offset: 60px;
+ animation:
+ var(--animation-duration-fast) ease-in both vtFade reverse,
+ var(--animation-duration-normal) ease-in-out both vtSlide reverse;
+}
+
+html[data-vt-direction="back"]::view-transition-new(root) {
+ --vt-slide-offset: -60px;
+ animation:
+ var(--animation-duration-fast) ease-out both vtFade,
+ var(--animation-duration-normal) ease-in-out both vtSlide;
+}
+
+@keyframes vtFade {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes vtSlide {
+ from {
+ translate: var(--vt-slide-offset);
+ }
+ to {
+ translate: 0;
+ }
+}
+
+@layer utilities {
+ .search-wrapper {
+ position: relative;
+ }
+
+ .search-icon {
+ position: absolute;
+ left: var(--spacing-3);
+ top: 50%;
+ transform: translateY(-50%);
+ pointer-events: none;
+ }
+
+ .search-input {
+ background: var(--surface-transparent-1);
+ border: 1px solid var(--surface-transparent-2);
+ color: var(--primary-foreground);
+ padding-left: calc(var(--spacing-3) * 2 + 16px);
+ border-radius: var(--radius);
+ }
+
+ .search-input::placeholder {
+ color: var(--primary-foreground);
+ }
+
+ .search-input:focus {
+ outline: var(--shadow);
+ border-color: var(--primary-border-strong);
+ box-shadow: 0 0 0 2px var(--primary-transparent-2);
+ }
+
+ .action-button-lift {
+ transition: transform var(--animation-duration-fast) ease;
+ }
+
+ .action-button-lift:hover {
+ transform: translateY(-1px);
+ }
+
+ .action-button-lift:active {
+ transform: translateY(0);
}
}
diff --git a/Build/src/helpers/addSong.ts b/Build/src/helpers/addSong.ts
new file mode 100644
index 0000000..0fde503
--- /dev/null
+++ b/Build/src/helpers/addSong.ts
@@ -0,0 +1,48 @@
+import type { Track, TrackSourceKind } from "../core/engine/types";
+import { saveAudio } from "../platform/storage/opfs";
+import { trackStorage } from "../platform/storage/trackStorage";
+
+export interface ImportContext {
+ sourceKind?: TrackSourceKind;
+ sourceId?: string;
+ path?: string;
+}
+
+export async function prepareAndStoreSong(
+ song: Track,
+ file: File,
+): Promise {
+ song.url = URL.createObjectURL(file);
+ song.hasStoredAudio = true;
+ await saveAudio(song.id, file);
+ await trackStorage.saveTrack(song);
+ return song;
+}
+
+export async function storeImportedSong(
+ song: Track,
+ file: File,
+ context?: ImportContext,
+): Promise {
+ const sourcePath = context?.path ?? song.path;
+ if (
+ context?.sourceKind === "folderHandle" &&
+ context.sourceId &&
+ sourcePath
+ ) {
+ song.sourceKind = context.sourceKind;
+ song.sourceId = context.sourceId;
+ song.path = sourcePath;
+ song.hasStoredAudio = true;
+ song.url = "";
+ await trackStorage.saveTrack(song);
+ return song;
+ }
+ return prepareAndStoreSong(song, file);
+}
+
+export async function storeRemoteSong(song: Track): Promise {
+ song.hasStoredAudio = false;
+ await trackStorage.saveTrack(song);
+ return song;
+}
diff --git a/Build/src/helpers/audioProcessor.ts b/Build/src/helpers/audioProcessor.ts
deleted file mode 100644
index c691d36..0000000
--- a/Build/src/helpers/audioProcessor.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { toast } from "sonner";
-import { musicIndexedDbHelper } from "./musicIndexedDbHelper";
-import i18n from "i18next";
-import initFlo from "@flo-audio/libflo-audio";
-
-export const createAudioProcessor = () => {
- let floInitialized = false;
- const processAudioBatch = async (songs: Song[]): Promise => {
- // Ensure flo WASM is initialized before any decode
- if (!floInitialized) {
- await initFlo();
- floInitialized = true;
- }
- const processedSongs: Song[] = [];
- const totalSongs = songs.length;
- let processedCount = 0;
-
- // Show initial toast
- const toastId = toast.loading(
- i18n.t("audioProcessor.processingZero", { totalSongs }),
- );
-
- for (const song of songs) {
- if (song.url.startsWith("blob:")) {
- try {
- // Load the audio data
- const res = await fetch(song.url);
- const buf = await res.arrayBuffer();
- let mimeType = res.headers.get("content-type") || "audio/mpeg";
- const ext = song.url.split(".").pop()?.toLowerCase() || "";
-
- // If flo file, decode using @flo-audio/libflo-audio (placeholder)
- if (ext === "flo") {
- // TODO: Integrate @flo-audio/libflo-audio decoder here
- // Example:
- // import { decodeFlo } from '@flo-audio/libflo-audio';
- // const pcmData = await decodeFlo(buf);
- // ...convert pcmData to AudioBuffer and store/play as needed...
- mimeType = "audio/x-flo";
- }
-
- // Save to IndexedDB audio store
- await musicIndexedDbHelper.saveSongAudio(song.id, {
- fileData: buf,
- mimeType,
- });
-
- // Add processed song without the audio data
- processedSongs.push({
- ...song,
- hasStoredAudio: true,
- albumArt: song.albumArt, // Preserve album art when processing
- });
-
- processedCount++;
- // Update toast with progress
- toast.loading(
- i18n.t("audioProcessor.processing", { processedCount, totalSongs }),
- {
- id: toastId,
- description: i18n.t("audioProcessor.current", {
- songTitle: song.title,
- }),
- },
- );
- } catch (error) {
- const err = error as Error;
- console.error(
- i18n.t("audioProcessor.failedToProcess", { songTitle: song.title }),
- err,
- );
- toast.error(`Failed to process "${song.title}"`, {
- description: err.message || i18n.t("common.unknownError"),
- });
- processedSongs.push(song);
- }
- } else {
- processedSongs.push(song);
- processedCount++;
- }
- }
-
- // Show completion toast
- toast.success(i18n.t("audioProcessor.processed", { processedCount }), {
- id: toastId,
- });
-
- return processedSongs;
- };
-
- const getValidTempo = (tempo: number | undefined) => {
- if (typeof tempo !== "number" || !Number.isFinite(tempo) || tempo <= 0) {
- return 1; // fallback to normal speed
- }
- return tempo;
- };
-
- return {
- processAudioBatch,
- getValidTempo,
- };
-};
diff --git a/Build/src/helpers/cacheManager.ts b/Build/src/helpers/cacheManager.ts
deleted file mode 100644
index ac312c8..0000000
--- a/Build/src/helpers/cacheManager.ts
+++ /dev/null
@@ -1,444 +0,0 @@
-import { MutableRefObject, useCallback } from "react";
-import { musicIndexedDbHelper } from "./musicIndexedDbHelper";
-
-const CACHE_CONFIG = {
- PREV_SONGS: 1, // Number of previous songs to cache
- NEXT_SONGS: 2, // Number of next songs to cache
- CACHE_EXPIRY: 5 * 60 * 1000, // 5 minutes
- MAX_CACHE_SIZE: 15, // Maximum number of songs to cache
- PRELOAD_THRESHOLD: 7 * 1024 * 1024, // 7MB, only preload smaller files
-};
-
-// Cache management utilities with improved error handling and performance
-export const createCacheManager = (
- songCacheRef: MutableRefObject>,
-) => {
- const cacheSong = async (song: Song): Promise => {
- // Check if song is already cached and valid
- const existingCache = songCacheRef.current.get(song.id);
- if (existingCache) {
- // Check if cache is still valid
- const cacheAge = Date.now() - existingCache.loadedAt;
- if (cacheAge < CACHE_CONFIG.CACHE_EXPIRY) {
- // Update URL if it's from IndexedDB and needs refresh
- if (song.hasStoredAudio && song.url.startsWith("indexeddb://")) {
- try {
- const audioData = await musicIndexedDbHelper.loadSongAudio(song.id);
- if (audioData && !existingCache.url.startsWith("blob:")) {
- // Need to create new blob URL
- const newUrl = URL.createObjectURL(
- new Blob([audioData.fileData], { type: audioData.mimeType }),
- );
- // Revoke old URL if it was a blob
- if (existingCache.url.startsWith("blob:")) {
- URL.revokeObjectURL(existingCache.url);
- }
- // Update cache with new URL
- songCacheRef.current.set(song.id, {
- ...existingCache,
- url: newUrl,
- song: { ...song, url: newUrl },
- loadedAt: Date.now(),
- });
- }
- } catch (error) {
- console.warn(
- "Failed to refresh IndexedDB cache for song:",
- song.id,
- error,
- );
- }
- }
- // Already cached, no need to return anything
- } else {
- // Cache expired, remove it
- if (existingCache.url.startsWith("blob:")) {
- URL.revokeObjectURL(existingCache.url);
- }
- songCacheRef.current.delete(song.id);
- }
- }
-
- try {
- let audioData;
- let mimeType: string;
-
- // First try to load from IndexedDB
- if (song.hasStoredAudio) {
- console.log("CacheManager: Loading song from IndexedDB:", song.id);
- audioData = await musicIndexedDbHelper.loadSongAudio(song.id);
- if (audioData) {
- const url = URL.createObjectURL(
- new Blob([audioData.fileData], { type: audioData.mimeType }),
- );
- songCacheRef.current.set(song.id, {
- song: { ...song, url },
- url,
- loadedAt: Date.now(),
- });
- console.log(
- "CacheManager: Successfully cached song from IndexedDB:",
- song.title,
- );
- return; // Successfully loaded from IndexedDB, exit early
- } else {
- // Audio was marked as stored but not found in IndexedDB
- console.warn(
- "CacheManager: Song has stored audio but not found in IndexedDB:",
- song.id,
- );
- return; // Don't try to fetch if audio should be in IndexedDB
- }
- }
-
- if (
- !song.url ||
- song.url.startsWith("indexeddb://") ||
- song.url.includes("about:blank")
- ) {
- console.error(
- "CacheManager: No valid URL to fetch song from:",
- song.id,
- );
- return;
- }
-
- console.log("CacheManager: Fetching song from URL:", song.title);
-
- // Check if we should preload based on file size (if available)
- let shouldCache = true;
-
- try {
- const headResponse = await fetch(song.url, { method: "HEAD" });
- const contentLength = headResponse.headers.get("content-length");
- if (contentLength) {
- const fileSize = parseInt(contentLength);
- if (fileSize > CACHE_CONFIG.PRELOAD_THRESHOLD) {
- console.log(
- "CacheManager: Large file detected, skipping aggressive caching:",
- song.title,
- );
- shouldCache = false;
- }
- }
- } catch (headError) {
- // HEAD request failed, continue with normal caching
- console.warn(
- "CacheManager: HEAD request failed, continuing with caching:",
- headError,
- );
- }
-
- const response = await fetch(song.url);
- if (!response.ok) {
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
- }
-
- const buffer = await response.arrayBuffer();
- mimeType = response.headers.get("content-type") || "audio/mpeg";
- const url = URL.createObjectURL(new Blob([buffer], { type: mimeType }));
-
- // Cache in memory if appropriate
- if (shouldCache || buffer.byteLength <= CACHE_CONFIG.PRELOAD_THRESHOLD) {
- songCacheRef.current.set(song.id, {
- song: { ...song, url },
- url,
- loadedAt: Date.now(),
- });
- }
-
- // Always save to IndexedDB for future use (unless it came from there originally)
- if (!song.hasStoredAudio) {
- try {
- await musicIndexedDbHelper.saveSongAudio(song.id, {
- fileData: buffer,
- mimeType: mimeType,
- });
- console.log("CacheManager: Saved song to IndexedDB:", song.title);
- } catch (dbError) {
- console.warn("CacheManager: Failed to save to IndexedDB:", dbError);
- }
- }
-
- console.log(
- "CacheManager: Successfully cached song from URL:",
- song.title,
- );
- } catch (error) {
- console.error("CacheManager: Failed to cache song:", song.title, error);
- }
- };
-
- const getCachedSong = (songId: string): CachedSong | undefined => {
- const cached = songCacheRef.current.get(songId);
- if (cached) {
- // Check if cache is still valid
- const cacheAge = Date.now() - cached.loadedAt;
- if (cacheAge < CACHE_CONFIG.CACHE_EXPIRY) {
- return cached;
- } else {
- // Cache expired, remove it
- if (cached.url.startsWith("blob:")) {
- URL.revokeObjectURL(cached.url);
- }
- songCacheRef.current.delete(songId);
- }
- }
- return undefined;
- };
-
- const clearExpiredCache = () => {
- const now = Date.now();
- const expiredKeys: string[] = [];
-
- for (const [id, cached] of songCacheRef.current.entries()) {
- if (now - cached.loadedAt > CACHE_CONFIG.CACHE_EXPIRY) {
- expiredKeys.push(id);
- if (cached.url.startsWith("blob:")) {
- URL.revokeObjectURL(cached.url);
- }
- }
- }
-
- expiredKeys.forEach((key) => songCacheRef.current.delete(key));
-
- if (expiredKeys.length > 0) {
- console.log(
- `CacheManager: Cleared ${expiredKeys.length} expired cache entries`,
- );
- }
- };
-
- const enforceCacheSize = () => {
- if (songCacheRef.current.size <= CACHE_CONFIG.MAX_CACHE_SIZE) return;
-
- // Sort by last accessed time (oldest first)
- const entries = Array.from(songCacheRef.current.entries()).sort(
- (a, b) => a[1].loadedAt - b[1].loadedAt,
- );
-
- const toRemove = entries.slice(
- 0,
- songCacheRef.current.size - CACHE_CONFIG.MAX_CACHE_SIZE,
- );
-
- for (const [id, cached] of toRemove) {
- if (cached.url.startsWith("blob:")) {
- URL.revokeObjectURL(cached.url);
- }
- songCacheRef.current.delete(id);
- }
-
- console.log(
- `CacheManager: Removed ${toRemove.length} entries to enforce cache size limit`,
- );
- };
-
- // Helper to ensure playlist songs have correct URLs
- const prepareSongsForPlaylist = useCallback((songs: Song[]): Song[] => {
- return songs.map((song) => {
- if (song.hasStoredAudio) {
- // Always use indexeddb:// URL for stored songs
- return {
- ...song,
- url: `indexeddb://${song.id}`,
- };
- } else if (songCacheRef.current.has(song.id)) {
- // If song is in cache, use its cached URL
- const cached = songCacheRef.current.get(song.id);
- return {
- ...song,
- url: cached?.url || song.url,
- };
- }
- return song;
- });
- }, []);
-
- const updateSongCache = async (
- currentSong: Song | null,
- playlist: Playlist | null,
- playerStateRef: MutableRefObject,
- settingsRef: MutableRefObject,
- playHistoryRef: MutableRefObject<
- Map
- >,
- getSmartShuffledSong: (
- availableSongs: Song[],
- currentSongId: string,
- playHistory: Map,
- ) => Song | null,
- ) => {
- if (!currentSong || !playlist) return;
-
- // Periodic cleanup
- clearExpiredCache();
- enforceCacheSize();
-
- const currentIndex = playlist.songs.findIndex(
- (s) => s.id === currentSong.id,
- );
- if (currentIndex === -1) return;
-
- // Get the range of songs to cache (surrounding the current song)
- const start = Math.max(0, currentIndex - CACHE_CONFIG.PREV_SONGS);
- const end = Math.min(
- playlist.songs.length - 1,
- currentIndex + CACHE_CONFIG.NEXT_SONGS,
- );
-
- // Get next shuffled songs if shuffle is enabled (cache multiple for better performance)
- const nextShuffledSongs: Song[] = [];
- if (playerStateRef.current.shuffle) {
- const availableSongs = playlist.songs.filter(
- (_, i) => i !== currentIndex,
- );
-
- if (availableSongs.length > 0) {
- // Cache multiple potential next songs for shuffle
- const songsToGenerate = Math.min(3, availableSongs.length);
- const usedSongs = new Set();
-
- for (let i = 0; i < songsToGenerate; i++) {
- let nextSong: Song | null = null;
-
- if (settingsRef.current.smartShuffle) {
- // Use smart shuffle for caching
- const availableForThis = availableSongs.filter(
- (s) => !usedSongs.has(s.id),
- );
- nextSong = getSmartShuffledSong(
- availableForThis,
- currentSong.id,
- playHistoryRef.current,
- );
- } else {
- // Use regular shuffle for caching
- const availableForThis = availableSongs.filter(
- (s) => !usedSongs.has(s.id),
- );
- if (availableForThis.length > 0) {
- const randomIndex = Math.floor(
- Math.random() * availableForThis.length,
- );
- nextSong = availableForThis[randomIndex];
- }
- }
-
- if (nextSong && !usedSongs.has(nextSong.id)) {
- nextShuffledSongs.push(nextSong);
- usedSongs.add(nextSong.id);
- }
- }
- }
- }
-
- // Create a set of songs to cache (prioritize nearby songs and shuffled options)
- const songsToCache = new Set([
- ...playlist.songs.slice(start, end + 1),
- ...nextShuffledSongs,
- ]);
-
- // Cache new songs (prioritize current and next songs)
- const cachePromises: Promise[] = [];
- const songsArray = Array.from(songsToCache);
-
- // Sort by priority: current song first, then immediate neighbors, then shuffled options
- songsArray.sort((a, b) => {
- if (a.id === currentSong.id) return -1;
- if (b.id === currentSong.id) return 1;
-
- const aIndex = playlist.songs.findIndex((s) => s.id === a.id);
- const bIndex = playlist.songs.findIndex((s) => s.id === b.id);
-
- const aDistance = Math.abs(aIndex - currentIndex);
- const bDistance = Math.abs(bIndex - currentIndex);
-
- return aDistance - bDistance;
- });
-
- // Cache songs in priority order
- for (const song of songsArray) {
- if (!songCacheRef.current.has(song.id)) {
- cachePromises.push(cacheSong(song));
- }
- }
-
- // Remove songs that are no longer needed (but keep some buffer)
- const currentCacheIds = new Set(Array.from(songCacheRef.current.keys()));
- const keepIds = new Set(songsArray.map((song) => song.id));
-
- for (const cachedId of currentCacheIds) {
- if (!keepIds.has(cachedId)) {
- const cached = songCacheRef.current.get(cachedId);
- if (cached) {
- // Only remove if it's not recently accessed
- const age = Date.now() - cached.loadedAt;
- if (age > CACHE_CONFIG.CACHE_EXPIRY / 2) {
- if (cached.url.startsWith("blob:")) {
- URL.revokeObjectURL(cached.url);
- }
- songCacheRef.current.delete(cachedId);
- }
- }
- }
- }
-
- // Wait for priority caches to complete (don't block on all)
- try {
- const results = await Promise.allSettled(cachePromises);
- const successful = results.filter(
- (r) => r.status === "fulfilled" && r.value,
- ).length;
- console.log(
- `CacheManager: Successfully cached ${successful} of ${cachePromises.length} songs`,
- );
- } catch (error) {
- console.error("CacheManager: Error in batch caching:", error);
- }
- };
-
- const clearAllCache = () => {
- console.log("CacheManager: Clearing all cache");
-
- // Revoke all object URLs and clear the cache
- for (const [, cached] of songCacheRef.current.entries()) {
- if (cached.url.startsWith("blob:")) {
- URL.revokeObjectURL(cached.url);
- }
- }
- songCacheRef.current.clear();
- };
-
- const getCacheStats = () => {
- const now = Date.now();
- let validCount = 0;
- let expiredCount = 0;
-
- for (const [, cached] of songCacheRef.current.entries()) {
- if (now - cached.loadedAt < CACHE_CONFIG.CACHE_EXPIRY) {
- validCount++;
- } else {
- expiredCount++;
- }
- }
-
- return {
- total: songCacheRef.current.size,
- valid: validCount,
- expired: expiredCount,
- maxSize: CACHE_CONFIG.MAX_CACHE_SIZE,
- };
- };
-
- return {
- cacheSong,
- getCachedSong,
- clearExpiredCache,
- enforceCacheSize,
- prepareSongsForPlaylist,
- updateSongCache,
- clearAllCache,
- getCacheStats,
- };
-};
diff --git a/Build/src/helpers/crossfadeHelper.ts b/Build/src/helpers/crossfadeHelper.ts
deleted file mode 100644
index 9bf6fc7..0000000
--- a/Build/src/helpers/crossfadeHelper.ts
+++ /dev/null
@@ -1,541 +0,0 @@
-import i18n from "i18next";
-
-export interface CrossfadeOptions {
- duration: number;
- curve?: "linear" | "exponential" | "smooth";
-}
-
-export interface AudioSource {
- element: HTMLAudioElement;
- source: MediaElementAudioSourceNode;
- gainNode: GainNode;
- id: string;
-}
-
-/**
- * Validate and clamp pitch value
- */
-function getValidPitch(pitch: number | undefined): number {
- if (typeof pitch !== "number" || !Number.isFinite(pitch)) {
- return 0; // Default to no pitch shift
- }
- // Clamp to -48 to +48 semitones
- return Math.max(-48, Math.min(48, pitch));
-}
-
-export class CrossfadeManager {
- private audioContext: AudioContext;
- private masterGain: GainNode;
- private analyzerNode: AnalyserNode;
-
- private currentSource: AudioSource | null = null;
- private nextSource: AudioSource | null = null;
-
- private crossfadeInProgress = false;
- private crossfadeTimeout: number | null = null;
- private crossfadePromise: Promise | null = null;
-
- // Track which audio element is the "active" one for UI updates
- private activeElement: HTMLAudioElement | null = null;
-
- // Current pitch setting
- private currentPitch: number = 0;
-
- // Track the current song ended handler for cleanup
- private currentEndedHandler: (() => void) | null = null;
-
- constructor(audioContext: AudioContext) {
- this.audioContext = audioContext;
-
- // Create master gain node
- this.masterGain = audioContext.createGain();
- this.masterGain.connect(audioContext.destination);
-
- // Create analyzer for visualizations
- this.analyzerNode = audioContext.createAnalyser();
- this.analyzerNode.fftSize = 2048;
- this.masterGain.connect(this.analyzerNode);
- }
-
- /**
- * Create an audio source with proper Web Audio setup
- */
- createAudioSource(audioElement: HTMLAudioElement): AudioSource {
- // Check if this element already has an audio source
- const existingSource = (audioElement as any)._webAudioSource;
- if (existingSource && existingSource.source.mediaElement === audioElement) {
- return existingSource;
- }
-
- try {
- const source = this.audioContext.createMediaElementSource(audioElement);
- const gainNode = this.audioContext.createGain();
-
- // Connect: MediaElementSource -> GainNode -> MasterGain
- source.connect(gainNode);
- gainNode.connect(this.masterGain);
-
- const audioSource: AudioSource = {
- element: audioElement,
- source,
- gainNode,
- id: Math.random().toString(36).substr(2, 9),
- };
-
- // Store reference to prevent multiple sources for same element
- (audioElement as any)._webAudioSource = audioSource;
-
- return audioSource;
- } catch (error) {
- console.error("Failed to create audio source:", error);
- throw error;
- }
- }
-
- /**
- * Set the current playing source
- */
- setCurrentSource(source: AudioSource) {
- if (this.currentSource !== source) {
- this.currentSource = source;
- this.activeElement = source.element;
-
- // Set to full volume
- this.currentSource.gainNode.gain.setValueAtTime(
- 1,
- this.audioContext.currentTime,
- );
-
- // Mute any previous sources
- if (this.nextSource && this.nextSource !== source) {
- this.nextSource.gainNode.gain.setValueAtTime(
- 0,
- this.audioContext.currentTime,
- );
- }
- }
- }
-
- /**
- * Prepare the next source for crossfading
- */
- prepareNextSource(source: AudioSource) {
- this.nextSource = source;
- // Start muted
- this.nextSource.gainNode.gain.setValueAtTime(
- 0,
- this.audioContext.currentTime,
- );
- }
-
- /**
- * Start crossfade from current to next source
- */
- async startCrossfade(options: CrossfadeOptions): Promise {
- if (!this.currentSource || !this.nextSource) {
- throw new Error("Cannot start crossfade - missing audio sources");
- }
-
- if (this.crossfadeInProgress) {
- console.warn("Crossfade already in progress, cancelling previous");
- this.cancelCrossfade();
- }
-
- // Ensure audio context is running (may be suspended on mobile after tab switch)
- if (this.audioContext.state === "suspended") {
- console.log("Resuming suspended audio context before crossfade");
- await this.audioContext.resume();
- }
-
- this.crossfadeInProgress = true;
- const { duration, curve = "smooth" } = options;
- const now = this.audioContext.currentTime;
-
- console.log("Starting crossfade transition...");
-
- this.crossfadePromise = new Promise(async (resolve, reject) => {
- try {
- // Ensure next audio is ready to play
- if (this.nextSource!.element.readyState < 2) {
- await new Promise((loadResolve, loadReject) => {
- const timeout = setTimeout(() => {
- loadReject(
- new Error(i18n.t("crossfade.nextAudioFailedToLoadInTime")),
- );
- }, 5000);
-
- const cleanup = () => {
- clearTimeout(timeout);
- this.nextSource!.element.removeEventListener("canplay", onReady);
- this.nextSource!.element.removeEventListener(
- "loadeddata",
- onReady,
- );
- this.nextSource!.element.removeEventListener("error", onError);
- };
-
- const onReady = () => {
- cleanup();
- loadResolve();
- };
-
- const onError = () => {
- cleanup();
- loadReject(new Error(i18n.t("crossfade.nextAudioFailedToLoad")));
- };
-
- this.nextSource!.element.addEventListener("canplay", onReady);
- this.nextSource!.element.addEventListener("loadeddata", onReady);
- this.nextSource!.element.addEventListener("error", onError);
- });
- }
-
- // Start playing the next audio element
- await this.nextSource!.element.play();
-
- // Set up crossfade curves
- this.setupCrossfadeCurves(duration, curve, now);
-
- // Switch active element immediately so UI shows the new song
- this.activeElement = this.nextSource!.element;
-
- // Listen for current song ending
- const handleCurrentEnded = () => {
- if (this.crossfadeInProgress) {
- console.log("Current song ended during crossfade");
- this.currentEndedHandler = null; // Clear reference since it fired
- this.completeCrossfade();
- resolve();
- }
- };
-
- // Store handler reference for potential cleanup in cancelCrossfade
- this.currentEndedHandler = handleCurrentEnded;
-
- this.currentSource!.element.addEventListener(
- "ended",
- handleCurrentEnded,
- { once: true },
- );
-
- // Set timeout for crossfade completion
- this.crossfadeTimeout = window.setTimeout(
- () => {
- if (this.crossfadeInProgress) {
- this.currentSource!.element.removeEventListener(
- "ended",
- handleCurrentEnded,
- );
- this.completeCrossfade();
- resolve();
- }
- },
- duration * 1000 + 100,
- );
- } catch (error) {
- console.error("Crossfade failed:", error);
- this.crossfadeInProgress = false;
- this.clearCrossfadeTimeout();
- reject(error);
- }
- });
-
- return this.crossfadePromise;
- }
-
- /**
- * Set up crossfade curves using Web Audio gain automation
- */
- private setupCrossfadeCurves(
- duration: number,
- curve: string,
- startTime: number,
- ) {
- if (!this.currentSource || !this.nextSource) return;
-
- const currentGain = this.currentSource.gainNode.gain;
- const nextGain = this.nextSource.gainNode.gain;
-
- // Cancel any existing automation
- currentGain.cancelScheduledValues(startTime);
- nextGain.cancelScheduledValues(startTime);
-
- const endTime = startTime + duration;
-
- switch (curve) {
- case "linear":
- // Linear crossfade
- currentGain.setValueAtTime(1, startTime);
- currentGain.linearRampToValueAtTime(0, endTime);
-
- nextGain.setValueAtTime(0, startTime);
- nextGain.linearRampToValueAtTime(1, endTime);
- break;
-
- case "exponential":
- // Exponential crossfade (more natural for audio)
- currentGain.setValueAtTime(1, startTime);
- currentGain.exponentialRampToValueAtTime(0.001, endTime); // Can't ramp to exactly 0
-
- nextGain.setValueAtTime(0.001, startTime);
- nextGain.exponentialRampToValueAtTime(1, endTime);
- break;
-
- case "smooth":
- default:
- // Equal-power crossfade (best for music)
- const steps = 20;
- const stepDuration = duration / steps;
-
- for (let i = 0; i <= steps; i++) {
- const progress = i / steps;
- const time = startTime + i * stepDuration;
-
- // Equal-power curves: sqrt(1-x) and sqrt(x)
- const currentLevel = Math.sqrt(1 - progress);
- const nextLevel = Math.sqrt(progress);
-
- if (i === 0) {
- currentGain.setValueAtTime(currentLevel, time);
- nextGain.setValueAtTime(nextLevel, time);
- } else {
- currentGain.linearRampToValueAtTime(currentLevel, time);
- nextGain.linearRampToValueAtTime(nextLevel, time);
- }
- }
- break;
- }
- }
-
- /**
- * Complete the crossfade transition
- */
- private completeCrossfade() {
- if (!this.crossfadeInProgress) return;
-
- try {
- console.log("Completing crossfade transition");
-
- // Clear the ended handler reference (it either fired or will be removed by {once: true})
- this.currentEndedHandler = null;
-
- // Stop the old audio
- if (this.currentSource) {
- this.currentSource.element.pause();
- this.currentSource.element.currentTime = 0;
- this.currentSource.gainNode.gain.setValueAtTime(
- 0,
- this.audioContext.currentTime,
- );
- }
-
- // Ensure next source is at full volume
- if (this.nextSource) {
- this.nextSource.gainNode.gain.setValueAtTime(
- 1,
- this.audioContext.currentTime,
- );
- }
-
- // Swap sources
- this.currentSource = this.nextSource;
- this.nextSource = null;
-
- this.crossfadeInProgress = false;
- this.crossfadePromise = null;
- this.clearCrossfadeTimeout();
- } catch (error) {
- console.error("Error completing crossfade:", error);
- this.crossfadeInProgress = false;
- }
- }
-
- /**
- * Cancel an ongoing crossfade
- */
- cancelCrossfade() {
- if (!this.crossfadeInProgress) return;
-
- console.log("Cancelling crossfade");
-
- try {
- const now = this.audioContext.currentTime;
-
- // Remove the ended event listener if it hasn't fired yet
- if (this.currentEndedHandler && this.currentSource) {
- this.currentSource.element.removeEventListener(
- "ended",
- this.currentEndedHandler,
- );
- this.currentEndedHandler = null;
- }
-
- // Stop any scheduled gain changes
- if (this.currentSource) {
- this.currentSource.gainNode.gain.cancelScheduledValues(now);
- this.currentSource.gainNode.gain.setValueAtTime(1, now);
- }
-
- if (this.nextSource) {
- this.nextSource.gainNode.gain.cancelScheduledValues(now);
- this.nextSource.gainNode.gain.setValueAtTime(0, now);
- this.nextSource.element.pause();
- this.nextSource.element.currentTime = 0;
- }
-
- // Reset active element to current source
- if (this.currentSource) {
- this.activeElement = this.currentSource.element;
- }
-
- this.crossfadeInProgress = false;
- this.crossfadePromise = null;
- this.clearCrossfadeTimeout();
- } catch (error) {
- console.error("Error cancelling crossfade:", error);
- }
- }
-
- /**
- * Clear crossfade timeout
- */
- private clearCrossfadeTimeout() {
- if (this.crossfadeTimeout) {
- clearTimeout(this.crossfadeTimeout);
- this.crossfadeTimeout = null;
- }
- }
-
- /**
- * Set master volume
- */
- setMasterVolume(volume: number) {
- const clampedVolume = Math.max(0, Math.min(1, volume));
- const now = this.audioContext.currentTime;
-
- this.masterGain.gain.cancelScheduledValues(now);
- this.masterGain.gain.setValueAtTime(this.masterGain.gain.value, now);
- this.masterGain.gain.linearRampToValueAtTime(clampedVolume, now + 0.1);
- }
-
- /**
- * Get the active audio element (for UI synchronization)
- */
- getActiveElement(): HTMLAudioElement | null {
- return this.activeElement;
- }
-
- /**
- * Check if crossfade is active
- */
- isCrossfading(): boolean {
- return this.crossfadeInProgress;
- }
-
- /**
- * Get master gain node for analyzer connections
- */
- getMasterGainNode(): GainNode {
- return this.masterGain;
- }
-
- /**
- * Get analyzer node for visualizations
- */
- getAnalyzerNode(): AnalyserNode {
- return this.analyzerNode;
- }
-
- /**
- * Seek the active audio element
- */
- seekTo(time: number) {
- if (this.activeElement) {
- this.activeElement.currentTime = time;
- }
- }
-
- /**
- * Get current time from active element
- */
- getCurrentTime(): number {
- return this.activeElement?.currentTime || 0;
- }
-
- /**
- * Get duration from active element
- */
- getDuration(): number {
- return this.activeElement?.duration || 0;
- }
-
- /**
- * Check if active element is playing
- */
- isPlaying(): boolean {
- return this.activeElement ? !this.activeElement.paused : false;
- }
-
- /**
- * Play the active element
- */
- async play(): Promise {
- if (this.activeElement) {
- await this.activeElement.play();
- }
- }
-
- /**
- * Pause the active element
- */
- pause() {
- if (this.activeElement) {
- this.activeElement.pause();
- }
- }
-
- /**
- * Update pitch for all audio sources
- */
- setPitch(pitch: number) {
- this.currentPitch = getValidPitch(pitch);
- }
-
- /**
- * Get current pitch setting
- */
- getPitch(): number {
- return this.currentPitch;
- }
-
- /**
- * Clean up resources
- */
- destroy() {
- console.log("Destroying crossfade manager");
-
- this.cancelCrossfade();
-
- try {
- // Disconnect all nodes
- if (this.currentSource) {
- this.currentSource.source.disconnect();
- this.currentSource.gainNode.disconnect();
- }
-
- if (this.nextSource) {
- this.nextSource.source.disconnect();
- this.nextSource.gainNode.disconnect();
- }
-
- this.analyzerNode.disconnect();
- this.masterGain.disconnect();
- } catch (error) {
- console.error("Error during cleanup:", error);
- }
-
- this.currentSource = null;
- this.nextSource = null;
- this.activeElement = null;
- }
-}
diff --git a/Build/src/helpers/crossfadeUtils.ts b/Build/src/helpers/crossfadeUtils.ts
deleted file mode 100644
index 7b70588..0000000
--- a/Build/src/helpers/crossfadeUtils.ts
+++ /dev/null
@@ -1,542 +0,0 @@
-import { MutableRefObject } from "react";
-import { CrossfadeManager, AudioSource } from "./crossfadeHelper";
-import { calculateGaplessOffsets } from "./gaplessHelper";
-import { getValidPlaybackRate } from "./musicPlayerUtils";
-
-export const createCrossfadeManager = (
- audioRef: MutableRefObject,
- nextAudioRef: MutableRefObject,
- crossfadeManagerRef: MutableRefObject,
- currentAudioSourceRef: MutableRefObject,
- nextAudioSourceRef: MutableRefObject,
- gaplessAdvanceTriggeredRef?: MutableRefObject,
- gaplessStartAppliedRef?: MutableRefObject,
-) => {
- const setupCrossfadeManager = (audioContext: AudioContext) => {
- try {
- if (!crossfadeManagerRef.current) {
- console.log("CrossfadeUtils: Creating new crossfade manager");
- crossfadeManagerRef.current = new CrossfadeManager(audioContext);
- }
-
- // Setup current audio source
- if (!currentAudioSourceRef.current && audioRef.current) {
- console.log("CrossfadeUtils: Setting up current audio source");
- currentAudioSourceRef.current =
- crossfadeManagerRef.current.createAudioSource(audioRef.current);
- crossfadeManagerRef.current.setCurrentSource(
- currentAudioSourceRef.current,
- );
- }
-
- return crossfadeManagerRef.current;
- } catch (error) {
- console.error(
- "CrossfadeUtils: Failed to setup crossfade manager:",
- error,
- );
- return null;
- }
- };
-
- const getNextSongForCrossfade = (
- getAndCacheNextSong: () => Song | null,
- ): Song | null => {
- try {
- return getAndCacheNextSong();
- } catch (error) {
- console.error(
- "CrossfadeUtils: Failed to get next song for crossfade:",
- error,
- );
- return null;
- }
- };
-
- const prepareNextSongForCrossfade = async (
- nextSong: Song,
- cacheSong: (song: Song) => Promise,
- getCachedSong: (songId: string) => any,
- settingsRef: MutableRefObject,
- ): Promise => {
- if (!nextAudioRef.current || !crossfadeManagerRef.current) {
- throw new Error(
- "CrossfadeUtils: Missing audio elements for crossfade preparation",
- );
- }
-
- console.log(
- "CrossfadeUtils: Preparing next song for crossfade:",
- nextSong.title,
- );
-
- try {
- // Cache the song first
- console.log("CrossfadeUtils: Caching next song");
- await cacheSong(nextSong);
- const cachedSong = getCachedSong(nextSong.id);
-
- if (!cachedSong) {
- throw new Error(`Failed to cache next song: ${nextSong.title}`);
- }
-
- // Set up the next audio element
- nextAudioRef.current.pause();
- nextAudioRef.current.currentTime = 0;
- nextAudioRef.current.src = cachedSong.url;
- // Apply combined tempo and pitch rate, clamped to browser limits
- nextAudioRef.current.playbackRate = getValidPlaybackRate(
- settingsRef.current.tempo,
- settingsRef.current.pitch,
- );
-
- console.log("CrossfadeUtils: Waiting for next audio to be ready");
-
- // Wait for the audio to be ready with timeout
- await new Promise((resolve, reject) => {
- const timeout = setTimeout(() => {
- cleanup();
- reject(new Error("Timeout waiting for audio to load"));
- }, 10000);
-
- const cleanup = () => {
- clearTimeout(timeout);
- nextAudioRef.current?.removeEventListener("canplay", onCanPlay);
- nextAudioRef.current?.removeEventListener("loadeddata", onCanPlay);
- nextAudioRef.current?.removeEventListener("error", onError);
- };
-
- const onCanPlay = () => {
- console.log("CrossfadeUtils: Next audio is ready");
- cleanup();
- resolve();
- };
-
- const onError = (e: Event) => {
- console.error("CrossfadeUtils: Error loading next audio:", e);
- cleanup();
- reject(new Error("Failed to load next audio"));
- };
-
- // Check if already ready
- if (nextAudioRef.current!.readyState >= 2) {
- cleanup();
- resolve();
- return;
- }
-
- nextAudioRef.current!.addEventListener("canplay", onCanPlay);
- nextAudioRef.current!.addEventListener("loadeddata", onCanPlay);
- nextAudioRef.current!.addEventListener("error", onError);
-
- // Trigger loading
- nextAudioRef.current!.load();
- });
-
- const offsets = calculateGaplessOffsets(nextSong);
- if (offsets.start > 0 && offsets.start < nextAudioRef.current.duration) {
- try {
- nextAudioRef.current.currentTime = offsets.start;
- } catch (error) {
- console.warn(
- "CrossfadeUtils: Failed to apply gapless start offset to next track:",
- error,
- );
- }
- }
-
- // Create and prepare audio source for crossfade manager
- if (
- !nextAudioSourceRef.current ||
- nextAudioSourceRef.current.element !== nextAudioRef.current
- ) {
- nextAudioSourceRef.current =
- crossfadeManagerRef.current.createAudioSource(nextAudioRef.current);
- }
-
- crossfadeManagerRef.current.prepareNextSource(nextAudioSourceRef.current);
- console.log(
- "CrossfadeUtils: Next song prepared successfully for crossfade",
- );
- } catch (error) {
- console.error(
- "CrossfadeUtils: Failed to prepare next song for crossfade:",
- error,
- );
- throw error;
- }
- };
-
- const updatePlayerStateAfterCrossfade = (
- nextSong: Song,
- playerStateRef: MutableRefObject,
- playHistoryRef: MutableRefObject<
- Map
- >,
- updatePlayHistory: (
- playHistoryRef: MutableRefObject<
- Map
- >,
- songId: string,
- ) => void,
- setPlayerState: (updater: (prev: any) => any) => void,
- audioRef: MutableRefObject,
- nextAudioRef: MutableRefObject,
- currentAudioSourceRef: MutableRefObject,
- nextAudioSourceRef: MutableRefObject,
- invalidateNextSongCache?: () => void,
- ) => {
- console.log(
- "CrossfadeUtils: Updating player state after crossfade to:",
- nextSong.title,
- );
-
- try {
- // Update play history ONLY if we're in shuffle mode and have a current song
- if (
- playerStateRef.current.currentSong &&
- playerStateRef.current.shuffle
- ) {
- updatePlayHistory(
- playHistoryRef,
- playerStateRef.current.currentSong.id,
- );
- console.log("CrossfadeUtils: Updated play history for shuffle mode");
- }
-
- // Swap audio elements - next becomes current
- const tempAudio = audioRef.current;
- audioRef.current = nextAudioRef.current;
- nextAudioRef.current = tempAudio;
-
- // Swap audio sources
- const tempSource = currentAudioSourceRef.current;
- currentAudioSourceRef.current = nextAudioSourceRef.current;
- nextAudioSourceRef.current = tempSource;
-
- // Clean up the old audio element (now in nextAudioRef) to prevent memory leaks
- // Revoke blob URL if present, then clear source
- if (nextAudioRef.current) {
- const oldSrc = nextAudioRef.current.src;
- if (oldSrc && oldSrc.startsWith("blob:")) {
- try {
- URL.revokeObjectURL(oldSrc);
- console.log("CrossfadeUtils: Revoked blob URL from previous song");
- } catch (e) {
- // Ignore errors from revoking already-revoked URLs
- }
- }
- // Pause and reset the old element for reuse
- nextAudioRef.current.pause();
- nextAudioRef.current.currentTime = 0;
- // Don't clear src yet: the cacheManager may still reference it
- }
-
- // Get current time from the crossfade manager (which tracks the active element)
- const currentTime = crossfadeManagerRef.current?.getCurrentTime() || 0;
-
- // Update player state
- setPlayerState((prev: any) => {
- console.log(
- "CrossfadeUtils: Finalizing player state after crossfade:",
- nextSong.title,
- "currentTime:",
- currentTime,
- );
- return {
- ...prev,
- currentTime: currentTime,
- // currentSong and duration already set at crossfade start
- };
- });
-
- // Invalidate next song cache since we changed songs
- if (invalidateNextSongCache) {
- invalidateNextSongCache();
- console.log(
- "CrossfadeUtils: Invalidated next song cache after crossfade",
- );
- }
-
- console.log("CrossfadeUtils: Player state updated successfully");
- } catch (error) {
- console.error(
- "CrossfadeUtils: Error updating player state after crossfade:",
- error,
- );
- }
- };
-
- const preloadNextSong = async (
- getNextSongForCrossfadeFunc: () => Song | null,
- cacheSong: (song: Song) => Promise,
- getCachedSong: (songId: string) => any,
- settingsRef: MutableRefObject,
- ) => {
- if (!nextAudioRef.current || crossfadeManagerRef.current?.isCrossfading()) {
- console.log(
- "CrossfadeUtils: Skipping preload - no audio element or crossfade in progress",
- );
- return;
- }
-
- try {
- const nextSong = getNextSongForCrossfadeFunc();
- if (!nextSong) {
- console.log("CrossfadeUtils: No next song to preload");
- return;
- }
-
- console.log("CrossfadeUtils: Preloading next song:", nextSong.title);
-
- // Cache the next song
- await cacheSong(nextSong);
- const cachedSong = getCachedSong(nextSong.id);
-
- if (cachedSong) {
- // Pre-set the source but don't play yet
- nextAudioRef.current.src = cachedSong.url;
- // Apply combined tempo and pitch rate, clamped to browser limits
- nextAudioRef.current.playbackRate = getValidPlaybackRate(
- settingsRef.current.tempo,
- settingsRef.current.pitch,
- );
-
- // Preload the audio data
- nextAudioRef.current.preload = "auto";
- nextAudioRef.current.load();
-
- console.log("CrossfadeUtils: Successfully preloaded next song");
- }
- } catch (error) {
- console.warn("CrossfadeUtils: Failed to preload next song:", error);
- }
- };
-
- const startCrossfadeTransition = async (
- playNextRef: MutableRefObject<(() => void) | null>,
- getNextSongForCrossfadeFunc: () => Song | null,
- prepareNextSongForCrossfadeFunc: (nextSong: Song) => Promise,
- playerStateRef: MutableRefObject,
- playHistoryRef: MutableRefObject<
- Map
- >,
- updatePlayHistory: (
- playHistoryRef: MutableRefObject<
- Map
- >,
- songId: string,
- ) => void,
- setPlayerState: (updater: (prev: any) => any) => void,
- settingsRef: MutableRefObject,
- audioContextRef?: MutableRefObject,
- invalidateNextSongCache?: () => void,
- gaplessAdvanceTriggeredRefParam?: MutableRefObject,
- gaplessStartAppliedRefParam?: MutableRefObject,
- ) => {
- console.log("CrossfadeUtils: Starting crossfade transition...");
-
- if (!playNextRef.current) {
- console.warn("CrossfadeUtils: No playNext function available");
- throw new Error("No playNext function available for crossfade");
- }
-
- // Initialize crossfade manager if needed
- if (!crossfadeManagerRef.current) {
- if (audioContextRef?.current) {
- console.log("CrossfadeUtils: Initializing crossfade manager");
- const manager = setupCrossfadeManager(audioContextRef.current);
- if (!manager) {
- throw new Error("Failed to initialize crossfade manager");
- }
- } else {
- throw new Error("No audio context available for crossfade");
- }
- }
-
- if (!audioRef.current) {
- throw new Error("No current audio element available");
- }
-
- if (!nextAudioRef.current) {
- throw new Error("No next audio element available");
- }
-
- // Ensure current source is properly set up
- if (
- !currentAudioSourceRef.current ||
- currentAudioSourceRef.current.element !== audioRef.current
- ) {
- console.log("CrossfadeUtils: Setting up current audio source");
- currentAudioSourceRef.current =
- crossfadeManagerRef.current!.createAudioSource(audioRef.current);
- crossfadeManagerRef.current!.setCurrentSource(
- currentAudioSourceRef.current,
- );
- }
-
- // Cancel any existing crossfade
- if (
- crossfadeManagerRef.current &&
- crossfadeManagerRef.current.isCrossfading()
- ) {
- console.log("CrossfadeUtils: Cancelling existing crossfade");
- crossfadeManagerRef.current.cancelCrossfade();
- }
-
- try {
- // Get the next song
- const nextSong = getNextSongForCrossfadeFunc();
- if (!nextSong) {
- throw new Error("No next song available for crossfade");
- }
-
- console.log(
- "CrossfadeUtils: Preparing next song for crossfade:",
- nextSong.title,
- );
-
- // Prepare the next audio source
- await prepareNextSongForCrossfadeFunc(nextSong);
-
- const offsets = calculateGaplessOffsets(nextSong);
- const rawDuration =
- nextAudioRef.current && Number.isFinite(nextAudioRef.current.duration)
- ? nextAudioRef.current.duration
- : nextSong.duration || 0;
- const trimmedDuration = rawDuration - offsets.start - offsets.end;
- const effectiveDuration =
- Number.isFinite(trimmedDuration) && trimmedDuration > 0.1
- ? trimmedDuration
- : rawDuration;
-
- if (gaplessAdvanceTriggeredRefParam) {
- gaplessAdvanceTriggeredRefParam.current = false;
- } else if (gaplessAdvanceTriggeredRef) {
- gaplessAdvanceTriggeredRef.current = false;
- }
-
- if (gaplessStartAppliedRefParam) {
- gaplessStartAppliedRefParam.current = offsets.start > 0;
- } else if (gaplessStartAppliedRef) {
- gaplessStartAppliedRef.current = offsets.start > 0;
- }
-
- // Ensure audio context is running
- if (audioContextRef?.current?.state === "suspended") {
- console.log("CrossfadeUtils: Resuming audio context");
- await audioContextRef.current.resume();
- }
-
- const crossfadeDuration = Math.max(
- 0.5,
- Math.min(10, settingsRef.current.crossfade || 3),
- );
-
- // If there's less time remaining than the crossfade duration, shorten the crossfade
- const timeRemaining = audioRef.current
- ? audioRef.current.duration - audioRef.current.currentTime
- : crossfadeDuration;
- const effectiveCrossfadeDuration = Math.min(
- crossfadeDuration,
- Math.max(0.5, timeRemaining),
- );
-
- console.log(
- "CrossfadeUtils: Starting crossfade with effective duration:",
- effectiveCrossfadeDuration,
- "(requested:",
- crossfadeDuration,
- "time remaining:",
- timeRemaining.toFixed(1) + ")",
- );
-
- // Update player state immediately when crossfade starts
- console.log("CrossfadeUtils: Updating player state at crossfade start");
- setPlayerState((prev: any) => ({
- ...prev,
- currentSong: nextSong,
- currentTime: 0, // Start from beginning for the new song
- duration:
- effectiveDuration && effectiveDuration > 0
- ? effectiveDuration
- : nextSong.duration || 0,
- isPlaying: true,
- }));
-
- // Start the crossfade
- await crossfadeManagerRef.current!.startCrossfade({
- duration: effectiveCrossfadeDuration,
- curve: "smooth",
- });
-
- console.log(
- "CrossfadeUtils: Crossfade completed, finalizing player state",
- );
-
- // Finalize player state after crossfade completes (swap audio elements)
- updatePlayerStateAfterCrossfade(
- nextSong,
- playerStateRef,
- playHistoryRef,
- updatePlayHistory,
- setPlayerState,
- audioRef,
- nextAudioRef,
- currentAudioSourceRef,
- nextAudioSourceRef,
- invalidateNextSongCache,
- );
-
- console.log(
- "CrossfadeUtils: Crossfade transition completed successfully",
- );
- } catch (error) {
- console.error("CrossfadeUtils: Crossfade transition failed:", error);
-
- // Revert UI state back to current song since crossfade failed
- console.log("CrossfadeUtils: Reverting UI state after failed crossfade");
- setPlayerState((prev: any) => ({
- ...prev,
- currentSong: playerStateRef.current.currentSong, // Revert to the song that was actually playing
- currentTime: audioRef.current?.currentTime || prev.currentTime,
- duration: playerStateRef.current.currentSong?.duration || prev.duration,
- }));
-
- // Cleanup failed crossfade
- if (crossfadeManagerRef.current?.isCrossfading()) {
- crossfadeManagerRef.current.cancelCrossfade();
- }
-
- throw error; // Re-throw to be handled by caller
- }
- };
-
- const cleanupCrossfadeManager = () => {
- console.log("CrossfadeUtils: Cleaning up crossfade manager");
-
- try {
- if (crossfadeManagerRef.current) {
- crossfadeManagerRef.current.destroy();
- crossfadeManagerRef.current = null;
- }
-
- currentAudioSourceRef.current = null;
- nextAudioSourceRef.current = null;
-
- console.log("CrossfadeUtils: Cleanup completed");
- } catch (error) {
- console.error("CrossfadeUtils: Error during cleanup:", error);
- }
- };
-
- return {
- setupCrossfadeManager,
- getNextSongForCrossfade,
- prepareNextSongForCrossfade,
- updatePlayerStateAfterCrossfade,
- preloadNextSong,
- startCrossfadeTransition,
- cleanupCrossfadeManager,
- };
-};
diff --git a/Build/src/helpers/discordService.ts b/Build/src/helpers/discordService.ts
deleted file mode 100644
index 258514a..0000000
--- a/Build/src/helpers/discordService.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Discord Rich Presence Service
- * Handles sending track updates to the Discord backend API
- */
-
-export interface DiscordPresenceData {
- userId: string;
- details: string; // Track name
- state: string; // Artist name
-}
-
-export class DiscordService {
- private static readonly API_BASE_URL =
- "https://htmlplayer-backend.onrender.com";
- private static instance: DiscordService | null = null;
-
- private constructor() {}
-
- public static getInstance(): DiscordService {
- if (!DiscordService.instance) {
- DiscordService.instance = new DiscordService();
- }
- return DiscordService.instance;
- }
-
- /**
- * Log track update instead of sending to Discord backend
- */
- public async updatePresence(data: DiscordPresenceData): Promise {
- console.log(
- `[DiscordService] Would POST to ${DiscordService.API_BASE_URL}/presence with:`,
- data,
- );
- return true;
- }
-
- /**
- * Log clear presence instead of sending to Discord backend
- */
- public async clearPresence(userId: string): Promise {
- console.log(`[DiscordService] Would clear presence for userId: ${userId}`);
- return true;
- }
-
- /**
- * Parse Discord user ID from OAuth callback URL
- * This would be called when the OAuth callback is handled
- */
- public static parseUserIdFromCallback(url: string): string | null {
- try {
- const urlObj = new URL(url);
- const code = urlObj.searchParams.get("code");
-
- if (!code) {
- return null;
- }
-
- // In a real implementation, you would exchange the code for user info
- // For now, we'll need to handle this differently since the callback goes to the backend
- // The backend should provide the user ID somehow
-
- return null; // This will be handled by the OAuth callback flow
- } catch (error) {
- console.error("Error parsing Discord callback:", error);
- return null;
- }
- }
-
- /**
- * Check if Discord integration is available and user is connected
- */
- public static isDiscordAvailable(userId?: string): boolean {
- return Boolean(userId && userId.length > 0);
- }
-}
-
-export default DiscordService;
diff --git a/Build/src/helpers/discordService_backup.ts b/Build/src/helpers/discordService_backup.ts
deleted file mode 100644
index 7c0e65e..0000000
--- a/Build/src/helpers/discordService_backup.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Discord Rich Presence Service
- * Handles sending track updates to the Discord backend API
- */
-
-export interface DiscordPresenceData {
- userId: string;
- details: string; // Track name
- state: string; // Artist name
-}
-
-export class DiscordService {
- private static readonly API_BASE_URL =
- "https://htmlplayer-backend.onrender.com";
- private static instance: DiscordService | null = null;
-
- private constructor() {}
-
- public static getInstance(): DiscordService {
- if (!DiscordService.instance) {
- DiscordService.instance = new DiscordService();
- }
- return DiscordService.instance;
- }
-
- /**
- * Send track update to Discord backend
- */
- public async updatePresence(data: DiscordPresenceData): Promise {
- try {
- const response = await fetch(`${DiscordService.API_BASE_URL}/presence`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(data),
- });
-
- if (!response.ok) {
- console.error(
- "Failed to update Discord presence:",
- response.status,
- response.statusText,
- );
- return false;
- }
-
- return true;
- } catch (error) {
- console.error("Error updating Discord presence:", error);
- return false;
- }
- }
-
- /**
- * Clear Discord presence (when music stops)
- */
- public async clearPresence(userId: string): Promise {
- try {
- // Send empty details and state to clear presence
- return await this.updatePresence({
- userId,
- details: "",
- state: "",
- });
- } catch (error) {
- console.error("Error clearing Discord presence:", error);
- return false;
- }
- }
-
- /**
- * Parse Discord user ID from OAuth callback URL
- * This would be called when the OAuth callback is handled
- */
- public static parseUserIdFromCallback(url: string): string | null {
- try {
- const urlObj = new URL(url);
- const code = urlObj.searchParams.get("code");
-
- if (!code) {
- return null;
- }
-
- // In a real implementation, you would exchange the code for user info
- // For now, we'll need to handle this differently since the callback goes to the backend
- // The backend should provide the user ID somehow
-
- return null; // This will be handled by the OAuth callback flow
- } catch (error) {
- console.error("Error parsing Discord callback:", error);
- return null;
- }
- }
-
- /**
- * Check if Discord integration is available and user is connected
- */
- public static isDiscordAvailable(userId?: string): boolean {
- return Boolean(userId && userId.length > 0);
- }
-}
-
-export default DiscordService;
diff --git a/Build/src/helpers/filePickerHelper.tsx b/Build/src/helpers/filePickerHelper.tsx
deleted file mode 100644
index 3e872a6..0000000
--- a/Build/src/helpers/filePickerHelper.tsx
+++ /dev/null
@@ -1,1017 +0,0 @@
-import { toast } from "sonner";
-import { parseBlob, selectCover } from "music-metadata";
-import Uppy from "@uppy/core";
-import Dashboard from "@uppy/react/dashboard";
-import "@uppy/core/css/style.min.css";
-import "@uppy/dashboard/css/style.min.css";
-import { useState, useEffect, useRef } from "react";
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
-} from "../components/Dialog";
-import ReactDOM from "react-dom/client";
-import { useTranslation } from "react-i18next";
-import i18n from "i18next";
-import { IconRegistryProvider } from "./iconLoader";
-import { importAudioFiles } from "./importAudioFiles";
-
-// Extend Window interface for File Handling API
-declare global {
- interface Window {
- launchQueue?: {
- setConsumer: (
- consumer: (launchParams: {
- files: FileSystemFileHandle[] | File[];
- }) => void,
- ) => void;
- };
- }
-}
-
-export interface AudioFile {
- file: File;
- name: string;
- size: number;
- type: string;
-}
-
-export interface AudioMetadata {
- title: string;
- artist: string;
- album: string;
- duration: number;
- albumArt?: string;
- embeddedLyrics?: EmbeddedLyrics[];
- encoding?: EncodingDetails;
- gapless?: GaplessInfo;
- metadataWarnings?: string[];
-}
-
-export interface EncodingDetails {
- bitrate?: number;
- codec?: string;
- sampleRate?: number;
- channels?: number;
- bitsPerSample?: number;
- container?: string;
- lossless?: boolean;
- profile?: string;
-}
-
-export interface GaplessInfo {
- encoderDelay?: number;
- encoderPadding?: number;
-}
-
-/**
- * Compress album art to reduce memory usage
- * Skips compression for animated images (WebP, GIF) to preserve animation
- */
-async function compressAlbumArt(
- base64: string,
- maxSize = 200,
-): Promise {
- // Check if it's an animated format
- const isAnimatedFormat =
- base64.startsWith("data:image/webp") || base64.startsWith("data:image/gif");
-
- if (isAnimatedFormat) {
- console.log("Skipping compression for animated image");
- return base64; // Return original to preserve animation
- }
-
- return new Promise((resolve, reject) => {
- const img = new Image();
-
- img.onerror = () => reject(new Error("Failed to load image"));
-
- img.onload = () => {
- const canvas = document.createElement("canvas");
- let width = img.width;
- let height = img.height;
-
- // Resize if too large (maintain aspect ratio)
- if (width > maxSize || height > maxSize) {
- if (width > height) {
- height = Math.round((height / width) * maxSize);
- width = maxSize;
- } else {
- width = Math.round((width / height) * maxSize);
- height = maxSize;
- }
- }
-
- canvas.width = width;
- canvas.height = height;
- const ctx = canvas.getContext("2d");
-
- if (!ctx) {
- reject(new Error("Failed to get canvas context"));
- return;
- }
-
- // Draw and compress
- ctx.drawImage(img, 0, 0, width, height);
-
- // Compress to JPEG at 70% quality
- const compressed = canvas.toDataURL("image/jpeg", 0.7);
-
- console.log(
- `Album art compressed: ${(base64.length / 1024).toFixed(1)}KB → ${(compressed.length / 1024).toFixed(1)}KB`,
- );
-
- // Clean up the canvas to free memory
- canvas.width = 0;
- canvas.height = 0;
-
- resolve(compressed);
- };
-
- img.src = base64;
- });
-}
-
-function buildEncodingDetails(format: any): EncodingDetails | undefined {
- if (!format) return undefined;
-
- const details: EncodingDetails = {
- bitrate: typeof format.bitrate === "number" ? format.bitrate : undefined,
- codec: typeof format.codec === "string" ? format.codec : undefined,
- sampleRate:
- typeof format.sampleRate === "number" ? format.sampleRate : undefined,
- channels:
- typeof format.numberOfChannels === "number"
- ? format.numberOfChannels
- : undefined,
- bitsPerSample:
- typeof format.bitsPerSample === "number"
- ? format.bitsPerSample
- : undefined,
- container:
- typeof format.container === "string" ? format.container : undefined,
- lossless:
- typeof format.lossless === "boolean" ? format.lossless : undefined,
- profile:
- typeof format.codecProfile === "string" ? format.codecProfile : undefined,
- };
-
- return Object.values(details).some((value) => value !== undefined)
- ? details
- : undefined;
-}
-
-function normaliseTagValue(value: unknown): string | null {
- if (typeof value === "string") return value;
- if (value instanceof Uint8Array) {
- try {
- return new TextDecoder("utf-8", { fatal: false }).decode(value);
- } catch {
- return null;
- }
- }
- if (Array.isArray(value) && value.length > 0) {
- return normaliseTagValue(value[0]);
- }
- return null;
-}
-
-function parseItunesGapless(value: unknown): GaplessInfo | null {
- const raw = normaliseTagValue(value);
- if (!raw) return null;
- const cleaned = raw.trim();
- if (!cleaned) return null;
-
- const hexMatches = cleaned.match(/[0-9A-Fa-f]{8}/g);
- if (!hexMatches || hexMatches.length < 3) return null;
-
- const delayHex = hexMatches[1];
- const paddingHex = hexMatches[2];
-
- const encoderDelay = Number.parseInt(delayHex, 16);
- const encoderPadding = Number.parseInt(paddingHex, 16);
-
- const result: GaplessInfo = {};
- if (Number.isFinite(encoderDelay) && encoderDelay > 0) {
- result.encoderDelay = encoderDelay;
- }
- if (Number.isFinite(encoderPadding) && encoderPadding > 0) {
- result.encoderPadding = encoderPadding;
- }
-
- return Object.keys(result).length > 0 ? result : null;
-}
-
-function buildGaplessInfo(metadata: any): GaplessInfo | undefined {
- if (!metadata) return undefined;
-
- let gapless: GaplessInfo | undefined;
- const format = metadata.format ?? {};
-
- const encoderDelay =
- typeof format.encoderDelay === "number" ? format.encoderDelay : undefined;
- if (
- typeof encoderDelay === "number" &&
- Number.isFinite(encoderDelay) &&
- encoderDelay > 0
- ) {
- gapless = { ...(gapless ?? {}), encoderDelay };
- }
-
- const encoderPadding =
- typeof format.encoderPadding === "number"
- ? format.encoderPadding
- : undefined;
- if (
- typeof encoderPadding === "number" &&
- Number.isFinite(encoderPadding) &&
- encoderPadding > 0
- ) {
- gapless = { ...(gapless ?? {}), encoderPadding };
- }
-
- for (const tagList of Object.values(metadata?.native ?? {})) {
- if (!Array.isArray(tagList)) continue;
- for (const tag of tagList) {
- const id = typeof tag?.id === "string" ? tag.id.toUpperCase() : "";
- if (!id) continue;
-
- if (id === "ITUNSMPB" || id.endsWith(":ITUNSMPB")) {
- const parsed = parseItunesGapless(tag?.value);
- if (parsed) gapless = { ...(gapless ?? {}), ...parsed };
- continue;
- }
-
- if (
- id === "MP4:----:COM.APPLE.ITUNES:ITUNSMPB" ||
- id === "----:COM.APPLE.ITUNES:ITUNSMPB"
- ) {
- const parsed = parseItunesGapless(tag?.value);
- if (parsed) gapless = { ...(gapless ?? {}), ...parsed };
- }
- }
- }
-
- return gapless;
-}
-
-export interface EmbeddedLyrics {
- synced: boolean;
- language?: string;
- description?: string;
- text?: string; // for unsynchronized lyrics
- lines?: Array<{
- // for synchronized lyrics
- text: string;
- timestamp: number;
- }>;
-}
-
-// Track processing state for beforeunload prompt
-let isProcessing = false;
-
-const handleBeforeUnload = (event: BeforeUnloadEvent) => {
- if (isProcessing) {
- event.preventDefault();
- event.returnValue = "";
- }
-};
-
-// Function to set processing state and manage beforeunload listener
-export function setProcessingState(processing: boolean) {
- isProcessing = processing;
- if (processing) {
- window.addEventListener("beforeunload", handleBeforeUnload);
- } else {
- window.removeEventListener("beforeunload", handleBeforeUnload);
- }
-}
-
-// Utility for promise with timeout and retries
-async function withTimeoutAndRetry(
- promise: Promise,
- timeoutMs: number,
- retries: number,
- errorMessage: string,
-): Promise {
- let lastError: Error | null = null;
- for (let attempt = 1; attempt <= retries; attempt++) {
- try {
- const timeoutPromise = new Promise((_, reject) => {
- setTimeout(
- () => reject(new Error(`Timeout: ${errorMessage}`)),
- timeoutMs,
- );
- });
- return await Promise.race([promise, timeoutPromise]);
- } catch (e) {
- lastError = e instanceof Error ? e : new Error(String(e));
- console.warn(`Attempt ${attempt} failed: ${lastError.message}`);
- if (attempt === retries) throw lastError;
- }
- }
- throw lastError || new Error("Unknown error after retries");
-}
-
-// ---------------------
-// pickAudioFiles (React Uppy version)
-// ---------------------
-export function pickAudioFiles(): Promise {
- return new Promise((resolve) => {
- const ReactUppyWrapper = () => {
- const { t } = useTranslation();
- const [uppy] = useState(
- () =>
- new Uppy({
- autoProceed: false,
- restrictions: {
- maxNumberOfFiles: null,
- allowedFileTypes: [
- ".mp3",
- ".wav",
- ".m4a",
- ".flac",
- ".aif",
- ".aiff",
- ".ogg",
- ".flo",
- "audio/*",
- ],
- },
- }),
- );
-
- const [open, setOpen] = useState(true); // modal open state
- const [theme, setTheme] = useState<"light" | "dark">(
- document.documentElement.classList.contains("dark") ? "dark" : "light",
- );
-
- // Watch for theme changes
- useEffect(() => {
- const observer = new MutationObserver(() => {
- const mode = document.documentElement.classList.contains("dark")
- ? "dark"
- : "light";
- setTheme(mode);
- });
- observer.observe(document.documentElement, {
- attributes: true,
- attributeFilter: ["class"],
- });
-
- return () => observer.disconnect();
- }, []);
-
- useEffect(() => {
- const audioFiles: AudioFile[] = [];
-
- const onFileAdded = (file: any) => {
- const processed = processFiles([file.data as File]);
- if (processed.length === 0) {
- uppy.removeFile(file.id);
- } else {
- audioFiles.push(...processed);
- }
- };
-
- const onComplete = () => {
- // resolve the outer promise
- resolve(audioFiles);
- setOpen(false);
- };
-
- uppy.on("file-added", onFileAdded);
- uppy.on("complete", onComplete);
-
- return () => {
- uppy.off("file-added", onFileAdded);
- uppy.off("complete", onComplete);
- uppy.cancelAll();
- };
- }, [uppy]);
-
- return (
-
- {
- setOpen(newOpen);
- if (!newOpen) {
- uppy.cancelAll();
- resolve([]); // resolves with [] if nothing selected
- }
- }}
- >
-
-
- {t("filePicker.selectAudioFiles")}
-
-
- {/* Force remount on theme change */}
-
-
-
-
-
-
- );
- };
-
- // Create a container div
- const container = document.createElement("div");
- document.body.appendChild(container);
- const root = ReactDOM.createRoot(container);
- root.render( );
- });
-}
-
-// ---------------------
-// Helper to filter valid audio files
-// ---------------------
-function processFiles(files: File[]): AudioFile[] {
- const valid: AudioFile[] = [];
- const audioTest = document.createElement("audio");
- const allowedExtensions = [
- "mp3",
- "wav",
- "m4a",
- "flac",
- "aif",
- "aiff",
- "ogg",
- "flo",
- ];
-
- for (const file of files) {
- const ext = file.name.split(".").pop()?.toLowerCase();
- if (
- !file.type.startsWith("audio/") &&
- !(ext && allowedExtensions.includes(ext))
- ) {
- // TODO: i18n-ize
- toast.error(`Skipping non-audio file: ${file.name}`);
- continue;
- }
- // For .flo files, skip browser canPlayType check (handled by custom decoder)
- if (ext !== "flo") {
- const canPlay = audioTest.canPlayType(file.type);
- if (canPlay !== "probably" && canPlay !== "maybe") {
- // TODO: i18n-ize
- toast.error(
- `Skipping unsupported audio format by browser: ${file.name} (${file.type})`,
- );
- continue;
- }
- }
- valid.push({ file, name: file.name, size: file.size, type: file.type });
- }
- return valid;
-}
-
-// ---------------------
-// Existing metadata extraction
-// ---------------------
-export async function extractAudioMetadata(file: File): Promise {
- setProcessingState(true);
-
- const ext = file.name.split(".").pop()?.toLowerCase();
-
- // Use flo-specific extraction for .flo files
- if (ext === "flo") {
- try {
- const arrayBuffer = await file.arrayBuffer();
- const { getFloMetadata, getFloCoverArt, getFloSyncedLyrics, getFloInfo } =
- await import("./floProcessor");
-
- // Get all flo data in parallel
- const [meta, cover, lyrics, info] = await Promise.all([
- getFloMetadata(arrayBuffer),
- getFloCoverArt(arrayBuffer),
- getFloSyncedLyrics(arrayBuffer),
- getFloInfo(arrayBuffer),
- ]);
-
- // Process album art if available
- let albumArt: string | undefined = undefined;
- if (cover && cover.data && cover.data.length > 0) {
- const blob = new Blob([cover.data], { type: cover.mime_type });
- albumArt = await new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onloadend = () => resolve(reader.result as string);
- reader.onerror = () => reject(new Error("Failed to read album art"));
- reader.readAsDataURL(blob);
- });
- }
-
- // Convert synced lyrics to EmbeddedLyrics format
- let embeddedLyrics: EmbeddedLyrics[] | undefined = undefined;
- if (Array.isArray(lyrics) && lyrics.length > 0) {
- embeddedLyrics = [
- {
- synced: true,
- lines: lyrics.map((l) => ({
- text: l.text,
- timestamp: l.timestamp_ms / 1000, // Convert ms to seconds
- })),
- },
- ];
- }
-
- // Build encoding details from info
- const encoding: EncodingDetails = {
- bitrate: undefined, // flo doesn't provide bitrate directly
- codec: "flo",
- sampleRate: info?.sample_rate,
- channels: info?.channels,
- bitsPerSample: info?.bit_depth,
- container: "flo",
- lossless: !info?.is_lossy,
- profile: info?.is_lossy ? "lossy" : "lossless",
- };
-
- return {
- title: meta?.title || file.name.replace(/\.[^/.]+$/, ""),
- artist: meta?.artist || i18n.t("common.unknownArtist"),
- album: meta?.album || i18n.t("common.unknownAlbum"),
- duration: info?.duration_secs || 0,
- albumArt,
- embeddedLyrics,
- encoding,
- gapless: undefined, // flo doesn't expose gapless info currently
- metadataWarnings: undefined,
- };
- } catch (error) {
- console.error("Failed to extract flo metadata:", error);
- // Fallback to basic file info
- return {
- title: file.name.replace(/\.[^/.]+$/, ""),
- artist: i18n.t("common.unknownArtist"),
- album: i18n.t("common.unknownAlbum"),
- duration: 0,
- albumArt: undefined,
- embeddedLyrics: undefined,
- encoding: {
- codec: "flo",
- container: "flo",
- },
- gapless: undefined,
- };
- } finally {
- setProcessingState(false);
- }
- }
- // Fallback to original (music-metadata) for all other formats
- let MetadataWorkerType: typeof Worker;
- if (typeof __IS_SINGLE_FILE__ !== "undefined" && __IS_SINGLE_FILE__) {
- MetadataWorkerType = (
- await import("../workers/metadataWorker.ts?worker&inline")
- ).default;
- } else {
- MetadataWorkerType = (await import("../workers/metadataWorker.ts?worker"))
- .default;
- }
- const worker = new MetadataWorkerType();
-
- try {
- const result = await withTimeoutAndRetry(
- new Promise((resolve, reject) => {
- worker.onmessage = (event) => {
- const { metadata, albumArt, warnings, error } = event.data;
- if (error) reject(new Error(error));
- else {
- // Translate placeholder values from worker
- const translatedMetadata = {
- ...metadata,
- artist:
- metadata.artist === "__UNKNOWN_ARTIST__"
- ? i18n.t("common.unknownArtist")
- : metadata.artist,
- album:
- metadata.album === "__UNKNOWN_ALBUM__"
- ? i18n.t("common.unknownAlbum")
- : metadata.album,
- albumArt,
- metadataWarnings: Array.isArray(warnings) ? warnings : undefined,
- };
- if (Array.isArray(warnings) && warnings.length > 0) {
- for (const warning of warnings) {
- // Suppress repetitive ID3v2.3 warnings that spam the console
- if (
- warning.includes("Invalid ID3v2.3 frame-header-ID") ||
- warning.includes("id3v2.3 header has empty tag type")
- ) {
- continue;
- }
- console.warn(`Metadata warning for ${file.name}:`, warning);
- }
- }
- resolve(translatedMetadata);
- }
- };
- worker.onerror = (error) =>
- reject(new Error("Worker error: " + error.message));
- worker.postMessage({ file, fileName: file.name });
- }),
- 15000,
- 3,
- `Metadata extraction for ${file.name}`,
- );
- return result;
- } catch (e) {
- console.warn(`Failed to read metadata for ${file.name}:`, e);
- const fileName = file.name.replace(/\.[^/.]+$/, "");
- let title = fileName,
- artist = i18n.t("common.unknownArtist"),
- album = i18n.t("common.unknownAlbum"),
- duration = 0,
- albumArt: string | undefined,
- encoding: EncodingDetails | undefined,
- gapless: GaplessInfo | undefined;
-
- try {
- const metadata = await withTimeoutAndRetry(
- parseBlob(file, { skipCovers: false, duration: true }),
- 15000,
- 3,
- `Fallback metadata parsing for ${file.name}`,
- );
-
- if (metadata.common) {
- if (typeof metadata.common.artist === "string")
- artist = metadata.common.artist;
- if (typeof metadata.common.title === "string")
- title = metadata.common.title;
- if (typeof metadata.common.album === "string")
- album = metadata.common.album;
- duration = metadata.format.duration ?? 0;
- encoding = buildEncodingDetails(metadata.format);
- gapless = buildGaplessInfo(metadata);
-
- // Find this section in extractAudioMetadata (around line 420)
- const cover = selectCover(metadata.common.picture);
- if (cover && cover.data.length > 0) {
- const blob = new Blob([new Uint8Array(cover.data)], {
- type: cover.format,
- });
- albumArt = await new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onloadend = async () => {
- try {
- const base64 = reader.result as string;
- // Compress album art to save memory
- const compressed = await compressAlbumArt(base64);
- resolve(compressed);
- } catch (error) {
- console.warn("Failed to compress album art:", error);
- // Fallback to original if compression fails
- resolve(reader.result as string);
- }
- };
- reader.onerror = () =>
- reject(new Error("Failed to read album art"));
- reader.readAsDataURL(blob);
- });
- }
- }
- } catch {
- if (fileName.includes(" - ")) {
- const parts = fileName.split(" - ");
- if (parts.length >= 2) {
- artist = parts[0].trim();
- title = parts[1].trim();
- }
- }
- }
-
- return { title, artist, album, duration, albumArt, encoding, gapless };
- } finally {
- worker.terminate();
- setProcessingState(false);
- }
-}
-
-// ---------------------
-// URL + ID helpers
-// ---------------------
-
-export function generateUniqueId(): string {
- return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
-}
-
-// ---------------------
-// File Handling API support for PWAs
-// ---------------------
-export interface FileHandlerResult {
- files: File[];
- successCount: number;
- errorCount: number;
-}
-
-export function setupFileHandler(
- onFilesReceived: (result: FileHandlerResult) => void,
-): () => void {
- if (
- !("launchQueue" in window) ||
- !window.launchQueue ||
- typeof window.launchQueue.setConsumer !== "function"
- ) {
- console.warn("File Handling API not supported in this browser");
- return () => {}; // Return empty cleanup function
- }
-
- const consumer = async (launchParams: any) => {
- if (!launchParams.files || launchParams.files.length === 0) {
- console.log("No files provided by File Handling or Share Target API");
- return;
- }
-
- const files: File[] = [];
- let successCount = 0;
- let errorCount = 0;
-
- for (const fileHandle of launchParams.files) {
- try {
- let file: File;
- if (fileHandle.getFile) {
- file = await fileHandle.getFile();
- } else {
- file = fileHandle;
- }
-
- const fileId = `${file.name}-${file.size}-${file.lastModified}`;
-
- // Check sessionStorage for processed files
- const processedFiles = JSON.parse(
- sessionStorage.getItem("processedFiles") || "[]",
- );
- if (processedFiles.includes(fileId)) {
- console.log("Skipping duplicate file:", file.name);
- continue;
- }
-
- const processed = processFiles([file]);
- if (processed.length > 0) {
- files.push(file);
- processedFiles.push(fileId);
- sessionStorage.setItem(
- "processedFiles",
- JSON.stringify(processedFiles),
- );
- successCount++;
- } else {
- errorCount++;
- }
- } catch (error) {
- console.error("Error processing file handle:", error);
- errorCount++;
- }
- }
-
- if (files.length > 0) {
- onFilesReceived({ files, successCount, errorCount });
- }
- };
-
- window.launchQueue.setConsumer(consumer);
-
- return () => {
- if (
- "launchQueue" in window &&
- window.launchQueue &&
- typeof window.launchQueue.setConsumer === "function"
- ) {
- try {
- window.launchQueue.setConsumer(() => {});
- } catch (e) {
- console.warn("Could not clear file handler consumer:", e);
- }
- }
- };
-}
-
-// ---------------------
-// Share Target API support for PWAs
-// ---------------------
-export interface ShareTargetResult {
- files: File[];
- title?: string;
- text?: string;
- url?: string;
- type: "files" | "search" | "none";
-}
-
-const SHARE_HANDLED_KEY = "last-shared-files";
-
-// Helper functions for duplicate tracking
-function getHandledShares(): Set {
- try {
- return new Set(
- JSON.parse(sessionStorage.getItem(SHARE_HANDLED_KEY) || "[]"),
- );
- } catch {
- return new Set();
- }
-}
-
-function markHandled(files: File[]) {
- const handled = getHandledShares();
- files.forEach((f) => handled.add(`${f.name}:${f.size}`));
- sessionStorage.setItem(
- SHARE_HANDLED_KEY,
- JSON.stringify(Array.from(handled)),
- );
-}
-
-export function clearHandledShares() {
- sessionStorage.removeItem(SHARE_HANDLED_KEY);
-}
-
-export function handleShareTarget(): ShareTargetResult | null {
- // Share targets can send data via URL parameters or launch queue
- if (typeof window === "undefined") {
- return null;
- }
-
- // Check URL parameters for share data
- const urlParams = new URLSearchParams(window.location.search);
- const title = urlParams.get("title") || undefined;
- const text = urlParams.get("text") || undefined;
- const url = urlParams.get("url") || undefined;
-
- // Determine what type of share this is
- // Files would typically come through launch queue or POST request
- if (title || text) {
- // Text-based share - could be song info to search for
- return {
- files: [],
- title,
- text,
- url,
- type: "search",
- };
- }
-
- return null;
-}
-
-// Hook to handle share targets and file shares
-export function useShareTarget(
- onShareReceived: (result: ShareTargetResult) => void,
-) {
- const hasProcessedRef = useRef(false);
-
- useEffect(() => {
- if (hasProcessedRef.current) return;
-
- async function processShare() {
- const urlParams = new URLSearchParams(window.location.search);
-
- // Multi-file support: attempt to load from cache with indexes
- if (urlParams.get("share-received") === "true") {
- try {
- const cache = await caches.open("incoming-shares");
- const files: File[] = [];
- // read /shared-file, /shared-file-1, /shared-file-2, etc
- let i = 0,
- foundAny = false;
- while (true) {
- const key = i === 0 ? "/shared-file" : `/shared-file-${i}`;
- const response = await cache.match(key);
- if (!response) break;
- const blob = await response.blob();
- const filenameRaw = response.headers.get("x-file-name");
- const filename = filenameRaw
- ? decodeURIComponent(filenameRaw)
- : `shared-audio${i ? "-" + i : ""}.mp3`;
- files.push(new File([blob], filename, { type: blob.type }));
- await cache.delete(key);
- foundAny = true;
- i++;
- }
-
- if (foundAny) {
- const handled = getHandledShares();
- const newFiles = files.filter(
- (f) => !handled.has(`${f.name}:${f.size}`),
- );
- if (newFiles.length === 0) {
- // all were previously handled
- return;
- }
- markHandled(newFiles);
-
- hasProcessedRef.current = true;
- onShareReceived({ files: newFiles, type: "files" });
-
- // cleanup share-received param
- const cleanUrl = new URL(window.location.href);
- cleanUrl.searchParams.delete("share-received");
- window.history.replaceState({}, "", cleanUrl.toString());
- return;
- }
- } catch (e) {
- console.error("Failed to retrieve shared file from cache", e);
- }
- }
-
- // Fallback to standard Text/URL share handling
- const shareResult = handleShareTarget();
- if (shareResult && shareResult.type !== "none") {
- hasProcessedRef.current = true;
- onShareReceived(shareResult);
-
- const url = new URL(window.location.href);
- ["title", "text", "url"].forEach((p) => url.searchParams.delete(p));
- window.history.replaceState({}, "", url.toString());
- }
- }
-
- processShare();
- }, [onShareReceived]);
-}
-
-export function useFileHandler(
- addSong: (song: Song) => Promise,
- t: any,
- isInitialized?: boolean,
-) {
- const [isSupported, setIsSupported] = useState(false);
- const processedFilesRef = useRef(new Set());
- const hasProcessedFilesRef = useRef(false);
- const pendingFilesRef = useRef([]);
-
- useEffect(() => {
- const supported =
- "launchQueue" in window &&
- typeof window.launchQueue?.setConsumer === "function";
- setIsSupported(supported);
-
- if (!supported) return;
-
- const cleanup = setupFileHandler(async (result) => {
- // Prevent processing if we've already handled files on this page load
- if (hasProcessedFilesRef.current) return;
-
- if (result.files.length > 0) {
- // If library is not initialized yet, queue the files
- if (isInitialized === false) {
- console.log(
- "Library not initialized, queuing files for later processing",
- );
- pendingFilesRef.current.push(...result.files);
- return;
- }
-
- hasProcessedFilesRef.current = true;
- toast.success(
- t("fileHandler.filesReceived", { count: result.successCount }),
- );
- await importAudioFiles(result.files, addSong, t);
- // Clear processed files after successful import to allow re-importing the same files
- processedFilesRef.current.clear();
- }
- if (result.errorCount > 0) {
- toast.error(
- t("fileHandler.filesSkipped", { count: result.errorCount }),
- );
- }
- });
-
- return cleanup;
- }, [addSong, t, isInitialized]);
-
- // Process queued files when library becomes initialized
- useEffect(() => {
- if (isInitialized && pendingFilesRef.current.length > 0) {
- console.log("Library initialized, processing queued files");
- const filesToProcess = [...pendingFilesRef.current];
- pendingFilesRef.current = [];
-
- // Process the queued files
- importAudioFiles(filesToProcess, addSong, t)
- .then(() => {
- hasProcessedFilesRef.current = true;
- processedFilesRef.current.clear();
- toast.success(
- t("fileHandler.filesReceived", { count: filesToProcess.length }),
- );
- })
- .catch((error) => {
- console.error("Failed to process queued files:", error);
- toast.error(
- t("filePicker.failedImport", { count: filesToProcess.length }),
- );
- });
- }
- }, [isInitialized, addSong, t]);
-
- return { isSupported };
-}
diff --git a/Build/src/helpers/floProcessor.ts b/Build/src/helpers/floProcessor.ts
deleted file mode 100644
index 701e728..0000000
--- a/Build/src/helpers/floProcessor.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-// floProcessor.ts - Fixed flo audio processing
-import initFlo, * as flo from "@flo-audio/libflo-audio";
-
-let floInitialized = false;
-
-async function ensureFloInitialized() {
- if (!floInitialized) {
- await initFlo();
- floInitialized = true;
- }
-}
-
-// Decode a .flo file buffer to AudioBuffer using @flo-audio/libflo-audio
-export async function decodeFloToAudioBuffer(
- floData: ArrayBuffer,
- audioContext: AudioContext,
-): Promise {
- await ensureFloInitialized();
-
- const uint8Flo = new Uint8Array(floData);
-
- // Decode flo to interleaved Float32Array samples
- const samples = flo.decode(uint8Flo);
-
- // Get file info for audio properties
- const fileInfo = flo.info(uint8Flo);
- const { channels, sample_rate } = fileInfo;
-
- // Calculate number of frames
- const frameCount = samples.length / channels;
-
- // Create AudioBuffer
- const audioBuffer = audioContext.createBuffer(
- channels,
- frameCount,
- sample_rate,
- );
-
- // Deinterleave samples into separate channels
- for (let ch = 0; ch < channels; ch++) {
- const channelData = audioBuffer.getChannelData(ch);
- for (let i = 0; i < frameCount; i++) {
- channelData[i] = samples[i * channels + ch];
- }
- }
-
- return audioBuffer;
-}
-
-// Get flo file info (returns object with sample_rate, channels, bit_depth, etc.)
-export async function getFloInfo(floData: ArrayBuffer): Promise<{
- sample_rate: number;
- channels: number;
- bit_depth: number;
- duration_secs: number;
- is_lossy: boolean;
- compression_ratio?: number;
-}> {
- await ensureFloInitialized();
- const uint8Flo = new Uint8Array(floData);
- return flo.info(uint8Flo);
-}
-
-// Validate flo file integrity (CRC32)
-export async function validateFlo(floData: ArrayBuffer): Promise {
- await ensureFloInitialized();
- const uint8Flo = new Uint8Array(floData);
- return flo.validate(uint8Flo);
-}
-
-// Extract metadata as JS object (returns null if no metadata)
-export async function getFloMetadata(floData: ArrayBuffer): Promise<{
- title?: string;
- artist?: string;
- album?: string;
- [key: string]: any;
-} | null> {
- await ensureFloInitialized();
- const uint8Flo = new Uint8Array(floData);
- return flo.get_metadata(uint8Flo);
-}
-
-// Extract cover art (returns { mime_type, data } or null)
-export async function getFloCoverArt(
- floData: ArrayBuffer,
-): Promise<{ mime_type: string; data: Uint8Array } | null> {
- await ensureFloInitialized();
- const uint8Flo = new Uint8Array(floData);
- return flo.get_cover_art(uint8Flo);
-}
-
-// Extract synchronized lyrics (returns array of { timestamp_ms, text } or null)
-export async function getFloSyncedLyrics(
- floData: ArrayBuffer,
-): Promise | null> {
- await ensureFloInitialized();
- const uint8Flo = new Uint8Array(floData);
- return flo.get_synced_lyrics(uint8Flo);
-}
-
-// Create flo metadata from JS object (returns Uint8Array)
-export async function createFloMetadataFromObject(
- obj: any,
-): Promise {
- await ensureFloInitialized();
- return flo.create_metadata_from_object(obj);
-}
-
-// Export initialization function
-export { initFlo, ensureFloInitialized };
diff --git a/Build/src/helpers/gaplessHelper.ts b/Build/src/helpers/gaplessHelper.ts
deleted file mode 100644
index 435addf..0000000
--- a/Build/src/helpers/gaplessHelper.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-export interface GaplessOffsets {
- start: number;
- end: number;
-}
-
-export function calculateGaplessOffsets(song?: Song | null): GaplessOffsets {
- if (!song || !song.gapless || !song.encoding?.sampleRate) {
- return { start: 0, end: 0 };
- }
-
- const sampleRate = song.encoding.sampleRate;
- if (
- typeof sampleRate !== "number" ||
- !Number.isFinite(sampleRate) ||
- sampleRate <= 0
- ) {
- return { start: 0, end: 0 };
- }
-
- const delaySamples = song.gapless.encoderDelay ?? 0;
- const paddingSamples = song.gapless.encoderPadding ?? 0;
-
- const startSeconds =
- typeof delaySamples === "number" &&
- Number.isFinite(delaySamples) &&
- delaySamples > 0
- ? delaySamples / sampleRate
- : 0;
- const endSeconds =
- typeof paddingSamples === "number" &&
- Number.isFinite(paddingSamples) &&
- paddingSamples > 0
- ? paddingSamples / sampleRate
- : 0;
-
- return {
- start: Number.isFinite(startSeconds) && startSeconds > 0 ? startSeconds : 0,
- end: Number.isFinite(endSeconds) && endSeconds > 0 ? endSeconds : 0,
- };
-}
diff --git a/Build/src/helpers/i18nManual.ts b/Build/src/helpers/i18nManual.ts
index ae4d12d..609e436 100644
--- a/Build/src/helpers/i18nManual.ts
+++ b/Build/src/helpers/i18nManual.ts
@@ -1,4 +1,3 @@
-// Import translations directly so Vite can bundle them
import enTranslation from "../locales/en/translation.json";
import frTranslation from "../locales/fr/translation.json";
diff --git a/Build/src/helpers/iconLoader.tsx b/Build/src/helpers/iconLoader.tsx
deleted file mode 100644
index 42626b4..0000000
--- a/Build/src/helpers/iconLoader.tsx
+++ /dev/null
@@ -1,801 +0,0 @@
-import React, {
- createContext,
- useCallback,
- useContext,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from "react";
-import {
- IconDefinition,
- IconDefinitionMap,
- IconLibraryConfigMap,
- IconLibraryMap,
- IconLookupOptions,
- IconPropTransformer,
- IconSetMetadata,
- IconSetModule,
- ResolvedIcon,
-} from "../types/icons";
-import { loadThemeJsonFromSourcePath } from "./themeMetadata";
-
-interface IconRegistrySet {
- id: string;
- label: string;
- themeName: string;
- metadata: IconSetMetadata & { id: string; label: string; themeName: string };
- icons: IconDefinitionMap;
- path: string;
- libraries?: IconLibraryMap;
- libraryConfig?: IconLibraryConfigMap;
-}
-
-interface IconDefinitionEntry {
- definition: IconDefinition;
- set: IconRegistrySet;
-}
-
-interface IconRegistryValue {
- iconSets: IconRegistrySet[];
- iconSetMap: Map;
- currentSet: IconRegistrySet | null;
- isLoading: boolean;
- iconsReady: boolean;
- error: string | null;
- setIconSet: (idOrName: string) => void;
- getIconDefinition: (
- name: string,
- options?: IconLookupOptions,
- ) => IconDefinition | undefined;
- loadIcon: (
- name: string,
- options?: IconLookupOptions,
- ) => Promise;
-}
-
-interface IconRegistryProviderProps {
- defaultSetId?: string;
- rememberSelection?: boolean;
- onSetChange?: (set: IconRegistrySet) => void;
- children: React.ReactNode;
-}
-
-const iconModuleLoaders = import.meta.glob("../themes/**/*.icons.{ts,tsx}");
-
-const builtinLibraryLoaders: Record<
- string,
- () => Promise>
-> = {
- lucide: async () => import("lucide-react"),
-};
-
-const IconRegistryContext = createContext(null);
-
-const LOCAL_STORAGE_KEY = "selected-icon-set";
-// LRU cache implementation for icons
-class LRUCache {
- private maxSize: number;
- private cache: Map;
-
- constructor(maxSize: number) {
- this.maxSize = maxSize;
- this.cache = new Map();
- }
-
- get(key: K): V | undefined {
- if (!this.cache.has(key)) return undefined;
- const value = this.cache.get(key)!;
- // Move to end (most recently used)
- this.cache.delete(key);
- this.cache.set(key, value);
- return value;
- }
-
- set(key: K, value: V): void {
- if (this.cache.has(key)) {
- this.cache.delete(key);
- }
- this.cache.set(key, value);
- if (this.cache.size > this.maxSize) {
- // Remove least recently used
- const lruKeyIter = this.cache.keys().next();
- if (!lruKeyIter.done) {
- const lruKey = lruKeyIter.value as K;
- this.cache.delete(lruKey);
- }
- }
- }
-
- clear(): void {
- this.cache.clear();
- }
-}
-
-const ICON_CACHE_SIZE = 128; // TODO: Tune
-const resolvedIconCache = new LRUCache(ICON_CACHE_SIZE);
-const libraryModuleCache = new LRUCache>(8); // Limit loaded libraries
-
-function deriveSetIdentity(
- path: string,
- metadata?: IconSetMetadata,
- themeJson?: any,
-): {
- id: string;
- label: string;
- themeName: string;
-} {
- const segments = path.split("/");
- const fileName = segments[segments.length - 1] ?? "";
- const baseName = fileName.replace(/\.icons\.(?:ts|tsx)$/, "");
-
- // Use theme JSON metadata if available
- const iconMeta = themeJson?.icons || {};
- const themeName =
- themeJson?.name ??
- metadata?.theme ??
- segments[segments.length - 2] ??
- baseName;
-
- // Priority: JSON metadata > TS metadata > derived values
- const derivedName =
- iconMeta.label ?? metadata?.label ?? metadata?.id ?? themeName ?? baseName;
- const normalizedId = (
- iconMeta.id ??
- metadata?.id ??
- themeName ??
- derivedName
- ).toLowerCase();
-
- return {
- id: normalizedId,
- label: iconMeta.label ?? metadata?.label ?? derivedName,
- themeName,
- };
-}
-
-const GLOBAL_LIBRARY_NAMESPACE = "__global";
-
-async function resolveLibraryModule(
- library: string,
- sourceSet?: IconRegistrySet,
-): Promise | null> {
- const cacheKey = `${sourceSet ? sourceSet.id : GLOBAL_LIBRARY_NAMESPACE}::${library}`;
- const cachedModule = libraryModuleCache.get(cacheKey);
- if (cachedModule) {
- return cachedModule;
- }
-
- // First check if the library is already available in the sourceSet
- let loaderCandidate = sourceSet?.libraries?.[library];
-
- if (!loaderCandidate) {
- // Check builtin loaders
- loaderCandidate = builtinLibraryLoaders[library];
- }
-
- if (!loaderCandidate) {
- // Try to load the library dynamically if it's a known library
- if (library === "lucide" && sourceSet?.id === "lucide") {
- try {
- const lucideModule = await import("lucide-react");
- libraryModuleCache.set(cacheKey, lucideModule);
- return lucideModule;
- } catch (error) {
- console.error(`Failed to dynamically load lucide-react`, error);
- return null;
- }
- }
- return null;
- }
-
- try {
- let module: Record;
- if (typeof loaderCandidate === "function") {
- const result = loaderCandidate();
- module = (result instanceof Promise ? await result : result) as Record<
- string,
- any
- >;
- } else {
- module = loaderCandidate as Record;
- }
-
- libraryModuleCache.set(cacheKey, module);
- return module;
- } catch (error) {
- console.error(`Failed to load icon library "${library}"`, error);
- return null;
- }
-}
-
-function getExportByPath(
- container: Record | undefined,
- path: string,
-): any {
- if (!container) return undefined;
- const segments = path.split(".");
- let current: any = container;
- for (const segment of segments) {
- if (current && typeof current === "object" && segment in current) {
- current = current[segment];
- } else {
- return undefined;
- }
- }
- return current;
-}
-
-async function loadLibraryIcon(
- library: string,
- iconName: string,
- sourceSet?: IconRegistrySet,
-): Promise> | null> {
- const module = await resolveLibraryModule(library, sourceSet);
-
- if (!module) {
- console.warn(
- `Unsupported icon library "${library}"${sourceSet ? ` for set "${sourceSet.label}"` : ""}`,
- );
- return null;
- }
-
- const candidateNames = new Set([iconName]);
- if (!iconName.includes(".") && !iconName.endsWith("Icon")) {
- candidateNames.add(`${iconName}Icon`);
- }
-
- const pascalCase = iconName.charAt(0).toUpperCase() + iconName.slice(1);
- const camelCase = iconName.charAt(0).toLowerCase() + iconName.slice(1);
- candidateNames.add(pascalCase);
- candidateNames.add(camelCase);
-
- const candidateContainers = [
- module,
- (module as any).default,
- (module as any).icons,
- (module as any).default?.icons,
- ].filter((container) => container && typeof container === "object");
-
- let resolvedExport: any;
- for (const container of candidateContainers) {
- for (const pathCandidate of candidateNames) {
- resolvedExport = getExportByPath(
- container as Record,
- pathCandidate,
- );
- if (resolvedExport) {
- break;
- }
- }
-
- if (resolvedExport) {
- break;
- }
- }
-
- if (
- resolvedExport &&
- typeof resolvedExport === "object" &&
- typeof resolvedExport.default === "function"
- ) {
- resolvedExport = resolvedExport.default;
- }
-
- // Check if it's a valid React component (function or forwardRef/memo)
- if (typeof resolvedExport === "function") {
- return resolvedExport as React.ComponentType>;
- }
-
- // Handle React.forwardRef/React.memo wrapped components
- if (
- resolvedExport &&
- typeof resolvedExport === "object" &&
- (resolvedExport.$$typeof || resolvedExport.render)
- ) {
- return resolvedExport as React.ComponentType>;
- }
-
- console.warn(`Icon "${iconName}" not found in library "${library}"`);
- return null;
-}
-
-export const IconRegistryProvider: React.FC = ({
- defaultSetId,
- rememberSelection = true,
- onSetChange,
- children,
-}) => {
- const [iconSets, setIconSets] = useState([]);
- const [currentSet, setCurrentSet] = useState(null);
- const [error, setError] = useState(null);
- const [isLoading, setIsLoading] = useState(true);
- const [iconsReady, setIconsReady] = useState(false);
-
- useEffect(() => {
- let cancelled = false;
-
- // Only load metadata for all sets, not the full icon maps
- const loadSetMetadatas = async () => {
- try {
- setIsLoading(true);
- setIconsReady(false);
- setError(null);
-
- const entries: IconRegistrySet[] = [];
-
- for (const [path] of Object.entries(iconModuleLoaders)) {
- try {
- // Load theme JSON for metadata without loading the full icon module
- const themeJson = await loadThemeJsonFromSourcePath(path);
- // Skip loading the full module at startup - only load metadata from themeJson
- const identity = deriveSetIdentity(path, undefined, themeJson);
- const iconMeta = themeJson?.icons || {};
- const fullMetadata: IconSetMetadata & {
- id: string;
- label: string;
- themeName: string;
- } = {
- id: identity.id,
- label: identity.label,
- themeName: identity.themeName,
- description: iconMeta.description,
- version: iconMeta.version,
- theme: identity.themeName,
- inheritsFrom: iconMeta.inheritsFrom,
- author: iconMeta.author ?? themeJson?.author,
- tags: iconMeta.tags,
- };
- // Only set icons to empty object until loaded
- const registrySet: IconRegistrySet = {
- id: identity.id,
- label: identity.label,
- themeName: identity.themeName,
- metadata: fullMetadata,
- icons: {},
- path,
- libraries: undefined,
- libraryConfig: undefined,
- };
- entries.push(registrySet);
- } catch (err) {
- console.error(
- `Failed to load icon registry module metadata at ${path}`,
- err,
- );
- }
- }
-
- if (!cancelled) {
- entries.sort((a, b) => a.label.localeCompare(b.label));
- setIconSets(entries);
-
- const storedId = rememberSelection
- ? typeof window !== "undefined"
- ? localStorage.getItem(LOCAL_STORAGE_KEY)
- : null
- : null;
-
- const preferredId = storedId ?? defaultSetId;
-
- const nextSet = preferredId
- ? entries.find(
- (entry) =>
- entry.id === preferredId || entry.themeName === preferredId,
- )
- : null;
-
- const fallbackSet =
- nextSet ??
- entries.find(
- (entry) => entry.metadata?.inheritsFrom === undefined,
- ) ??
- entries[0] ??
- null;
-
- // Only load icons for the current set, not all sets
- if (fallbackSet) {
- // Load icons for fallbackSet only
- const loader = iconModuleLoaders[fallbackSet.path];
- if (loader) {
- loader().then((module: any) => {
- const loadedSet = {
- ...fallbackSet,
- icons: module.default,
- libraries: module.libraries,
- libraryConfig: module.libraryConfig,
- };
- setIconSets((sets) =>
- sets.map((s) => (s.id === loadedSet.id ? loadedSet : s)),
- );
- setCurrentSet(loadedSet);
- setIconsReady(true);
- if (rememberSelection && typeof window !== "undefined") {
- localStorage.setItem(LOCAL_STORAGE_KEY, loadedSet.id);
- }
- });
- } else {
- setCurrentSet(fallbackSet);
- setIconsReady(true);
- if (rememberSelection && typeof window !== "undefined") {
- localStorage.setItem(LOCAL_STORAGE_KEY, fallbackSet.id);
- }
- }
- }
- }
- } catch (err) {
- if (!cancelled) {
- const message =
- err instanceof Error ? err.message : "Unable to load icon registry";
- setError(message);
- console.error("Icon registry loading error:", err);
- }
- } finally {
- if (!cancelled) {
- setIsLoading(false);
- }
- }
- };
-
- loadSetMetadatas();
-
- return () => {
- cancelled = true;
- };
- }, [defaultSetId, rememberSelection]);
-
- const iconSetMap = useMemo(() => {
- const map = new Map();
- for (const set of iconSets) {
- map.set(set.id, set);
- map.set(set.themeName.toLowerCase(), set);
- }
- return map;
- }, [iconSets]);
-
- const notifyChange = useRef(onSetChange);
- notifyChange.current = onSetChange;
-
- const setIconSet = useCallback(
- async (idOrName: string) => {
- const normalized = idOrName.toLowerCase();
- let next =
- iconSetMap.get(normalized) ??
- iconSets.find(
- (set) =>
- set.id === normalized || set.themeName.toLowerCase() === normalized,
- );
- if (!next) {
- console.warn(`Icon set "${idOrName}" not found`);
- return;
- }
-
- setIconsReady(false);
-
- // If icons not loaded, load them now
- if (!next.icons || Object.keys(next.icons).length === 0) {
- try {
- const loader = iconModuleLoaders[next.path];
- if (loader) {
- const module = (await loader()) as IconSetModule;
- next = {
- ...next,
- icons: module.default,
- libraries: module.libraries,
- libraryConfig: module.libraryConfig,
- };
- // Update iconSets and iconSetMap
- if (next) {
- setIconSets((sets) => {
- return sets.map((s) => {
- if (s.id === next!.id) {
- return next!;
- }
- return s;
- });
- });
- }
- }
- } catch (err) {
- console.error(`Failed to load icon set "${next.label}"`, err);
- }
- }
-
- setCurrentSet(next);
- setIconsReady(true);
- if (typeof window !== "undefined" && rememberSelection) {
- localStorage.setItem(LOCAL_STORAGE_KEY, next.id);
- }
-
- notifyChange.current?.(next);
- },
- [iconSetMap, iconSets, rememberSelection],
- );
-
- const resolveIconEntry = useCallback(
- (
- name: string,
- startSet: IconRegistrySet | null,
- visited: Set,
- ): IconDefinitionEntry | undefined => {
- if (!startSet || visited.has(startSet.id)) {
- return undefined;
- }
-
- visited.add(startSet.id);
-
- const definition = startSet.icons[name];
- if (definition) {
- return { definition, set: startSet };
- }
-
- const parentId = startSet.metadata?.inheritsFrom;
- if (parentId) {
- const parent =
- iconSetMap.get(parentId) ?? iconSetMap.get(parentId.toLowerCase());
- if (parent) {
- return resolveIconEntry(name, parent, visited);
- }
- }
-
- return undefined;
- },
- [iconSetMap],
- );
-
- const findIconEntry = useCallback(
- (
- name: string,
- options?: IconLookupOptions,
- ): IconDefinitionEntry | undefined => {
- if (!name) return undefined;
-
- const primary = options?.setId
- ? (iconSetMap.get(options.setId) ??
- iconSetMap.get(options.setId.toLowerCase()) ??
- null)
- : (currentSet ?? iconSets[0] ?? null);
-
- const primaryEntry = resolveIconEntry(name, primary, new Set());
- if (primaryEntry) {
- return primaryEntry;
- }
-
- if (options?.fallbackOrder && options.fallbackOrder.length > 0) {
- for (const fallback of options.fallbackOrder) {
- const fallbackSet =
- iconSetMap.get(fallback) ?? iconSetMap.get(fallback.toLowerCase());
- const entry = resolveIconEntry(
- name,
- fallbackSet ?? null,
- new Set(),
- );
- if (entry) {
- return entry;
- }
- }
- }
-
- return undefined;
- },
- [currentSet, iconSetMap, iconSets, resolveIconEntry],
- );
-
- const getIconDefinition = useCallback(
- (name: string, options?: IconLookupOptions) =>
- findIconEntry(name, options)?.definition,
- [findIconEntry],
- );
-
- // Use refs for values needed in loadIcon to keep the callback stable
- const currentSetRef = useRef(currentSet);
- const iconSetsRef = useRef(iconSets);
- const iconModuleLoadersRef = useRef(iconModuleLoaders);
-
- // Update refs when state changes
- useEffect(() => {
- currentSetRef.current = currentSet;
- }, [currentSet]);
-
- useEffect(() => {
- iconSetsRef.current = iconSets;
- }, [iconSets]);
-
- const loadIcon = useCallback(
- async (
- name: string,
- options?: IconLookupOptions,
- ): Promise => {
- if (!name) {
- return null;
- }
-
- // Use ref values to avoid triggering re-renders
- const localCurrentSet = currentSetRef.current;
-
- // Ensure currentSet icons are loaded (but don't update state from inside the callback)
- if (
- localCurrentSet &&
- (!localCurrentSet.icons ||
- Object.keys(localCurrentSet.icons).length === 0)
- ) {
- try {
- const loader = iconModuleLoadersRef.current[localCurrentSet.path];
- if (loader) {
- const module = (await loader()) as IconSetModule;
- // Update the set in iconSets without triggering re-renders in loadIcon
- const updatedSet = {
- ...localCurrentSet,
- icons: module.default,
- libraries: module.libraries,
- libraryConfig: module.libraryConfig,
- };
- // Update the ref immediately for the current request
- currentSetRef.current = updatedSet;
- // Schedule state update for the next render cycle
- queueMicrotask(() => {
- setIconSets((sets) =>
- sets.map((s) => (s.id === localCurrentSet.id ? updatedSet : s)),
- );
- });
- }
- } catch (err) {
- console.error(
- `Failed to load icon set "${localCurrentSet.label}"`,
- err,
- );
- }
- }
-
- const entry = findIconEntry(name, options);
- if (!entry) {
- return null;
- }
-
- const cacheKeyParts = [entry.set.id, name];
- if (options?.setId) {
- cacheKeyParts.push(`requested:${options.setId}`);
- }
- if (options?.fallbackOrder && options.fallbackOrder.length > 0) {
- cacheKeyParts.push(`fallback:${options.fallbackOrder.join("|")}`);
- }
- const cacheKey = cacheKeyParts.join("::");
-
- const cached = resolvedIconCache.get(cacheKey);
- if (cached) {
- return cached;
- }
-
- const { definition, set } = entry;
-
- switch (definition.type) {
- case "library": {
- const component = await loadLibraryIcon(
- definition.library,
- definition.icon,
- set,
- );
- if (!component) {
- console.warn(
- `Icon "${definition.icon}" from library "${definition.library}" not found.`,
- );
- return null;
- }
-
- // Extract prop transformer for this library
- const libraryConfig = set.libraryConfig?.[definition.library];
- let propTransformer: IconPropTransformer | undefined;
-
- if (
- libraryConfig &&
- typeof libraryConfig === "object" &&
- "propTransformer" in libraryConfig
- ) {
- const transformer = (libraryConfig as any).propTransformer;
- if (typeof transformer === "function") {
- propTransformer = transformer as IconPropTransformer;
- }
- }
-
- const resolved: ResolvedIcon = {
- type: "component",
- Component: component,
- defaultProps: {},
- propTransformer,
- title: definition.title,
- };
-
- resolvedIconCache.set(cacheKey, resolved);
- return resolved;
- }
- case "component": {
- const resolved: ResolvedIcon = {
- type: "component",
- Component: definition.component,
- defaultProps: definition.props,
- title: definition.title,
- };
- resolvedIconCache.set(cacheKey, resolved);
- return resolved;
- }
- case "image": {
- const resolved: ResolvedIcon = {
- type: "image",
- src: definition.src,
- alt: definition.alt,
- title: definition.title,
- };
- resolvedIconCache.set(cacheKey, resolved);
- return resolved;
- }
- case "svg-inline": {
- const resolved: ResolvedIcon = {
- type: "svg-inline",
- content: definition.content,
- viewBox: definition.viewBox,
- alt: definition.alt,
- title: definition.title,
- };
- resolvedIconCache.set(cacheKey, resolved);
- return resolved;
- }
- default: {
- console.warn(`Unsupported icon definition type for icon "${name}"`);
- return null;
- }
- }
- },
- [findIconEntry, setIconSets],
- );
-
- const contextValue = useMemo(
- () => ({
- iconSets,
- iconSetMap,
- currentSet,
- isLoading,
- iconsReady,
- error,
- setIconSet,
- getIconDefinition,
- loadIcon,
- }),
- [
- currentSet,
- error,
- getIconDefinition,
- iconSetMap,
- iconSets,
- isLoading,
- iconsReady,
- loadIcon,
- setIconSet,
- ],
- );
-
- useEffect(() => {
- if (typeof window !== "undefined") {
- (window as any).iconRegistry = {
- list: () => iconSets,
- current: () => currentSet,
- set: (id: string) => setIconSet(id),
- };
- }
- }, [iconSets, currentSet, setIconSet]);
-
- return (
-
- {children}
-
- );
-};
-
-export const useIconRegistry = () => {
- const context = useContext(IconRegistryContext);
- if (!context) {
- throw new Error(
- "useIconRegistry must be used within an IconRegistryProvider",
- );
- }
- return context;
-};
diff --git a/Build/src/helpers/importAudioFiles.tsx b/Build/src/helpers/importAudioFiles.tsx
index 45187e9..5799785 100644
--- a/Build/src/helpers/importAudioFiles.tsx
+++ b/Build/src/helpers/importAudioFiles.tsx
@@ -1,33 +1,205 @@
import { toast } from "sonner";
-import { extractAudioMetadata, generateUniqueId } from "./filePickerHelper";
-import { musicIndexedDbHelper } from "./musicIndexedDbHelper";
-import { setAlbumArtInCache } from "../hooks/useAlbumArt";
+import { logger } from "./logger";
+import {
+ createDuplicateDetector,
+ findTrackBySourcePath,
+} from "../platform/library/duplicateDetector";
+import {
+ createMetadataExtractor,
+ createFloMetadataExtractor,
+ compressAlbumArt,
+ generateUniqueId,
+} from "../platform/metadata";
+import { albumArtStorage } from "../platform/storage";
+import { dataUrlToBlob } from "../platform/storage/albumArt";
+import {
+ AlbumArtManager,
+ MusicBrainzProvider,
+ DiscogsProvider,
+} from "../platform/providers";
+import type { ImportContext } from "./addSong";
+import type { ExtractedMetadata } from "../platform/metadata";
+import type { Track } from "../core/engine/types";
+
+export type Translate = (
+ key: string,
+ options?: Record,
+) => string;
+
+export interface AudioImportOpts {
+ t: Translate;
+ addSong: (song: Track, file: File, context?: ImportContext) => Promise;
+ getExistingTracks?: () => Track[];
+}
+
+export interface ImportFileItem {
+ file: File | null;
+ path?: string;
+}
+
+export interface ImportAudioResult {
+ successCount: number;
+ duplicateCount: number;
+ errorCount: number;
+ songs: Array;
+}
+
+function getMetadataExtractor(file: File) {
+ const ext = file.name.split(".").pop()?.toLowerCase();
+ if (ext === "flo") {
+ return createFloMetadataExtractor();
+ }
+ return createMetadataExtractor();
+}
+
+function createAlbumArtManager(): AlbumArtManager {
+ const manager = new AlbumArtManager();
+ manager.addProvider(new MusicBrainzProvider());
+ manager.addProvider(new DiscogsProvider());
+ return manager;
+}
+
+async function blobToDataUrl(blob: Blob): Promise {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result as string);
+ reader.onerror = () =>
+ reject(reader.error ?? new Error("Failed to read blob"));
+ reader.readAsDataURL(blob);
+ });
+}
+
+async function fetchRemoteAlbumArt(
+ artist: string,
+ album: string,
+ manager: AlbumArtManager,
+): Promise {
+ try {
+ const result = await manager.fetchAlbumArt({ artist, album });
+ if (!result) return undefined;
+
+ const response = await fetch(result.url, { mode: "cors" });
+ if (!response.ok) return undefined;
+
+ const blob = await response.blob();
+ if (!blob.type.startsWith("image/")) return undefined;
+
+ return await blobToDataUrl(blob);
+ } catch (error) {
+ logger.warn("Failed to fetch remote album art", {
+ error: String(error),
+ });
+ return undefined;
+ }
+}
+
+async function extractAudioMetadata(
+ file: File,
+ t: Translate,
+): Promise<{
+ metadata: ExtractedMetadata;
+ albumArt: string | undefined;
+}> {
+ const extractor = getMetadataExtractor(file);
+ const metadata = await extractor.extractMetadata(file);
+
+ let albumArt = metadata.albumArt;
+ if (albumArt) {
+ try {
+ albumArt = await compressAlbumArt(albumArt);
+ } catch (e) {
+ if (e instanceof Error) {
+ logger.warn("Failed to compress album art:", { error: e.message });
+ } else {
+ logger.warn("Failed to compress album art");
+ }
+ }
+ }
+
+ const translated: ExtractedMetadata = {
+ ...metadata,
+ artist:
+ metadata.artist === "Unknown Artist"
+ ? t("common.unknownArtist")
+ : metadata.artist,
+ album:
+ metadata.album === "Unknown Album"
+ ? t("common.unknownAlbum")
+ : metadata.album,
+ };
+
+ return { metadata: translated, albumArt };
+}
export async function importAudioFiles(
- audioFiles: Array<{ file: File } | File>,
- addSong: (song: Song, file: File) => Promise,
- t: any,
-) {
- if (!audioFiles || audioFiles.length === 0) return;
+ audioFiles: Array,
+ addSong: AudioImportOpts["addSong"],
+ t: Translate,
+ getExistingTracks?: () => Track[],
+ context?: ImportContext,
+): Promise {
+ if (!audioFiles || audioFiles.length === 0) {
+ return {
+ successCount: 0,
+ duplicateCount: 0,
+ errorCount: 0,
+ songs: [],
+ };
+ }
const BATCH_SIZE = 10;
let successCount = 0;
let errorCount = 0;
+ let duplicateCount = 0;
let currentBatch = 1;
- const totalBatches = Math.ceil(audioFiles.length / BATCH_SIZE);
+ const albumArtManager = createAlbumArtManager();
+ const duplicateDetector = createDuplicateDetector();
+ const resolvedSongs: Array = new Array(audioFiles.length).fill(
+ null,
+ );
+
+ const pending: Array<{ item: ImportFileItem | File; index: number }> = [];
+ for (let index = 0; index < audioFiles.length; index++) {
+ const item = audioFiles[index]!;
+ const sourceFile = "file" in item ? item.file : item;
+ if (sourceFile === null) continue;
+
+ const itemPath = "file" in item ? item.path : undefined;
+ const known = findTrackBySourcePath(
+ getExistingTracks ? getExistingTracks() : [],
+ {
+ sourceKind: context?.sourceKind,
+ sourceId: context?.sourceKind ? context?.sourceId : undefined,
+ path: itemPath ?? context?.path,
+ },
+ );
+
+ if (known) {
+ duplicateCount++;
+ resolvedSongs[index] = known;
+ if ("file" in item) item.file = null;
+ continue;
+ }
- for (let i = 0; i < audioFiles.length; i += BATCH_SIZE) {
- const batch = audioFiles.slice(i, i + BATCH_SIZE);
+ pending.push({ item, index });
+ }
+
+ const totalBatches = Math.ceil(pending.length / BATCH_SIZE);
+
+ for (let i = 0; i < pending.length; i += BATCH_SIZE) {
+ const batch = pending.slice(i, i + BATCH_SIZE);
toast.loading(t("batch.processing", { currentBatch, totalBatches }));
- // Process sequentially to reduce memory pressure
- for (const audioFile of batch) {
+ for (const { item: audioFile, index: absoluteIndex } of batch) {
try {
- const file: File = (audioFile as any).file || (audioFile as File);
- const metadata = await extractAudioMetadata(file);
+ const sourceFile = "file" in audioFile ? audioFile.file : audioFile;
+ if (sourceFile === null) continue;
+ const file: File = sourceFile;
+ const itemPath = "file" in audioFile ? audioFile.path : undefined;
+ const { metadata, albumArt: compressedArt } =
+ await extractAudioMetadata(file, t);
const songId = generateUniqueId();
- // Pre-decode flo files for better performance
let processedFile = file;
let processedMimeType = file.type;
@@ -36,86 +208,48 @@ export async function importAudioFiles(
metadata.encoding?.codec === "flo";
if (isFlo) {
- try {
- const arrayBuffer = await file.arrayBuffer();
- const isSafari = /^((?!chrome|android).)*safari/i.test(
- navigator.userAgent,
- );
-
- if (isSafari) {
- // Safari: Pre-decode to WAV for compatibility
- const { decodeFloToWav } = await import("./refloWavHelper");
- const wavBytes = await decodeFloToWav(arrayBuffer);
- const wavBlob = new Blob([wavBytes], { type: "audio/wav" });
- processedFile = new File(
- [wavBlob],
- file.name.replace(/\.flo$/i, ".wav"),
- { type: "audio/wav" },
- );
- processedMimeType = "audio/wav";
- console.log(`Pre-decoded flo to WAV for Safari: ${file.name}`);
- } else {
- // Non-Safari: Pre-decode to PCM for Web Audio API
- const { decodeFloToAudioBuffer } = await import("./floProcessor");
- const audioContext = new AudioContext();
- const audioBuffer = await decodeFloToAudioBuffer(
- arrayBuffer,
- audioContext,
- );
-
- // Store as interleaved Float32Array PCM
- const frameCount = audioBuffer.length;
- const channels = audioBuffer.numberOfChannels;
- const pcmData = new Float32Array(frameCount * channels);
-
- // Interleave channels
- for (let i = 0; i < frameCount; i++) {
- for (let ch = 0; ch < channels; ch++) {
- pcmData[i * channels + ch] =
- audioBuffer.getChannelData(ch)[i];
- }
- }
+ processedMimeType = "audio/x-flo";
+ }
+
+ let albumArtDataUrl = compressedArt;
+ let hasAlbumArt = !!compressedArt;
- const pcmBlob = new Blob([pcmData.buffer], { type: "audio/pcm" });
- processedFile = new File(
- [pcmBlob],
- file.name.replace(/\.flo$/i, ".pcm"),
- { type: "audio/pcm" },
- );
- processedMimeType = "audio/pcm";
-
- // Store AudioBuffer properties for reconstruction
- metadata.encoding = {
- ...metadata.encoding,
- sampleRate: audioBuffer.sampleRate,
- channels: audioBuffer.numberOfChannels,
- bitsPerSample: 32, // Float32
- codec: "pcm-float32",
- };
-
- // Close the temporary AudioContext
- await audioContext.close();
-
- console.log(`Pre-decoded flo to PCM: ${file.name}`);
+ const isUnknownArtist = metadata.artist === t("common.unknownArtist");
+ const isUnknownAlbum = metadata.album === t("common.unknownAlbum");
+
+ if (!hasAlbumArt && !isUnknownArtist && !isUnknownAlbum) {
+ const remoteArt = await fetchRemoteAlbumArt(
+ metadata.artist,
+ metadata.album,
+ albumArtManager,
+ );
+
+ if (remoteArt) {
+ try {
+ albumArtDataUrl = await compressAlbumArt(remoteArt);
+ hasAlbumArt = true;
+ } catch (e) {
+ if (e instanceof Error) {
+ logger.warn("Failed to compress remote album art", {
+ error: e.message,
+ });
+ } else {
+ logger.warn("Failed to compress remote album art");
+ }
}
- } catch (error) {
- console.warn(
- "Failed to pre-decode flo file, storing original:",
- error,
- );
- // Keep original file if pre-decoding fails
- processedMimeType = "audio/x-flo";
}
}
- // Save album art separately if present
- const hasAlbumArt = !!metadata.albumArt;
- if (hasAlbumArt && metadata.albumArt) {
- await musicIndexedDbHelper.saveAlbumArt(songId, metadata.albumArt);
- setAlbumArtInCache(songId, metadata.albumArt);
+ let albumArtUrl: string | undefined;
+ if (hasAlbumArt && albumArtDataUrl) {
+ albumArtUrl =
+ (await albumArtStorage.save(
+ songId,
+ dataUrlToBlob(albumArtDataUrl),
+ )) ?? albumArtDataUrl;
}
- const song: Song = {
+ const song: Track = {
id: songId,
title: metadata.title,
artist: metadata.artist,
@@ -123,32 +257,64 @@ export async function importAudioFiles(
metadata.album ||
t("songInfo.album", { title: t("common.unknownAlbum") }),
duration: metadata.duration,
- url: "", // Will be set by addSong
- albumArt: metadata.albumArt, // Keep for immediate display
+ url: "",
+ albumArt: albumArtUrl,
hasAlbumArt,
embeddedLyrics: metadata.embeddedLyrics,
encoding: metadata.encoding,
gapless: metadata.gapless,
+ replayGain: metadata.replayGain,
mimeType: processedMimeType,
};
- await addSong(song, processedFile);
+ if (context?.sourceKind) {
+ song.sourceKind = context.sourceKind;
+ if (context.sourceId) song.sourceId = context.sourceId;
+ }
+ song.path = itemPath ?? context?.path;
+
+ const candidates = getExistingTracks ? getExistingTracks() : [];
+ const duplicate =
+ findTrackBySourcePath(candidates, {
+ sourceKind: song.sourceKind,
+ sourceId: song.sourceId,
+ path: song.path,
+ }) ??
+ (await duplicateDetector.findDuplicateTrack(
+ processedFile,
+ song,
+ candidates,
+ ));
+
+ if (duplicate) {
+ duplicateCount++;
+ resolvedSongs[absoluteIndex] = duplicate;
+ if (typeof audioFile === "object" && "file" in audioFile) {
+ audioFile.file = null;
+ }
+ continue;
+ }
+
+ await addSong(song, processedFile, context);
+ resolvedSongs[absoluteIndex] = song;
- // Clear file reference to help GC
if (typeof audioFile === "object" && "file" in audioFile) {
- (audioFile as { file: File }).file = null as any;
+ audioFile.file = null;
}
successCount++;
} catch (error) {
- console.error("Failed to process song:", error);
+ if (error instanceof Error) {
+ logger.error("Failed to process song:", { error: error.message });
+ } else {
+ logger.error("Failed to process song");
+ }
errorCount++;
}
}
currentBatch++;
- // Give browser time to garbage collect between batches
await new Promise((r) => setTimeout(r, 100));
}
@@ -156,7 +322,12 @@ export async function importAudioFiles(
if (successCount > 0) {
toast.success(t("filePicker.successImport", { count: successCount }));
}
+ if (duplicateCount > 0) {
+ toast.info(t("filePicker.duplicatesSkipped", { count: duplicateCount }));
+ }
if (errorCount > 0) {
toast.error(t("filePicker.failedImport", { count: errorCount }));
}
+
+ return { successCount, duplicateCount, errorCount, songs: resolvedSongs };
}
diff --git a/Build/src/helpers/logger.ts b/Build/src/helpers/logger.ts
new file mode 100644
index 0000000..c857fea
--- /dev/null
+++ b/Build/src/helpers/logger.ts
@@ -0,0 +1,50 @@
+import { createSatori, type SatoriInstance } from "@nisoku/satori";
+
+export const satori: SatoriInstance = createSatori({
+ logLevel: "debug",
+ rateLimiting: {
+ enabled: true,
+ maxEventsPerSecond: 100,
+ },
+});
+
+export const logger = {
+ debug: (message: string, data?: Record) => {
+ satori.rootLogger.debug(message, data ? { state: data } : undefined);
+ },
+ info: (message: string, data?: Record) => {
+ satori.rootLogger.info(message, data ? { state: data } : undefined);
+ },
+ warn: (message: string, data?: Record) => {
+ satori.rootLogger.warn(message, data ? { state: data } : undefined);
+ },
+ error: (message: string, data?: Record) => {
+ satori.rootLogger.error(message, data ? { state: data } : undefined);
+ },
+};
+
+export const createLogger = (scope: string) => {
+ const scoped = satori.createLogger(scope);
+ return {
+ debug: (message: string, data?: Record) => {
+ scoped.debug(message, data ? { state: data } : undefined);
+ },
+ info: (message: string, data?: Record) => {
+ scoped.info(message, data ? { state: data } : undefined);
+ },
+ warn: (message: string, data?: Record) => {
+ scoped.warn(message, data ? { state: data } : undefined);
+ },
+ error: (message: string, data?: Record) => {
+ scoped.error(message, data ? { state: data } : undefined);
+ },
+ };
+};
+
+export const throwError = (
+ message: string,
+ data?: Record,
+): never => {
+ satori.rootLogger.error(message, { state: { ...data, fatal: true } });
+ throw new Error(message);
+};
diff --git a/Build/src/helpers/musicIndexedDbHelper.ts b/Build/src/helpers/musicIndexedDbHelper.ts
deleted file mode 100644
index eb6336c..0000000
--- a/Build/src/helpers/musicIndexedDbHelper.ts
+++ /dev/null
@@ -1,672 +0,0 @@
-// IndexedDB configuration
-import i18n from "i18next";
-
-const DB_NAME = "HTMLPlayerDB";
-const DB_VERSION = 2; // Bump version for album art store
-const STORES = {
- LIBRARY: "library",
- SETTINGS: "settings",
- AUDIO_DATA: "audioData", // Store for actual audio data
- ALBUM_ART: "albumArt", // New store for album art (lazy loaded)
-} as const;
-
-// In-memory cache for album art to avoid repeated IndexedDB reads
-const albumArtCache = new Map();
-const MAX_ALBUM_ART_CACHE = 50; // Only keep 50 album arts in memory
-
-// IndexedDB utilities
-const openDatabase = (): Promise => {
- return new Promise((resolve, reject) => {
- const request = indexedDB.open(DB_NAME, DB_VERSION);
-
- request.onerror = () => {
- console.error("Failed to open IndexedDB:", request.error);
- reject(request.error);
- };
-
- request.onsuccess = () => {
- resolve(request.result);
- };
-
- request.onupgradeneeded = (event) => {
- const db = (event.target as IDBOpenDBRequest).result;
- const oldVersion = event.oldVersion;
-
- // Create object stores if they don't exist
- if (!db.objectStoreNames.contains(STORES.LIBRARY)) {
- db.createObjectStore(STORES.LIBRARY, { keyPath: "id" });
- }
- if (!db.objectStoreNames.contains(STORES.SETTINGS)) {
- db.createObjectStore(STORES.SETTINGS, { keyPath: "id" });
- }
- if (!db.objectStoreNames.contains(STORES.AUDIO_DATA)) {
- const audioStore = db.createObjectStore(STORES.AUDIO_DATA, {
- keyPath: "songId",
- });
- audioStore.createIndex("lastAccessed", "lastAccessed", {
- unique: false,
- });
- }
- // Create album art store for lazy loading
- if (!db.objectStoreNames.contains(STORES.ALBUM_ART)) {
- db.createObjectStore(STORES.ALBUM_ART, { keyPath: "songId" });
- }
-
- // Migration: Move album art from library to separate store
- if (oldVersion < 2 && oldVersion > 0) {
- const transaction = (event.target as IDBOpenDBRequest).transaction;
- if (transaction) {
- const libraryStore = transaction.objectStore(STORES.LIBRARY);
- const albumArtStore = transaction.objectStore(STORES.ALBUM_ART);
-
- libraryStore.get("musicLibrary").onsuccess = function (e: any) {
- const library = e.target.result?.data;
- if (library?.songs) {
- library.songs.forEach((song: any) => {
- // Migrate album art to separate store
- if (song.albumArt) {
- albumArtStore.put({
- songId: song.id,
- albumArt: song.albumArt,
- });
- // Mark that album art exists but don't store it in library
- song.hasAlbumArt = true;
- delete song.albumArt;
- }
- // Also migrate audio data if present (from version 0)
- if (song.fileData && song.mimeType) {
- const audioStore = transaction.objectStore(STORES.AUDIO_DATA);
- audioStore.put({
- songId: song.id,
- fileData: song.fileData,
- mimeType: song.mimeType,
- lastAccessed: Date.now(),
- });
- delete song.fileData;
- delete song.mimeType;
- }
- });
- // Save cleaned up library
- libraryStore.put({ id: "musicLibrary", data: library });
- }
- };
- }
- }
- };
- });
-};
-
-const saveToIndexedDB = async (
- storeName: string,
- key: string,
- data: any,
-): Promise => {
- try {
- // Open database
- const db = await openDatabase();
-
- // For library data, we need to save album art separately
- if (key === "musicLibrary" && data?.songs) {
- // First pass: extract album art and save to separate store
- const albumArtsToSave: { songId: string; albumArt: string }[] = [];
-
- const BATCH_SIZE = 100;
- const processedSongs: any[] = [];
-
- // Process songs in batches to prevent RAM spikes
- for (let i = 0; i < data.songs.length; i += BATCH_SIZE) {
- const batch = data.songs.slice(i, i + BATCH_SIZE);
- const processedBatch = batch.map((song: any) => {
- // Extract album art for separate storage
- if (song.albumArt) {
- albumArtsToSave.push({ songId: song.id, albumArt: song.albumArt });
- }
-
- return {
- ...song,
- hasStoredAudio: song.hasStoredAudio || false,
- hasAlbumArt: !!song.albumArt || song.hasAlbumArt || false,
- url: "", // Clear URL - will be created on-demand
- albumArt: undefined, // Don't store album art in library - load lazily
- embeddedLyrics: song.embeddedLyrics, // Preserve embedded lyrics
- encoding: song.encoding, // Preserve encoding
- gapless: song.gapless, // Preserve gapless flag
- };
- });
- processedSongs.push(...processedBatch);
-
- // Yield to main thread between batches for large libraries
- if (
- i + BATCH_SIZE < data.songs.length &&
- data.songs.length > BATCH_SIZE
- ) {
- await new Promise((resolve) => setTimeout(resolve, 0));
- }
- }
-
- // Save album art separately in batches (don't block library save)
- if (albumArtsToSave.length > 0) {
- // Do this in background after library is saved
- setTimeout(async () => {
- try {
- const artDb = await openDatabase();
- const ART_BATCH_SIZE = 20; // Smaller batches for album art (they're big)
-
- for (let i = 0; i < albumArtsToSave.length; i += ART_BATCH_SIZE) {
- const artBatch = albumArtsToSave.slice(i, i + ART_BATCH_SIZE);
- const artTransaction = artDb.transaction(
- [STORES.ALBUM_ART],
- "readwrite",
- );
- const artStore = artTransaction.objectStore(STORES.ALBUM_ART);
-
- for (const art of artBatch) {
- artStore.put(art);
- }
-
- await new Promise((resolve, reject) => {
- artTransaction.oncomplete = () => resolve();
- artTransaction.onerror = () => reject(artTransaction.error);
- });
-
- // Yield between batches
- if (i + ART_BATCH_SIZE < albumArtsToSave.length) {
- await new Promise((resolve) => setTimeout(resolve, 10));
- }
- }
- artDb.close();
- console.log(
- `Saved ${albumArtsToSave.length} album arts to IndexedDB`,
- );
- } catch (error) {
- console.error("Failed to save album art:", error);
- }
- }, 100);
- }
-
- // Save library without album art data
- const transaction = db.transaction([storeName], "readwrite");
- const store = transaction.objectStore(storeName);
-
- const processedData = {
- ...data,
- songs: processedSongs,
- };
-
- const savePromise = new Promise((resolve, reject) => {
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => reject(transaction.error);
- store.put({ id: key, data: processedData });
- });
-
- await savePromise;
- db.close();
- console.log(`Saved ${key} to IndexedDB`);
- return;
- }
-
- // Non-library data - save normally
- const transaction = db.transaction([storeName], "readwrite");
- const store = transaction.objectStore(storeName);
-
- // Create a promise that resolves when the transaction completes
- const savePromise = new Promise((resolve, reject) => {
- transaction.oncomplete = () => resolve();
- transaction.onerror = () => reject(transaction.error);
- store.put({ id: key, data });
- });
-
- // Wait for transaction to complete before closing
- await savePromise;
- db.close();
- console.log(`Saved ${key} to IndexedDB`);
- } catch (error) {
- console.error(`Failed to save ${key} to IndexedDB:`, error);
- throw error;
- }
-};
-
-const loadFromIndexedDB = async (
- storeName: string,
- key: string,
-): Promise => {
- try {
- const db = await openDatabase();
- const transaction = db.transaction([storeName], "readonly");
- const store = transaction.objectStore(storeName);
-
- const result = await new Promise((resolve, reject) => {
- const request = store.get(key);
- request.onsuccess = () => resolve(request.result?.data);
- request.onerror = () => reject(request.error);
- });
-
- db.close();
- console.log(`Loaded ${key} from IndexedDB`);
-
- // If loading library data, create placeholder URLs for display
- if (key === "musicLibrary" && result?.songs) {
- // Ensure we have a songs array even if empty
- const rawSongs = result.songs || [];
-
- // Process songs in batches to prevent RAM spikes on large libraries
- const BATCH_SIZE = 100;
- const songsWithoutAudio: any[] = [];
-
- for (let i = 0; i < rawSongs.length; i += BATCH_SIZE) {
- const batch = rawSongs.slice(i, i + BATCH_SIZE);
-
- // Transform this batch - don't include albumArt, it will be loaded lazily
- const transformedBatch = batch.map((song: any) => {
- // Always set up the indexeddb URL if the song has stored audio
- const placeholderUrl = song.hasStoredAudio
- ? `indexeddb://${song.id}` // Will be loaded from IndexedDB
- : song.url || ""; // Keep original URL if no stored data, or empty if none
-
- return {
- // Ensure all required fields exist first
- id: song.id || `song-${Date.now()}-${Math.random()}`,
- title: song.title || i18n.t("common.unknownTitle"),
- artist: song.artist || i18n.t("common.unknownArtist"),
- album: song.album || i18n.t("common.unknownAlbum"),
- duration: song.duration || 0,
- // Then add the library-specific fields
- url: placeholderUrl,
- hasStoredAudio: song.hasStoredAudio || false,
- // DON'T load albumArt here - it will be lazy loaded on-demand
- // This is the key memory optimization - album art is loaded only when visible
- hasAlbumArt: song.hasAlbumArt || !!song.albumArt || false,
- albumArt: undefined, // Will be loaded lazily via loadAlbumArt()
- embeddedLyrics: song.embeddedLyrics, // Restore embedded lyrics
- encoding: song.encoding, // Restore encoding
- gapless: song.gapless, // Restore gapless flag
- };
- });
-
- songsWithoutAudio.push(...transformedBatch);
-
- // Yield to main thread between batches for large libraries
- if (i + BATCH_SIZE < rawSongs.length && rawSongs.length > BATCH_SIZE) {
- await new Promise((resolve) => setTimeout(resolve, 0));
- }
- }
-
- return {
- songs: songsWithoutAudio,
- playlists: result.playlists || [],
- favorites: result.favorites || [],
- };
- }
-
- return result;
- } catch (error) {
- console.error(`Failed to load ${key} from IndexedDB:`, error);
- return null;
- }
-};
-
-// Add new type for song audio data
-interface SongAudioData {
- fileData: ArrayBuffer;
- mimeType: string;
-}
-
-export const musicIndexedDbHelper = {
- async loadLibrary(): Promise {
- try {
- const library = await loadFromIndexedDB(STORES.LIBRARY, "musicLibrary");
- console.log("Loaded library state:", {
- songCount: library?.songs?.length || 0,
- playlistCount: library?.playlists?.length || 0,
- favoriteCount: library?.favorites?.length || 0,
- });
- return library;
- } catch (error) {
- console.error("Failed to load library:", error);
- return {
- songs: [],
- playlists: [],
- favorites: [],
- };
- }
- },
-
- async saveLibrary(library: MusicLibrary): Promise {
- await saveToIndexedDB(STORES.LIBRARY, "musicLibrary", library);
- },
-
- async loadSettings(): Promise {
- return await loadFromIndexedDB(STORES.SETTINGS, "playerSettings");
- },
-
- async saveSettings(settings: PlayerSettings): Promise {
- await saveToIndexedDB(STORES.SETTINGS, "playerSettings", settings);
- },
-
- async loadSongAudio(songId: string): Promise {
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.AUDIO_DATA], "readwrite");
- const store = transaction.objectStore(STORES.AUDIO_DATA);
-
- const result = await new Promise((resolve, reject) => {
- const request = store.get(songId);
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(request.error);
- });
-
- if (result) {
- // Update last accessed time
- store.put({
- ...result,
- lastAccessed: Date.now(),
- });
-
- return {
- fileData: result.fileData,
- mimeType: result.mimeType,
- };
- }
-
- db.close();
- return null;
- } catch (error) {
- console.error(`Failed to load audio data for song ${songId}:`, error);
- return null;
- }
- },
-
- async saveSongAudio(songId: string, audioData: SongAudioData): Promise {
- try {
- const db = await openDatabase();
- const transaction = db.transaction(
- [STORES.AUDIO_DATA, STORES.LIBRARY],
- "readwrite",
- );
- const audioStore = transaction.objectStore(STORES.AUDIO_DATA);
- const libraryStore = transaction.objectStore(STORES.LIBRARY);
-
- // Save audio data
- await new Promise((resolve, reject) => {
- const request = audioStore.put({
- songId,
- fileData: audioData.fileData,
- mimeType: audioData.mimeType,
- lastAccessed: Date.now(),
- });
- request.onsuccess = () => resolve();
- request.onerror = () => reject(request.error);
- });
-
- // Update song metadata to indicate audio is available
- const libraryData = await new Promise((resolve, reject) => {
- const request = libraryStore.get("musicLibrary");
- request.onsuccess = () => resolve(request.result?.data);
- request.onerror = () => reject(request.error);
- });
-
- if (libraryData?.songs) {
- const updatedSongs = libraryData.songs.map((song: any) => {
- if (song.id === songId) {
- return {
- ...song,
- hasStoredAudio: true,
- };
- }
- return song;
- });
-
- await new Promise((resolve, reject) => {
- const request = libraryStore.put({
- id: "musicLibrary",
- data: {
- ...libraryData,
- songs: updatedSongs,
- },
- });
- request.onsuccess = () => resolve();
- request.onerror = () => reject(request.error);
- });
- }
-
- db.close();
- } catch (error) {
- console.error(`Failed to save audio data for song ${songId}:`, error);
- throw error;
- }
- },
-
- async removeSongAudio(songId: string): Promise {
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.AUDIO_DATA], "readwrite");
- const store = transaction.objectStore(STORES.AUDIO_DATA);
-
- await new Promise((resolve, reject) => {
- const request = store.delete(songId);
- request.onsuccess = () => resolve();
- request.onerror = () => reject(request.error);
- });
-
- db.close();
- } catch (error) {
- console.error(`Failed to remove audio data for song ${songId}:`, error);
- throw error;
- }
- },
-
- async shouldShowDialog(dialogKey: string): Promise {
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.SETTINGS], "readonly");
- const store = transaction.objectStore(STORES.SETTINGS);
-
- const result = await new Promise((resolve, reject) => {
- const request = store.get(`dialog-${dialogKey}`);
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(request.error);
- });
-
- db.close();
- // Return true if no preference is set (show by default), false if user chose not to show
- return result?.data?.dontShowAgain !== true;
- } catch (error) {
- console.error(
- `Failed to check dialog preference for ${dialogKey}:`,
- error,
- );
- return true; // Default to showing the dialog if there's an error
- }
- },
-
- async setDialogPreference(
- dialogKey: string,
- dontShowAgain: boolean,
- ): Promise {
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.SETTINGS], "readwrite");
- const store = transaction.objectStore(STORES.SETTINGS);
-
- await new Promise((resolve, reject) => {
- const request = store.put({
- id: `dialog-${dialogKey}`,
- data: { dontShowAgain, timestamp: Date.now() },
- });
- request.onsuccess = () => resolve();
- request.onerror = () => reject(request.error);
- });
-
- db.close();
- console.log(
- `Saved dialog preference for ${dialogKey}: dontShowAgain=${dontShowAgain}`,
- );
- } catch (error) {
- console.error(
- `Failed to save dialog preference for ${dialogKey}:`,
- error,
- );
- throw error;
- }
- },
-
- // Lazy load album art for a single song
- async loadAlbumArt(songId: string): Promise {
- // Check in-memory cache first
- if (albumArtCache.has(songId)) {
- return albumArtCache.get(songId)!;
- }
-
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.ALBUM_ART], "readonly");
- const store = transaction.objectStore(STORES.ALBUM_ART);
-
- const result = await new Promise<
- { songId: string; albumArt: string } | undefined
- >((resolve, reject) => {
- const request = store.get(songId);
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(request.error);
- });
-
- db.close();
-
- if (result?.albumArt) {
- // Cache in memory (with LRU eviction)
- if (albumArtCache.size >= MAX_ALBUM_ART_CACHE) {
- // Remove oldest entry (first key)
- const firstKey = albumArtCache.keys().next().value;
- if (firstKey) albumArtCache.delete(firstKey);
- }
- albumArtCache.set(songId, result.albumArt);
- return result.albumArt;
- }
-
- return null;
- } catch (error) {
- console.error(`Failed to load album art for ${songId}:`, error);
- return null;
- }
- },
-
- // Load album art for multiple songs at once (more efficient than one-by-one)
- async loadAlbumArtBatch(songIds: string[]): Promise> {
- const result = new Map();
- const toLoad: string[] = [];
-
- // Check cache first
- for (const songId of songIds) {
- if (albumArtCache.has(songId)) {
- result.set(songId, albumArtCache.get(songId)!);
- } else {
- toLoad.push(songId);
- }
- }
-
- if (toLoad.length === 0) {
- return result;
- }
-
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.ALBUM_ART], "readonly");
- const store = transaction.objectStore(STORES.ALBUM_ART);
-
- // Load all needed album arts in parallel
- const loadPromises = toLoad.map((songId) => {
- return new Promise<{ songId: string; albumArt: string } | null>(
- (resolve, reject) => {
- const request = store.get(songId);
- request.onsuccess = () => resolve(request.result || null);
- request.onerror = () => reject(request.error);
- },
- );
- });
-
- const loadedArts = await Promise.all(loadPromises);
- db.close();
-
- // Process results and cache
- for (const art of loadedArts) {
- if (art?.albumArt) {
- // Cache with LRU eviction
- if (albumArtCache.size >= MAX_ALBUM_ART_CACHE) {
- const firstKey = albumArtCache.keys().next().value;
- if (firstKey) albumArtCache.delete(firstKey);
- }
- albumArtCache.set(art.songId, art.albumArt);
- result.set(art.songId, art.albumArt);
- }
- }
-
- return result;
- } catch (error) {
- console.error("Failed to load album art batch:", error);
- return result;
- }
- },
-
- // Save album art for a single song (used when adding new songs)
- async saveAlbumArt(songId: string, albumArt: string): Promise {
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.ALBUM_ART], "readwrite");
- const store = transaction.objectStore(STORES.ALBUM_ART);
-
- await new Promise((resolve, reject) => {
- const request = store.put({ songId, albumArt });
- request.onsuccess = () => resolve();
- request.onerror = () => reject(request.error);
- });
-
- db.close();
-
- // Update cache
- if (albumArtCache.size >= MAX_ALBUM_ART_CACHE) {
- const firstKey = albumArtCache.keys().next().value;
- if (firstKey) albumArtCache.delete(firstKey);
- }
- albumArtCache.set(songId, albumArt);
- } catch (error) {
- console.error(`Failed to save album art for ${songId}:`, error);
- }
- },
-
- // Clear album art cache to free memory
- clearAlbumArtCache(): void {
- albumArtCache.clear();
- },
-};
-
-export default musicIndexedDbHelper;
-
-export async function resetAllDialogPreferences(): Promise {
- try {
- const db = await openDatabase();
- const transaction = db.transaction([STORES.SETTINGS], "readwrite");
- const store = transaction.objectStore(STORES.SETTINGS);
- // Get all keys
- const keys = await new Promise((resolve, reject) => {
- const request = store.getAllKeys();
- request.onsuccess = () => resolve(request.result as string[]);
- request.onerror = () => reject(request.error);
- });
- // Delete all dialog-* keys
- await Promise.all(
- keys
- .filter((key) => key.startsWith("dialog-"))
- .map((key) => {
- return new Promise((resolve, reject) => {
- const req = store.delete(key);
- req.onsuccess = () => resolve();
- req.onerror = () => reject(req.error);
- });
- }),
- );
- db.close();
- } catch (error) {
- console.error("Failed to reset dialog preferences:", error);
- throw error;
- }
-}
diff --git a/Build/src/helpers/musicPlayerUtils.ts b/Build/src/helpers/musicPlayerUtils.ts
deleted file mode 100644
index 0a5bebb..0000000
--- a/Build/src/helpers/musicPlayerUtils.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-// Debouncing utility for IndexedDB saves
-
-export const getValidTempo = (tempo: number | undefined) => {
- if (typeof tempo !== "number" || !Number.isFinite(tempo) || tempo <= 0) {
- return 1; // fallback to normal speed
- }
- return tempo;
-};
-
-/**
- * Calculate combined playback rate from tempo and pitch, clamped to browser limits (0.25-4.0)
- * Tempo and pitch are applied multiplicatively: rate = tempo × 2^(pitch/12)
- */
-export const getValidPlaybackRate = (
- tempo: number | undefined,
- pitch: number | undefined,
-): number => {
- const validTempo = getValidTempo(tempo);
- const validPitch = pitch ?? 0;
-
- // Convert pitch (semitones) to frequency multiplier
- const pitchMultiplier = Math.pow(2, validPitch / 12);
-
- // Combine tempo and pitch
- const combinedRate = validTempo * pitchMultiplier;
-
- // Clamp to browser's supported playback rate range
- return Math.max(0.25, Math.min(4.0, combinedRate));
-};
diff --git a/Build/src/helpers/pitchShiftHelper.ts b/Build/src/helpers/pitchShiftHelper.ts
deleted file mode 100644
index 4cdb05c..0000000
--- a/Build/src/helpers/pitchShiftHelper.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-export interface PitchShiftProcessor {
- setPitch: (semitones: number) => void;
- getPitch: () => number;
- getPassThroughNode: () => GainNode;
- connectToAudioElement: (element: HTMLAudioElement) => void;
- destroy: () => void;
-}
-
-/**
- * Create a pitch shifter using playbackRate (affects both pitch and tempo)
- * Pitch is measured in semitones: -100 to +100
- * 0 means no pitch shift
- *
- * NOTE: This implementation uses HTMLAudioElement.playbackRate which changes
- * both pitch and tempo together (like playing a record at different speeds).
- * For true pitch shifting without tempo change, complex DSP would be required.
- */
-export function createPitchShifter(
- audioContext: AudioContext,
-): PitchShiftProcessor {
- let currentPitch = 0;
- let isDestroyed = false;
-
- // Create a gain node to maintain the audio chain
- const passThroughGain = audioContext.createGain();
- passThroughGain.gain.value = 1.0;
-
- const processor: PitchShiftProcessor = {
- setPitch(semitones: number) {
- if (isDestroyed) return;
-
- // Clamp to -48 to +48 semitones (4 octaves, staying within browser playback rate limits)
- currentPitch = Math.max(-48, Math.min(48, semitones));
- },
-
- getPitch() {
- return currentPitch;
- },
-
- getPassThroughNode() {
- return passThroughGain;
- },
-
- connectToAudioElement(_element: HTMLAudioElement) {
- // No-op: pitch control is handled elsewhere
- },
-
- destroy() {
- if (isDestroyed) return;
- isDestroyed = true;
-
- try {
- passThroughGain.disconnect();
- } catch (error) {
- console.error("Error destroying pitch shifter:", error);
- }
- },
- };
-
- return processor;
-}
-
-/**
- * Validate and clamp pitch value
- */
-export function getValidPitch(pitch: number | undefined): number {
- if (typeof pitch !== "number" || !Number.isFinite(pitch)) {
- return 0; // Default to no pitch shift
- }
- // Clamp to -48 to +48 semitones (4 octaves, staying within browser playback rate limits)
- return Math.max(-48, Math.min(48, pitch));
-}
-
-/**
- * Convert semitones to a human-readable string
- */
-export function formatPitchValue(semitones: number): string {
- if (semitones === 0) return "0";
- const sign = semitones > 0 ? "+" : "";
- return `${sign}${semitones}`;
-}
diff --git a/Build/src/helpers/platform.ts b/Build/src/helpers/platform.ts
deleted file mode 100644
index 9646562..0000000
--- a/Build/src/helpers/platform.ts
+++ /dev/null
@@ -1,323 +0,0 @@
-// Platform Detection Utilities
-// Use these helpers throughout the app to handle platform-specific behavior
-
-/**
- * Platform capabilities and feature detection
- */
-export const platform = {
- /**
- * Check if running in a web browser (not Tauri)
- */
- get isWeb(): boolean {
- return typeof window !== "undefined" && !("__TAURI__" in window);
- },
-
- /**
- * Check if running in Tauri desktop app
- */
- get isDesktop(): boolean {
- return typeof window !== "undefined" && "__TAURI__" in window;
- },
-
- /**
- * Check if PWA features are available
- */
- get isPWA(): boolean {
- return "serviceWorker" in navigator;
- },
-
- /**
- * Check if IndexedDB is available
- */
- get hasIndexedDB(): boolean {
- return typeof indexedDB !== "undefined";
- },
-
- /**
- * Check if native file system is available (Tauri)
- */
- get hasNativeFileSystem(): boolean {
- return this.isDesktop;
- },
-
- /**
- * Check if native dialogs are available (Tauri)
- */
- get hasNativeDialogs(): boolean {
- return this.isDesktop;
- },
-
- /**
- * Check if can install as PWA
- */
- get canInstallPWA(): boolean {
- return this.isWeb && "BeforeInstallPromptEvent" in window;
- },
-
- /**
- * Check if Web Audio API is available
- */
- get hasWebAudio(): boolean {
- return (
- typeof AudioContext !== "undefined" ||
- typeof (window as any).webkitAudioContext !== "undefined"
- );
- },
-
- /**
- * Detect Safari browser (for background playback workarounds)
- */
- get isSafari(): boolean {
- const ua = navigator.userAgent.toLowerCase();
- return (
- /^((?!chrome|android).)*safari/i.test(ua) || /iphone|ipad|ipod/i.test(ua)
- );
- },
-};
-
-/**
- * Audio file picker - unified interface for web and desktop
- * Uses Uppy Dashboard on web, native file picker on desktop
- */
-export async function pickAudioFiles(options?: {
- multiple?: boolean;
-}): Promise {
- if (platform.isDesktop) {
- // Use Tauri's native file picker
- const { open } = await import("@tauri-apps/plugin-dialog");
- const selected = await open({
- multiple: options?.multiple ?? true,
- filters: [
- {
- name: "Audio Files",
- extensions: [
- "mp3",
- "wav",
- "m4a",
- "flac",
- "aif",
- "aiff",
- "ogg",
- "opus",
- "webm",
- ],
- },
- ],
- });
-
- if (!selected) return [];
-
- // Convert Tauri paths to File objects
- const { readFile } = await import("@tauri-apps/plugin-fs");
- const paths = Array.isArray(selected) ? selected : [selected];
-
- const files = await Promise.all(
- paths.map(async (path) => {
- const contents = await readFile(path);
- const fileName = path.split("/").pop() ?? "unknown";
- const ext = fileName.split(".").pop()?.toLowerCase() ?? "mp3";
-
- // Determine MIME type from extension
- const mimeTypes: Record = {
- mp3: "audio/mpeg",
- wav: "audio/wav",
- m4a: "audio/mp4",
- flac: "audio/flac",
- aif: "audio/aiff",
- aiff: "audio/aiff",
- ogg: "audio/ogg",
- opus: "audio/opus",
- webm: "audio/webm",
- };
-
- return new File([contents], fileName, {
- type: mimeTypes[ext] || "audio/mpeg",
- });
- }),
- );
-
- return files;
- } else {
- // Web: Use existing Uppy implementation from filePickerHelper.tsx
- // This returns a promise that resolves when user completes selection
- const { pickAudioFiles: webPickAudioFiles } =
- await import("./filePickerHelper");
- const audioFiles = await webPickAudioFiles();
- return audioFiles.map((af) => af.file);
- }
-}
-
-/**
- * Export playlist file - unified interface for web and desktop
- */
-export async function exportPlaylistFile(
- content: string,
- fileName: string,
- fileType: "json" | "m3u",
-): Promise {
- const mimeType = fileType === "json" ? "application/json" : "audio/x-mpegurl";
- const blob = new Blob([content], { type: mimeType });
-
- if (platform.isDesktop) {
- // Use Tauri's native save dialog
- const { save } = await import("@tauri-apps/plugin-dialog");
- const { writeTextFile } = await import("@tauri-apps/plugin-fs");
-
- const filePath = await save({
- defaultPath: fileName,
- filters: [
- {
- name: fileType === "json" ? "JSON Files" : "M3U Playlist",
- extensions: [fileType],
- },
- ],
- });
-
- if (filePath) {
- await writeTextFile(filePath, content);
- }
- } else {
- // Web: Use download link
- const url = URL.createObjectURL(blob);
- const a = document.createElement("a");
- a.href = url;
- a.download = fileName;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
- }
-}
-
-/**
- * Import playlist file - unified interface for web and desktop
- */
-export async function importPlaylistFile(): Promise {
- if (platform.isDesktop) {
- const { open } = await import("@tauri-apps/plugin-dialog");
- const { readTextFile } = await import("@tauri-apps/plugin-fs");
-
- const selected = await open({
- multiple: false,
- filters: [
- {
- name: "Playlist Files",
- extensions: ["json", "m3u", "m3u8"],
- },
- ],
- });
-
- if (!selected || Array.isArray(selected)) return null;
-
- const content = await readTextFile(selected);
- const fileName = selected.split("/").pop() ?? "playlist";
- const ext = fileName.split(".").pop()?.toLowerCase() ?? "json";
- const mimeType = ext === "json" ? "application/json" : "audio/x-mpegurl";
-
- return new File([content], fileName, { type: mimeType });
- } else {
- // Web: Use file input
- return new Promise((resolve) => {
- const input = document.createElement("input");
- input.type = "file";
- input.accept = ".json,.m3u,.m3u8";
- input.onchange = () => {
- resolve(input.files?.[0] || null);
- };
- input.click();
- });
- }
-}
-
-/**
- * Show native notification
- */
-export async function showNotification(
- title: string,
- body: string,
-): Promise {
- if (platform.isDesktop) {
- // Use Tauri's native notifications
- try {
- const { sendNotification } =
- await import("@tauri-apps/plugin-notification");
- await sendNotification({ title, body });
- } catch (error) {
- console.warn("Desktop notification failed:", error);
- }
- } else {
- // Use web Notification API
- if ("Notification" in window && Notification.permission === "granted") {
- new Notification(title, { body });
- } else if (
- "Notification" in window &&
- Notification.permission !== "denied"
- ) {
- const permission = await Notification.requestPermission();
- if (permission === "granted") {
- new Notification(title, { body });
- }
- }
- }
-}
-
-/**
- * Get app version
- */
-export async function getAppVersion(): Promise {
- if (platform.isDesktop) {
- try {
- const { getVersion } = await import("@tauri-apps/api/app");
- return await getVersion();
- } catch {
- return "2.0.0";
- }
- } else {
- // Return version from package.json
- return "2.0.0";
- }
-}
-
-/**
- * Open external URL in default browser
- */
-export async function openExternal(url: string): Promise {
- if (platform.isDesktop) {
- const { openUrl } = await import("@tauri-apps/plugin-opener");
- await openUrl(url);
- } else {
- window.open(url, "_blank", "noopener,noreferrer");
- }
-}
-
-/**
- * Check if a specific audio format is supported
- */
-export function isAudioFormatSupported(format: string): boolean {
- const audio = document.createElement("audio");
- const canPlay = audio.canPlayType(format);
- return canPlay === "probably" || canPlay === "maybe";
-}
-
-/**
- * Get persistent storage estimate (IndexedDB usage)
- */
-export async function getStorageEstimate(): Promise<{
- usage: number;
- quota: number;
- percentage: number;
-} | null> {
- if ("storage" in navigator && "estimate" in navigator.storage) {
- try {
- const estimate = await navigator.storage.estimate();
- const usage = estimate.usage || 0;
- const quota = estimate.quota || 0;
- const percentage = quota > 0 ? (usage / quota) * 100 : 0;
- return { usage, quota, percentage };
- } catch (error) {
- console.warn("Failed to get storage estimate:", error);
- return null;
- }
- }
- return null;
-}
diff --git a/Build/src/helpers/playlistImageHelper.ts b/Build/src/helpers/playlistImageHelper.ts
deleted file mode 100644
index 74cdb6d..0000000
--- a/Build/src/helpers/playlistImageHelper.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-export const generatePlaylistImage = async (songs: Song[]): Promise => {
- // Create a canvas element
- const canvas = document.createElement("canvas");
- canvas.width = 80; // Same size as album art
- canvas.height = 80;
- const ctx = canvas.getContext("2d");
-
- if (!ctx) return "";
-
- // Get up to 4 unique album arts
- const uniqueAlbumArts = Array.from(
- new Set(songs.filter((song) => song.albumArt).map((song) => song.albumArt)),
- ).slice(0, 4);
-
- // If no album arts, return empty string
- if (uniqueAlbumArts.length === 0) return "";
-
- // Load all images first
- const loadImage = (src: string): Promise => {
- return new Promise((resolve, reject) => {
- const img = new Image();
- img.crossOrigin = "anonymous";
- img.onload = () => resolve(img);
- img.onerror = reject;
- img.src = src;
- });
- };
-
- try {
- const images = await Promise.all(
- uniqueAlbumArts.map((art) => loadImage(art!)),
- );
-
- // Clear the canvas
- ctx.fillStyle = "#1E3A8A"; // Default background
- ctx.fillRect(0, 0, canvas.width, canvas.height);
-
- // Draw images based on count
- switch (images.length) {
- case 1:
- // Single image takes up the whole space
- ctx.drawImage(images[0], 0, 0, 80, 80);
- break;
-
- case 2:
- // Two images side by side
- ctx.drawImage(images[0], 0, 0, 40, 80);
- ctx.drawImage(images[1], 40, 0, 40, 80);
- break;
-
- case 3:
- // One on top, two on bottom
- ctx.drawImage(images[0], 0, 0, 80, 40);
- ctx.drawImage(images[1], 0, 40, 40, 40);
- ctx.drawImage(images[2], 40, 40, 40, 40);
- break;
-
- case 4:
- // 2x2 grid
- ctx.drawImage(images[0], 0, 0, 40, 40);
- ctx.drawImage(images[1], 40, 0, 40, 40);
- ctx.drawImage(images[2], 0, 40, 40, 40);
- ctx.drawImage(images[3], 40, 40, 40, 40);
- break;
- }
-
- // Add a slight overlay to make it cohesive
- ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
- ctx.fillRect(0, 0, 80, 80);
-
- const result = canvas.toDataURL("image/jpeg", 0.7); // Reduced from 0.8 to 0.7 for memory savings
-
- // Clean up canvas to free memory
- canvas.width = 0;
- canvas.height = 0;
-
- return result;
- } catch (error) {
- console.error("Failed to generate playlist image:", error);
- // Clean up canvas on error too
- canvas.width = 0;
- canvas.height = 0;
- return "";
- }
-};
diff --git a/Build/src/helpers/playlistManager.ts b/Build/src/helpers/playlistManager.ts
deleted file mode 100644
index 47ec998..0000000
--- a/Build/src/helpers/playlistManager.ts
+++ /dev/null
@@ -1,655 +0,0 @@
-import { toast } from "sonner";
-import i18n from "i18next";
-
-export const createPlaylistManager = (
- setLibrary: (updater: (prev: MusicLibrary) => MusicLibrary) => void,
- library: MusicLibrary,
- setSearchQuery: (query: string) => void,
- searchQuery: string,
- setPlayerState: (updater: (prev: any) => any) => void,
-) => {
- const prepareSongsForPlaylist = (
- songs: Song[],
- songCacheRef?: React.MutableRefObject>,
- ): Song[] => {
- return songs.map((song) => {
- if (song.hasStoredAudio) {
- // Always use indexeddb:// URL for stored songs
- return {
- ...song,
- url: `indexeddb://${song.id}`,
- };
- } else if (songCacheRef?.current.has(song.id)) {
- // If song is in cache, use its cached URL
- const cached = songCacheRef.current.get(song.id);
- return {
- ...song,
- url: cached?.url || song.url,
- };
- }
- return song;
- });
- };
-
- const uuid = () =>
- crypto.randomUUID
- ? crypto.randomUUID()
- : Math.random().toString(36).slice(2) + Date.now();
-
- const createPlaylist = (name: string, songs: Song[] = []) => {
- const newPlaylist: Playlist = {
- id: uuid(),
- name,
- songs: prepareSongsForPlaylist(songs),
- };
- setLibrary((prev) => ({
- ...prev,
- playlists: [...prev.playlists, newPlaylist],
- }));
- return newPlaylist;
- };
-
- const createFolder = (name: string) => {
- const newFolder: PlaylistFolder = {
- id: uuid(),
- name,
- children: [],
- };
- setLibrary((prev) => ({
- ...prev,
- playlists: [...prev.playlists, newFolder],
- }));
- return newFolder;
- };
-
- const removePlaylist = (playlistId: string) => {
- setLibrary((prev) => {
- // Recursive function to remove playlist from the tree
- const removeFrom = (
- items: (Playlist | PlaylistFolder)[],
- ): (Playlist | PlaylistFolder)[] => {
- return items
- .filter((p) => p.id !== playlistId)
- .map((p) => {
- if ("children" in p) {
- return { ...p, children: removeFrom(p.children) };
- }
- return p;
- });
- };
-
- return {
- ...prev,
- playlists: removeFrom(prev.playlists),
- };
- });
- };
-
- const addToFavorites = (songId: string) => {
- setLibrary((prev) => ({
- ...prev,
- favorites: prev.favorites.includes(songId)
- ? prev.favorites
- : [...prev.favorites, songId],
- }));
- };
-
- const removeFromFavorites = (songId: string) => {
- setLibrary((prev) => ({
- ...prev,
- favorites: prev.favorites.filter((id) => id !== songId),
- }));
- };
-
- const addToPlaylist = (playlistId: string, songId: string) => {
- setLibrary((prev) => {
- // Find the song
- const song = prev.songs.find((s) => s.id === songId);
- if (!song) return prev;
-
- // Recursive function to update playlists in the tree
- const updatePlaylists = (
- items: (Playlist | PlaylistFolder)[],
- ): (Playlist | PlaylistFolder)[] => {
- return items.map((p) => {
- if (p.id === playlistId && "songs" in p) {
- // Don't add if song is already in playlist
- if (p.songs.some((s) => s.id === songId)) return p;
- return {
- ...p,
- songs: [...p.songs, song],
- };
- }
- if ("children" in p) {
- return { ...p, children: updatePlaylists(p.children) };
- }
- return p;
- });
- };
-
- return {
- ...prev,
- playlists: updatePlaylists(prev.playlists),
- };
- });
- };
-
- const reorderPlaylistSongs = (
- playlistId: string | null,
- newSongs: Song[],
- ) => {
- setLibrary((prev) => {
- // If playlistId is undefined, update root songs (for All Songs)
- if (!playlistId) {
- return {
- ...prev,
- songs: newSongs,
- playlists: prev.playlists.map((p) =>
- p.id === "all-songs" ? { ...p, songs: newSongs } : p,
- ),
- };
- }
- // Otherwise, update the playlist in the tree
- const updatePlaylists = (
- items: (Playlist | PlaylistFolder)[],
- ): (Playlist | PlaylistFolder)[] => {
- return items.map((p) => {
- if (p.id === playlistId && "songs" in p) {
- return {
- ...p,
- songs: newSongs,
- };
- }
- if ("children" in p) {
- return { ...p, children: updatePlaylists(p.children) };
- }
- return p;
- });
- };
- return {
- ...prev,
- playlists: updatePlaylists(prev.playlists),
- };
- });
- };
-
- const moveSongToPlaylist = (
- songId: string,
- sourcePlaylistId: string | null,
- targetPlaylistId: string,
- ) => {
- setLibrary((prev) => {
- // Find the song first
- const song = prev.songs.find((s) => s.id === songId);
- if (!song) return prev;
-
- // Helper function to remove song from a playlist
- const removeSongFromPlaylist = (
- items: (Playlist | PlaylistFolder)[],
- playlistId: string | null,
- ): (Playlist | PlaylistFolder)[] => {
- if (playlistId === null || playlistId === "all-songs") {
- // Don't remove from "all-songs" or null (root songs)
- return items;
- }
-
- return items.map((p) => {
- if (p.id === playlistId && "songs" in p) {
- return {
- ...p,
- songs: p.songs.filter((s) => s.id !== songId),
- };
- }
- if ("children" in p) {
- return {
- ...p,
- children: removeSongFromPlaylist(p.children, playlistId),
- };
- }
- return p;
- });
- };
-
- // Helper function to add song to a playlist
- const addSongToPlaylist = (
- items: (Playlist | PlaylistFolder)[],
- playlistId: string,
- ): (Playlist | PlaylistFolder)[] => {
- return items.map((p) => {
- if (p.id === playlistId && "songs" in p) {
- // Don't add if song is already in playlist
- if (p.songs.some((s) => s.id === songId)) return p;
- return {
- ...p,
- songs: [...p.songs, song],
- };
- }
- if ("children" in p) {
- return {
- ...p,
- children: addSongToPlaylist(p.children, playlistId),
- };
- }
- return p;
- });
- };
-
- // Remove from source playlist (if specified and not "all-songs")
- let updatedPlaylists = prev.playlists;
- if (sourcePlaylistId && sourcePlaylistId !== "all-songs") {
- updatedPlaylists = removeSongFromPlaylist(
- updatedPlaylists,
- sourcePlaylistId,
- );
- }
-
- // Add to target playlist
- updatedPlaylists = addSongToPlaylist(updatedPlaylists, targetPlaylistId);
-
- return {
- ...prev,
- playlists: updatedPlaylists,
- };
- });
- };
-
- const moveToFolder = (
- itemId: string,
- folderId: string | null,
- beforeId?: string | null,
- ) => {
- setLibrary((prev) => {
- // Debug logs: log the intent of the move
- console.debug("[playlistManager] moveToFolder called with", {
- itemId,
- folderId,
- beforeId,
- });
- // Recursively find and remove the item from any depth
- let removedItem: Playlist | PlaylistFolder | null = null;
- const removeRecursive = (
- items: (Playlist | PlaylistFolder)[],
- ): (Playlist | PlaylistFolder)[] => {
- return items
- .filter((p) => {
- if (p.id === itemId) {
- removedItem = p;
- return false;
- }
- return true;
- })
- .map((p) => {
- if ("children" in p) {
- return { ...p, children: removeRecursive(p.children) };
- }
- return p;
- });
- };
-
- // Remove the item from the tree
- let newPlaylists = removeRecursive(prev.playlists);
- if (!removedItem) {
- // eslint-disable-next-line no-console
- console.warn("[playlistManager] moveToFolder: item not found", itemId);
- return prev;
- }
-
- // Prevent moving folder into itself or its descendants
- if (folderId && removedItem && "children" in removedItem) {
- const isDescendant = (
- items: (Playlist | PlaylistFolder)[],
- targetId: string,
- ): boolean => {
- for (const item of items) {
- if (item.id === targetId) return true;
- if ("children" in item && isDescendant(item.children, targetId))
- return true;
- }
- return false;
- };
- // Find the target folder
- const findFolder = (
- items: (Playlist | PlaylistFolder)[],
- id: string,
- ): PlaylistFolder | null => {
- for (const item of items) {
- if (item.id === id && "children" in item)
- return item as PlaylistFolder;
- if ("children" in item) {
- const found = findFolder(item.children, id);
- if (found) return found;
- }
- }
- return null;
- };
- const targetFolder = findFolder(newPlaylists, folderId);
- const removedFolder = removedItem as PlaylistFolder;
- if (targetFolder && isDescendant(removedFolder.children, folderId)) {
- return prev;
- }
- }
-
- // Recursively insert the item into the target folder or root
- const insertRecursive = (
- items: (Playlist | PlaylistFolder)[],
- parentId: string | null,
- newItem: Playlist | PlaylistFolder,
- beforeId: string | null,
- ): (Playlist | PlaylistFolder)[] => {
- if (parentId === null) {
- // Insert at root
- if (!beforeId) return [...items, newItem];
- const idx = items.findIndex((p) => p.id === beforeId);
- if (idx === -1) return [...items, newItem];
- return [...items.slice(0, idx), newItem, ...items.slice(idx)];
- }
- return items.map((p) => {
- if (p.id === parentId && "children" in p) {
- const children = p.children;
- if (!beforeId) {
- return { ...p, children: [...children, newItem] };
- }
- const idx = children.findIndex((c) => c.id === beforeId);
- if (idx === -1) {
- return { ...p, children: [...children, newItem] };
- }
- return {
- ...p,
- children: [
- ...children.slice(0, idx),
- newItem,
- ...children.slice(idx),
- ],
- };
- } else if ("children" in p) {
- return {
- ...p,
- children: insertRecursive(
- p.children,
- parentId,
- newItem,
- beforeId,
- ),
- };
- }
- return p;
- });
- };
-
- if (folderId) {
- // eslint-disable-next-line no-console
- console.debug(
- "[playlistManager] inserting into folder",
- folderId,
- "beforeId",
- beforeId,
- );
- newPlaylists = insertRecursive(
- newPlaylists,
- folderId,
- removedItem,
- beforeId || null,
- );
- } else {
- // eslint-disable-next-line no-console
- console.debug(
- "[playlistManager] inserting into root beforeId",
- beforeId,
- );
- newPlaylists = insertRecursive(
- newPlaylists,
- null,
- removedItem,
- beforeId || null,
- );
- }
-
- return { ...prev, playlists: newPlaylists };
- });
- };
-
- const toggleFavorite = (songId: string) => {
- const isFav = library.favorites.includes(songId);
- if (isFav) removeFromFavorites(songId);
- else addToFavorites(songId);
- return !isFav;
- };
-
- const isFavorited = (songId: string) => {
- return library.favorites.includes(songId);
- };
-
- const getFavoriteSongs = () => {
- return library.songs.filter((s) => library.favorites.includes(s.id));
- };
-
- const searchSongs = (query: string) => {
- setSearchQuery(query);
- if (!query.trim()) return library.songs;
- return library.songs.filter(
- (s) =>
- s.title.toLowerCase().includes(query.toLowerCase()) ||
- s.artist.toLowerCase().includes(query.toLowerCase()),
- );
- };
-
- const getSearchResults = () => {
- return searchSongs(searchQuery);
- };
-
- const navigateToArtist = (artist: string) => {
- setPlayerState((prev: any) => ({
- ...prev,
- view: "artist",
- currentArtist: artist,
- }));
- };
-
- const navigateToAlbum = (album: string) => {
- setPlayerState((prev: any) => ({
- ...prev,
- view: "album",
- currentAlbum: album,
- }));
- };
-
- const navigateToHome = () => {
- setPlayerState((prev: any) => ({
- ...prev,
- view: "home",
- currentArtist: undefined,
- currentAlbum: undefined,
- }));
- };
-
- const navigateToSongs = () => {
- setPlayerState((prev: any) => ({
- ...prev,
- view: "songs",
- currentArtist: undefined,
- currentAlbum: undefined,
- }));
- };
-
- // Export playlist to JSON or M3U format
- const exportPlaylist = (
- playlist: Playlist,
- format: "json" | "m3u" = "json",
- ) => {
- try {
- let content: string;
- let filename: string;
- let mimeType: string;
-
- if (format === "json") {
- // Export as JSON with full metadata
- const exportData = {
- name: playlist.name,
- created: new Date().toISOString(),
- songs: playlist.songs.map((song) => ({
- title: song.title,
- artist: song.artist,
- album: song.album,
- duration: song.duration,
- // Don't include URL or file data for privacy/size reasons
- })),
- };
- content = JSON.stringify(exportData, null, 2);
- filename = `${playlist.name.replace(/[^a-z0-9]/gi, "_")}.json`;
- mimeType = "application/json";
- } else {
- // Export as M3U playlist
- content = "#EXTM3U\n";
- playlist.songs.forEach((song) => {
- content += `#EXTINF:${Math.floor(song.duration)},${song.artist} - ${
- song.title
- }\n`;
- content += `# ${song.album}\n`;
- });
- filename = `${playlist.name.replace(/[^a-z0-9]/gi, "_")}.m3u`;
- mimeType = "audio/x-mpegurl";
- }
-
- // Create and download file
- const blob = new Blob([content], { type: mimeType });
- const url = URL.createObjectURL(blob);
- const a = document.createElement("a");
- a.href = url;
- a.download = filename;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
-
- toast.success(
- i18n.t("playlist.exportedAs", {
- name: playlist.name,
- format: format.toUpperCase(),
- }),
- );
- } catch (error) {
- console.error("Export failed:", error);
- toast.error(
- i18n.t("playlist.exportFailed") +
- " " +
- (error instanceof Error
- ? error.message
- : i18n.t("common.unknownError")),
- );
- }
- };
-
- // Import playlist from JSON file
- const importPlaylist = (file: File) => {
- return new Promise((resolve, reject) => {
- const reader = new FileReader();
-
- reader.onload = (e) => {
- try {
- const content = e.target?.result as string;
-
- if (file.name.endsWith(".json")) {
- // Parse JSON playlist
- const playlistData = JSON.parse(content);
-
- if (!playlistData.name || !Array.isArray(playlistData.songs)) {
- throw new Error(i18n.t("playlist.invalidFormat"));
- }
-
- // Create new playlist with imported metadata (songs will need to be matched/re-added)
- const newPlaylist: Playlist = {
- id: Date.now().toString(),
- name: `${playlistData.name} (Imported)`,
- songs: [], // Empty for now, user will need to add songs manually
- };
-
- // Add the playlist
- createPlaylist(newPlaylist.name, newPlaylist.songs);
-
- toast.success(
- i18n.t("playlist.importedPlaylist", {
- name: playlistData.name,
- count: playlistData.songs.length,
- }),
- );
- toast.info(i18n.t("playlist.noteManualAdd"));
- resolve();
- } else if (
- file.name.endsWith(".m3u") ||
- file.name.endsWith(".m3u8")
- ) {
- // Parse M3U playlist
- const lines = content.split("\n").filter((line) => line.trim());
- const songs: Array<{ title: string; artist: string }> = [];
-
- for (let i = 0; i < lines.length; i++) {
- const line = lines[i].trim();
- if (line.startsWith("#EXTINF:")) {
- // Extract artist and title from M3U format
- const match = line.match(/#EXTINF:\d+,(.+?) - (.+)/);
- if (match) {
- songs.push({
- artist: match[1],
- title: match[2],
- });
- }
- }
- }
-
- // Create playlist
- const playlistName = file.name.replace(/\.(m3u|m3u8)$/i, "");
- createPlaylist(`${playlistName} (Imported)`, []);
-
- toast.success(
- i18n.t("playlist.importedM3u", { count: songs.length }),
- );
- toast.info(i18n.t("playlist.noteManualAdd"));
- resolve();
- } else {
- throw new Error(i18n.t("playlist.unsupportedFormat"));
- }
- } catch (error) {
- console.error("Import failed:", error);
- const message =
- error instanceof Error
- ? error.message
- : i18n.t("playlist.failedToParse");
- toast.error(i18n.t("playlist.importFailedWithMessage", { message }));
- reject(error);
- }
- };
-
- reader.onerror = () => {
- const error = new Error(i18n.t("playlist.failedToReadFile"));
- toast.error(i18n.t("playlist.failedToReadFile"));
- reject(error);
- };
-
- reader.readAsText(file);
- });
- };
-
- return {
- prepareSongsForPlaylist,
- createPlaylist,
- createFolder,
- removePlaylist,
- addToFavorites,
- removeFromFavorites,
- addToPlaylist,
- reorderPlaylistSongs,
- moveSongToPlaylist,
- moveToFolder,
- toggleFavorite,
- isFavorited,
- getFavoriteSongs,
- searchSongs,
- getSearchResults,
- navigateToHome,
- navigateToArtist,
- navigateToAlbum,
- navigateToSongs,
- exportPlaylist,
- importPlaylist,
- };
-};
diff --git a/Build/src/helpers/reducedMotion.ts b/Build/src/helpers/reducedMotion.ts
new file mode 100644
index 0000000..72f5bf1
--- /dev/null
+++ b/Build/src/helpers/reducedMotion.ts
@@ -0,0 +1,3 @@
+export const prefersReducedMotion = (): boolean =>
+ typeof window !== "undefined" &&
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches;
diff --git a/Build/src/helpers/refloWavHelper.ts b/Build/src/helpers/refloWavHelper.ts
deleted file mode 100644
index 7c3a5e6..0000000
--- a/Build/src/helpers/refloWavHelper.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import initReflo, * as reflo from "@flo-audio/reflo/reflo.js";
-
-let refloInitialized = false;
-
-async function ensureRefloInitialized() {
- if (!refloInitialized) {
- await initReflo(); // Initialize WASM module
- refloInitialized = true;
- }
-}
-
-/**
- * Decode a .flo file to WAV format using @flo-audio/reflo
- * This is used for Safari which needs standard formats for background playback
- *
- * @param floData - ArrayBuffer containing flo audio data
- * @returns Uint8Array containing complete WAV file (headers + audio data)
- */
-export async function decodeFloToWav(
- floData: ArrayBuffer,
-): Promise {
- await ensureRefloInitialized();
-
- const uint8Flo = new Uint8Array(floData);
-
- // reflo.decode_flo_to_wav returns a complete WAV file
- const wavData = reflo.decode_flo_to_wav(uint8Flo);
-
- return wavData;
-}
-
-export { initReflo, ensureRefloInitialized };
diff --git a/Build/src/helpers/safariHelper.ts b/Build/src/helpers/safariHelper.ts
deleted file mode 100644
index 5ff9253..0000000
--- a/Build/src/helpers/safariHelper.ts
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * Safari/WebKit background audio helper
- * Safari requires an actual element in the DOM to play audio in the background
- * AudioContext and new Audio() don't work in background on Safari
- */
-
-/**
- * Detect if the current browser is Safari or WebKit-based
- */
-export function isSafari(): boolean {
- const ua = navigator.userAgent.toLowerCase();
- const isSafari =
- ua.includes("safari") && !ua.includes("chrome") && !ua.includes("android");
- const isWebKit = ua.includes("applewebkit") && !ua.includes("chrome");
-
- return isSafari || isWebKit;
-}
-
-/**
- * Safari Audio Manager
- * Manages a element that stays in sync with the main audio
- * This allows background playback on Safari
- */
-export class SafariAudioManager {
- private audioElement: HTMLAudioElement | null = null;
- private isEnabled: boolean = false;
-
- constructor() {
- this.isEnabled = isSafari();
-
- if (this.isEnabled) {
- this.initializeAudioElement();
- }
- }
-
- /**
- * Create and configure the audio element
- */
- private initializeAudioElement(): void {
- // Create audio element
- this.audioElement = document.createElement("audio");
- this.audioElement.crossOrigin = "anonymous";
- this.audioElement.preload = "auto";
-
- // Start muted - will be unmuted if used as primary audio element
- this.audioElement.volume = 0;
- this.audioElement.muted = true;
-
- // Make it invisible but present in DOM
- this.audioElement.style.position = "fixed";
- this.audioElement.style.opacity = "0";
- this.audioElement.style.pointerEvents = "none";
- this.audioElement.style.width = "1px";
- this.audioElement.style.height = "1px";
- this.audioElement.style.bottom = "0";
- this.audioElement.style.left = "0";
-
- // Add to DOM - required for Safari background playback
- document.body.appendChild(this.audioElement);
-
- console.log(
- "[Safari Audio] Initialized audio element for background playback",
- );
- }
-
- /**
- * Check if Safari audio manager is enabled
- */
- public isActive(): boolean {
- return this.isEnabled && this.audioElement !== null;
- }
-
- /**
- * Set the audio source
- */
- public setSrc(src: string): void {
- if (!this.audioElement) return;
-
- try {
- // Only set src if it's a valid URL (not empty, not about:blank, and not indexeddb://)
- // IndexedDB URLs are internal references that need to be resolved to blob URLs first
- if (
- src &&
- !src.includes("about:blank") &&
- !src.startsWith("indexeddb://")
- ) {
- this.audioElement.src = src;
- console.log("[Safari Audio] Set source:", src.substring(0, 50) + "...");
- } else if (src.startsWith("indexeddb://")) {
- console.log(
- "[Safari Audio] Skipping IndexedDB URL - waiting for blob URL",
- );
- }
- } catch (error) {
- console.error("[Safari Audio] Failed to set src:", error);
- }
- }
-
- /**
- * Play the audio
- */
- public async play(): Promise