diff --git a/bun.lock b/bun.lock index 1231b0fe..d02ee205 100644 --- a/bun.lock +++ b/bun.lock @@ -5,7 +5,7 @@ "": { "name": "betterseqtaplus", "dependencies": { - "@bedframe/core": "^0.0.46", + "@bedframe/core": "^0.1.0", "@codemirror/autocomplete": "^6.18.6", "@codemirror/commands": "^6.8.0", "@codemirror/lang-css": "^6.3.1", @@ -13,7 +13,7 @@ "@codemirror/search": "^6.5.10", "@codemirror/state": "^6.5.2", "@codemirror/view": "^6.36.4", - "@sveltejs/vite-plugin-svelte": "^5.0.3", + "@sveltejs/vite-plugin-svelte": "^7.0.0", "@tailwindcss/forms": "^0.5.10", "@tsconfig/svelte": "^5.0.4", "@types/chrome": "^0.1.4", @@ -52,17 +52,17 @@ "react-dom": "17", "rss-parser": "^3.13.0", "sortablejs": "^1.15.6", - "svelte": "^5.22.6", + "svelte": "^5.46.4", "typescript": "^5.8.2", "uuid": "^11.1.0", - "vite": "^6.2.1", + "vite": "^8.0.5", "webextension-polyfill": "^0.12.0", }, "devDependencies": { "@babel/plugin-transform-runtime": "^7.26.9", "@babel/runtime": "^7.26.9", - "@bedframe/cli": "^0.0.95", - "@crxjs/vite-plugin": "^2.2.0", + "@bedframe/cli": "^0.1.2", + "@crxjs/vite-plugin": "^2.4.0", "@types/mime-types": "^3.0.1", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", @@ -127,9 +127,9 @@ "@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "7.27.1", "@babel/helper-validator-identifier": "7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="], - "@bedframe/cli": ["@bedframe/cli@0.0.95", "", { "dependencies": { "@bedframe/core": "0.0.46", "commander": "14.0.0", "execa": "9.6.0", "kolorist": "1.8.0", "listr": "0.14.3", "nanospinner": "1.2.2", "node-fetch": "3.3.2", "pkg-install": "1.0.0", "prompts": "2.4.2", "vite": "6.3.5" }, "peerDependencies": { "concurrently": "8.2.2" }, "bin": { "bedframe": "dist/bedframe.js", "create-bedframe": "dist/create-bedframe.js" } }, "sha512-WSb0HhHCfH7/tS5dDC/HL/VgKrIFGLmI0OesmcwQntrJdHVirtjrDVjcTFG3lC3LB5Ax85P1CY50Gy5aDNc0sQ=="], + "@bedframe/cli": ["@bedframe/cli@0.1.2", "", { "dependencies": { "@bedframe/core": "0.1.0", "commander": "^14.0.2", "execa": "^9.6.1", "kolorist": "^1.8.0", "listr": "^0.14.3", "nanospinner": "^1.2.2", "node-fetch": "^3.3.2", "pkg-install": "^1.0.0", "prompts": "^2.4.2", "vite": "^6.4.1" }, "peerDependencies": { "concurrently": "^8.2.1" }, "bin": { "bedframe": "dist/bedframe.js", "create-bedframe": "dist/create-bedframe.js" } }, "sha512-nu0VSfGLhY9f62w+fDRQi2YnfoY9c6u28ZlJ8rH6f57ItLo5TNrZetfw37fYNnh8yK2RSAWU7+6KCkdVm0Fokg=="], - "@bedframe/core": ["@bedframe/core@0.0.46", "", { "dependencies": { "@crxjs/vite-plugin": "2.0.2" }, "peerDependencies": { "vite-plugin-dts": "3.9.1", "vite-plugin-externalize-deps": "0.7.0", "vitest": "0.34.6" } }, "sha512-cOshFUrBksWnVQ08chunlvAetwhuytkX7NdH6blNNylYzsgCaLGBbCJ2EZ0d18kimFVNZoODrc+812if5dio/w=="], + "@bedframe/core": ["@bedframe/core@0.1.0", "", { "dependencies": { "@crxjs/vite-plugin": "2.3.0" }, "peerDependencies": { "vite-plugin-dts": "^3.7.0", "vite-plugin-externalize-deps": "^0.7.0", "vitest": "^0.34.6" } }, "sha512-bM9vuYG67m9lVTui966AmkoxPPdEHEDOKKjzAWV/Ymgur818fRhMMpblx3+PLs8kTCek1m79fjYKoE8PhqJ22g=="], "@codemirror/autocomplete": ["@codemirror/autocomplete@6.18.6", "", { "dependencies": { "@codemirror/language": "6.11.3", "@codemirror/state": "6.5.2", "@codemirror/view": "6.38.1", "@lezer/common": "1.2.3" } }, "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg=="], @@ -147,7 +147,13 @@ "@codemirror/view": ["@codemirror/view@6.38.1", "", { "dependencies": { "@codemirror/state": "6.5.2", "crelt": "1.0.6", "style-mod": "4.1.2", "w3c-keyname": "2.2.8" } }, "sha512-RmTOkE7hRU3OVREqFVITWHz6ocgBjv08GoePscAakgVQfciA3SGCEk7mb9IzwW61cKKmlTpHXG6DUE5Ubx+MGQ=="], - "@crxjs/vite-plugin": ["@crxjs/vite-plugin@2.2.0", "", { "dependencies": { "@rollup/pluginutils": "4.2.1", "@webcomponents/custom-elements": "1.6.0", "acorn-walk": "8.3.4", "cheerio": "1.1.2", "convert-source-map": "1.9.0", "debug": "4.4.1", "es-module-lexer": "0.10.5", "fast-glob": "3.3.3", "fs-extra": "10.1.0", "jsesc": "3.1.0", "magic-string": "0.30.18", "pathe": "2.0.3", "picocolors": "1.1.1", "react-refresh": "0.13.0", "rollup": "2.79.2", "rxjs": "7.5.7" } }, "sha512-HpT1GLbUQy42nlpN4sGzFgulacBraMM778s8Q+oPo4cb26DwO9tTwdndlvAS8fe6vEProFXvbdt37objp/0IQA=="], + "@crxjs/vite-plugin": ["@crxjs/vite-plugin@2.4.0", "", { "dependencies": { "@rollup/pluginutils": "^4.1.2", "@webcomponents/custom-elements": "^1.5.0", "acorn-walk": "^8.2.0", "convert-source-map": "^1.7.0", "debug": "^4.3.3", "es-module-lexer": "^0.10.0", "fast-glob": "^3.2.11", "fs-extra": "^10.0.1", "jsesc": "^3.0.2", "magic-string": "^0.30.12", "node-html-parser": "^7.0.2", "pathe": "^2.0.1", "picocolors": "^1.1.1", "react-refresh": "^0.13.0", "rollup": "2.79.2", "rxjs": "7.5.7" }, "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-bDLdq0W2V1SkMQDJjrcYyjK9/uKtdl4joT7GRImcootCjZdKRiRYt+cv9z8tJoU/tK3o1lX48LTqN7JMsk5AQg=="], + + "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], "@epic-web/invariant": ["@epic-web/invariant@1.0.0", "", {}, "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA=="], @@ -293,12 +299,16 @@ "@napi-rs/canvas-win32-x64-msvc": ["@napi-rs/canvas-win32-x64-msvc@0.1.89", "", { "os": "win32", "cpu": "x64" }, "sha512-WMej0LZrIqIncQcx0JHaMXlnAG7sncwJh7obs/GBgp0xF9qABjwoRwIooMWCZkSansapKGNUHhamY6qEnFN7gA=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "1.2.0" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "1.19.1" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@oxc-project/types": ["@oxc-project/types@0.124.0", "", {}, "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg=="], + "@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "1.0.3", "is-glob": "4.0.3", "micromatch": "4.0.8", "node-addon-api": "7.1.1" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="], "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="], @@ -349,6 +359,38 @@ "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.15", "", { "os": "android", "cpu": "arm64" }, "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.15", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm" }, "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ=="], + + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "ppc64" }, "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ=="], + + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "s390x" }, "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.15", "", { "os": "none", "cpu": "arm64" }, "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.15", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.3" }, "cpu": "none" }, "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "x64" }, "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.15", "", {}, "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g=="], + "@rollup/pluginutils": ["@rollup/pluginutils@4.2.1", "", { "dependencies": { "estree-walker": "2.0.2", "picomatch": "2.3.1" } }, "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.49.0", "", { "os": "android", "cpu": "arm" }, "sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA=="], @@ -409,14 +451,14 @@ "@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "8.15.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="], - "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.1.1", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "4.0.1", "debug": "4.4.1", "deepmerge": "4.3.1", "kleur": "4.1.5", "magic-string": "0.30.18", "vitefu": "1.1.1" }, "peerDependencies": { "svelte": "5.38.6", "vite": "6.3.5" } }, "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ=="], - - "@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "4.4.1" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "5.1.1", "svelte": "5.38.6", "vite": "6.3.5" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="], + "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@7.0.0", "", { "dependencies": { "deepmerge": "^4.3.1", "magic-string": "^0.30.21", "obug": "^2.1.0", "vitefu": "^1.1.2" }, "peerDependencies": { "svelte": "^5.46.4", "vite": "^8.0.0-beta.7 || ^8.0.0" } }, "sha512-ILXmxC7HAsnkK2eslgPetrqqW1BKSL7LktsFgqzNj83MaivMGZzluWq32m25j2mDOjmSKX7GGWahePhuEs7P/g=="], "@tailwindcss/forms": ["@tailwindcss/forms@0.5.10", "", { "dependencies": { "mini-svg-data-uri": "1.4.4" }, "peerDependencies": { "tailwindcss": "3.4.17" } }, "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw=="], "@tsconfig/svelte": ["@tsconfig/svelte@5.0.5", "", {}, "sha512-48fAnUjKye38FvMiNOj0J9I/4XlQQiZlpe9xaNPfe8vy2Y1hFBt8g1yqf2EGjVvHavo4jf2lC+TQyENCr4BJBQ=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@types/argparse": ["@types/argparse@1.0.38", "", {}, "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA=="], "@types/chai": ["@types/chai@4.3.20", "", {}, "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ=="], @@ -527,7 +569,7 @@ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], - "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], + "aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="], "assertion-error": ["assertion-error@1.1.0", "", {}, "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="], @@ -631,7 +673,7 @@ "colors-named-hex": ["colors-named-hex@1.0.2", "", {}, "sha512-k6kq1e1pUCQvSVwIaGFq2l0LrkAPQZWyeuZn1Z8nOiYSEZiKoFj4qx690h2Kd34DFl9Me0gKS6MUwAMBJj8nuA=="], - "commander": ["commander@14.0.0", "", {}, "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA=="], + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], "complex.js": ["complex.js@2.4.2", "", {}, "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g=="], @@ -693,6 +735,8 @@ "detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="], + "devalue": ["devalue@5.7.1", "", {}, "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA=="], + "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], "diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="], @@ -773,7 +817,7 @@ "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "5.3.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], - "esrap": ["esrap@2.1.0", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA=="], + "esrap": ["esrap@2.2.5", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, "peerDependencies": { "@typescript-eslint/types": "^8.2.0" }, "optionalPeers": ["@typescript-eslint/types"] }, "sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig=="], "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "5.3.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], @@ -787,7 +831,7 @@ "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], - "execa": ["execa@9.6.0", "", { "dependencies": { "@sindresorhus/merge-streams": "4.0.0", "cross-spawn": "7.0.6", "figures": "6.1.0", "get-stream": "9.0.1", "human-signals": "8.0.1", "is-plain-obj": "4.1.0", "is-stream": "4.0.1", "npm-run-path": "6.0.0", "pretty-ms": "9.2.0", "signal-exit": "4.1.0", "strip-final-newline": "4.0.0", "yoctocolors": "2.1.2" } }, "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw=="], + "execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="], "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], @@ -995,6 +1039,30 @@ "lie": ["lie@3.1.1", "", { "dependencies": { "immediate": "3.0.6" } }, "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw=="], + "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], @@ -1125,6 +1193,8 @@ "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], + "node-html-parser": ["node-html-parser@7.1.0", "", { "dependencies": { "css-select": "^5.1.0", "he": "1.2.0" } }, "sha512-iJo8b2uYGT40Y8BTyy5ufL6IVbN8rbm/1QK2xffXU/1a/v3AAa0d1YAoqBNYqaS4R/HajkWIpIfdE6KcyFh1AQ=="], + "node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], @@ -1143,6 +1213,8 @@ "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + "ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1.0.2" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], @@ -1293,6 +1365,8 @@ "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + "rolldown": ["rolldown@1.0.0-rc.15", "", { "dependencies": { "@oxc-project/types": "=0.124.0", "@rolldown/pluginutils": "1.0.0-rc.15" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-x64": "1.0.0-rc.15", "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g=="], + "rollup": ["rollup@2.79.2", "", { "optionalDependencies": { "fsevents": "2.3.3" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ=="], "rss-parser": ["rss-parser@3.13.0", "", { "dependencies": { "entities": "2.2.0", "xml2js": "0.5.0" } }, "sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w=="], @@ -1397,7 +1471,7 @@ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "svelte": ["svelte@5.38.6", "", { "dependencies": { "@jridgewell/remapping": "2.3.5", "@jridgewell/sourcemap-codec": "1.5.5", "@sveltejs/acorn-typescript": "1.0.5", "@types/estree": "1.0.8", "acorn": "8.15.0", "aria-query": "5.3.2", "axobject-query": "4.1.0", "clsx": "2.1.1", "esm-env": "1.2.2", "esrap": "2.1.0", "is-reference": "3.0.3", "locate-character": "3.0.0", "magic-string": "0.30.18", "zimmerframe": "1.1.2" } }, "sha512-ltBPlkvqk3bgCK7/N323atUpP3O3Y+DrGV4dcULrsSn4fZaaNnOmdplNznwfdWclAgvSr5rxjtzn/zJhRm6TKg=="], + "svelte": ["svelte@5.55.4", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@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.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.4", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-q8DFohk6vUswSng95IZb9nzWJnbINZsK7OiM1snAa3qCjJBL0ZQpvMyAaVXjUukdM75J/m8UE8xwqat8Ors/zQ=="], "symbol-observable": ["symbol-observable@1.2.0", "", {}, "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="], @@ -1423,7 +1497,7 @@ "tinycolor2": ["tinycolor2@1.4.2", "", {}, "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA=="], - "tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "6.5.0", "picomatch": "4.0.3" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="], + "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], "tinypool": ["tinypool@0.7.0", "", {}, "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww=="], @@ -1477,7 +1551,7 @@ "validator": ["validator@13.15.15", "", {}, "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A=="], - "vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "0.25.9", "fdir": "6.5.0", "picomatch": "4.0.3", "postcss": "8.5.6", "rollup": "4.49.0", "tinyglobby": "0.2.14" }, "optionalDependencies": { "@types/node": "24.3.0", "fsevents": "2.3.3", "jiti": "1.21.7", "sass": "1.91.0", "yaml": "2.8.1" }, "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], + "vite": ["vite@8.0.8", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.15", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw=="], "vite-node": ["vite-node@0.34.6", "", { "dependencies": { "cac": "6.7.14", "debug": "4.4.1", "mlly": "1.8.0", "pathe": "1.1.2", "picocolors": "1.1.1", "vite": "5.4.19" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA=="], @@ -1485,7 +1559,7 @@ "vite-plugin-externalize-deps": ["vite-plugin-externalize-deps@0.7.0", "", { "peerDependencies": { "vite": "6.3.5" } }, "sha512-do2gPrR79Tm8UKcqsw3RTAtN4YO8GkVRBckWdJWINZ3Qdp3KN9S1oyUZxKszTB/iyg4zdOUweLOeBI8t86QVow=="], - "vitefu": ["vitefu@1.1.1", "", { "optionalDependencies": { "vite": "6.3.5" } }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], + "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], "vitest": ["vitest@0.34.6", "", { "dependencies": { "@types/chai": "4.3.20", "@types/chai-subset": "1.3.6", "@types/node": "24.3.0", "@vitest/expect": "0.34.6", "@vitest/runner": "0.34.6", "@vitest/snapshot": "0.34.6", "@vitest/spy": "0.34.6", "@vitest/utils": "0.34.6", "acorn": "8.15.0", "acorn-walk": "8.3.4", "cac": "6.7.14", "chai": "4.5.0", "debug": "4.4.1", "local-pkg": "0.4.3", "magic-string": "0.30.18", "pathe": "1.1.2", "picocolors": "1.1.1", "std-env": "3.9.0", "strip-literal": "1.3.0", "tinybench": "2.9.0", "tinypool": "0.7.0", "vite": "5.4.19", "vite-node": "0.34.6", "why-is-node-running": "2.3.0" }, "bin": { "vitest": "vitest.mjs" } }, "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q=="], @@ -1555,7 +1629,9 @@ "@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@bedframe/core/@crxjs/vite-plugin": ["@crxjs/vite-plugin@2.0.2", "", { "dependencies": { "@rollup/pluginutils": "4.2.1", "@webcomponents/custom-elements": "1.6.0", "acorn-walk": "8.3.4", "cheerio": "1.1.2", "convert-source-map": "1.9.0", "debug": "4.4.1", "es-module-lexer": "0.10.5", "fast-glob": "3.3.3", "fs-extra": "10.1.0", "jsesc": "3.1.0", "magic-string": "0.30.18", "pathe": "2.0.3", "picocolors": "1.1.1", "react-refresh": "0.13.0", "rollup": "2.79.2", "rxjs": "7.5.7" } }, "sha512-BeaVEkCTmna2tzl5DL9nw1kxll1IpIFZ+wbl2+iILz4fNJy1xRD6c1nF8w8/CvrWUuPYTFTpyX9K+A30ISDXHA=="], + "@bedframe/cli/vite": ["vite@6.4.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="], + + "@bedframe/core/@crxjs/vite-plugin": ["@crxjs/vite-plugin@2.3.0", "", { "dependencies": { "@rollup/pluginutils": "^4.1.2", "@webcomponents/custom-elements": "^1.5.0", "acorn-walk": "^8.2.0", "cheerio": "^1.0.0-rc.10", "convert-source-map": "^1.7.0", "debug": "^4.3.3", "es-module-lexer": "^0.10.0", "fast-glob": "^3.2.11", "fs-extra": "^10.0.1", "jsesc": "^3.0.2", "magic-string": "^0.30.12", "pathe": "^2.0.1", "picocolors": "^1.1.1", "react-refresh": "^0.13.0", "rollup": "2.79.2", "rxjs": "7.5.7" } }, "sha512-+0CNVGS4bB30OoaF1vUsHVwWU1Lm7MxI0XWY9Fd/Ob+ZVTZgEFNqJ1ZC69IVwQsoYhY0sMQLvpLWiFIuDz8htg=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], @@ -1591,6 +1667,8 @@ "@samverschueren/stream-to-observable/rxjs": ["rxjs@6.6.7", "", { "dependencies": { "tslib": "1.14.1" } }, "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ=="], + "@sveltejs/vite-plugin-svelte/magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "@vitest/runner/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], "@vitest/snapshot/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], @@ -1621,6 +1699,8 @@ "concurrently/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "8.0.1", "escalade": "3.2.0", "get-caller-file": "2.0.5", "require-directory": "2.1.1", "string-width": "4.2.3", "y18n": "5.0.8", "yargs-parser": "21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + "dependency-cruiser/commander": ["commander@14.0.0", "", {}, "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA=="], + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], "eslint/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "3.1.3", "fast-json-stable-stringify": "2.1.0", "json-schema-traverse": "0.4.1", "uri-js": "4.4.1" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], @@ -1633,6 +1713,8 @@ "htmlparser2/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + "lightningcss/detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], + "listr/is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="], "listr/rxjs": ["rxjs@6.6.7", "", { "dependencies": { "tslib": "1.14.1" } }, "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ=="], @@ -1715,9 +1797,13 @@ "tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "3.1.3", "braces": "3.0.3", "glob-parent": "5.1.2", "is-binary-path": "2.1.0", "is-glob": "4.0.3", "normalize-path": "3.0.0", "readdirp": "3.6.0" }, "optionalDependencies": { "fsevents": "2.3.3" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + "tinyglobby/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + "uri-js/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], - "vite/rollup": ["rollup@4.49.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.49.0", "@rollup/rollup-android-arm64": "4.49.0", "@rollup/rollup-darwin-arm64": "4.49.0", "@rollup/rollup-darwin-x64": "4.49.0", "@rollup/rollup-freebsd-arm64": "4.49.0", "@rollup/rollup-freebsd-x64": "4.49.0", "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", "@rollup/rollup-linux-arm-musleabihf": "4.49.0", "@rollup/rollup-linux-arm64-gnu": "4.49.0", "@rollup/rollup-linux-arm64-musl": "4.49.0", "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", "@rollup/rollup-linux-ppc64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-musl": "4.49.0", "@rollup/rollup-linux-s390x-gnu": "4.49.0", "@rollup/rollup-linux-x64-gnu": "4.49.0", "@rollup/rollup-linux-x64-musl": "4.49.0", "@rollup/rollup-win32-arm64-msvc": "4.49.0", "@rollup/rollup-win32-ia32-msvc": "4.49.0", "@rollup/rollup-win32-x64-msvc": "4.49.0", "fsevents": "2.3.3" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA=="], + "vite/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + + "vite/postcss": ["postcss@8.5.10", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ=="], "vite-node/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], @@ -1725,6 +1811,8 @@ "vite-plugin-dts/@rollup/pluginutils": ["@rollup/pluginutils@5.2.0", "", { "dependencies": { "@types/estree": "1.0.8", "estree-walker": "2.0.2", "picomatch": "4.0.3" }, "optionalDependencies": { "rollup": "4.49.0" } }, "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw=="], + "vite-plugin-dts/vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "0.25.9", "fdir": "6.5.0", "picomatch": "4.0.3", "postcss": "8.5.6", "rollup": "4.49.0", "tinyglobby": "0.2.14" }, "optionalDependencies": { "@types/node": "24.3.0", "fsevents": "2.3.3", "jiti": "1.21.7", "sass": "1.91.0", "yaml": "2.8.1" }, "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], + "vitest/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], "vitest/vite": ["vite@5.4.19", "", { "dependencies": { "esbuild": "0.21.5", "postcss": "8.5.6", "rollup": "4.49.0" }, "optionalDependencies": { "@types/node": "24.3.0", "fsevents": "2.3.3", "sass": "1.91.0" }, "bin": { "vite": "bin/vite.js" } }, "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA=="], @@ -1741,6 +1829,14 @@ "z-schema/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], + "@bedframe/cli/vite/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + + "@bedframe/cli/vite/postcss": ["postcss@8.5.10", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ=="], + + "@bedframe/cli/vite/rollup": ["rollup@4.49.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.49.0", "@rollup/rollup-android-arm64": "4.49.0", "@rollup/rollup-darwin-arm64": "4.49.0", "@rollup/rollup-darwin-x64": "4.49.0", "@rollup/rollup-freebsd-arm64": "4.49.0", "@rollup/rollup-freebsd-x64": "4.49.0", "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", "@rollup/rollup-linux-arm-musleabihf": "4.49.0", "@rollup/rollup-linux-arm64-gnu": "4.49.0", "@rollup/rollup-linux-arm64-musl": "4.49.0", "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", "@rollup/rollup-linux-ppc64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-musl": "4.49.0", "@rollup/rollup-linux-s390x-gnu": "4.49.0", "@rollup/rollup-linux-x64-gnu": "4.49.0", "@rollup/rollup-linux-x64-musl": "4.49.0", "@rollup/rollup-win32-arm64-msvc": "4.49.0", "@rollup/rollup-win32-ia32-msvc": "4.49.0", "@rollup/rollup-win32-x64-msvc": "4.49.0", "fsevents": "2.3.3" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA=="], + + "@bedframe/core/@crxjs/vite-plugin/magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "@eslint/eslintrc/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], @@ -1865,6 +1961,10 @@ "vite-plugin-dts/@rollup/pluginutils/rollup": ["rollup@4.49.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.49.0", "@rollup/rollup-android-arm64": "4.49.0", "@rollup/rollup-darwin-arm64": "4.49.0", "@rollup/rollup-darwin-x64": "4.49.0", "@rollup/rollup-freebsd-arm64": "4.49.0", "@rollup/rollup-freebsd-x64": "4.49.0", "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", "@rollup/rollup-linux-arm-musleabihf": "4.49.0", "@rollup/rollup-linux-arm64-gnu": "4.49.0", "@rollup/rollup-linux-arm64-musl": "4.49.0", "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", "@rollup/rollup-linux-ppc64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-musl": "4.49.0", "@rollup/rollup-linux-s390x-gnu": "4.49.0", "@rollup/rollup-linux-x64-gnu": "4.49.0", "@rollup/rollup-linux-x64-musl": "4.49.0", "@rollup/rollup-win32-arm64-msvc": "4.49.0", "@rollup/rollup-win32-ia32-msvc": "4.49.0", "@rollup/rollup-win32-x64-msvc": "4.49.0", "fsevents": "2.3.3" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA=="], + "vite-plugin-dts/vite/rollup": ["rollup@4.49.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.49.0", "@rollup/rollup-android-arm64": "4.49.0", "@rollup/rollup-darwin-arm64": "4.49.0", "@rollup/rollup-darwin-x64": "4.49.0", "@rollup/rollup-freebsd-arm64": "4.49.0", "@rollup/rollup-freebsd-x64": "4.49.0", "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", "@rollup/rollup-linux-arm-musleabihf": "4.49.0", "@rollup/rollup-linux-arm64-gnu": "4.49.0", "@rollup/rollup-linux-arm64-musl": "4.49.0", "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", "@rollup/rollup-linux-ppc64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-musl": "4.49.0", "@rollup/rollup-linux-s390x-gnu": "4.49.0", "@rollup/rollup-linux-x64-gnu": "4.49.0", "@rollup/rollup-linux-x64-musl": "4.49.0", "@rollup/rollup-win32-arm64-msvc": "4.49.0", "@rollup/rollup-win32-ia32-msvc": "4.49.0", "@rollup/rollup-win32-x64-msvc": "4.49.0", "fsevents": "2.3.3" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA=="], + + "vite-plugin-dts/vite/tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "6.5.0", "picomatch": "4.0.3" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="], + "vitest/vite/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], "vitest/vite/rollup": ["rollup@4.49.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.49.0", "@rollup/rollup-android-arm64": "4.49.0", "@rollup/rollup-darwin-arm64": "4.49.0", "@rollup/rollup-darwin-x64": "4.49.0", "@rollup/rollup-freebsd-arm64": "4.49.0", "@rollup/rollup-freebsd-x64": "4.49.0", "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", "@rollup/rollup-linux-arm-musleabihf": "4.49.0", "@rollup/rollup-linux-arm64-gnu": "4.49.0", "@rollup/rollup-linux-arm64-musl": "4.49.0", "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", "@rollup/rollup-linux-ppc64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-musl": "4.49.0", "@rollup/rollup-linux-s390x-gnu": "4.49.0", "@rollup/rollup-linux-x64-gnu": "4.49.0", "@rollup/rollup-linux-x64-musl": "4.49.0", "@rollup/rollup-win32-arm64-msvc": "4.49.0", "@rollup/rollup-win32-ia32-msvc": "4.49.0", "@rollup/rollup-win32-x64-msvc": "4.49.0", "fsevents": "2.3.3" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA=="], diff --git a/src/background.ts b/src/background.ts index 62fb69f0..b98b5514 100644 --- a/src/background.ts +++ b/src/background.ts @@ -10,6 +10,21 @@ import { runCloudSettingsPoll, } from "./background/cloudSettingsAutoSync"; +/** + * Session-only dev-mode override of the content API base. + * + * Stored in a module-level variable (not `chrome.storage`) so it is wiped + * automatically when the browser/service-worker process restarts. Content + * scripts re-sync this on every page load via `setDevApiBase` so the value + * survives transient service-worker terminations within the same browser + * session. + */ +const DEFAULT_API_BASE = "https://betterseqta.org"; +let DEV_API_BASE: string | null = null; +function apiBase(): string { + return DEV_API_BASE ?? DEFAULT_API_BASE; +} + function reloadSeqtaPages() { const result = browser.tabs.query({}); function open(tabs: any) { @@ -30,7 +45,7 @@ type MessageSender = { (response?: unknown): void }; function handleFetchThemes(request: any, sendResponse: MessageSender): boolean { const { token } = request; - const apiUrl = `https://betterseqta.org/api/themes?type=betterseqta&limit=100&nocache=${Date.now()}`; + const apiUrl = `${apiBase()}/api/themes?type=betterseqta&limit=100&nocache=${Date.now()}`; const githubUrl = `https://raw.githubusercontent.com/BetterSEQTA/BetterSEQTA-Themes/main/store/themes.json?nocache=${Date.now()}`; const headers: Record = {}; if (token) headers["Authorization"] = `Bearer ${token}`; @@ -58,7 +73,7 @@ function handleFetchThemeDetails(request: any, sendResponse: MessageSender): boo } const headers: Record = {}; if (token) headers["Authorization"] = `Bearer ${token}`; - fetch(`https://betterseqta.org/api/themes/${themeId}`, { cache: "no-store", headers }) + fetch(`${apiBase()}/api/themes/${themeId}`, { cache: "no-store", headers }) .then((r) => r.json()) .then(sendResponse) .catch((err) => { @@ -284,7 +299,7 @@ function handleCloudFavorite(request: any, sendResponse: MessageSender): boolean return false; } const isFavorite = action === "favorite"; - fetch(`https://betterseqta.org/api/themes/${themeId}/favorite`, { + fetch(`${apiBase()}/api/themes/${themeId}/favorite`, { method: isFavorite ? "POST" : "DELETE", headers: { Authorization: `Bearer ${token}` }, }) @@ -311,8 +326,19 @@ function isSeqtaOrigin(origin: string): boolean { } } +function handleSetDevApiBase(request: any): boolean { + const url = typeof request?.url === "string" ? request.url.trim() : null; + if (url && /^https?:\/\//.test(url)) { + DEV_API_BASE = url.replace(/\/$/, ""); + } else { + DEV_API_BASE = null; + } + return false; +} + const MESSAGE_HANDLERS: Record = { reloadTabs: () => reloadSeqtaPages(), + setDevApiBase: handleSetDevApiBase, extensionPages: (req) => { browser.tabs.query({}).then((tabs) => { for (const tab of tabs) { @@ -470,6 +496,7 @@ function getDefaultValues(): SettingsState { adaptiveThemeColour: false, adaptiveThemeGradient: false, adaptiveThemeColourTransition: true, + themeOfTheMonthDisabled: false, autoCloudSettingsSync: true, }; } diff --git a/src/css/injected.scss b/src/css/injected.scss index 9c5fe51c..57f7fc64 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -3726,6 +3726,150 @@ div.day-empty { color: var(--text-primary); } +.themeOfTheMonthCard { + position: fixed; + right: max(18px, env(safe-area-inset-right)); + bottom: max(18px, env(safe-area-inset-bottom)); + z-index: 48; + width: min(360px, calc(100vw - 36px)); + overflow: visible; + border: 1px solid color-mix(in srgb, var(--text-primary) 12%, transparent); + border-radius: 20px; + background: var(--background-primary); + color: var(--text-primary); + box-shadow: 0 22px 70px rgba(0, 0, 0, 0.35); + animation: themeOfTheMonthCardIn 0.24s ease-out; +} +.themeOfTheMonthCard::before { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + overflow: hidden; + border-radius: inherit; + background: inherit; +} +.themeOfTheMonthCardClosing { + pointer-events: none; + animation: themeOfTheMonthCardOut 0.18s ease-in forwards; +} +.themeOfTheMonthCardClose { + position: absolute !important; + top: 4px !important; + right: 4px !important; + z-index: 2; + width: 32px; + height: 32px; + border: 1px solid rgba(255, 255, 255, 0.22); + border-radius: 16px !important; + background: rgba(0, 0, 0, 0.42); + color: white; + cursor: pointer; + font-size: 1.35rem; + line-height: 1; +} +.themeOfTheMonthCardImage { + display: block; + width: 100%; + height: 150px; + margin: 0; + border-radius: 20px 20px 0 0; + object-fit: cover; +} +.themeOfTheMonthCardBody { + padding: 14px 16px 16px; +} +.themeOfTheMonthCardEyebrow { + margin: 0 0 6px; + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + color: color-mix(in srgb, var(--better-pri, #6366f1) 82%, var(--text-primary) 18%); +} +.themeOfTheMonthCard h2 { + margin: 0; + font-size: 1.2rem; + line-height: 1.2; +} +.themeOfTheMonthCardDescription { + display: -webkit-box; + margin: 8px 0 14px; + overflow: hidden; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + font-size: 0.92rem; + line-height: 1.45; + color: color-mix(in srgb, var(--text-primary) 78%, transparent); +} +.themeOfTheMonthCardActions { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 8px; +} +.themeOfTheMonthCardPrimary, +.themeOfTheMonthCardSecondary { + appearance: none; + border: none; + cursor: pointer; + border-radius: 9999px; + padding: 0.58rem 0.9rem; + font-size: 0.86rem; + font-weight: 700; + transition: transform 0.15s ease, filter 0.15s ease, background 0.15s ease; +} +.themeOfTheMonthCardPrimary { + background: var(--better-pri, #6366f1); + color: white; +} +.themeOfTheMonthCardSecondary { + background: color-mix(in srgb, var(--text-primary) 10%, transparent); + color: var(--text-primary); +} +.themeOfTheMonthCardPrimary:hover, +.themeOfTheMonthCardSecondary:hover { + filter: brightness(1.08); + transform: translateY(-1px); +} +.themeOfTheMonthCardPrimary:active, +.themeOfTheMonthCardSecondary:active { + transform: translateY(0); +} +@keyframes themeOfTheMonthCardIn { + from { + opacity: 0; + transform: translateY(18px) scale(0.98); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} +@keyframes themeOfTheMonthCardOut { + to { + opacity: 0; + transform: translateY(12px) scale(0.98); + } +} +@media (max-width: 900px) { + .themeOfTheMonthCard { + z-index: 2147483645; + } +} + +.bsplus-theme-highlight { + animation: bsplusThemeHighlightPulse 1.4s ease-in-out 2; +} +@keyframes bsplusThemeHighlightPulse { + 0%, 100% { + box-shadow: 0 0 0 0 color-mix(in srgb, var(--better-pri, #6366f1) 0%, transparent); + } + 50% { + box-shadow: 0 0 0 6px color-mix(in srgb, var(--better-pri, #6366f1) 60%, transparent); + } +} + .popup-media-fullscreenable { cursor: pointer; transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out; @@ -4375,38 +4519,63 @@ h2.home-subtitle { .bsplus-toast { position: fixed; - bottom: 24px; - right: 24px; + right: max(18px, env(safe-area-inset-right)); + bottom: max(18px, env(safe-area-inset-bottom)); z-index: 10000; - display: flex; - align-items: flex-start; - gap: 12px; - max-width: 380px; - padding: 16px 18px; - border-radius: 12px; - background: var(--background-secondary, #fff); + width: min(360px, calc(100vw - 36px)); + padding: 14px 16px 16px; + border: 1px solid color-mix(in srgb, var(--text-primary) 12%, transparent); + border-radius: 20px; + background: var(--background-primary, #fff); color: var(--text-primary, #1a1a1a); - box-shadow: 0 8px 30px rgba(0, 0, 0, 0.18); + box-shadow: 0 22px 70px rgba(0, 0, 0, 0.35); font-size: 0.9rem; - line-height: 1.5; + line-height: 1.45; } -.bsplus-toast-content p { - margin: 6px 0 0; - opacity: 0.8; - font-size: 0.85rem; +.bsplus-toast-eyebrow { + margin: 0 0 6px !important; + font-size: 0.72rem !important; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + color: color-mix(in srgb, #ea580c 82%, var(--text-primary) 18%); + opacity: 1 !important; +} +.dark .bsplus-toast-eyebrow { + color: color-mix(in srgb, #fb923c 82%, var(--text-primary) 18%); +} +.bsplus-toast-content strong { + display: block; + padding-right: 34px; + font-size: 1.2rem; + line-height: 1.2; +} +.bsplus-toast-content p:not(.bsplus-toast-eyebrow) { + display: -webkit-box; + margin: 8px 0 0; + overflow: hidden; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + color: color-mix(in srgb, var(--text-primary) 78%, transparent); + font-size: 0.92rem; + line-height: 1.45; } .bsplus-toast-close { - flex-shrink: 0; - background: none; - border: none; - color: var(--text-primary, #1a1a1a); - font-size: 1.3rem; + position: absolute !important; + top: 4px !important; + right: 4px !important; + z-index: 2; + width: 32px; + height: 32px; + border: 1px solid rgba(255, 255, 255, 0.22); + border-radius: 16px !important; + background: rgba(0, 0, 0, 0.42); + color: white; cursor: pointer; - padding: 0 2px; + font-size: 1.35rem; line-height: 1; - opacity: 0.5; - transition: opacity 0.15s; + transition: filter 0.15s ease; } .bsplus-toast-close:hover { - opacity: 1; + filter: brightness(1.08); } diff --git a/src/interface/pages/settings/general.svelte b/src/interface/pages/settings/general.svelte index 2928fffa..7bc7ecc9 100644 --- a/src/interface/pages/settings/general.svelte +++ b/src/interface/pages/settings/general.svelte @@ -15,10 +15,37 @@ import CloudHeader from "@/interface/components/store/CloudHeader.svelte" import { cloudAuth } from "@/seqta/utils/CloudAuth" import { showPrivacyNotification } from "@/seqta/utils/Openers/OpenPrivacyNotification" + import { showThemeOfTheMonthPopupNow } from "@/seqta/utils/Openers/OpenThemeOfTheMonthPopup" import { closeExtensionPopup } from "@/seqta/utils/Closers/closeExtensionPopup" import { getSnapshotForUpload } from "@/seqta/utils/cloudSettingsSync" + import { getStoredOverride, setApiBase } from "@/seqta/utils/DevApiBase" + + let devApiBaseInput = $state(getStoredOverride() ?? "") + let devApiBaseActive = $state(getStoredOverride()) + + function applyDevApiBase() { + const trimmed = devApiBaseInput.trim() + if (trimmed === "") { + setApiBase(null) + devApiBaseActive = null + return + } + if (!/^https?:\/\//.test(trimmed)) { + alert("Please enter a full URL starting with http:// or https://") + return + } + setApiBase(trimmed) + devApiBaseActive = trimmed.replace(/\/$/, "") + } + + function clearDevApiBase() { + devApiBaseInput = "" + setApiBase(null) + devApiBaseActive = null + } import { getAllPluginSettings } from "@/plugins" + import { isSeqtaEngageExperience } from "@/seqta/utils/isSeqtaEngage" import type { BooleanSetting, StringSetting, NumberSetting, SelectSetting, ButtonSetting, HotkeySetting, ComponentSetting } from "@/plugins/core/types" // Union type representing all possible settings @@ -53,7 +80,9 @@ settings: Record; } - const pluginSettings = getAllPluginSettings() as Plugin[]; + const pluginSettings = getAllPluginSettings().filter( + (plugin) => !(isSeqtaEngageExperience() && plugin.pluginId === "global-search"), + ) as Plugin[]; const pluginSettingsValues = $state>>({}); let cloudState = $state(cloudAuth.state); @@ -483,6 +512,22 @@ /> +
+
+

Show Theme of the Month

+

Fetch and show the current month's popup now (ignores dismissed state)

+
+
+
+

Export cloud settings JSON

@@ -492,6 +537,31 @@
+
+
+
+

API Base URL (session only)

+

Override the content API host for this browser session. Cleared on restart. Affects themes, theme of the month, and other server-driven content.

+ {#if devApiBaseActive} +

+ Override active: {devApiBaseActive} +

+ {/if} +
+
+
+ +
+
{/if} diff --git a/src/interface/pages/store.svelte b/src/interface/pages/store.svelte index 92bcef14..b1e6649c 100644 --- a/src/interface/pages/store.svelte +++ b/src/interface/pages/store.svelte @@ -18,6 +18,7 @@ import Backgrounds from '../components/store/Backgrounds.svelte' import { cloudAuth } from '@/seqta/utils/CloudAuth' import SignInToFavoriteModal from '../components/SignInToFavoriteModal.svelte' + import { consumePendingHighlightThemeId } from '@/seqta/utils/openThemeStoreWithHighlight' const themeManager = ThemeManager.getInstance(); let cloudLoggedIn = $state(cloudAuth.state.isLoggedIn); @@ -122,13 +123,39 @@ } }; + function focusThemeById(themeId: string) { + const match = themes.find((t) => t.id === themeId) + ?? themes.find((t) => t.flavours?.some((f) => f.id === themeId)); + if (match) { + activeTab = 'themes'; + searchTerm = ''; + displayTheme = match; + } + } + + function onHighlightThemeEvent(e: Event) { + const detail = (e as CustomEvent).detail; + if (detail?.themeId && typeof detail.themeId === 'string') { + focusThemeById(detail.themeId); + } + } + // On mount onMount(async () => { + window.addEventListener('bsplus:highlight-theme', onHighlightThemeEvent); + await fetchThemes(); await fetchCurrentThemes(); darkMode = (await browser.storage.local.get('DarkMode')).DarkMode === 'true'; darkMode = $settingsState.DarkMode; + + const pending = consumePendingHighlightThemeId(); + if (pending) focusThemeById(pending); + + return () => { + window.removeEventListener('bsplus:highlight-theme', onHighlightThemeEvent); + }; }); // Filter themes (list is already featured-first, then newest; filter preserves order) diff --git a/src/plugins/built-in/assessmentsAverage/engage.ts b/src/plugins/built-in/assessmentsAverage/engage.ts new file mode 100644 index 00000000..1010e74a --- /dev/null +++ b/src/plugins/built-in/assessmentsAverage/engage.ts @@ -0,0 +1,46 @@ +import { getEngageAssessmentStudentId } from "@/seqta/utils/engageAssessmentStudent"; + +function randomEngagePdfFileName(): string { + const token = Math.random().toString(36).slice(2, 10); + return `${token}.pdf`; +} + +export async function requestEngageAssessmentPdf(params: { + assessmentID: string | number; + metaclassID: string | number; + studentID: string | number; +}): Promise { + const fileName = randomEngagePdfFileName(); + const cacheBuster = Math.random().toString(36).slice(2, 10); + + const response = await fetch( + `${location.origin}/seqta/parent/print/assessment?${cacheBuster}`, + { + method: "POST", + headers: { "Content-Type": "application/json; charset=utf-8" }, + credentials: "include", + body: JSON.stringify({ + id: params.assessmentID, + metaclass: params.metaclassID, + student: Number(params.studentID), + fileName, + }), + }, + ); + + if (!response.ok) { + throw new Error( + `Failed to generate PDF: ${response.status} ${response.statusText}`, + ); + } + + const data = (await response.json()) as { + payload?: { file?: string }; + }; + + return data.payload?.file ?? fileName; +} + +export function getEngageAssessmentReportUrl(fileName: string): string { + return `${location.origin}/seqta/parent/report/get?file=${encodeURIComponent(fileName)}`; +} diff --git a/src/plugins/built-in/assessmentsAverage/index.ts b/src/plugins/built-in/assessmentsAverage/index.ts index ed7140f1..b3438ea6 100644 --- a/src/plugins/built-in/assessmentsAverage/index.ts +++ b/src/plugins/built-in/assessmentsAverage/index.ts @@ -7,11 +7,11 @@ import { import { type Plugin } from "@/plugins/core/types"; import stringToHTML from "@/seqta/utils/stringToHTML"; import { waitForElm } from "@/seqta/utils/waitForElm"; -import ReactFiber from "@/seqta/utils/ReactFiber.ts"; import { clearStuck, getClassByPattern, initStorage, + injectWeightingsTab, letterToNumber, parseAssessments, processAssessments, @@ -20,6 +20,7 @@ import { interface weightingsStorage { weightings: Record; assessments: Record; + weightingOverrides: Record; } const settings = defineSettings({ @@ -37,6 +38,8 @@ class AssessmentsAveragePluginClass extends BasePlugin { const instance = new AssessmentsAveragePluginClass(); +let overrideListenerController: AbortController | null = null; + const assessmentsAveragePlugin: Plugin = { id: "assessments-average", name: "Assessment Averages", @@ -58,143 +61,149 @@ const assessmentsAveragePlugin: Plugin = { ); await parseAssessments(api); - - const sampleAssessmentItem = document.querySelector( - "[class*='AssessmentItem__AssessmentItem___']", + await renderSubjectAverage(api); + overrideListenerController?.abort(); + overrideListenerController = new AbortController(); + document.addEventListener( + "betterseqta:overrideChanged", + () => renderSubjectAverage(api), + { signal: overrideListenerController.signal }, ); - if (!sampleAssessmentItem) return; - - const assessmentItemClass = - Array.from(sampleAssessmentItem.classList).find((c) => - c.startsWith("AssessmentItem__AssessmentItem___"), - ) || ""; - - const metaContainerClass = getClassByPattern( - sampleAssessmentItem, - "AssessmentItem__metaContainer___", - ); - const metaClass = getClassByPattern( - sampleAssessmentItem, - "AssessmentItem__meta___", - ); - const simpleResultClass = getClassByPattern( - sampleAssessmentItem, - "AssessmentItem__simpleResult___", - ); - const titleClass = getClassByPattern( - sampleAssessmentItem, - "AssessmentItem__title___", - ); - - const thermoscoreElement = document.querySelector( - "[class*='Thermoscore__Thermoscore___']", - ); - if (!thermoscoreElement) return; - - const thermoscoreClass = - Array.from(thermoscoreElement.classList).find((c) => - c.startsWith("Thermoscore__Thermoscore___"), - ) || ""; - const fillClass = getClassByPattern( - thermoscoreElement, - "Thermoscore__fill___", - ); - const textClass = getClassByPattern( - thermoscoreElement, - "Thermoscore__text___", - ); - - const assessmentsList = document.querySelector( - "#main > .assessmentsWrapper .assessments [class*='AssessmentList__items___']", - ); - if (!assessmentsList) return; - - const state = await ReactFiber.find( - "[class*='AssessmentList__items___']", - ).getState(); - const marks = state["marks"]; - if (!marks || !marks.length) return; - - const assessmentItems = Array.from( - assessmentsList.querySelectorAll( - `[class*='AssessmentItem__AssessmentItem___']`, - ), - ).filter( - (item) => - !item - .querySelector(`[class*='AssessmentItem__title___']`) - ?.textContent?.includes("Subject Average"), - ); - - const { weightedTotal, totalWeight, hasInaccurateWeighting, count } = - await processAssessments(api, assessmentItems); - - if (!count || totalWeight === 0) return; - - const avg = weightedTotal / totalWeight; - const rounded = Math.ceil(avg / 5) * 5; - const numberToLetter = Object.entries(letterToNumber).reduce( - (acc, [k, v]) => { - acc[v] = k; - return acc; - }, - {} as Record, - ); - - const letterAvg = numberToLetter[rounded] ?? "N/A"; - const display = api.settings.lettergrade - ? letterAvg - : `${avg.toFixed(2)}%`; - - const existing = assessmentsList.querySelector( - `[class*='AssessmentItem__title___']`, - ); - if (existing?.textContent === "Subject Average") return; - - let warningHTML = ""; - if (hasInaccurateWeighting) { - warningHTML = /* html */ ` -
- ⚠ Some weightings unavailable -
- `; - } - - assessmentsList.insertBefore( - stringToHTML(/* html */ ` -
-
-
-
-
Subject Average
- ${warningHTML} -
-
-
-
-
-
${display}
-
-
-
- `).firstChild!, - assessmentsList.firstChild, - ); - - applySubjectColourToOverallResult(); - - const observer = new MutationObserver(() => { - applySubjectColourToOverallResult(); - }); const wrapper = document.querySelector(".assessmentsWrapper"); if (wrapper) { + const observer = new MutationObserver(() => { + applySubjectColourToOverallResult(); + }); observer.observe(wrapper, { childList: true, subtree: true }); setTimeout(() => observer.disconnect(), 10000); } }); + api.seqta.onMount("[class*='SelectedAssessment__']", () => { + injectWeightingsTab(api); + }); }, }; +let renderInFlight = false; +async function renderSubjectAverage(api: any) { + if (renderInFlight) return; + renderInFlight = true; + + try { + const assessmentsList = document.querySelector( + "#main > .assessmentsWrapper .assessments [class*='AssessmentList__items___']", + ); + if (!assessmentsList) return; + + // Remove existing subject average before re-rendering + Array.from( + assessmentsList.querySelectorAll(`[class*='AssessmentItem__title___']`), + ) + .find((el) => el.textContent === "Subject Average") + ?.closest("[class*='AssessmentItem__AssessmentItem___']") + ?.remove(); + + const sampleAssessmentItem = document.querySelector( + "[class*='AssessmentItem__AssessmentItem___']", + ); + if (!sampleAssessmentItem) return; + const assessmentItemClass = + Array.from(sampleAssessmentItem.classList).find((c) => + c.startsWith("AssessmentItem__AssessmentItem___"), + ) || ""; + const metaContainerClass = getClassByPattern( + sampleAssessmentItem, + "AssessmentItem__metaContainer___", + ); + const metaClass = getClassByPattern( + sampleAssessmentItem, + "AssessmentItem__meta___", + ); + const simpleResultClass = getClassByPattern( + sampleAssessmentItem, + "AssessmentItem__simpleResult___", + ); + const titleClass = getClassByPattern( + sampleAssessmentItem, + "AssessmentItem__title___", + ); + + const assessmentItems = Array.from( + assessmentsList.querySelectorAll( + `[class*='AssessmentItem__AssessmentItem___']`, + ), + ).filter( + (item) => + !item + .querySelector(`[class*='AssessmentItem__title___']`) + ?.textContent?.includes("Subject Average"), + ); + + const { weightedTotal, totalWeight, hasInaccurateWeighting, count } = + await processAssessments(api, assessmentItems); + if (!count || totalWeight === 0) return; + + const thermoscoreElement = document.querySelector( + "[class*='Thermoscore__Thermoscore___']", + ); + if (!thermoscoreElement) return; + const thermoscoreClass = + Array.from(thermoscoreElement.classList).find((c) => + c.startsWith("Thermoscore__Thermoscore___"), + ) || ""; + const fillClass = getClassByPattern( + thermoscoreElement, + "Thermoscore__fill___", + ); + const textClass = getClassByPattern( + thermoscoreElement, + "Thermoscore__text___", + ); + + const avg = weightedTotal / totalWeight; + const rounded = Math.ceil(avg / 5) * 5; + const numberToLetter = Object.entries(letterToNumber).reduce( + (acc, [k, v]) => { + acc[v] = k; + return acc; + }, + {} as Record, + ); + const letterAvg = numberToLetter[rounded] ?? "N/A"; + const display = api.settings.lettergrade ? letterAvg : `${avg.toFixed(2)}%`; + let warningHTML = ""; + if (hasInaccurateWeighting) { + warningHTML = /* html */ ` +
+ ⚠ Some weightings unavailable +
+ `; + } + assessmentsList.insertBefore( + stringToHTML(/* html */ ` +
+
+
+
+
Subject Average
+ ${warningHTML} +
+
+
+
+
+
${display}
+
+
+
+ `).firstChild!, + assessmentsList.firstChild, + ); + applySubjectColourToOverallResult(); + } finally { + renderInFlight = false; + } +} function applySubjectColourToOverallResult() { const selectedAssessmentItem = document.querySelector( "[class*='AssessmentItem__AssessmentItem___'][class*='selected___']", diff --git a/src/plugins/built-in/assessmentsAverage/utils.ts b/src/plugins/built-in/assessmentsAverage/utils.ts index d833cc98..4bdc044c 100644 --- a/src/plugins/built-in/assessmentsAverage/utils.ts +++ b/src/plugins/built-in/assessmentsAverage/utils.ts @@ -1,5 +1,11 @@ import { getUserInfo } from "@/seqta/ui/AddBetterSEQTAElements.ts"; import ReactFiber from "@/seqta/utils/ReactFiber.ts"; +import { isSeqtaEngageExperience } from "@/seqta/utils/isSeqtaEngage"; +import { getEngageAssessmentStudentId } from "@/seqta/utils/engageAssessmentStudent"; +import { + getEngageAssessmentReportUrl, + requestEngageAssessmentPdf, +} from "./engage.ts"; import { ensurePdfjsWorker, getPdfjsPageContextUrls, @@ -17,6 +23,9 @@ export async function initStorage(api: any) { if (!api.storage.assessments) { api.storage.assessments = {}; } + if (!api.storage.weightingOverrides) { + api.storage.weightingOverrides = {}; + } } export function clearStuck(api: any) { @@ -79,52 +88,84 @@ function createWeightLabel( assessmentItem: Element, weighting: string | undefined, ) { - const statsContainer = assessmentItem.querySelector( - `[class*='AssessmentItem__stats___']`, - ) as HTMLElement; + let statsContainer = assessmentItem.querySelector( + `[class*='AssessmentItem__stats___'], .betterseqta-stats-container`, + ) as HTMLElement | null; - if ( - !statsContainer || - statsContainer.querySelector(".betterseqta-weight-label") - ) - return; + if (!statsContainer) { + const statsClass = getClassByPattern(document, "AssessmentItem__stats___"); + statsContainer = document.createElement("div"); + statsContainer.className = statsClass; + statsContainer.classList.add("betterseqta-stats-container"); + const thermoscore = assessmentItem.querySelector(`[class*='Thermoscore__Thermoscore___']`); + if (thermoscore) { + thermoscore.insertAdjacentElement("afterend", statsContainer); + } else { + assessmentItem.appendChild(statsContainer); + } + } - const label = statsContainer.querySelector( - `[class*='Label__Label___']`, - ) as HTMLElement; - - if (!label) return; - - const weightLabel = label.cloneNode(true) as HTMLElement; - weightLabel.classList.add("betterseqta-weight-label"); - - const innerTextDiv = weightLabel.querySelector( - `[class*='Label__innerText___']`, + const hasNativeLabel = !!statsContainer.querySelector( + `[class*='Label__Label___']:not(.betterseqta-weight-label)`, ); + statsContainer.style.justifyContent = hasNativeLabel + ? "space-between" + : "flex-end"; + + const displayText = + weighting && weighting !== "processing" && weighting !== "N/A" + ? `${Number(weighting) % 1 === 0 ? Number(weighting) : weighting}%` + : "N/A"; + + const existingLabel = statsContainer.querySelector( + ".betterseqta-weight-label", + ) as HTMLElement | null; + + if (existingLabel) { + const textNodes = Array.from(existingLabel.childNodes).filter( + (node) => node.nodeType === Node.TEXT_NODE, + ); + if (textNodes.length) textNodes[0].textContent = displayText; + return; + } + + statsContainer.style.display = "flex"; + statsContainer.style.alignItems = "center"; + statsContainer.style.width = "100%"; + + // Try to clone an existing label from the stats container first, + // fall back to building from scratch if none exists + const existingNativeLabel = statsContainer.querySelector( + `[class*='Label__Label___']`, + ) as HTMLElement | null; + + const weightLabel = existingNativeLabel + ? (existingNativeLabel.cloneNode(true) as HTMLElement) + : (() => { + const labelClass = getClassByPattern(document, "Label__Label___"); + const innerTextClass = getClassByPattern(document, "Label__innerText___"); + const el = document.createElement("label"); + el.className = labelClass; + el.innerHTML = `
Weight
`; + return el; + })(); + + weightLabel.classList.add("betterseqta-weight-label"); + weightLabel.style.flex = "none"; + weightLabel.style.width = "fit-content"; + + const innerTextDiv = weightLabel.querySelector(`[class*='Label__innerText___']`); if (innerTextDiv) innerTextDiv.textContent = "Weight"; const textNodes = Array.from(weightLabel.childNodes).filter( (node) => node.nodeType === Node.TEXT_NODE, ); - if (textNodes.length) { - textNodes[0].textContent = - weighting && weighting !== "processing" - ? `${Number(weighting) % 1 === 0 ? Number(weighting) : weighting}%` - : "N/A"; + textNodes[0].textContent = displayText; + } else { + weightLabel.appendChild(document.createTextNode(displayText)); } - // Stack weight under Max/native stats — absolute right:0 overlapped the max column (#414). - statsContainer.style.display = "flex"; - statsContainer.style.flexDirection = "column"; - statsContainer.style.alignItems = "flex-end"; - statsContainer.style.gap = "2px"; - statsContainer.style.justifyContent = "center"; - - weightLabel.style.position = "relative"; - weightLabel.style.inset = "unset"; - weightLabel.style.transform = "none"; - statsContainer.appendChild(weightLabel); } @@ -228,7 +269,8 @@ async function fetchPDFAsArrayBuffer(url: string): Promise { export async function extractPDFText(url: string): Promise { try { if (isFirefox) { - const { lib: pdfLibUrl, worker: pdfWorkerUrl } = getPdfjsPageContextUrls(); + const { lib: pdfLibUrl, worker: pdfWorkerUrl } = + getPdfjsPageContextUrls(); const escJsSingleQuoted = (s: string) => s.replace(/\\/g, "\\\\").replace(/'/g, "\\'"); const pdfLibInj = escJsSingleQuoted(pdfLibUrl); @@ -428,8 +470,6 @@ export async function extractPDFText(url: string): Promise { async function handleWeightings(mark: any, api: any) { const assessmentID = mark.id; const metaclassID = mark.metaclassID; - const userInfo = await getUserInfo(); - const userID = userInfo.id; const title = mark.title; if ( @@ -450,35 +490,55 @@ async function handleWeightings(mark: any, api: any) { }; try { - const filename = - "BetterSEQTA-" + - String(Math.floor(Math.random() * 1e15)).padStart(15, "0"); + let pdfUrl: string; - const printResponse = await fetch( - `${location.origin}/seqta/student/print/assessment`, - { - method: "POST", - headers: { "Content-Type": "application/json; charset=utf-8" }, - credentials: "include", - body: JSON.stringify({ - fileName: filename, - id: assessmentID, - metaclass: metaclassID, - student: userID, - }), - }, - ); + if (isSeqtaEngageExperience()) { + const studentID = getEngageAssessmentStudentId(); + if (!studentID) { + throw new Error("Could not resolve Engage student ID from URL or storage"); + } - if (!printResponse.ok) { - throw new Error( - `Failed to generate PDF: ${printResponse.status} ${printResponse.statusText}`, + const reportFile = await requestEngageAssessmentPdf({ + assessmentID, + metaclassID, + studentID, + }); + await new Promise((resolve) => setTimeout(resolve, 1000)); + pdfUrl = getEngageAssessmentReportUrl(reportFile); + } else { + const userInfo = await getUserInfo(); + const userID = userInfo.id; + + const filename = + "BetterSEQTA-" + + String(Math.floor(Math.random() * 1e15)).padStart(15, "0"); + + const printResponse = await fetch( + `${location.origin}/seqta/student/print/assessment`, + { + method: "POST", + headers: { "Content-Type": "application/json; charset=utf-8" }, + credentials: "include", + body: JSON.stringify({ + fileName: filename, + id: assessmentID, + metaclass: metaclassID, + student: userID, + }), + }, ); + + if (!printResponse.ok) { + throw new Error( + `Failed to generate PDF: ${printResponse.status} ${printResponse.statusText}`, + ); + } + + await new Promise((resolve) => setTimeout(resolve, 1000)); + + pdfUrl = `${location.origin}/seqta/student/report/get?file=${filename}`; } - await new Promise((resolve) => setTimeout(resolve, 1000)); - - const pdfUrl = `${location.origin}/seqta/student/report/get?file=${filename}`; - if (pdfUrl.startsWith("blob:")) { throw new Error(`Cannot fetch blob URL from extension: ${pdfUrl}`); } @@ -519,7 +579,11 @@ export async function parseAssessments(api: any) { "[class*='AssessmentList__items___']", ).getState(); - const marks = state["marks"]; + const marks = [ + ...(state["marks"] ?? []), + ...(state["upcoming"] ?? []), + ...(state["pending"] ?? []), + ]; if (!marks) return; await Promise.all(marks.map((mark: any) => handleWeightings(mark, api))); @@ -532,15 +596,6 @@ export async function processAssessments(api: any, assessmentItems: Element[]) { let count = 0; for (const assessmentItem of assessmentItems) { - const gradeElement = assessmentItem.querySelector( - `[class*='Thermoscore__text___']`, - ); - - if (!gradeElement) continue; - - const grade = parseGrade(gradeElement.textContent || ""); - if (grade <= 0) continue; - const titleEl = assessmentItem.querySelector( `[class*='AssessmentItem__title___']`, ); @@ -550,12 +605,23 @@ export async function processAssessments(api: any, assessmentItems: Element[]) { if (!title) continue; const assessmentID = api.storage.assessments?.[title]; - const weighting = assessmentID + const autoWeighting = assessmentID ? api.storage.weightings?.[assessmentID] : undefined; + const override = assessmentID + ? api.storage.weightingOverrides?.[assessmentID] + : undefined; + const weighting = override ?? autoWeighting; createWeightLabel(assessmentItem, weighting); + const gradeElement = assessmentItem.querySelector( + `[class*='Thermoscore__text___']`, + ); + if (!gradeElement) continue; + const grade = parseGrade(gradeElement.textContent || ""); + if (grade <= 0) continue; + if ( weighting === null || weighting === undefined || @@ -563,8 +629,7 @@ export async function processAssessments(api: any, assessmentItems: Element[]) { weighting === "processing" ) { hasInaccurateWeighting = true; - weightedTotal += grade; - totalWeight += 1; + continue } else { const weight = parseFloat(weighting); @@ -587,3 +652,271 @@ export async function processAssessments(api: any, assessmentItems: Element[]) { count, }; } + +function resolveTabSetClasses(): Record { + const patterns = [ + "TabSet__tabsheet___", + "TabSet__hidden___", + "TabSet__selected___", + "TabSet__disappearToLeft___", + "TabSet__disappearToRight___", + "TabSet__appearFromRight___", + "TabSet__appearFromLeft___", + ]; + + const resolved: Record = {}; + + // First pass: scan live DOM elements (fast, covers currently-applied classes) + const allClasses = Array.from( + document.querySelectorAll('[class*="TabSet__"]'), + ).flatMap((el) => Array.from(el.classList)); + + for (const pattern of patterns) { + const found = allClasses.find((c) => c.startsWith(pattern)); + if (found) resolved[pattern] = found; + } + + // Second pass: scan stylesheets for any classes not yet in the DOM + // (e.g. animation classes that haven't been applied yet) + const missing = patterns.filter((p) => !resolved[p]); + if (missing.length > 0) { + try { + for (const sheet of Array.from(document.styleSheets)) { + if (missing.every((p) => resolved[p])) break; + try { + for (const rule of Array.from(sheet.cssRules ?? [])) { + if (!(rule instanceof CSSStyleRule)) continue; + const selectorClasses = + rule.selectorText.match(/\.([\w-]+)/g) ?? []; + for (const pattern of missing) { + if (!resolved[pattern]) { + const match = selectorClasses.find((c) => + c.slice(1).startsWith(pattern), + ); + if (match) resolved[pattern] = match.slice(1); + } + } + } + } catch { + // Cross-origin stylesheet + } + } + } catch {} + } + + // Fallback: use the base pattern as-is so the function doesn't crash, + // though styles won't apply if the hash is truly unknown. + for (const pattern of patterns) { + if (!resolved[pattern]) resolved[pattern] = pattern; + } + + return resolved; +} + +function buildWeightingsTabContent(api: any, sheet: HTMLElement) { + const titleEl = document.querySelector( + "[class*='AssessmentItem__AssessmentItem___'][class*='selected___'] [class*='AssessmentItem__title___']", + ); + const title = titleEl?.textContent?.trim(); + const assessmentID = title ? api.storage.assessments?.[title] : undefined; + + const rawWeight = assessmentID + ? api.storage.weightings?.[assessmentID] + : undefined; + + const weightingUnavailable = rawWeight === "N/A"; + + const autoWeight = + rawWeight && rawWeight !== "processing" && rawWeight !== "N/A" + ? rawWeight + : undefined; + + const override = assessmentID + ? api.storage.weightingOverrides?.[assessmentID] + : undefined; + + const statusNote = !assessmentID + ? "" + : rawWeight === "processing" + ? "Weighting is still being detected." + : weightingUnavailable + ? "No weighting was found in the marksheet. Set one manually." + : "Overrides the auto-detected value."; + + sheet.innerHTML = ` + +
+

