diff --git a/package-lock.json b/package-lock.json index 81df767..4045eaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,19 @@ "version": "3.7.2", "license": "Apache-2.0", "dependencies": { + "@embedpdf/core": "^2.15.0", + "@embedpdf/engines": "^2.15.0", + "@embedpdf/models": "^2.15.0", + "@embedpdf/pdfium": "^2.15.0", + "@embedpdf/plugin-document-manager": "^2.15.0", + "@embedpdf/plugin-render": "^2.15.0", + "@embedpdf/plugin-scroll": "^2.15.0", + "@embedpdf/plugin-tiling": "^2.15.0", + "@embedpdf/plugin-viewport": "^2.15.0", + "@embedpdf/plugin-zoom": "^2.15.0", + "@extend-ai/react-docx": "^0.8.3", + "@extend-ai/react-pptx": "^0.1.2", + "@extend-ai/react-xlsx": "^0.16.1", "@formkit/auto-animate": "^0.9.0", "@heroui/react": "^2.7.11", "@mux/mux-player-react": "^3.13.2", @@ -33,6 +46,8 @@ "@tauri-apps/plugin-store": "^2.4.3", "@tauri-apps/plugin-updater": "^2.10.1", "@tauri-apps/plugin-window-state": "^2.4.1", + "@uiw/codemirror-extensions-langs": "^4.25.11", + "@uiw/react-codemirror": "^4.25.11", "cronstrue": "^3.24.0", "date-fns": "^4.4.0", "framer-motion": "^12.42.2", @@ -238,20 +253,18 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, + "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==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "dev": true, + "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==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -282,13 +295,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", - "dev": true, + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.0" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -373,14 +385,13 @@ } }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", - "dev": true, + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -541,6 +552,589 @@ "node": ">=14.21.3" } }, + "node_modules/@chenglou/pretext": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@chenglou/pretext/-/pretext-0.0.8.tgz", + "integrity": "sha512-yqm2GMxnPI7VHcHwe84P8ZF0JK/2d2DMKPqMN+s95jQhwDMYYXKVFVJUMEaVWckQStdsjdLav/0Vu+d9YbtGxA==", + "license": "MIT" + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.20.3", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.3.tgz", + "integrity": "sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.11.0.tgz", + "integrity": "sha512-/K4Rl5BN0OtTiPWmJCdqODu38XnDMsDxKY5rgrPnCkutPTJf2wVbkoixLfealF5Kwse/s8P8M5jAiURiwSwnFA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.7.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-cpp": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.3.tgz", + "integrity": "sha512-URM26M3vunFFn9/sm6rzqrBzDgfWuDixp85uTY49wKudToc2jTHUrKIGGKs+QWND+YLofNNZpxcNGRynFJfvgA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/cpp": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-css": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", + "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.1.7" + } + }, + "node_modules/@codemirror/lang-go": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-go/-/lang-go-6.0.1.tgz", + "integrity": "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/go": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.12", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.12.tgz", + "integrity": "sha512-pw2ReWKUqSkbvh76RAT4NYxiogRu+PWkR2ukAwO9uOgrm8uipkzjtKKtNpyeAQwHOqxEeSvAXZ6vr3AfyB9y/w==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.12" + } + }, + "node_modules/@codemirror/lang-java": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.2.tgz", + "integrity": "sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/java": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.5.tgz", + "integrity": "sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-jinja": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-jinja/-/lang-jinja-6.0.1.tgz", + "integrity": "sha512-P5kyHLObzjtbGj16h+hyvZTxJhSjBEeSx4wMjbnAf3b0uwTy2+F0zGjMZL4PQOm/mh2eGZ5xUDVZXgwP783Nsw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.2.0", + "@lezer/lr": "^1.4.0" + } + }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz", + "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-less": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-less/-/lang-less-6.0.2.tgz", + "integrity": "sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==", + "license": "MIT", + "dependencies": { + "@codemirror/lang-css": "^6.2.0", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-liquid": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-liquid/-/lang-liquid-6.3.2.tgz", + "integrity": "sha512-6PDVU3ZnfeYyz1at1E/ttorErZvZFXXt1OPhtfe1EZJ2V2iDFa0CwPqPgG5F7NXN0yONGoBogKmFAafKTqlwIw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.1" + } + }, + "node_modules/@codemirror/lang-markdown": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.5.2.tgz", + "integrity": "sha512-AwBOdkWYuA//WcM0xO5PfHPUcmz/O2i5o0Nsg1U69SII/loCJlFI1Romd9xp2HYb1kYJRGZotyqRghuHH5n8Kw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.7.1", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/markdown": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-php": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.2.tgz", + "integrity": "sha512-ZKy2v1n8Fc8oEXj0Th0PUMXzQJ0AIR6TaZU+PbDHExFwdu+guzOA4jmCHS1Nz4vbFezwD7LyBdDnddSJeScMCA==", + "license": "MIT", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/php": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-python": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.2.1.tgz", + "integrity": "sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.3.2", + "@codemirror/language": "^6.8.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/python": "^1.1.4" + } + }, + "node_modules/@codemirror/lang-rust": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.2.tgz", + "integrity": "sha512-EZaGjCUegtiU7kSMvOfEZpaCReowEf3yNidYu7+vfuGTm9ow4mthAparY5hisJqOHmJowVH3Upu+eJlUji6qqA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/rust": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-sass": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz", + "integrity": "sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==", + "license": "MIT", + "dependencies": { + "@codemirror/lang-css": "^6.2.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/sass": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-sql": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.10.0.tgz", + "integrity": "sha512-6ayPkEd/yRw0XKBx5uAiToSgGECo/GY2NoJIHXIIQh1EVwLuKoU8BP/qK0qH5NLXAbtJRLuT73hx7P9X34iO4w==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-vue": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz", + "integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==", + "license": "MIT", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-javascript": "^6.1.2", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.1" + } + }, + "node_modules/@codemirror/lang-wast": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz", + "integrity": "sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-xml": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz", + "integrity": "sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/xml": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-yaml": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-yaml/-/lang-yaml-6.1.3.tgz", + "integrity": "sha512-AZ8DJBuXGVHybpBQhmZtgew5//4hv3tdkXnr3vDmOUMJRuB6vn/uuwtmTOTlqEaQFg3hQSVeA90NmvIQyUV6FQ==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.2.0", + "@lezer/lr": "^1.0.0", + "@lezer/yaml": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.4.tgz", + "integrity": "sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.5.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/legacy-modes": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.5.3.tgz", + "integrity": "sha512-xCsmIzH78MyWkib9jlPaaun57XNkfbMIhagfaZVd0iLTqlpw3jXaIcbZm72MTmmn64eTZpBVNjbyYh+QXnxRsg==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.7.tgz", + "integrity": "sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.42.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.1.tgz", + "integrity": "sha512-uMe5UO6PamJtSHrXhhHOzSX3ReWtiJrva6GnPMwSOrZtiExb5X5eExhr2OUZQVvdxPsKpY3Ro2mFbQadpPWmHA==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.37.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.1.tgz", + "integrity": "sha512-9QzNDgE4EYDnAHfrTlR2lwiPciiOymLtwKK+8yHQzCc7GXhAP9xdEbEJFy2IWB1j9UGUl9BsgMmTo/ImA02T7A==", + "license": "MIT", + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "node_modules/@codemirror/theme-one-dark": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.3.tgz", + "integrity": "sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.43.9", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.9.tgz", + "integrity": "sha512-sTuUzTpPMFebRhg6dawChoKKgndIwfjmJgKVxBefPElcU2NwQ6AFroupk0SFqEerQyZOGRfDNnSN8Dw/lMAsXw==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.7.0", + "crelt": "^1.0.6", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@dukelib/sheets-wasm": { + "version": "0.1.21", + "resolved": "https://registry.npmjs.org/@dukelib/sheets-wasm/-/sheets-wasm-0.1.21.tgz", + "integrity": "sha512-YJpLUo/K7N9iGZv+A74D8o6XlT1VjMdlq9i/pIj/DwAO9/7jqppaV60VdL0TgJ0UzUlbhChWR+qQGNTmESINlw==", + "license": "MIT" + }, + "node_modules/@embedpdf/core": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/core/-/core-2.15.0.tgz", + "integrity": "sha512-0yaPCgvbE5/cBf+5rHBUsRUm8i6hSl894xjC19HTOmb8DqrhxOxbOQSyjiTbJTQK52zZrNL79SigsPgGHPrYWA==", + "license": "MIT", + "dependencies": { + "@embedpdf/engines": "2.15.0", + "@embedpdf/models": "2.15.0" + }, + "peerDependencies": { + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, + "node_modules/@embedpdf/engines": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/engines/-/engines-2.15.0.tgz", + "integrity": "sha512-fW5UoqpDRkAWDbGMl3y6ril3l2qXzoYz+klt4O2P8gWzYzhG3fmr0L2+qzjD+BPO+QfYMNNvmBI+teT/nYjm/g==", + "license": "MIT", + "dependencies": { + "@embedpdf/fonts-arabic": "1.0.0", + "@embedpdf/fonts-hebrew": "1.0.0", + "@embedpdf/fonts-jp": "1.0.0", + "@embedpdf/fonts-kr": "1.0.0", + "@embedpdf/fonts-latin": "1.0.0", + "@embedpdf/fonts-sc": "1.0.0", + "@embedpdf/fonts-tc": "1.0.0", + "@embedpdf/models": "2.15.0", + "@embedpdf/pdfium": "2.15.0" + }, + "peerDependencies": { + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, + "node_modules/@embedpdf/fonts-arabic": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@embedpdf/fonts-arabic/-/fonts-arabic-1.0.0.tgz", + "integrity": "sha512-SnGvQb+LwPZQO2WjjvlmXrJZolJUfLYbLZQSaYUw1vrQyMyJKT4LewvJGG+hZ+Yz2fz7OMIQ+4Gc98mGODZtOg==", + "license": "OFL-1.1" + }, + "node_modules/@embedpdf/fonts-hebrew": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@embedpdf/fonts-hebrew/-/fonts-hebrew-1.0.0.tgz", + "integrity": "sha512-5HVAKGL7VqPeTxxADDrSqAFBxfmAXdP8fIqrPwJIKkqdK2643bOer8CqnnpO3/nPoFhkzxhttWMB9BGiqSW62w==", + "license": "OFL-1.1" + }, + "node_modules/@embedpdf/fonts-jp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@embedpdf/fonts-jp/-/fonts-jp-1.0.0.tgz", + "integrity": "sha512-BY2tv/mcICUUKf+M/bizf3RU65PMqKClJ/e5o9mgMibxyML0OQvEDwYMRPODQkKgJKXCO3ScHmVvcmXp6kt+fA==", + "license": "OFL-1.1" + }, + "node_modules/@embedpdf/fonts-kr": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@embedpdf/fonts-kr/-/fonts-kr-1.0.0.tgz", + "integrity": "sha512-bh88HXSvOBS581kgmihWY7Ijp9hBsvlmXogFG5LSNx9UBAobRcakZiFMGieRBc06hUSkpo7WhjaFM/z/SfQ8dQ==", + "license": "OFL-1.1" + }, + "node_modules/@embedpdf/fonts-latin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@embedpdf/fonts-latin/-/fonts-latin-1.0.0.tgz", + "integrity": "sha512-LLYysdr8O6sRNzhmW3PbF3AeA8xnqvOi4XLFfIfNlW5uEZ+qsJdcfd78Q78sFJMhlaOAYFMziMMsnOzmx463rA==", + "license": "OFL-1.1" + }, + "node_modules/@embedpdf/fonts-sc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@embedpdf/fonts-sc/-/fonts-sc-1.0.0.tgz", + "integrity": "sha512-ETXl7XCwaQLSSvMO3EUDwMNqtL64kX2LlFxarTRi/NsIGGOIxUurGfKtrkmtnKHrWy1jAJSt6oxK2uJhvdvQIw==", + "license": "OFL-1.1" + }, + "node_modules/@embedpdf/fonts-tc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@embedpdf/fonts-tc/-/fonts-tc-1.0.0.tgz", + "integrity": "sha512-rGZJbVD6DYS5BbXdpEMnWkpVF0Knar+bsiyb2o3+YRx7O8eyFubEBQUSUInirQk69HA6fc3GhYCg7TyC/oD76Q==", + "license": "OFL-1.1" + }, + "node_modules/@embedpdf/models": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/models/-/models-2.15.0.tgz", + "integrity": "sha512-gHr+hAN094kmzCB+6J2zaiHS8o4tKeY0IfTOxVEGwqntgKk8LCWD3s+P7dlVY3V8XUVmdyFWhFt7zwm0uw+VMg==", + "license": "MIT" + }, + "node_modules/@embedpdf/pdfium": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/pdfium/-/pdfium-2.15.0.tgz", + "integrity": "sha512-KgpRND2MYcdbhzb2EMb4WzWcJYrR0A6JXvhMv4WthEHKt6qmNo2v/MC68bpYvpveYT9GNnUnY/+TG5MpXY3pRw==", + "license": "MIT" + }, + "node_modules/@embedpdf/plugin-document-manager": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/plugin-document-manager/-/plugin-document-manager-2.15.0.tgz", + "integrity": "sha512-M8EwOuonICSHfOklTMwk0XfyPhG9v9EMDRU9Pvz0zAe1DJzUPtIxUh+CgxtFSSnUeKSfxE7JpTRryrbUW0XcGg==", + "license": "MIT", + "dependencies": { + "@embedpdf/models": "2.15.0" + }, + "peerDependencies": { + "@embedpdf/core": "2.15.0", + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, + "node_modules/@embedpdf/plugin-render": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/plugin-render/-/plugin-render-2.15.0.tgz", + "integrity": "sha512-EVfn8XsdU10VgrSs9qKo8nqjfUyt2/NWFJtlW3nX4sZ74Pi9xSvEa7/B99/LYZZMa0ENzi+4HKAXiQ6NUXisDg==", + "license": "MIT", + "dependencies": { + "@embedpdf/models": "2.15.0" + }, + "peerDependencies": { + "@embedpdf/core": "2.15.0", + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, + "node_modules/@embedpdf/plugin-scroll": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/plugin-scroll/-/plugin-scroll-2.15.0.tgz", + "integrity": "sha512-UqjLH3lafrpqN1qcxIpfd1MfWW5Fdf6/4LjneUabHt+3gxy1qd2KU9oPR5wwinsh3vmjn90qURsnqIHL5jnaOg==", + "license": "MIT", + "dependencies": { + "@embedpdf/models": "2.15.0" + }, + "peerDependencies": { + "@embedpdf/core": "2.15.0", + "@embedpdf/plugin-viewport": "2.15.0", + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, + "node_modules/@embedpdf/plugin-tiling": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/plugin-tiling/-/plugin-tiling-2.15.0.tgz", + "integrity": "sha512-zBjKCToAkL1tYvkIjFCjsbfUzZ0QBPczL3wRy/IdNZ9CQuZrqqqp3xEFrI4Nz2o9XQd9heBlMA9Zo/yieuazqA==", + "license": "MIT", + "dependencies": { + "@embedpdf/models": "2.15.0" + }, + "peerDependencies": { + "@embedpdf/core": "2.15.0", + "@embedpdf/plugin-render": "2.15.0", + "@embedpdf/plugin-scroll": "2.15.0", + "@embedpdf/plugin-viewport": "2.15.0", + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, + "node_modules/@embedpdf/plugin-viewport": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/plugin-viewport/-/plugin-viewport-2.15.0.tgz", + "integrity": "sha512-MXNBQOitr1cAoCoBKwAR3O78eLtHBbIngOkWqgm6EpWTdoYDBVhZlvVcmwmjheZKjMJFnU3sFr98w6Qwix3Cjg==", + "license": "MIT", + "dependencies": { + "@embedpdf/models": "2.15.0" + }, + "peerDependencies": { + "@embedpdf/core": "2.15.0", + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, + "node_modules/@embedpdf/plugin-zoom": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@embedpdf/plugin-zoom/-/plugin-zoom-2.15.0.tgz", + "integrity": "sha512-d+YhwqcQNZaaHczVGe4pbaAYQXWO4MEoivcW7jOpE31VnKqEAdjCMye8F0ctcF5OjgbXeb6AKCk4L4fDdLF4mg==", + "license": "MIT", + "dependencies": { + "@embedpdf/models": "2.15.0" + }, + "peerDependencies": { + "@embedpdf/core": "2.15.0", + "@embedpdf/plugin-scroll": "2.15.0", + "@embedpdf/plugin-viewport": "2.15.0", + "preact": "^10.26.4", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "svelte": ">=5 <6", + "vue": ">=3.2.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", @@ -983,6 +1577,146 @@ "node": ">=18" } }, + "node_modules/@extend-ai/react-docx": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@extend-ai/react-docx/-/react-docx-0.8.3.tgz", + "integrity": "sha512-pj05+VT6YFkABrw0EDgcqHOv4AnxIoBZdWVYUxV1OQyYlN4bHnu8KriD684q5ejGnN87rPYaNMT4HmZcjvFagQ==", + "license": "MIT", + "dependencies": { + "@chenglou/pretext": "^0.0.8", + "@tanstack/react-virtual": "^3.13.12", + "fast-png": "^8.0.0", + "utif": "^3.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@extend-ai/react-docx/node_modules/@tanstack/react-virtual": { + "version": "3.14.10", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.14.10.tgz", + "integrity": "sha512-SRyoUbdFMRHuYXMijV5H4ZarQWpXkj3iANq8OFre+pybeVap8ZJjZ3Nz9bVjx4d8PfobVUQUdKyyyHYk3E+djw==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.17.8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@extend-ai/react-docx/node_modules/@tanstack/virtual-core": { + "version": "3.17.8", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.17.8.tgz", + "integrity": "sha512-BfEvehNpOT75r5Ksc5xW6NZuXujTfb7nlSEyVu4XHG3gdxNg1KqXruWbDewXOUaUYIo4oRbSfkjIajz4MAT8tA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@extend-ai/react-pptx": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@extend-ai/react-pptx/-/react-pptx-0.1.2.tgz", + "integrity": "sha512-eT1whkI0BjjNOXgBiJlR2wiAWDydhNY1DL0+2xBFzu0O88XPR+COuqkY6ia1JeXHegA/jjhxyHvMgurdOttReg==", + "license": "MIT", + "dependencies": { + "@tanstack/react-virtual": "^3.13.12", + "@tanstack/virtual-core": "^3.13.12", + "d3-geo": "^3.1.1", + "d3-hierarchy": "^3.1.2", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "regl": "^2.1.1", + "topojson-client": "^3.1.0" + }, + "peerDependencies": { + "react": ">=18.2 <20", + "react-dom": ">=18.2 <20" + } + }, + "node_modules/@extend-ai/react-pptx/node_modules/@tanstack/react-virtual": { + "version": "3.14.10", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.14.10.tgz", + "integrity": "sha512-SRyoUbdFMRHuYXMijV5H4ZarQWpXkj3iANq8OFre+pybeVap8ZJjZ3Nz9bVjx4d8PfobVUQUdKyyyHYk3E+djw==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.17.8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@extend-ai/react-pptx/node_modules/@tanstack/virtual-core": { + "version": "3.17.8", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.17.8.tgz", + "integrity": "sha512-BfEvehNpOT75r5Ksc5xW6NZuXujTfb7nlSEyVu4XHG3gdxNg1KqXruWbDewXOUaUYIo4oRbSfkjIajz4MAT8tA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@extend-ai/react-xlsx": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@extend-ai/react-xlsx/-/react-xlsx-0.16.1.tgz", + "integrity": "sha512-yDaBv4YzpDi91OH16oN8aBxO+JySyn1cOPdA7cus1hjDSIjU4ddCyKSPDoMG5CoFdFZQNNovjG6zjpbZQ1bfow==", + "license": "MIT", + "dependencies": { + "@dukelib/sheets-wasm": "0.1.21", + "@tanstack/react-virtual": "^3.13.12", + "d3-geo": "^3.1.1", + "d3-hierarchy": "^3.1.2", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "fflate": "^0.8.2", + "regl": "^2.1.1", + "topojson-client": "^3.1.0", + "us-atlas": "^3.0.1", + "world-atlas": "^2.0.2" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@extend-ai/react-xlsx/node_modules/@tanstack/react-virtual": { + "version": "3.14.10", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.14.10.tgz", + "integrity": "sha512-SRyoUbdFMRHuYXMijV5H4ZarQWpXkj3iANq8OFre+pybeVap8ZJjZ3Nz9bVjx4d8PfobVUQUdKyyyHYk3E+djw==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.17.8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@extend-ai/react-xlsx/node_modules/@tanstack/virtual-core": { + "version": "3.17.8", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.17.8.tgz", + "integrity": "sha512-BfEvehNpOT75r5Ksc5xW6NZuXujTfb7nlSEyVu4XHG3gdxNg1KqXruWbDewXOUaUYIo4oRbSfkjIajz4MAT8tA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@formatjs/ecma402-abstract": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz", @@ -2601,6 +3335,17 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -2610,9 +3355,10 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.29", @@ -2624,6 +3370,189 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lezer/common": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz", + "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", + "license": "MIT" + }, + "node_modules/@lezer/cpp": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.6.tgz", + "integrity": "sha512-vh9gWWJOXFVY8HBHK3Twzq8MgwG2iN4GSyzBP9sCGTe37P15x2R14VaBQk0VA0ezTRN1KHYBBsHhvpGZ2Xy/pA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/css": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.3.6.tgz", + "integrity": "sha512-YJE78Wcg+zX8f10hiHWQ4Az48Qr/c13eId0VtRQYLBpxHDmDeSrXIlkbl+fJGW42rWC/uoUco9mhBZeVWP/A1g==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/go": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lezer/go/-/go-1.0.1.tgz", + "integrity": "sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/highlight": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz", + "integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.3.0" + } + }, + "node_modules/@lezer/html": { + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.13.tgz", + "integrity": "sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/java": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.3.tgz", + "integrity": "sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.4.tgz", + "integrity": "sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/json": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", + "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz", + "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/markdown": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.7.2.tgz", + "integrity": "sha512-iTkYvoVcKt3WkeL7qUDyXHONZEwLio4wj8KTNi2dnjQEXBZKMV63BpQrPqfsM+OkvuRbiSTAcycYAsQzLhRNoQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.5.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@lezer/php": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.5.tgz", + "integrity": "sha512-W7asp9DhM6q0W6DYNwIkLSKOvxlXRrif+UXBMxzsJUuqmhE7oVU+gS3THO4S/Puh7Xzgm858UNaFi6dxTP8dJA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.1.0" + } + }, + "node_modules/@lezer/python": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.19.tgz", + "integrity": "sha512-MhQIURHRytsNzP/YXnqpYKW6la6voAH3kyplTOOiCdjyFY6cWWGFVmYVdHIPrElqSDf4iCDktQCockB9FxuhzQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/rust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.2.tgz", + "integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/sass": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lezer/sass/-/sass-1.1.0.tgz", + "integrity": "sha512-3mMGdCTUZ/84ArHOuXWQr37pnf7f+Nw9ycPUeKX+wu19b7pSMcZGLbaXwvD2APMBDOGxPmpK/O6S1v1EvLoqgQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/xml": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.6.tgz", + "integrity": "sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/yaml": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@lezer/yaml/-/yaml-1.0.4.tgz", + "integrity": "sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.4.0" + } + }, + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.3.tgz", + "integrity": "sha512-FY+MKLBoTsLNJF/eLWaOsXGdz6uh3Iu1axjPf6TUq92IYumcTcXWHoS747JARLkcdlJ/Waiaxc5wQfFO8jC6NA==", + "license": "MIT" + }, "node_modules/@mux/mux-data-google-ima": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@mux/mux-data-google-ima/-/mux-data-google-ima-0.3.17.tgz", @@ -5136,6 +6065,52 @@ "node": ">=14.0.0" } }, + "node_modules/@replit/codemirror-lang-nix": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@replit/codemirror-lang-nix/-/codemirror-lang-nix-6.0.1.tgz", + "integrity": "sha512-lvzjoYn9nfJzBD5qdm3Ut6G3+Or2wEacYIDJ49h9+19WSChVnxv4ojf+rNmQ78ncuxIt/bfbMvDLMeMP0xze6g==", + "license": "MIT", + "peerDependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@replit/codemirror-lang-solidity": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@replit/codemirror-lang-solidity/-/codemirror-lang-solidity-6.0.2.tgz", + "integrity": "sha512-/dpTVH338KFV6SaDYYSadkB4bI/0B0QRF/bkt1XS3t3QtyR49mn6+2k0OUQhvt2ZSO7kt10J+OPilRAtgbmX0w==", + "license": "MIT", + "dependencies": { + "@lezer/highlight": "^1.2.0" + }, + "peerDependencies": { + "@codemirror/language": "^6.0.0" + } + }, + "node_modules/@replit/codemirror-lang-svelte": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@replit/codemirror-lang-svelte/-/codemirror-lang-svelte-6.0.0.tgz", + "integrity": "sha512-U2OqqgMM6jKelL0GNWbAmqlu1S078zZNoBqlJBW+retTc5M4Mha6/Y2cf4SVg6ddgloJvmcSpt4hHrVoM4ePRA==", + "license": "MIT", + "peerDependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.1", + "@codemirror/lang-html": "^6.2.0", + "@codemirror/lang-javascript": "^6.1.1", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/javascript": "^1.2.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -5568,6 +6543,16 @@ "node": ">=18" } }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.13.tgz", + "integrity": "sha512-wgKggnhZVL9Bfx1OaKKTrYY9BFRk6C8UAkQNUcIv1+llzYrIqy+RZm5HPKzn0NpEBvTVhTqB4kQyllZywsRBRQ==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^8.9.0" + } + }, "node_modules/@swc/helpers": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", @@ -6062,7 +7047,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/google_interactive_media_ads_types": { @@ -6115,6 +7099,106 @@ "@types/react": "^18.0.0" } }, + "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==", + "license": "MIT", + "peer": true + }, + "node_modules/@uiw/codemirror-extensions-basic-setup": { + "version": "4.25.11", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.25.11.tgz", + "integrity": "sha512-otyFa+n9IOYtEjaKOxPedHkj15fTPUF21wdR9pv0GpZPfuGl27cvmcv6+tognbRu9VvEcsHKE+ESoszeo3KfTw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@codemirror/autocomplete": ">=6.0.0", + "@codemirror/commands": ">=6.0.0", + "@codemirror/language": ">=6.0.0", + "@codemirror/lint": ">=6.0.0", + "@codemirror/search": ">=6.0.0", + "@codemirror/state": ">=6.0.0", + "@codemirror/view": ">=6.0.0" + } + }, + "node_modules/@uiw/codemirror-extensions-langs": { + "version": "4.25.11", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-langs/-/codemirror-extensions-langs-4.25.11.tgz", + "integrity": "sha512-RJ6MQTGInT+HBnzEs6PoUmPBgLFbWH3e9ZiF0+H1bdWJXrqN0Kfkiopumz1OCcbWFJ8aVJCD6KPK9mXV/LQ4yA==", + "license": "MIT", + "dependencies": { + "@codemirror/lang-cpp": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-go": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-java": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/lang-jinja": "^6.0.0", + "@codemirror/lang-json": "^6.0.0", + "@codemirror/lang-less": "^6.0.0", + "@codemirror/lang-liquid": "^6.0.0", + "@codemirror/lang-markdown": "^6.0.0", + "@codemirror/lang-php": "^6.0.0", + "@codemirror/lang-python": "^6.0.0", + "@codemirror/lang-rust": "^6.0.0", + "@codemirror/lang-sass": "^6.0.0", + "@codemirror/lang-sql": "^6.0.0", + "@codemirror/lang-vue": "^0.1.0", + "@codemirror/lang-wast": "^6.0.0", + "@codemirror/lang-xml": "^6.0.0", + "@codemirror/lang-yaml": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/legacy-modes": "^6.0.0", + "@replit/codemirror-lang-nix": "^6.0.1", + "@replit/codemirror-lang-solidity": "^6.0.1", + "@replit/codemirror-lang-svelte": "^6.0.0", + "codemirror-lang-mermaid": "^0.5.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@codemirror/language": ">=6.0.0" + } + }, + "node_modules/@uiw/react-codemirror": { + "version": "4.25.11", + "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.25.11.tgz", + "integrity": "sha512-DYVFAKLX+F/4JS9N/7xexh+TICrlncwkX9HKKInrP1bwO0tSfc3k0GB6oawTYhelVKh20cX3TuRx+NJSkVXuMw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.6", + "@codemirror/commands": "^6.1.0", + "@codemirror/state": "^6.1.1", + "@codemirror/theme-one-dark": "^6.0.0", + "@uiw/codemirror-extensions-basic-setup": "4.25.11", + "codemirror": "^6.0.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.11.0", + "@codemirror/state": ">=6.0.0", + "@codemirror/theme-one-dark": ">=6.0.0", + "@codemirror/view": ">=6.0.0", + "codemirror": ">=6.0.0", + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, "node_modules/@vitejs/plugin-react": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", @@ -6136,12 +7220,132 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, + "node_modules/@vue/compiler-core": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.41.tgz", + "integrity": "sha512-q0Xtv/F9w2YO/7htQhtiL+Ev2WCJbe5N2hc+XfgyKkEKqWpSxknmT8QOuGdEKNdjPq0c3F7rNpFkTo3Kfrm7pg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/parser": "^7.29.8", + "@vue/shared": "3.5.41", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.41.tgz", + "integrity": "sha512-oKacVfNglLvGjnS6BXOlGL7EyG2h8X03pqXCjzotRZUaXGjbrTJUnVAQjrCqUnS+lyu31nwQjZY/d817GmCnfw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-core": "3.5.41", + "@vue/shared": "3.5.41" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.41.tgz", + "integrity": "sha512-XJhip7R2wy6vX3knCxdZN4KracFaZUef58s1KYewqluedHIJaPIVfXoYT7MF1F8nCvv6k8bWWxDC8opMkg1VTQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/parser": "^7.29.8", + "@vue/compiler-core": "3.5.41", + "@vue/compiler-dom": "3.5.41", + "@vue/compiler-ssr": "3.5.41", + "@vue/shared": "3.5.41", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.19", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.41.tgz", + "integrity": "sha512-U3v5OejKEGqOI0Wy0+Sz7hGuIFZHA4LSXzrNM3IMIeDyJEBBfTpX26n3SDgToRpP2bLc9FfI2j/kSgcJ8Emq5A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.5.41", + "@vue/shared": "3.5.41" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.41.tgz", + "integrity": "sha512-rznsqKM0np0x18EjzF8x88MpEhdNsffbvFbckLL5+oUKz1BxAImEmO7J1ArRYSyo6aQaVoBDp7jEkT91OOxydA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/shared": "3.5.41" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.41.tgz", + "integrity": "sha512-Vcry58hiAKwGen9Z1jUZE0feFsNArPCMOImYI8el48A9Idf6DuQYD0U05zZIF2Iad1hGhPSvcbBbAOhNr55fhg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/reactivity": "3.5.41", + "@vue/shared": "3.5.41" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.41.tgz", + "integrity": "sha512-3vVBahVBS9+U6cmXBLyb8nE6/yYo4J/CGI9eVFs3KiMc0YHuudwKyShTD65jtJy/L9PUUxNAFu4cj4LiJ0UFbw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/reactivity": "3.5.41", + "@vue/runtime-core": "3.5.41", + "@vue/shared": "3.5.41", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.41.tgz", + "integrity": "sha512-n6hx/pNFfbD6SuyeuMVkvqox8bwf/ET9JlA/kAz/imw8sw++wkqKe2mHX5KutjPpbKE4Z56yTHszoOjGMI9igQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-ssr": "3.5.41", + "@vue/runtime-dom": "3.5.41", + "@vue/shared": "3.5.41" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.41.tgz", + "integrity": "sha512-IOnwSCma8j+9xJT6b8H0dEYidC80NsYmNMlZxRsukYcSoGaDBohog5hDxzeUXdFeGWFA++vWvxqOmrr96VlqMA==", + "license": "MIT", + "peer": true + }, "node_modules/abs-svg-path": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz", "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==", "license": "MIT" }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -6186,6 +7390,16 @@ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/autoprefixer": { "version": "10.5.4", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz", @@ -6223,6 +7437,16 @@ "postcss": "^8.1.0" } }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/babel-plugin-react-compiler": { "version": "19.1.0-rc.3", "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-19.1.0-rc.3.tgz", @@ -6453,6 +7677,32 @@ "node": ">=6" } }, + "node_modules/codemirror": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz", + "integrity": "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/codemirror-lang-mermaid": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/codemirror-lang-mermaid/-/codemirror-lang-mermaid-0.5.0.tgz", + "integrity": "sha512-Taw/2gPCyNArQJCxIP/HSUif+3zrvD+6Ugt7KJZ2dUKou/8r3ZhcfG8krNTZfV2iu8AuGnymKuo7bLPFyqsh/A==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.9.0", + "@lezer/highlight": "^1.1.6", + "@lezer/lr": "^1.3.10" + } + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -6519,6 +7769,12 @@ "dev": true, "license": "MIT" }, + "node_modules/crelt": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.7.tgz", + "integrity": "sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==", + "license": "MIT" + }, "node_modules/cronstrue": { "version": "3.24.0", "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-3.24.0.tgz", @@ -6553,10 +7809,10 @@ } }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "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/custom-media-element": { "version": "1.4.6", @@ -6564,6 +7820,130 @@ "integrity": "sha512-/HRYqJOa1ob5ik4q7FIJVYxTJCFs/FL3+cQPAJjUf2uiqrDEzbTgB315gQ2rG8oK3w094W9m5tcB8S5Qah+caA==", "license": "MIT" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/date-fns": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.4.0.tgz", @@ -6617,6 +7997,13 @@ "node": ">=6" } }, + "node_modules/devalue": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.0.tgz", + "integrity": "sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==", + "license": "MIT", + "peer": true + }, "node_modules/dfa": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", @@ -6656,6 +8043,19 @@ "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", "license": "MIT" }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esbuild": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", @@ -6708,6 +8108,38 @@ "node": ">=6" } }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT", + "peer": true + }, + "node_modules/esrap": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.3.5.tgz", + "integrity": "sha512-KciPkeZZX8srrh6xELzLR2cBaWOzgBQ4CwggO6Dh/KMlrfOcIcfyXCVy/Vvc3/OlS5gvFOd5tcxUYuaGM8o45A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "peerDependencies": { + "@typescript-eslint/types": "^8.2.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/types": { + "optional": true + } + } + }, + "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==", + "license": "MIT", + "peer": true + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -6749,6 +8181,16 @@ "node": ">= 6" } }, + "node_modules/fast-png": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/fast-png/-/fast-png-8.0.0.tgz", + "integrity": "sha512-gCysNasJ8KEMgfdYIKd/wTDo6ENK1PWT0RJO7O+0pgmuHPw2O6tA1WvdxFRJoLf9V8yFYpG0FA1YgI8X97OhJA==", + "license": "MIT", + "dependencies": { + "fflate": "^0.8.2", + "iobuffer": "^6.0.1" + } + }, "node_modules/fastq": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", @@ -6986,6 +8428,15 @@ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/intl-messageformat": { "version": "10.7.16", "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz", @@ -6998,6 +8449,12 @@ "tslib": "^2.8.0" } }, + "node_modules/iobuffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-6.0.1.tgz", + "integrity": "sha512-SZWYkWNfjIXIBYSDpXDYIgshqtbOPsi4lviawAEceR1Kqk+sHDlcQjWrzNQsii80AyBY0q5c8HCTNjqo74ul+Q==", + "license": "MIT" + }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", @@ -7076,6 +8533,16 @@ "node": ">=0.12.0" } }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.6" + } + }, "node_modules/is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", @@ -7190,6 +8657,13 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT", + "peer": true + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -7220,6 +8694,16 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, "node_modules/media-chrome": { "version": "4.19.2", "resolved": "https://registry.npmjs.org/media-chrome/-/media-chrome-4.19.2.tgz", @@ -7670,6 +9154,25 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, + "node_modules/preact": { + "version": "10.29.8", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.8.tgz", + "integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "peerDependencies": { + "preact-render-to-string": ">=5" + }, + "peerDependenciesMeta": { + "preact-render-to-string": { + "optional": true + } + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -7858,6 +9361,12 @@ "node": ">=8.10.0" } }, + "node_modules/regl": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/regl/-/regl-2.1.1.tgz", + "integrity": "sha512-+IOGrxl3FZ8ZM9ixCWQZzFRiRn7Rzn9bu3iFHwg/yz4tlOUQgbO4PHLgG+1ZT60zcIV8tief6Qrmyl8qcoJP0g==", + "license": "MIT" + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -8159,6 +9668,12 @@ "node": ">=8" } }, + "node_modules/style-mod": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz", + "integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==", + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -8191,6 +9706,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svelte": { + "version": "5.56.9", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.9.tgz", + "integrity": "sha512-VT8kSnlEg8069w7AiCcAk3Yf5xvMnrGTagVOmU/OpOLHaHnNqXhWZCH/4EVga/bT/HtWhvE6/fHrXLErx7OnJA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.10", + "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", + "acorn": "^8.12.1", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.8.1", + "esm-env": "^1.2.1", + "esrap": "^2.2.12", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/svg-arc-to-cubic-bezier": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz", @@ -8423,6 +9976,26 @@ "node": ">=8.0" } }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "license": "ISC", + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, + "node_modules/topojson-client/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==", + "license": "MIT" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -8518,6 +10091,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/us-atlas": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/us-atlas/-/us-atlas-3.0.1.tgz", + "integrity": "sha512-wEIZCq0ImPvGblTd8gZMqNNCPkQshugMUG/8nkSWXb02+XqNFREg9atHOKP9w6prLZTpqcLhSvdBW81MkV3/0Q==", + "license": "ISC" + }, "node_modules/use-broadcast-ts": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/use-broadcast-ts/-/use-broadcast-ts-2.0.2.tgz", @@ -8594,6 +10173,21 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/utif": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/utif/-/utif-3.1.0.tgz", + "integrity": "sha512-WEo4D/xOvFW53K5f5QTaTbbiORcm2/pCL9P6qmJnup+17eYfKaEhDeX9PeQkuyEoIxlbGklDuGl8xwuXYMrrXQ==", + "license": "MIT", + "dependencies": { + "pako": "^1.0.5" + } + }, + "node_modules/utif/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -9200,6 +10794,34 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/vue": { + "version": "3.5.41", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.41.tgz", + "integrity": "sha512-2laE0p+aK+/AOPG/XL/WepOs/GlK755LJ1XECi9kDUrz1FKNw8rb2Xzlw9JS1rqEV55nb0ttsKxVlTCcd+R5cg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.5.41", + "@vue/compiler-sfc": "3.5.41", + "@vue/runtime-dom": "3.5.41", + "@vue/server-renderer": "3.5.41", + "@vue/shared": "3.5.41" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9214,6 +10836,12 @@ "node": ">= 8" } }, + "node_modules/world-atlas": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/world-atlas/-/world-atlas-2.0.2.tgz", + "integrity": "sha512-IXfV0qwlKXpckz1FhwXVwKRjiIhOnWttOskm5CtxMsjgE/MXAYRHWJqgXOpM8IkcPBoXnyTU5lFHcYa5ChG0LQ==", + "license": "ISC" + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -9326,6 +10954,13 @@ "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", "license": "MIT" }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "license": "MIT", + "peer": true + }, "node_modules/zustand": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.15.tgz", diff --git a/package.json b/package.json index 645ef23..abe9c33 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,19 @@ "pub": "npm publish ./cli" }, "dependencies": { + "@embedpdf/core": "^2.15.0", + "@embedpdf/engines": "^2.15.0", + "@embedpdf/models": "^2.15.0", + "@embedpdf/pdfium": "^2.15.0", + "@embedpdf/plugin-document-manager": "^2.15.0", + "@embedpdf/plugin-render": "^2.15.0", + "@embedpdf/plugin-scroll": "^2.15.0", + "@embedpdf/plugin-tiling": "^2.15.0", + "@embedpdf/plugin-viewport": "^2.15.0", + "@embedpdf/plugin-zoom": "^2.15.0", + "@extend-ai/react-docx": "^0.8.3", + "@extend-ai/react-pptx": "^0.1.2", + "@extend-ai/react-xlsx": "^0.16.1", "@formkit/auto-animate": "^0.9.0", "@heroui/react": "^2.7.11", "@mux/mux-player-react": "^3.13.2", @@ -56,6 +69,8 @@ "@tauri-apps/plugin-store": "^2.4.3", "@tauri-apps/plugin-updater": "^2.10.1", "@tauri-apps/plugin-window-state": "^2.4.1", + "@uiw/codemirror-extensions-langs": "^4.25.11", + "@uiw/react-codemirror": "^4.25.11", "cronstrue": "^3.24.0", "date-fns": "^4.4.0", "framer-motion": "^12.42.2", diff --git a/src/components/navigator/FileIcon.tsx b/src/components/navigator/FileIcon.tsx index fba4f2d..c29e4f1 100644 --- a/src/components/navigator/FileIcon.tsx +++ b/src/components/navigator/FileIcon.tsx @@ -117,6 +117,23 @@ const CODE_EXTENSIONS = new Set([ 'vb', 'asm', 's', + // Markup / web / query / misc — all highlighted by the CodeMirror langs pack. + 'html', + 'htm', + 'xml', + 'css', + 'scss', + 'sass', + 'less', + 'sql', + 'vue', + 'svelte', + 'dart', + 'gradle', + 'groovy', + 'proto', + 'diff', + 'patch', ]) const CONFIG_EXTENSIONS = new Set([ @@ -190,7 +207,11 @@ export function isPreviewable(entry: Entry): boolean { type === 'video' || type === 'audio' || type === 'text' || - type === 'document' + type === 'code' || + type === 'config' || + type === 'document' || + type === 'spreadsheet' || + type === 'presentation' ) } diff --git a/src/components/navigator/FileList.tsx b/src/components/navigator/FileList.tsx index 475d0fb..29f149f 100644 --- a/src/components/navigator/FileList.tsx +++ b/src/components/navigator/FileList.tsx @@ -1,6 +1,6 @@ import { Button, Checkbox, Listbox, ListboxItem, cn } from '@heroui/react' import { platform } from '@tauri-apps/plugin-os' -import { DownloadIcon, EyeIcon, PencilIcon, Share2Icon, StarIcon, Trash2Icon } from 'lucide-react' +import { DownloadIcon, PencilIcon, Share2Icon, StarIcon, Trash2Icon } from 'lucide-react' import { useCallback } from 'react' import { formatBytes } from '../../../lib/format.ts' import FileIcon from './FileIcon' @@ -243,7 +243,13 @@ export default function FileList({
onNavigate(entry)} + // Folders navigate in; files open the preview (falls back + // to onNavigate — a no-op for files — where preview is off). + onClick={() => + entry.isDir || !onPreviewClick + ? onNavigate(entry) + : onPreviewClick(entry) + } > @@ -280,17 +286,6 @@ export default function FileList({ /> )} - {!entry.isDir && onPreviewClick && ( - - )} {onDownload && ( -
- ) - } - - if (!canPreview) { - return ( -
- -

Preview not available for this file type

- -
- ) - } - - switch (fileType) { - case 'image': - return ( -
- {item.name} -
- ) - - case 'video': - return ( -
- {/* biome-ignore lint/a11y/useMediaCaption: */} - -
- ) - - case 'audio': - return ( -
- -

{item.name}

- {/* biome-ignore lint/a11y/useMediaCaption: */} - -
- ) - - case 'text': { - if (isLoadingText) { - return ( -
- -
- ) - } - if (textError) { - return ( -
-

Error loading file: {textError}

-
- ) - } - return ( -
-
-                            {textContent}
-                        
-
- ) - } - - case 'document': - return ( -
- {/* PDF preview disabled - uncomment when react-pdf is configured */} -
- ) - - default: - return ( -
- -

Preview not available

- -
- ) - } - } - - return ( - - - -
- {item && } - {item?.name ?? 'Preview'} -
- -
- - -
-
{renderPreview()}
- - {item && ( - <> - -
-
- Type: - {fileType} -
- {item.size !== undefined && ( -
- Size: - {formatBytes(item.size)} -
- )} - {item.modTime && ( -
- Modified: - {item.modTime} -
- )} -
- Location: - - {item.remote === 'UI_LOCAL_FS' ? 'Local' : item.remote} - -
-
- - )} -
-
-
-
- ) -} diff --git a/src/components/navigator/index.ts b/src/components/navigator/index.ts index 622b25a..50f9e01 100644 --- a/src/components/navigator/index.ts +++ b/src/components/navigator/index.ts @@ -3,7 +3,7 @@ export { default as FileIcon, getFileType, isPreviewable } from './FileIcon' export { default as FileList } from './FileList' export { default as PanelToolbar, type ToolbarButtons } from './PanelToolbar' export { default as PathBreadcrumb } from './PathBreadcrumb' -export { default as PreviewDrawer } from './PreviewDrawer' +export { default as PreviewDrawer } from './preview/PreviewDrawer' export { default as RemoteSidebar } from './RemoteSidebar' export { default as useCreateFolder } from './useCreateFolder' export { default as useFileNavigation } from './useFileNavigation' diff --git a/src/components/navigator/preview/CodeMirrorPreview.tsx b/src/components/navigator/preview/CodeMirrorPreview.tsx new file mode 100644 index 0000000..a373a8b --- /dev/null +++ b/src/components/navigator/preview/CodeMirrorPreview.tsx @@ -0,0 +1,78 @@ +import { type LanguageName, loadLanguage } from '@uiw/codemirror-extensions-langs' +import CodeMirror, { EditorView } from '@uiw/react-codemirror' +import { useMemo } from 'react' +import { getFileExtension } from '../utils' +import { PreviewError, PreviewLoading, type PreviewViewerProps } from './previewStates' +import usePreviewText from './usePreviewText' + +// A handful of extensions the langs pack doesn't key directly — alias each to the +// closest available mode. Anything still unmatched renders as plain text (line +// numbers, no highlighting), which is the right fallback for .txt/.log/.csv/etc. +const LANGUAGE_ALIASES: Record = { + zsh: 'sh', + hrl: 'erl', + conf: 'ini', + config: 'ini', + env: 'properties', + sol: 'solidity', +} + +// Hardcoded dark-on-white content color. The built-in `light` theme leaves the content +// color unset, so it inherits the app's dark-mode (near-white) foreground and the text +// is invisible on the white editor. Applied via `extensions` (which win over the `theme` +// prop) so it overrides that. Syntax-highlighted tokens keep their own darker colors. +const LIGHT_CONTENT_THEME = EditorView.theme( + { + '&': { backgroundColor: '#ffffff', color: '#111827' }, + '.cm-content': { color: '#111827', caretColor: '#111827' }, + '.cm-gutters': { backgroundColor: '#f9fafb', color: '#9ca3af', border: 'none' }, + }, + { dark: false } +) + +// Read-only viewer, hardcoded light (like the other preview viewers). basicSetup is +// trimmed for a static view — syntax highlighting + line numbers, no active-line chrome. +export default function CodeMirrorPreview({ + url, + name, + authHeader, + onDownload, +}: PreviewViewerProps) { + const { text, error, progress } = usePreviewText(url, authHeader) + + const extensions = useMemo(() => { + const ext = getFileExtension(name) + const lang = loadLanguage((LANGUAGE_ALIASES[ext] ?? ext) as LanguageName) + // Wrap long lines (no horizontal scroll) — nicer for logs/csv/prose. + const base = [EditorView.lineWrapping, LIGHT_CONTENT_THEME] + return lang ? [...base, lang] : base + }, [name]) + + if (error) { + return + } + + if (text === null) { + return + } + + return ( + + ) +} diff --git a/src/components/navigator/preview/DocxPreview.tsx b/src/components/navigator/preview/DocxPreview.tsx new file mode 100644 index 0000000..97921db --- /dev/null +++ b/src/components/navigator/preview/DocxPreview.tsx @@ -0,0 +1,34 @@ +import { ReactDocxViewer, setWasmSource, useDocxModel } from '@extend-ai/react-docx' +// Bundle the docx layout wasm locally (Vite ?url) so it loads same-origin offline. +import docxWasmUrl from '@extend-ai/react-docx/docx_wasm_bg.wasm?url' +import { PreviewError, PreviewLoading, type PreviewViewerProps } from './previewStates' +import usePreviewSource from './usePreviewSource' + +export default function DocxPreview({ url, authHeader, onDownload }: PreviewViewerProps) { + // `buffer` is null until the wasm is configured, so parsing only starts once the + // import worker can instantiate from the ArrayBuffer source. + const { + buffer, + error: sourceError, + progress, + } = usePreviewSource(url, authHeader, docxWasmUrl, setWasmSource) + const { model, isLoading: modelLoading, error: modelError } = useDocxModel(buffer ?? undefined) + + const errorMessage = sourceError ?? modelError?.message + + if (errorMessage) { + return + } + + if (!buffer || modelLoading || !model) { + return + } + + // text-black sets the inherited color so runs with no explicit color (docx "auto") + // render black, instead of inheriting the app's light dark-mode text color. + return ( +
+ +
+ ) +} diff --git a/src/components/navigator/preview/PdfPreview.tsx b/src/components/navigator/preview/PdfPreview.tsx new file mode 100644 index 0000000..2941bbe --- /dev/null +++ b/src/components/navigator/preview/PdfPreview.tsx @@ -0,0 +1,214 @@ +import { createPluginRegistration } from '@embedpdf/core' +import { EmbedPDF } from '@embedpdf/core/react' +import { usePdfiumEngine } from '@embedpdf/engines/react' +// Bundle PDFium's wasm locally (via Vite ?url) so the preview works offline inside +// the Tauri webview instead of reaching for the default CDN url. +import pdfiumWasmUrl from '@embedpdf/pdfium/pdfium.wasm?url' +import { + DocumentContent, + DocumentManagerPluginPackage, +} from '@embedpdf/plugin-document-manager/react' +import { RenderLayer, RenderPluginPackage } from '@embedpdf/plugin-render/react' +import { ScrollPluginPackage, Scroller, useScroll } from '@embedpdf/plugin-scroll/react' +import { TilingLayer, TilingPluginPackage } from '@embedpdf/plugin-tiling/react' +import { Viewport, ViewportPluginPackage } from '@embedpdf/plugin-viewport/react' +import { ZoomMode, ZoomPluginPackage, useZoom } from '@embedpdf/plugin-zoom/react' +import { Button } from '@heroui/react' +import { DownloadIcon, ZoomInIcon, ZoomOutIcon } from 'lucide-react' +import { useEffect, useMemo, useRef } from 'react' +import { PreviewError, PreviewLoading, type PreviewViewerProps } from './previewStates' +import usePreviewSource from './usePreviewSource' + +export default function PdfPreview({ url, name, authHeader, onDownload }: PreviewViewerProps) { + const { + engine, + isLoading: engineLoading, + error: engineError, + } = usePdfiumEngine({ + wasmUrl: pdfiumWasmUrl, + // Run PDFium on the main thread. The worker engine's async create/destroy + // lifecycle races with React StrictMode's double-mount, orphaning the + // openDocumentBuffer request so the document hangs in "loading" forever. + worker: false, + // Desktop app: never fetch fallback fonts from a remote CDN. + fontFallback: null, + }) + + // Fetch the bytes ourselves and hand PDFium a buffer. This avoids EmbedPDF's + // default range-request loader (which the rclone serve endpoint doesn't reliably + // answer) and the webview CORS block. No wasm arg: the pdfium wasm is loaded by + // the engine (usePdfiumEngine) above, not via setWasmSource. + const { buffer, error: fetchError, progress } = usePreviewSource(url, authHeader) + + const plugins = useMemo( + () => + buffer + ? [ + createPluginRegistration(DocumentManagerPluginPackage, { + initialDocuments: [{ buffer, name }], + }), + createPluginRegistration(ViewportPluginPackage), + createPluginRegistration(ScrollPluginPackage), + createPluginRegistration(RenderPluginPackage), + createPluginRegistration(TilingPluginPackage), + createPluginRegistration(ZoomPluginPackage, { + defaultZoomLevel: ZoomMode.FitWidth, + }), + ] + : null, + [buffer, name] + ) + + const errorMessage = engineError?.message ?? fetchError + + if (errorMessage) { + return + } + + if (engineLoading || !engine || !buffer || !plugins) { + return + } + + return ( + // Re-key on the url so switching to another PDF reloads the document cleanly. + + {({ activeDocumentId }) => { + if (!activeDocumentId) { + return + } + return ( + + {({ isLoaded, isError, documentState }) => { + if (isError) { + return ( + + ) + } + + if (!isLoaded) { + return + } + + return ( + + ) + }} + + ) + }} + + ) +} + +function PdfViewport({ + documentId, + onDownload, +}: { + documentId: string + onDownload: () => void +}) { + const containerRef = useRef(null) + const lastWidthRef = useRef(0) + const { provides: zoom } = useZoom(documentId) + + // Fit the page to the viewport width on load AND whenever the container's WIDTH + // changes (e.g. expanding the drawer to 97%). The plugin's own `defaultZoomLevel` + // is unreliable because the viewport only mounts after the document loads, so its + // initial recalc runs while clientWidth is still 0. A ResizeObserver fires once the + // element has a width; we defer a frame so EmbedPDF's viewport metrics are populated. + // + // Two guards keep this from fighting the user: only react to width changes (ignore + // height/scrollbar churn), and only auto-fit while still in fit-width mode — once the + // user zooms manually, we leave their zoom alone instead of snapping back to fit + // (which otherwise produced a resize/zoom flicker loop). + useEffect(() => { + const el = containerRef.current + if (!el || !zoom) return + const observer = new ResizeObserver(() => { + const width = el.clientWidth + if (width === 0 || width === lastWidthRef.current) return + lastWidthRef.current = width + requestAnimationFrame(() => { + if (zoom.getState().zoomLevel === ZoomMode.FitWidth) { + zoom.requestZoom(ZoomMode.FitWidth) + } + }) + }) + observer.observe(el) + return () => observer.disconnect() + }, [zoom]) + + return ( +
+ + + ( +
+ + +
+ )} + /> +
+
+ ) +} + +function PdfToolbar({ + documentId, + onDownload, +}: { + documentId: string + onDownload: () => void +}) { + const { state: zoomState, provides: zoom } = useZoom(documentId) + const { state: scrollState } = useScroll(documentId) + + return ( +
+
+ + + {Math.round(zoomState.currentZoomLevel * 100)}% + + +
+ + {scrollState.currentPage} / {scrollState.totalPages} + + +
+ ) +} diff --git a/src/components/navigator/preview/PptxPreview.tsx b/src/components/navigator/preview/PptxPreview.tsx new file mode 100644 index 0000000..f608987 --- /dev/null +++ b/src/components/navigator/preview/PptxPreview.tsx @@ -0,0 +1,36 @@ +import { ReactPptxViewer, setWasmSource } from '@extend-ai/react-pptx' +// Bundle the pptx wasm locally (Vite ?url) so it loads same-origin offline. +import pptxWasmUrl from '@extend-ai/react-pptx/pptx_wasm_bg.wasm?url' +import '@extend-ai/react-pptx/styles.css' +import { PreviewError, PreviewLoading, type PreviewViewerProps } from './previewStates' +import usePreviewSource from './usePreviewSource' + +export default function PptxPreview({ url, authHeader, onDownload }: PreviewViewerProps) { + const { buffer, error, progress } = usePreviewSource( + url, + authHeader, + pptxWasmUrl, + setWasmSource + ) + + if (error) { + return + } + + if (!buffer) { + return + } + + return ( + } + renderError={(err) => } + /> + ) +} diff --git a/src/components/navigator/preview/PreviewDrawer.tsx b/src/components/navigator/preview/PreviewDrawer.tsx new file mode 100644 index 0000000..e49f596 --- /dev/null +++ b/src/components/navigator/preview/PreviewDrawer.tsx @@ -0,0 +1,373 @@ +import { Button, Divider, Drawer, DrawerBody, DrawerContent, DrawerHeader, cn } from '@heroui/react' +import { + DownloadIcon, + FileIcon as FileIconLucide, + Maximize2Icon, + Minimize2Icon, + XIcon, +} from 'lucide-react' +import { + type ComponentType, + type LazyExoticComponent, + Suspense, + lazy, + useCallback, + useMemo, + useState, +} from 'react' +import { formatBytes } from '../../../../lib/format.ts' +import { openWindow } from '../../../../lib/window.ts' +import { useCurrentHost, usePersistedStore } from '../../../../store/persisted.ts' +import FileIcon, { getFileType, isPreviewable } from '../FileIcon' +import type { Entry } from '../types' +import { getFileExtension } from '../utils' +import PreviewProLock from './PreviewProLock' +import { PreviewLoading, type PreviewViewerProps } from './previewStates' + +// Lazy-loaded so each viewer's heavy WASM/WebGL bundle only loads when a matching +// file is actually opened, keeping them out of the main + Commander bundle. +const PdfPreview = lazy(() => import('./PdfPreview')) +const DocxPreview = lazy(() => import('./DocxPreview')) +const XlsxPreview = lazy(() => import('./XlsxPreview')) +const PptxPreview = lazy(() => import('./PptxPreview')) +// CodeMirror + its ~140 bundled languages are heavy; keep them out of the main chunk too. +const CodeMirrorPreview = lazy(() => import('./CodeMirrorPreview')) + +// Text-like file types (plus .csv) render in the CodeMirror viewer. +const CODE_VIEWER_TYPES = new Set(['text', 'code', 'config']) + +// Documents route to a dedicated inline viewer by extension; any other extension +// falls through to the media/text switch or the download fallback below. +const DOCUMENT_VIEWERS: Record>> = { + pdf: PdfPreview, + docx: DocxPreview, + xlsx: XlsxPreview, + ppt: PptxPreview, + pptx: PptxPreview, +} + +const TRAILING_SLASH_RE = /\/$/ +const LEADING_SLASHES_RE = /^\/+/ +const WINDOWS_DRIVE_RE = /^([a-zA-Z]:\/)/ +const MAX_PREVIEW_SIZE = 500_000_000 + +// The daemon runs with `--rc-serve`, exposing objects at `/[fs]/remote/path` where +// `[fs]` is an rclone connection string. The local filesystem must be addressed via +// the `:local:` backend rooted at the filesystem root — the same fs the app uses for +// local `/operations/list` calls (see searchPath()/getFsInfo()). A bare `[local]` +// names a non-existent remote, so local previews 404'd while remotes worked. +function buildLocalFs(fullPath: string): { fs: string; path: string } { + const normalized = fullPath.replace(/\\/g, '/') + const drive = normalized.match(WINDOWS_DRIVE_RE) + if (drive) { + // e.g. C:/Users/x → fs ":local:C:/", path "Users/x" + return { + fs: `:local:${drive[1]}`, + path: normalized.slice(drive[0].length).replace(LEADING_SLASHES_RE, ''), + } + } + // POSIX absolute path → local backend rooted at "/", path relative to it. + return { fs: ':local:/', path: normalized.replace(LEADING_SLASHES_RE, '') } +} + +function buildPreviewUrl(entry: Entry, hostUrl: string, auth?: string): string { + const normalizedHost = hostUrl.replace(TRAILING_SLASH_RE, '') + + let url: string + if (entry.remote === 'UI_LOCAL_FS') { + const { fs, path } = buildLocalFs(entry.fullPath) + url = `${normalizedHost}/[${fs}]/${path}` + } else { + const pathPart = entry.fullPath.includes(':/') + ? entry.fullPath.split(':/').slice(1).join('/') + : entry.fullPath + url = `${normalizedHost}/[${entry.remote}:]/${pathPart}` + } + + if (auth) { + url = `${url}?auth=${encodeURIComponent(auth)}` + } + + return url +} + +export default function PreviewDrawer({ + item, + onClose, +}: { + item: Entry | null + onClose: () => void +}) { + const currentHost = useCurrentHost() + const hostUrl = currentHost?.url + const authUser = currentHost?.authUser + const authPassword = currentHost?.authPassword + + // File previews are a PRO feature — without a valid license we tease the preview + // behind an upsell overlay instead of unlocking it. + const licenseValid = usePersistedStore((state) => state.licenseValid) + + // When expanded, the drawer widens to ~90% of the window (the Commander). + const [expanded, setExpanded] = useState(false) + + const auth = useMemo(() => { + if (authUser) { + return btoa(`${authUser}:${authPassword ?? ''}`) + } + return undefined + }, [authUser, authPassword]) + + const authHeader = auth ? `Basic ${auth}` : undefined + + const fileType = item ? getFileType(item) : 'unknown' + const canPreview = item ? isPreviewable(item) : false + + const isTooLarge = + item?.size !== undefined && MAX_PREVIEW_SIZE > 0 && item.size > MAX_PREVIEW_SIZE + + const previewUrl = useMemo(() => { + if (!item || !hostUrl) return null + return buildPreviewUrl(item, hostUrl, auth) + }, [item, hostUrl, auth]) + + const handleDownload = useCallback(() => { + if (!previewUrl) return + window.open(previewUrl, '_blank') + }, [previewUrl]) + + const handleClose = useCallback(() => { + setExpanded(false) + onClose() + }, [onClose]) + + const handleUnlock = useCallback(() => { + openWindow({ name: 'Settings', url: '/settings?tab=license' }) + }, []) + + // Only tease the paywall over an actual rendered preview — not the "select a file", + // "too large", or unsupported/download-fallback states. + const showProLock = !licenseValid && !!previewUrl && !isTooLarge && canPreview + + const renderPreview = () => { + if (!item || !previewUrl) { + return ( +
+ +