Weighting Override

+

+ Set the weighting for this assessment. + ${statusNote} +

+
+ + ${autoWeight != null ? `${autoWeight}%` : "none"} +
+
+ + +
+
+ +
+ ${!assessmentID ? `

Assessment not yet indexed — try refreshing.

` : ""} +
+ `; + + if (!assessmentID) return; + + const input = sheet.querySelector( + "#betterseqta-weight-override", + ) as HTMLInputElement; + const statusEl = sheet.querySelector( + ".betterseqta-save-status", + ) as HTMLElement; + + const save = () => { + const raw = input.value.trim(); + if (raw === "") { + const { [assessmentID]: _, ...rest } = api.storage.weightingOverrides; + api.storage.weightingOverrides = rest; + } else { + const val = parseFloat(raw); + if (isNaN(val) || val < 0) { + input.style.borderColor = "rgba(255,80,80,0.6)"; + statusEl.textContent = "Invalid. Must be 0 or greater"; + statusEl.style.color = "rgba(255,80,80,0.8)"; + return; + } + input.style.borderColor = "rgba(128,128,128,0.3)"; + api.storage.weightingOverrides = { + ...api.storage.weightingOverrides, + [assessmentID]: String(val), + }; + } + statusEl.textContent = "Saved"; + statusEl.style.color = ""; + setTimeout(() => (statusEl.textContent = ""), 2000); + document.dispatchEvent(new CustomEvent("betterseqta:overrideChanged")); + }; + + input.addEventListener("blur", save); + input.addEventListener("keydown", (e) => { + if (e.key === "Enter") { + input.blur(); + save(); + } + }); + input.addEventListener("input", () => { + input.style.borderColor = "rgba(128,128,128,0.3)"; + if (statusEl.textContent === "Invalid. Must be 0 or greater.") + statusEl.textContent = ""; + }); +} + +export function injectWeightingsTab(api: any) { + const tabList = document.querySelector( + '[class*="TabSet__tabs___"]', + ) as HTMLElement; + const container = document.querySelector( + '[class*="TabSet__tabContainer___"]', + ) as HTMLElement; + if (!tabList || !container) return; + if (tabList.querySelector(".betterseqta-weightings-tab")) return; + + const cls = resolveTabSetClasses(); + + const prefix = (tabList.querySelector("li") as HTMLElement).id.replace( + /-tab-\d+$/, + "", + ); + const newIndex = tabList.querySelectorAll("li").length; + + const newTab = document.createElement("li"); + newTab.id = `${prefix}-tab-${newIndex}`; + newTab.className = ""; + newTab.setAttribute("aria-selected", "false"); + newTab.setAttribute("aria-controls", `${prefix}-tabsheet-${newIndex}`); + newTab.classList.add("betterseqta-weightings-tab"); + newTab.textContent = "Weightings"; + tabList.appendChild(newTab); + + const newSheet = document.createElement("div"); + newSheet.id = `${prefix}-tabsheet-${newIndex}`; + newSheet.setAttribute("aria-labelledby", `${prefix}-tab-${newIndex}`); + newSheet.className = [ + cls["TabSet__tabsheet___"], + cls["TabSet__hidden___"], + cls["TabSet__disappearToRight___"], + ].join(" "); + container.appendChild(newSheet); + + let populated = false; + newTab.addEventListener("click", () => { + if (!populated) { + buildWeightingsTabContent(api, newSheet); + populated = true; + } + }); + + const allTabs = Array.from(tabList.querySelectorAll("li")); + const allSheets = Array.from( + container.querySelectorAll('[class*="tabsheet"]'), + ); + + allTabs.forEach((tab, i) => { + tab.addEventListener("click", () => { + const currentIndex = allTabs.findIndex((t) => + t.className.includes("TabSet__selected___"), + ); + if (i === currentIndex) return; + const goingRight = i > currentIndex; + + allTabs.forEach((t) => { + t.className = ""; + t.setAttribute("aria-selected", "false"); + }); + + allSheets[currentIndex].className = [ + cls["TabSet__tabsheet___"], + cls["TabSet__hidden___"], + goingRight + ? cls["TabSet__disappearToLeft___"] + : cls["TabSet__disappearToRight___"], + ].join(" "); + + allSheets[i].className = [ + cls["TabSet__tabsheet___"], + cls["TabSet__selected___"], + goingRight + ? cls["TabSet__appearFromRight___"] + : cls["TabSet__appearFromLeft___"], + ].join(" "); + + tab.className = cls["TabSet__selected___"]; + tab.setAttribute("aria-selected", "true"); + }); + }); +} diff --git a/src/plugins/built-in/assessmentsOverview/AssessmentsOverview.svelte b/src/plugins/built-in/assessmentsOverview/AssessmentsOverview.svelte index 821f4b2e..c30c1835 100644 --- a/src/plugins/built-in/assessmentsOverview/AssessmentsOverview.svelte +++ b/src/plugins/built-in/assessmentsOverview/AssessmentsOverview.svelte @@ -1,12 +1,15 @@ @@ -352,6 +383,14 @@

Assessments

+ {#if showStudentFilter} + + {/if}