Select a file to preview

+
+ ) + } + + if (isTooLarge) { + return ( +
+ +

File is too large for preview

+

+ {formatBytes(item.size ?? 0)} (max: {formatBytes(MAX_PREVIEW_SIZE)}) +

+ +
+ ) + } + + // Shown for types we can't render inline (and for the sub-formats of an + // otherwise-previewable type that this viewer doesn't handle, e.g. .odt / .csv). + const unsupportedFallback = ( +
+ +

Preview not available for this file type

+ +
+ ) + + if (!canPreview) { + return unsupportedFallback + } + + // Documents (pdf/docx/xlsx/pptx) route to their dedicated inline viewer; + // unsupported document sub-formats (e.g. .odt) fall through to download. + const ext = getFileExtension(item.name) + const DocumentViewer = DOCUMENT_VIEWERS[ext] + if (DocumentViewer) { + return ( + + ) + } + + // Text, code and config files — plus .csv (classified as a spreadsheet, but we + // show it as delimited text) — render in the CodeMirror viewer. + if (CODE_VIEWER_TYPES.has(fileType) || ext === 'csv') { + return ( + + ) + } + + switch (fileType) { + case 'image': + return ( +
+ {item.name} +
+ ) + + case 'video': + return ( +
+ {/* biome-ignore lint/a11y/useMediaCaption: */} + +
+ ) + + case 'audio': + return ( +
+ +

{item.name}

+ {/* biome-ignore lint/a11y/useMediaCaption: */} + +
+ ) + + default: + return ( +
+ +

Preview not available

+ +
+ ) + } + } + + return ( + + + +
+ {item && ( + + )} + {item?.name ?? 'Preview'} +
+ +
+ + +
+
+ }>{renderPreview()} + {showProLock && } +
+ + {item && ( + <> + +
+
+ Type: + {fileType} +
+ {item.size !== undefined && ( +
+ Size: + {formatBytes(item.size)} +
+ )} + {item.modTime && ( +
+ Modified: + {item.modTime} +
+ )} +
+ Location: + + {item.remote === 'UI_LOCAL_FS' ? 'Local' : item.remote} + +
+
+ + )} +
+
+
+
+ ) +} diff --git a/src/components/navigator/preview/PreviewProLock.tsx b/src/components/navigator/preview/PreviewProLock.tsx new file mode 100644 index 0000000..b94aac7 --- /dev/null +++ b/src/components/navigator/preview/PreviewProLock.tsx @@ -0,0 +1,34 @@ +import { Button } from '@heroui/react' + +/** + * Paywall teaser shown over the preview for users without a valid license. The preview + * renders underneath, blurred and darkened by a full-height transparent-to-black + * gradient (smooth over heavy coverage) with the upsell copy and Unlock CTA at the + * bottom. It captures pointer events, so the locked preview can be glimpsed but not + * interacted with. + */ +export default function PreviewProLock({ onUnlock }: { onUnlock: () => void }) { + return ( +
+
+

+ Unlock File Previews +

+ +

+ Plus Schedules, Notifications and everything else in Rclone UI Pro. +

+ + +
+
+ ) +} diff --git a/src/components/navigator/preview/XlsxPreview.tsx b/src/components/navigator/preview/XlsxPreview.tsx new file mode 100644 index 0000000..c45186f --- /dev/null +++ b/src/components/navigator/preview/XlsxPreview.tsx @@ -0,0 +1,41 @@ +import { XlsxViewer, setWasmSource } from '@extend-ai/react-xlsx' +// Bundle the sheets wasm locally (Vite ?url) so it loads same-origin offline. +import xlsxWasmUrl from '@extend-ai/react-xlsx/duke_sheets_wasm_bg.wasm?url' +import { PreviewError, PreviewLoading, type PreviewViewerProps } from './previewStates' +import usePreviewSource from './usePreviewSource' + +export default function XlsxPreview({ url, name, authHeader, onDownload }: PreviewViewerProps) { + const { buffer, error, progress } = usePreviewSource( + url, + authHeader, + xlsxWasmUrl, + setWasmSource + ) + + if (error) { + return + } + + if (!buffer) { + return + } + + return ( +
+ } + errorState={(err) => } + fileTooLargeState={ + + } + /> +
+ ) +} diff --git a/src/components/navigator/preview/previewStates.tsx b/src/components/navigator/preview/previewStates.tsx new file mode 100644 index 0000000..b8cb704 --- /dev/null +++ b/src/components/navigator/preview/previewStates.tsx @@ -0,0 +1,59 @@ +import { Button, Progress } from '@heroui/react' +import { DownloadIcon } from 'lucide-react' + +/** Common props shared by every inline file-preview viewer. */ +export interface PreviewViewerProps { + url: string + name: string + authHeader?: string + onDownload: () => void +} + +/** + * Shared centered loading indicator for the preview area. Shows a determinate download + * progress bar when `progress` (0..1) is known, and an indeterminate bar otherwise + * (e.g. the server sent no Content-Length, or a viewer is still parsing/initializing). + */ +export function PreviewLoading({ progress }: { progress?: number | null }) { + const determinate = typeof progress === 'number' + const percent = determinate ? Math.round(progress * 100) : 0 + + return ( +
+ + {determinate && ( + {percent}% + )} +
+ ) +} + +/** Shared "couldn't render, download instead" fallback for the preview area. */ +export function PreviewError({ + message, + onDownload, +}: { + message?: string + onDownload: () => void +}) { + return ( +
+

Could not load preview

+ {message &&

{message}

} + +
+ ) +} diff --git a/src/components/navigator/preview/usePreviewBytes.ts b/src/components/navigator/preview/usePreviewBytes.ts new file mode 100644 index 0000000..0e5bff0 --- /dev/null +++ b/src/components/navigator/preview/usePreviewBytes.ts @@ -0,0 +1,107 @@ +// Native HTTP client: runs the request from Rust so it isn't blocked by the +// webview's cross-origin (CORS) policy, the same way lib/rclone/client.ts fetches. +import { fetch as tauriFetch } from '@tauri-apps/plugin-http' +import { useEffect, useState } from 'react' + +export interface PreviewBytes { + buffer: ArrayBuffer | null + isLoading: boolean + error: string | null + // Download progress in 0..1, or null when the total size is unknown (no Content-Length). + progress: number | null +} + +/** + * Downloads a preview target's bytes via the native (Tauri) HTTP client and hands + * back an ArrayBuffer. Fetching the bytes ourselves — instead of letting a viewer + * load by URL — avoids the webview CORS block against the rclone serve origin, so + * any viewer that accepts a buffer can render local and remote files alike. + * + * The body is read as a stream so `progress` can track bytes-received / Content-Length + * for a download progress bar; it stays null when the server sends no Content-Length. + */ +export default function usePreviewBytes(url: string, authHeader?: string): PreviewBytes { + const [state, setState] = useState({ + buffer: null, + isLoading: true, + error: null, + progress: null, + }) + + useEffect(() => { + setState({ buffer: null, isLoading: true, error: null, progress: null }) + + const abortController = new AbortController() + let cancelled = false + + const run = async () => { + try { + const res = await tauriFetch(url, { + headers: authHeader ? { Authorization: authHeader } : undefined, + signal: abortController.signal, + }) + if (!res.ok) throw new Error(`HTTP ${res.status}`) + + const totalHeader = res.headers.get('content-length') + const total = totalHeader ? Number.parseInt(totalHeader, 10) : 0 + + // No streamable body: fall back to reading the buffer directly. + if (!res.body) { + const buffer = await res.arrayBuffer() + if (!cancelled) { + setState({ buffer, isLoading: false, error: null, progress: 1 }) + } + return + } + + const reader = res.body.getReader() + const chunks: Uint8Array[] = [] + let received = 0 + let lastPercent = -1 + + let result = await reader.read() + while (!result.done) { + const chunk = result.value + chunks.push(chunk) + received += chunk.byteLength + // Throttle to whole-percent changes so we don't re-render per chunk. + if (total > 0 && !cancelled) { + const percent = Math.floor(Math.min(received / total, 1) * 100) + if (percent !== lastPercent) { + lastPercent = percent + setState((s) => ({ ...s, progress: percent / 100 })) + } + } + result = await reader.read() + } + + const merged = new Uint8Array(received) + let offset = 0 + for (const chunk of chunks) { + merged.set(chunk, offset) + offset += chunk.byteLength + } + if (!cancelled) { + setState({ buffer: merged.buffer, isLoading: false, error: null, progress: 1 }) + } + } catch (err) { + if (cancelled || abortController.signal.aborted) return + setState({ + buffer: null, + isLoading: false, + error: (err as Error).message, + progress: null, + }) + } + } + + run() + + return () => { + cancelled = true + abortController.abort() + } + }, [url, authHeader]) + + return state +} diff --git a/src/components/navigator/preview/usePreviewSource.ts b/src/components/navigator/preview/usePreviewSource.ts new file mode 100644 index 0000000..4f74169 --- /dev/null +++ b/src/components/navigator/preview/usePreviewSource.ts @@ -0,0 +1,24 @@ +import usePreviewBytes from './usePreviewBytes' +import usePreviewWasm from './usePreviewWasm' + +/** + * Prepares an inline viewer's input: fetches the document bytes (CORS-safe) and, when + * the viewer needs it, configures the library's wasm — exposing the buffer only once + * BOTH are ready. + * + * The @extend-ai libraries parse in a Web Worker that instantiates wasm from the + * configured source, so the viewer must not mount before `setWasmSource` runs; gating + * on this hook's `buffer` (null until wasm is configured) enforces that in one place. + * Pass no `wasmUrl`/`setWasmSource` for viewers that manage their own wasm (PdfPreview). + */ +export default function usePreviewSource( + url: string, + authHeader: string | undefined, + wasmUrl?: string, + setWasmSource?: (source: ArrayBuffer) => void +): { buffer: ArrayBuffer | null; error: string | null; progress: number | null } { + const wasmReady = usePreviewWasm(wasmUrl, setWasmSource) + const { buffer, error, progress } = usePreviewBytes(url, authHeader) + + return { buffer: wasmReady ? buffer : null, error, progress } +} diff --git a/src/components/navigator/preview/usePreviewText.ts b/src/components/navigator/preview/usePreviewText.ts new file mode 100644 index 0000000..200e0b7 --- /dev/null +++ b/src/components/navigator/preview/usePreviewText.ts @@ -0,0 +1,16 @@ +import { useMemo } from 'react' +import usePreviewBytes from './usePreviewBytes' + +// Reused across renders; UTF-8, non-fatal (invalid bytes become U+FFFD rather than throwing). +const decoder = new TextDecoder('utf-8') + +/** + * Fetches a preview target's bytes via the native (Tauri) HTTP client — same path as + * the binary viewers, so it works for remote hosts without hitting the webview CORS + * block — and decodes them to a UTF-8 string for the code/text viewer. + */ +export default function usePreviewText(url: string, authHeader?: string) { + const { buffer, isLoading, error, progress } = usePreviewBytes(url, authHeader) + const text = useMemo(() => (buffer ? decoder.decode(buffer) : null), [buffer]) + return { text, isLoading, error, progress } +} diff --git a/src/components/navigator/preview/usePreviewWasm.ts b/src/components/navigator/preview/usePreviewWasm.ts new file mode 100644 index 0000000..6b440b4 --- /dev/null +++ b/src/components/navigator/preview/usePreviewWasm.ts @@ -0,0 +1,55 @@ +import { useEffect, useState } from 'react' + +// One shared fetch per wasm asset, reused across mounts (incl. StrictMode remounts). +const wasmCache = new Map>() + +/** + * Fetches a viewer library's wasm (a same-origin, bundled asset — no CORS) and hands + * it to that library's `setWasmSource` as an **ArrayBuffer**, then reports readiness. + * + * These libraries parse inside a Web Worker and forward the configured wasm source to + * it. A string URL makes the worker fetch the wasm itself, which it can't resolve in + * the Tauri webview — so we pass raw bytes instead: the buffer is structured-cloned to + * the worker and instantiated directly. Gate the viewer on the returned flag so the + * source is configured before the library spins up its worker. + */ +export default function usePreviewWasm( + wasmUrl?: string, + setWasmSource?: (source: ArrayBuffer) => void +): boolean { + const [ready, setReady] = useState(false) + + useEffect(() => { + // Nothing to configure — e.g. PdfPreview loads its own wasm via the engine. + if (!wasmUrl || !setWasmSource) { + setReady(true) + return + } + + let cancelled = false + + let promise = wasmCache.get(wasmUrl) + if (!promise) { + promise = fetch(wasmUrl) + .then((res) => res.arrayBuffer()) + .then((buffer) => setWasmSource(buffer)) + wasmCache.set(wasmUrl, promise) + } + + promise + .then(() => { + if (!cancelled) setReady(true) + }) + .catch(() => { + // Drop the failed attempt so a later mount can retry the fetch. + wasmCache.delete(wasmUrl) + // Leave `ready` false; the viewer stays on its loading state. + }) + + return () => { + cancelled = true + } + }, [wasmUrl, setWasmSource]) + + return ready +} diff --git a/vite.config.ts b/vite.config.ts index 8a6dff1..63aecfa 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -27,6 +27,41 @@ export default defineConfig(async () => ({ // ], plugins: [react()], + // Some viewer libs (e.g. @extend-ai/react-xlsx) ship code-splitting Web Workers, + // which require ES-module worker output rather than the default iife. + worker: { format: 'es' }, + + optimizeDeps: { + // These viewer libs create Web Workers via `new URL('./worker.js', import.meta.url)`. + // Vite's dep pre-bundler doesn't emit those worker files, so in dev the worker URL + // 404s ("file does not exist in the optimize deps directory"). Excluding them routes + // the workers through Vite's normal worker pipeline. (Prod/Rollup handles them fine.) + exclude: [ + '@extend-ai/react-docx', + '@extend-ai/react-xlsx', + '@extend-ai/react-pptx', + ], + // Because the packages above are excluded, Vite never scans them to discover their + // own dependencies — so their (often CJS) imports like `react-dom/server` aren't + // pre-bundled and named imports fail ("Importing binding name ... is not found"). + // Force-optimize the deps they import by name so interop is applied. + include: [ + 'react-dom/server', + 'regl', + 'topojson-client', + 'utif', + 'fast-png', + '@chenglou/pretext', + 'fflate', + 'd3-geo', + 'd3-hierarchy', + 'd3-scale', + 'd3-shape', + '@tanstack/react-virtual', + '@tanstack/virtual-core', + ], + }, + build: { chunkSizeWarningLimit: 5120 }, esbuild: {