mirror of https://github.com/VERT-sh/VERT.git
Merge branch 'feat/merge-big-stuff'
This commit is contained in:
commit
237aa402cf
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"inlang.vs-code-extension"
|
||||||
|
]
|
||||||
|
}
|
||||||
373
bun.lock
373
bun.lock
|
|
@ -2,59 +2,66 @@
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"name": "VERT",
|
"name": "vert",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bjorn3/browser_wasi_shim": "^0.4.1",
|
"@bjorn3/browser_wasi_shim": "^0.4.2",
|
||||||
"@ffmpeg/ffmpeg": "^0.12.15",
|
"@ffmpeg/ffmpeg": "^0.12.15",
|
||||||
"@ffmpeg/util": "^0.12.2",
|
"@ffmpeg/util": "^0.12.2",
|
||||||
"@fontsource/azeret-mono": "^5.1.1",
|
"@fontsource/azeret-mono": "^5.2.9",
|
||||||
"@fontsource/lexend": "^5.1.2",
|
"@fontsource/lexend": "^5.2.9",
|
||||||
"@fontsource/radio-canada-big": "^5.1.1",
|
"@fontsource/radio-canada-big": "^5.2.6",
|
||||||
"@imagemagick/magick-wasm": "^0.0.34",
|
"@imagemagick/magick-wasm": "^0.0.35",
|
||||||
"@stripe/stripe-js": "^7.4.0",
|
"@stripe/stripe-js": "^7.9.0",
|
||||||
"byte-data": "^19.0.1",
|
"byte-data": "^19.0.1",
|
||||||
"client-zip": "^2.4.6",
|
"client-zip": "^2.5.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-svelte": "^0.475.0",
|
"lucide-svelte": "^0.542.0",
|
||||||
"music-metadata": "^11.0.0",
|
"music-metadata": "^11.8.3",
|
||||||
|
"overlayscrollbars": "^2.12.0",
|
||||||
|
"overlayscrollbars-svelte": "^0.5.5",
|
||||||
"p-queue": "^8.1.0",
|
"p-queue": "^8.1.0",
|
||||||
"riff-file": "^1.0.3",
|
"riff-file": "^1.0.3",
|
||||||
"svelte-stripe": "^1.4.0",
|
"svelte-stripe": "^1.4.0",
|
||||||
"vert-wasm": "^0.0.2",
|
"vert-wasm": "^0.0.2",
|
||||||
"vite-plugin-wasm": "^3.4.1",
|
"vite-plugin-wasm": "^3.5.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@poppanator/sveltekit-svg": "^5.0.0",
|
"@inlang/paraglide-js": "2.2.0",
|
||||||
"@sveltejs/adapter-static": "^3.0.8",
|
"@poppanator/sveltekit-svg": "^5.0.1",
|
||||||
"@sveltejs/kit": "^2.16.0",
|
"@sveltejs/adapter-static": "^3.0.9",
|
||||||
|
"@sveltejs/kit": "^2.37.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
||||||
"@types/eslint": "^9.6.1",
|
"@types/eslint": "^9.6.1",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.21",
|
||||||
"css-select": "5.1.0",
|
"css-select": "5.1.0",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.34.0",
|
||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-svelte": "^2.46.1",
|
"eslint-plugin-svelte": "^2.46.1",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.15.0",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.6.2",
|
||||||
"prettier-plugin-svelte": "^3.3.3",
|
"prettier-plugin-svelte": "^3.4.0",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.10",
|
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||||
"sass": "^1.83.4",
|
"sass": "^1.91.0",
|
||||||
"svelte": "^5.19.0",
|
"svelte": "^5.38.6",
|
||||||
"svelte-check": "^4.1.4",
|
"svelte-check": "^4.3.1",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.9.2",
|
||||||
"typescript-eslint": "^8.20.0",
|
"typescript-eslint": "^8.42.0",
|
||||||
"vite": "^5.4.11",
|
"vite": "^5.4.19",
|
||||||
"vite-plugin-top-level-await": "^1.5.0",
|
"vite-plugin-top-level-await": "^1.6.0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"trustedDependencies": [
|
||||||
|
"@swc/core",
|
||||||
|
"@parcel/watcher",
|
||||||
|
],
|
||||||
"packages": {
|
"packages": {
|
||||||
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
||||||
|
|
||||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
"@bjorn3/browser_wasi_shim": ["@bjorn3/browser_wasi_shim@0.4.2", "", {}, "sha512-/iHkCVUG3VbcbmEHn5iIUpIrh7a7WPiwZ3sHy4HZKZzBdSadwdddYDZAII2zBvQYV0Lfi8naZngPCN7WPHI/hA=="],
|
||||||
|
|
||||||
"@bjorn3/browser_wasi_shim": ["@bjorn3/browser_wasi_shim@0.4.1", "", {}, "sha512-54kpBQX69TZ8I1zyDC8sziv/zPT1zoIadv3CmdIZNZ5WDF1houMjAzRZ3dwWvhXObiEBjOxXyS8Ja7vA0EfGEQ=="],
|
"@borewit/text-codec": ["@borewit/text-codec@0.2.0", "", {}, "sha512-X999CKBxGwX8wW+4gFibsbiNdwqmdQEXmUejIWaIqdrHBgS5ARIOOeyiQbHjP9G58xVEPcuvP6VwwH3A0OFTOA=="],
|
||||||
|
|
||||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
|
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
|
||||||
|
|
||||||
|
|
@ -102,21 +109,23 @@
|
||||||
|
|
||||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
|
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
|
||||||
|
|
||||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA=="],
|
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
|
||||||
|
|
||||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
||||||
|
|
||||||
"@eslint/config-array": ["@eslint/config-array@0.19.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w=="],
|
"@eslint/config-array": ["@eslint/config-array@0.21.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ=="],
|
||||||
|
|
||||||
"@eslint/core": ["@eslint/core@0.12.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg=="],
|
"@eslint/config-helpers": ["@eslint/config-helpers@0.3.1", "", {}, "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="],
|
||||||
|
|
||||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ=="],
|
"@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="],
|
||||||
|
|
||||||
"@eslint/js": ["@eslint/js@9.21.0", "", {}, "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw=="],
|
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
|
||||||
|
|
||||||
|
"@eslint/js": ["@eslint/js@9.34.0", "", {}, "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw=="],
|
||||||
|
|
||||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||||
|
|
||||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.7", "", { "dependencies": { "@eslint/core": "^0.12.0", "levn": "^0.4.1" } }, "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g=="],
|
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
|
||||||
|
|
||||||
"@ffmpeg/ffmpeg": ["@ffmpeg/ffmpeg@0.12.15", "", { "dependencies": { "@ffmpeg/types": "^0.12.4" } }, "sha512-1C8Obr4GsN3xw+/1Ww6PFM84wSQAGsdoTuTWPOj2OizsRDLT4CXTaVjPhkw6ARyDus1B9X/L2LiXHqYYsGnRFw=="],
|
"@ffmpeg/ffmpeg": ["@ffmpeg/ffmpeg@0.12.15", "", { "dependencies": { "@ffmpeg/types": "^0.12.4" } }, "sha512-1C8Obr4GsN3xw+/1Ww6PFM84wSQAGsdoTuTWPOj2OizsRDLT4CXTaVjPhkw6ARyDus1B9X/L2LiXHqYYsGnRFw=="],
|
||||||
|
|
||||||
|
|
@ -124,11 +133,11 @@
|
||||||
|
|
||||||
"@ffmpeg/util": ["@ffmpeg/util@0.12.2", "", {}, "sha512-ouyoW+4JB7WxjeZ2y6KpRvB+dLp7Cp4ro8z0HIVpZVCM7AwFlHa0c4R8Y/a4M3wMqATpYKhC7lSFHQ0T11MEDw=="],
|
"@ffmpeg/util": ["@ffmpeg/util@0.12.2", "", {}, "sha512-ouyoW+4JB7WxjeZ2y6KpRvB+dLp7Cp4ro8z0HIVpZVCM7AwFlHa0c4R8Y/a4M3wMqATpYKhC7lSFHQ0T11MEDw=="],
|
||||||
|
|
||||||
"@fontsource/azeret-mono": ["@fontsource/azeret-mono@5.2.5", "", {}, "sha512-GRzKYuD1CVOS6Jag/ohDCycLV9a3TK6y1T73A8q0JoDZTVO85DNapqLK+SV2gYtTFldahNAlDSIaizv9MLhR1A=="],
|
"@fontsource/azeret-mono": ["@fontsource/azeret-mono@5.2.9", "", {}, "sha512-1qnbVspQPI38qhSTSidWU4bjG5ynWCfkMwfPxahqxejJO/u4yT1FbPqG73s4fDmQSuDQYoA8jfTpoQiod7+fuA=="],
|
||||||
|
|
||||||
"@fontsource/lexend": ["@fontsource/lexend@5.2.5", "", {}, "sha512-Mv2XQ+B4ek2lNCGRW5ddLTW8T3xTT17AnCk1IETpoef57XHz+e42fUfLAYMrmiJLOGpR44qnyJ5S6D323A5EIw=="],
|
"@fontsource/lexend": ["@fontsource/lexend@5.2.9", "", {}, "sha512-0a5xzwksBilec8Q+QwPvTFKFcXYw31oyf5CthPKd+C5NJZDl1aHw4FcMz9bcRMPhq0LXO69BXI8aVxmj15pzNA=="],
|
||||||
|
|
||||||
"@fontsource/radio-canada-big": ["@fontsource/radio-canada-big@5.2.5", "", {}, "sha512-cNwWV/zPZuxtmMfoD0/v1AIL0X09hZ6yNMqnTgUw5Jy0rV4bPn32+RhKziU/itO4zgxDKjrKnR7Tb1h0+Khh+Q=="],
|
"@fontsource/radio-canada-big": ["@fontsource/radio-canada-big@5.2.6", "", {}, "sha512-7ziSRyjIA1uTT5avHTaYHyoQfDiKihCy1wGz+hlKsxkHfpM5G5uVHAhiLcSzIjcMqykMtkyw5shRmgLZgebqTA=="],
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
|
|
@ -136,21 +145,31 @@
|
||||||
|
|
||||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||||
|
|
||||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
|
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
||||||
|
|
||||||
"@imagemagick/magick-wasm": ["@imagemagick/magick-wasm@0.0.34", "", {}, "sha512-vSTe4cfR8U8r2Ityo6s3iRFVK903W4fhur3t/ixc6vLSAJXmqXC9cKXz2NkkDBUVU7ssJTYMiTKAb1S9RY+ZdQ=="],
|
"@imagemagick/magick-wasm": ["@imagemagick/magick-wasm@0.0.35", "", {}, "sha512-Wh5C15QyOkJb1i37j9Vpi5OhqCoXwZ/v9LBxo+LUAhiBBtBnRK7Nlg98KGHdtiJocBE3C4FJ+rv+BMrFevzwnw=="],
|
||||||
|
|
||||||
|
"@inlang/paraglide-js": ["@inlang/paraglide-js@2.2.0", "", { "dependencies": { "@inlang/recommend-sherlock": "0.2.1", "@inlang/sdk": "2.4.9", "commander": "11.1.0", "consola": "3.4.0", "json5": "2.2.3", "unplugin": "^2.1.2", "urlpattern-polyfill": "^10.0.0" }, "bin": { "paraglide-js": "bin/run.js" } }, "sha512-pkpXu1LanvpcAbvpVPf7PgF11Uq7DliSEBngrcUN36l4ZOOpzn3QBTvVr/tJxvks0O67WseQgiMHet8KH7Oz5A=="],
|
||||||
|
|
||||||
|
"@inlang/recommend-sherlock": ["@inlang/recommend-sherlock@0.2.1", "", { "dependencies": { "comment-json": "^4.2.3" } }, "sha512-ckv8HvHy/iTqaVAEKrr+gnl+p3XFNwe5D2+6w6wJk2ORV2XkcRkKOJ/XsTUJbPSiyi4PI+p+T3bqbmNx/rDUlg=="],
|
||||||
|
|
||||||
|
"@inlang/sdk": ["@inlang/sdk@2.4.9", "", { "dependencies": { "@lix-js/sdk": "0.4.7", "@sinclair/typebox": "^0.31.17", "kysely": "^0.27.4", "sqlite-wasm-kysely": "0.3.0", "uuid": "^10.0.0" } }, "sha512-cvz/C1rF5WBxzHbEoiBoI6Sz6q6M+TdxfWkEGBYTD77opY8i8WN01prUWXEM87GPF4SZcyIySez9U0Ccm12oFQ=="],
|
||||||
|
|
||||||
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
||||||
|
|
||||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||||
|
|
||||||
|
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
||||||
|
|
||||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||||
|
|
||||||
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
|
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||||
|
|
||||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
|
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.30", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q=="],
|
||||||
|
|
||||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
"@lix-js/sdk": ["@lix-js/sdk@0.4.7", "", { "dependencies": { "@lix-js/server-protocol-schema": "0.1.1", "dedent": "1.5.1", "human-id": "^4.1.1", "js-sha256": "^0.11.0", "kysely": "^0.27.4", "sqlite-wasm-kysely": "0.3.0", "uuid": "^10.0.0" } }, "sha512-pRbW+joG12L0ULfMiWYosIW0plmW4AsUdiPCp+Z8rAsElJ+wJ6in58zhD3UwUcd4BNcpldEGjg6PdA7e0RgsDQ=="],
|
||||||
|
|
||||||
|
"@lix-js/server-protocol-schema": ["@lix-js/server-protocol-schema@0.1.1", "", {}, "sha512-jBeALB6prAbtr5q4vTuxnRZZv1M2rKe8iNqRQhFJ4Tv7150unEa0vKyz0hs8Gl3fUGsWaNJBh3J8++fpbrpRBQ=="],
|
||||||
|
|
||||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||||
|
|
||||||
|
|
@ -188,91 +207,103 @@
|
||||||
|
|
||||||
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
||||||
|
|
||||||
"@polka/url": ["@polka/url@1.0.0-next.28", "", {}, "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw=="],
|
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
||||||
|
|
||||||
"@poppanator/sveltekit-svg": ["@poppanator/sveltekit-svg@5.0.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "peerDependencies": { "svelte": ">=5.x", "svgo": ">=3.x", "vite": ">=5.x" } }, "sha512-b7hk55SF0HjTS+xFgMG20hy6W0F/m+yRA/ZWcjnsa391rB3Ys3desCiUyIKQYcfvcyuRiQCPedUJMYgu00VdCA=="],
|
"@poppanator/sveltekit-svg": ["@poppanator/sveltekit-svg@5.0.1", "", { "dependencies": { "@rollup/pluginutils": "5.1.4", "svgo": "^3.2.0" }, "peerDependencies": { "svelte": ">=5.x", "vite": ">=5.x || >= 6.x" } }, "sha512-eCOm9Wb1eO9N5N49JNokxgbUZN79QV/fe02cRrrWbDbcAOvGoIFU0YKDZEluIaFTP2zOtOxMeCSSobM4foMShA=="],
|
||||||
|
|
||||||
"@rollup/plugin-virtual": ["@rollup/plugin-virtual@3.0.2", "", { "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A=="],
|
"@rollup/plugin-virtual": ["@rollup/plugin-virtual@3.0.2", "", { "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A=="],
|
||||||
|
|
||||||
"@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="],
|
"@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.9", "", { "os": "android", "cpu": "arm" }, "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA=="],
|
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.50.0", "", { "os": "android", "cpu": "arm" }, "sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.9", "", { "os": "android", "cpu": "arm64" }, "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg=="],
|
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.50.0", "", { "os": "android", "cpu": "arm64" }, "sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw=="],
|
||||||
|
|
||||||
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ=="],
|
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.50.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg=="],
|
||||||
|
|
||||||
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q=="],
|
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.50.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw=="],
|
||||||
|
|
||||||
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.34.9", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw=="],
|
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.50.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g=="],
|
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.50.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.9", "", { "os": "linux", "cpu": "arm" }, "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg=="],
|
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.50.0", "", { "os": "linux", "cpu": "arm" }, "sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.34.9", "", { "os": "linux", "cpu": "arm" }, "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA=="],
|
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.50.0", "", { "os": "linux", "cpu": "arm" }, "sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw=="],
|
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.50.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.34.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A=="],
|
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.50.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.9", "", { "os": "linux", "cpu": "none" }, "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg=="],
|
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.50.0", "", { "os": "linux", "cpu": "none" }, "sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.9", "", { "os": "linux", "cpu": "ppc64" }, "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA=="],
|
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.50.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.9", "", { "os": "linux", "cpu": "none" }, "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg=="],
|
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.50.0", "", { "os": "linux", "cpu": "none" }, "sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.9", "", { "os": "linux", "cpu": "s390x" }, "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ=="],
|
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.50.0", "", { "os": "linux", "cpu": "none" }, "sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.9", "", { "os": "linux", "cpu": "x64" }, "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A=="],
|
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.50.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ=="],
|
||||||
|
|
||||||
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.34.9", "", { "os": "linux", "cpu": "x64" }, "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA=="],
|
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.50.0", "", { "os": "linux", "cpu": "x64" }, "sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA=="],
|
||||||
|
|
||||||
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q=="],
|
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.50.0", "", { "os": "linux", "cpu": "x64" }, "sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw=="],
|
||||||
|
|
||||||
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.34.9", "", { "os": "win32", "cpu": "ia32" }, "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w=="],
|
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.50.0", "", { "os": "none", "cpu": "arm64" }, "sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q=="],
|
||||||
|
|
||||||
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.9", "", { "os": "win32", "cpu": "x64" }, "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw=="],
|
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.50.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg=="],
|
||||||
|
|
||||||
"@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="],
|
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.50.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw=="],
|
||||||
|
|
||||||
"@stripe/stripe-js": ["@stripe/stripe-js@7.4.0", "", {}, "sha512-lQHQPfXPTBeh0XFjq6PqSBAyR7umwcJbvJhXV77uGCUDD6ymXJU/f2164ydLMLCCceNuPlbV9b+1smx98efwWQ=="],
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.50.0", "", { "os": "win32", "cpu": "x64" }, "sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg=="],
|
||||||
|
|
||||||
|
"@sinclair/typebox": ["@sinclair/typebox@0.31.28", "", {}, "sha512-/s55Jujywdw/Jpan+vsy6JZs1z2ZTGxTmbZTPiuSL2wz9mfzA2gN1zzaqmvfi4pq+uOt7Du85fkiwv5ymW84aQ=="],
|
||||||
|
|
||||||
|
"@sqlite.org/sqlite-wasm": ["@sqlite.org/sqlite-wasm@3.48.0-build4", "", { "bin": { "sqlite-wasm": "bin/index.js" } }, "sha512-hI6twvUkzOmyGZhQMza1gpfqErZxXRw6JEsiVjUbo7tFanVD+8Oil0Ih3l2nGzHdxPI41zFmfUQG7GHqhciKZQ=="],
|
||||||
|
|
||||||
|
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
||||||
|
|
||||||
|
"@stripe/stripe-js": ["@stripe/stripe-js@7.9.0", "", {}, "sha512-ggs5k+/0FUJcIgNY08aZTqpBTtbExkJMYMLSMwyucrhtWexVOEY1KJmhBsxf+E/Q15f5rbwBpj+t0t2AW2oCsQ=="],
|
||||||
|
|
||||||
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
||||||
|
|
||||||
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.8", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg=="],
|
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.9", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-aytHXcMi7lb9ljsWUzXYQ0p5X1z9oWud2olu/EpmH7aCu4m84h7QLvb5Wp+CFirKcwoNnYvYWhyP/L8Vh1ztdw=="],
|
||||||
|
|
||||||
"@sveltejs/kit": ["@sveltejs/kit@2.18.0", "", { "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", "devalue": "^5.1.0", "esm-env": "^1.2.2", "import-meta-resolve": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^3.0.0" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0" }, "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-4DGCGiwNzgnPJySlMe/Qi6rKMK3ntphJaV95BTW+aggaTIAVZ5x3Bp+LURVLMxAEAtWAI5U449NafVxTS+kXbQ=="],
|
"@sveltejs/kit": ["@sveltejs/kit@2.37.0", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.3.2", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["@opentelemetry/api"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-xgKtpjQ6Ry4mdShd01ht5AODUsW7+K1iValPDq7QX8zI1hWOKREH9GjG8SRCN5tC4K7UXmMhuQam7gbLByVcnw=="],
|
||||||
|
|
||||||
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@4.0.4", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^3.0.0-next.0||^3.0.0", "debug": "^4.3.7", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.12", "vitefu": "^1.0.3" }, "peerDependencies": { "svelte": "^5.0.0-next.96 || ^5.0.0", "vite": "^5.0.0" } }, "sha512-0ba1RQ/PHen5FGpdSrW7Y3fAMQjrXantECALeOiOdBdzR5+5vPP6HVZRLmZaQL+W8m++o+haIAKq5qT+MiZ7VA=="],
|
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@4.0.4", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^3.0.0-next.0||^3.0.0", "debug": "^4.3.7", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.12", "vitefu": "^1.0.3" }, "peerDependencies": { "svelte": "^5.0.0-next.96 || ^5.0.0", "vite": "^5.0.0" } }, "sha512-0ba1RQ/PHen5FGpdSrW7Y3fAMQjrXantECALeOiOdBdzR5+5vPP6HVZRLmZaQL+W8m++o+haIAKq5qT+MiZ7VA=="],
|
||||||
|
|
||||||
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@3.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^4.0.0-next.0||^4.0.0", "svelte": "^5.0.0-next.96 || ^5.0.0", "vite": "^5.0.0" } }, "sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ=="],
|
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@3.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^4.0.0-next.0||^4.0.0", "svelte": "^5.0.0-next.96 || ^5.0.0", "vite": "^5.0.0" } }, "sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ=="],
|
||||||
|
|
||||||
"@swc/core": ["@swc/core@1.11.21", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.21" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.21", "@swc/core-darwin-x64": "1.11.21", "@swc/core-linux-arm-gnueabihf": "1.11.21", "@swc/core-linux-arm64-gnu": "1.11.21", "@swc/core-linux-arm64-musl": "1.11.21", "@swc/core-linux-x64-gnu": "1.11.21", "@swc/core-linux-x64-musl": "1.11.21", "@swc/core-win32-arm64-msvc": "1.11.21", "@swc/core-win32-ia32-msvc": "1.11.21", "@swc/core-win32-x64-msvc": "1.11.21" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-/Y3BJLcwd40pExmdar8MH2UGGvCBrqNN7hauOMckrEX2Ivcbv3IMhrbGX4od1dnF880Ed8y/E9aStZCIQi0EGw=="],
|
"@swc/core": ["@swc/core@1.13.5", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.24" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.13.5", "@swc/core-darwin-x64": "1.13.5", "@swc/core-linux-arm-gnueabihf": "1.13.5", "@swc/core-linux-arm64-gnu": "1.13.5", "@swc/core-linux-arm64-musl": "1.13.5", "@swc/core-linux-x64-gnu": "1.13.5", "@swc/core-linux-x64-musl": "1.13.5", "@swc/core-win32-arm64-msvc": "1.13.5", "@swc/core-win32-ia32-msvc": "1.13.5", "@swc/core-win32-x64-msvc": "1.13.5" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ=="],
|
||||||
|
|
||||||
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.21", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v6gjw9YFWvKulCw3ZA1dY+LGMafYzJksm1mD4UZFZ9b36CyHFowYVYug1ajYRIRqEvvfIhHUNV660zTLoVFR8g=="],
|
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.13.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ=="],
|
||||||
|
|
||||||
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.21", "", { "os": "darwin", "cpu": "x64" }, "sha512-CUiTiqKlzskwswrx9Ve5NhNoab30L1/ScOfQwr1duvNlFvarC8fvQSgdtpw2Zh3MfnfNPpyLZnYg7ah4kbT9JQ=="],
|
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.13.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng=="],
|
||||||
|
|
||||||
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.21", "", { "os": "linux", "cpu": "arm" }, "sha512-YyBTAFM/QPqt1PscD8hDmCLnqPGKmUZpqeE25HXY8OLjl2MUs8+O4KjwPZZ+OGxpdTbwuWFyMoxjcLy80JODvg=="],
|
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.13.5", "", { "os": "linux", "cpu": "arm" }, "sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ=="],
|
||||||
|
|
||||||
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.21", "", { "os": "linux", "cpu": "arm64" }, "sha512-DQD+ooJmwpNsh4acrftdkuwl5LNxxg8U4+C/RJNDd7m5FP9Wo4c0URi5U0a9Vk/6sQNh9aSGcYChDpqCDWEcBw=="],
|
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.13.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw=="],
|
||||||
|
|
||||||
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.21", "", { "os": "linux", "cpu": "arm64" }, "sha512-y1L49+snt1a1gLTYPY641slqy55QotPdtRK9Y6jMi4JBQyZwxC8swWYlQWb+MyILwxA614fi62SCNZNznB3XSA=="],
|
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.13.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ=="],
|
||||||
|
|
||||||
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.21", "", { "os": "linux", "cpu": "x64" }, "sha512-NesdBXv4CvVEaFUlqKj+GA4jJMNUzK2NtKOrUNEtTbXaVyNiXjFCSaDajMTedEB0jTAd9ybB0aBvwhgkJUWkWA=="],
|
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.13.5", "", { "os": "linux", "cpu": "x64" }, "sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA=="],
|
||||||
|
|
||||||
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.21", "", { "os": "linux", "cpu": "x64" }, "sha512-qFV60pwpKVOdmX67wqQzgtSrUGWX9Cibnp1CXyqZ9Mmt8UyYGvmGu7p6PMbTyX7vdpVUvWVRf8DzrW2//wmVHg=="],
|
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.13.5", "", { "os": "linux", "cpu": "x64" }, "sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q=="],
|
||||||
|
|
||||||
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.21", "", { "os": "win32", "cpu": "arm64" }, "sha512-DJJe9k6gXR/15ZZVLv1SKhXkFst8lYCeZRNHH99SlBodvu4slhh/MKQ6YCixINRhCwliHrpXPym8/5fOq8b7Ig=="],
|
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.13.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw=="],
|
||||||
|
|
||||||
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.21", "", { "os": "win32", "cpu": "ia32" }, "sha512-TqEXuy6wedId7bMwLIr9byds+mKsaXVHctTN88R1UIBPwJA92Pdk0uxDgip0pEFzHB/ugU27g6d8cwUH3h2eIw=="],
|
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.13.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw=="],
|
||||||
|
|
||||||
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.21", "", { "os": "win32", "cpu": "x64" }, "sha512-BT9BNNbMxdpUM1PPAkYtviaV0A8QcXttjs2MDtOeSqqvSJaPtyM+Fof2/+xSwQDmDEFzbGCcn75M5+xy3lGqpA=="],
|
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.13.5", "", { "os": "win32", "cpu": "x64" }, "sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q=="],
|
||||||
|
|
||||||
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
|
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
|
||||||
|
|
||||||
"@swc/types": ["@swc/types@0.1.21", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ=="],
|
"@swc/types": ["@swc/types@0.1.24", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng=="],
|
||||||
|
|
||||||
|
"@swc/wasm": ["@swc/wasm@1.13.5", "", {}, "sha512-ZBZcxieydxNwgEU9eFAXGMaDb1Xoh+ZkZcUQ27LNJzc2lPSByoL6CSVqnYiaVo+n9JgqbYyHlMq+i7z0wRNTfA=="],
|
||||||
|
|
||||||
|
"@tokenizer/inflate": ["@tokenizer/inflate@0.2.7", "", { "dependencies": { "debug": "^4.4.0", "fflate": "^0.8.2", "token-types": "^6.0.0" } }, "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg=="],
|
||||||
|
|
||||||
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||||
|
|
||||||
|
|
@ -282,33 +313,37 @@
|
||||||
|
|
||||||
"@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="],
|
"@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="],
|
||||||
|
|
||||||
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
|
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||||
|
|
||||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.26.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.26.0", "@typescript-eslint/type-utils": "8.26.0", "@typescript-eslint/utils": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q=="],
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.42.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/type-utils": "8.42.0", "@typescript-eslint/utils": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.42.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.26.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.26.0", "@typescript-eslint/types": "8.26.0", "@typescript-eslint/typescript-estree": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA=="],
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.42.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg=="],
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.26.0", "", { "dependencies": { "@typescript-eslint/types": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0" } }, "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA=="],
|
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.42.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.42.0", "@typescript-eslint/types": "^8.42.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg=="],
|
||||||
|
|
||||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.26.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.26.0", "@typescript-eslint/utils": "8.26.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q=="],
|
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.42.0", "", { "dependencies": { "@typescript-eslint/types": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0" } }, "sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw=="],
|
||||||
|
|
||||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.26.0", "", {}, "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA=="],
|
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.42.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.26.0", "", { "dependencies": { "@typescript-eslint/types": "8.26.0", "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ=="],
|
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.42.0", "", { "dependencies": { "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/utils": "8.42.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.26.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.26.0", "@typescript-eslint/types": "8.26.0", "@typescript-eslint/typescript-estree": "8.26.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig=="],
|
"@typescript-eslint/types": ["@typescript-eslint/types@8.42.0", "", {}, "sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw=="],
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.26.0", "", { "dependencies": { "@typescript-eslint/types": "8.26.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg=="],
|
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.42.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.42.0", "@typescript-eslint/tsconfig-utils": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ=="],
|
||||||
|
|
||||||
"acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="],
|
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.42.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.42.0", "", { "dependencies": { "@typescript-eslint/types": "8.42.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ=="],
|
||||||
|
|
||||||
|
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
|
|
||||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||||
|
|
||||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||||
|
|
||||||
"ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
|
"ansi-regex": ["ansi-regex@6.2.0", "", {}, "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg=="],
|
||||||
|
|
||||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||||
|
|
||||||
|
|
@ -322,7 +357,9 @@
|
||||||
|
|
||||||
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
|
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
|
||||||
|
|
||||||
"autoprefixer": ["autoprefixer@10.4.20", "", { "dependencies": { "browserslist": "^4.23.3", "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g=="],
|
"array-timsort": ["array-timsort@1.0.3", "", {}, "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ=="],
|
||||||
|
|
||||||
|
"autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="],
|
||||||
|
|
||||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
|
|
@ -332,11 +369,11 @@
|
||||||
|
|
||||||
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
|
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
|
||||||
|
|
||||||
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||||
|
|
||||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||||
|
|
||||||
"browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="],
|
"browserslist": ["browserslist@4.25.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg=="],
|
||||||
|
|
||||||
"byte-data": ["byte-data@19.0.1", "", {}, "sha512-xRvkTvO28wr0+0rErSETHD8Cw+P444Az3/jkTezaMw5R+TTW8ZNXuvPZf9/ZhnSRRvlMnJsVhc+ecYvOMy/MQQ=="],
|
"byte-data": ["byte-data@19.0.1", "", {}, "sha512-xRvkTvO28wr0+0rErSETHD8Cw+P444Az3/jkTezaMw5R+TTW8ZNXuvPZf9/ZhnSRRvlMnJsVhc+ecYvOMy/MQQ=="],
|
||||||
|
|
||||||
|
|
@ -344,13 +381,13 @@
|
||||||
|
|
||||||
"camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="],
|
"camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="],
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001702", "", {}, "sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001739", "", {}, "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA=="],
|
||||||
|
|
||||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
|
|
||||||
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
||||||
|
|
||||||
"client-zip": ["client-zip@2.4.6", "", {}, "sha512-e7t1u14h/yT0A12qBwFsaus8UZZ8+MCaNAEn/z53mrukLq/LFcKX7TkbntAppGu8he2p8pz9vc5NEGE/h4ohlw=="],
|
"client-zip": ["client-zip@2.5.0", "", {}, "sha512-ydG4nDZesbFurnNq0VVCp/yyomIBh+X/1fZPI/P24zbnG4dtC4tQAfI5uQsomigsUMeiRO2wiTPizLWQh+IAyQ=="],
|
||||||
|
|
||||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||||
|
|
||||||
|
|
@ -358,27 +395,35 @@
|
||||||
|
|
||||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||||
|
|
||||||
"commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
"commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
|
||||||
|
|
||||||
|
"comment-json": ["comment-json@4.2.5", "", { "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", "esprima": "^4.0.1", "has-own-prop": "^2.0.0", "repeat-string": "^1.6.1" } }, "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw=="],
|
||||||
|
|
||||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
|
"consola": ["consola@3.4.0", "", {}, "sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA=="],
|
||||||
|
|
||||||
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
||||||
|
|
||||||
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
||||||
|
|
||||||
|
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
||||||
|
|
||||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||||
|
|
||||||
"css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="],
|
"css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="],
|
||||||
|
|
||||||
"css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="],
|
"css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="],
|
||||||
|
|
||||||
"css-what": ["css-what@6.1.0", "", {}, "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="],
|
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
|
||||||
|
|
||||||
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
|
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
|
||||||
|
|
||||||
"csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="],
|
"csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="],
|
||||||
|
|
||||||
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
|
"dedent": ["dedent@1.5.1", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg=="],
|
||||||
|
|
||||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||||
|
|
||||||
|
|
@ -386,7 +431,7 @@
|
||||||
|
|
||||||
"detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
"detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||||
|
|
||||||
"devalue": ["devalue@5.1.1", "", {}, "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw=="],
|
"devalue": ["devalue@5.3.2", "", {}, "sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw=="],
|
||||||
|
|
||||||
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
|
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
|
||||||
|
|
||||||
|
|
@ -402,7 +447,7 @@
|
||||||
|
|
||||||
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
|
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
|
||||||
|
|
||||||
"electron-to-chromium": ["electron-to-chromium@1.5.112", "", {}, "sha512-oen93kVyqSb3l+ziUgzIOlWt/oOuy4zRmpwestMn4rhFWAoFJeFuCVte9F2fASjeZZo7l/Cif9TiyrdW4CwEMA=="],
|
"electron-to-chromium": ["electron-to-chromium@1.5.212", "", {}, "sha512-gE7ErIzSW+d8jALWMcOIgf+IB6lpfsg6NwOhPVwKzDtN2qcBix47vlin4yzSregYDxTCXOUqAZjVY/Z3naS7ww=="],
|
||||||
|
|
||||||
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||||
|
|
||||||
|
|
@ -416,25 +461,27 @@
|
||||||
|
|
||||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||||
|
|
||||||
"eslint": ["eslint@9.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.0", "@eslint/js": "9.21.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg=="],
|
"eslint": ["eslint@9.34.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.34.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg=="],
|
||||||
|
|
||||||
"eslint-compat-utils": ["eslint-compat-utils@0.5.1", "", { "dependencies": { "semver": "^7.5.4" }, "peerDependencies": { "eslint": ">=6.0.0" } }, "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q=="],
|
"eslint-compat-utils": ["eslint-compat-utils@0.5.1", "", { "dependencies": { "semver": "^7.5.4" }, "peerDependencies": { "eslint": ">=6.0.0" } }, "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q=="],
|
||||||
|
|
||||||
"eslint-config-prettier": ["eslint-config-prettier@10.0.2", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "build/bin/cli.js" } }, "sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg=="],
|
"eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="],
|
||||||
|
|
||||||
"eslint-plugin-svelte": ["eslint-plugin-svelte@2.46.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@jridgewell/sourcemap-codec": "^1.4.15", "eslint-compat-utils": "^0.5.1", "esutils": "^2.0.3", "known-css-properties": "^0.35.0", "postcss": "^8.4.38", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.1.0", "semver": "^7.6.2", "svelte-eslint-parser": "^0.43.0" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw=="],
|
"eslint-plugin-svelte": ["eslint-plugin-svelte@2.46.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@jridgewell/sourcemap-codec": "^1.4.15", "eslint-compat-utils": "^0.5.1", "esutils": "^2.0.3", "known-css-properties": "^0.35.0", "postcss": "^8.4.38", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.1.0", "semver": "^7.6.2", "svelte-eslint-parser": "^0.43.0" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw=="],
|
||||||
|
|
||||||
"eslint-scope": ["eslint-scope@8.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="],
|
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
||||||
|
|
||||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
|
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
|
||||||
|
|
||||||
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
||||||
|
|
||||||
"espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
|
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
||||||
|
|
||||||
|
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
|
||||||
|
|
||||||
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
||||||
|
|
||||||
"esrap": ["esrap@1.4.5", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g=="],
|
"esrap": ["esrap@2.1.0", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA=="],
|
||||||
|
|
||||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||||
|
|
||||||
|
|
@ -456,11 +503,13 @@
|
||||||
|
|
||||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
||||||
|
|
||||||
"fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="],
|
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||||
|
|
||||||
|
"fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="],
|
||||||
|
|
||||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||||
|
|
||||||
"file-type": ["file-type@19.6.0", "", { "dependencies": { "get-stream": "^9.0.1", "strtok3": "^9.0.1", "token-types": "^6.0.0", "uint8array-extras": "^1.3.0" } }, "sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ=="],
|
"file-type": ["file-type@21.0.0", "", { "dependencies": { "@tokenizer/inflate": "^0.2.7", "strtok3": "^10.2.2", "token-types": "^6.0.0", "uint8array-extras": "^1.4.0" } }, "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg=="],
|
||||||
|
|
||||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||||
|
|
||||||
|
|
@ -478,8 +527,6 @@
|
||||||
|
|
||||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
|
|
||||||
"get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
|
|
||||||
|
|
||||||
"glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
"glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||||
|
|
||||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||||
|
|
@ -490,20 +537,22 @@
|
||||||
|
|
||||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||||
|
|
||||||
|
"has-own-prop": ["has-own-prop@2.0.0", "", {}, "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ=="],
|
||||||
|
|
||||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||||
|
|
||||||
|
"human-id": ["human-id@4.1.1", "", { "bin": { "human-id": "dist/cli.js" } }, "sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg=="],
|
||||||
|
|
||||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||||
|
|
||||||
"ieee754-buffer": ["ieee754-buffer@2.0.0", "", {}, "sha512-AXUAT0nMEi7h1Is8HXGXof3eejl/GabZFKSj8Ym6kVRUSwrAb52EkAXywiCQYSHGQMRn7lvfY7vhPMjVc+Kybg=="],
|
"ieee754-buffer": ["ieee754-buffer@2.0.0", "", {}, "sha512-AXUAT0nMEi7h1Is8HXGXof3eejl/GabZFKSj8Ym6kVRUSwrAb52EkAXywiCQYSHGQMRn7lvfY7vhPMjVc+Kybg=="],
|
||||||
|
|
||||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||||
|
|
||||||
"immutable": ["immutable@5.0.3", "", {}, "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw=="],
|
"immutable": ["immutable@5.1.3", "", {}, "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg=="],
|
||||||
|
|
||||||
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
||||||
|
|
||||||
"import-meta-resolve": ["import-meta-resolve@4.1.0", "", {}, "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw=="],
|
|
||||||
|
|
||||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||||
|
|
||||||
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
|
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
|
||||||
|
|
@ -520,14 +569,14 @@
|
||||||
|
|
||||||
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
||||||
|
|
||||||
"is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="],
|
|
||||||
|
|
||||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||||
|
|
||||||
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
|
||||||
|
|
||||||
"jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="],
|
"jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="],
|
||||||
|
|
||||||
|
"js-sha256": ["js-sha256@0.11.1", "", {}, "sha512-o6WSo/LUvY2uC4j7mO50a2ms7E/EAdbP0swigLV+nzHKTTaYnaLIWJ02VdXrsJX0vGedDESQnLsOekr94ryfjg=="],
|
||||||
|
|
||||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||||
|
|
||||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||||
|
|
@ -536,20 +585,22 @@
|
||||||
|
|
||||||
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
||||||
|
|
||||||
|
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
||||||
|
|
||||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||||
|
|
||||||
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
||||||
|
|
||||||
"known-css-properties": ["known-css-properties@0.35.0", "", {}, "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A=="],
|
"known-css-properties": ["known-css-properties@0.35.0", "", {}, "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A=="],
|
||||||
|
|
||||||
|
"kysely": ["kysely@0.27.6", "", {}, "sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ=="],
|
||||||
|
|
||||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||||
|
|
||||||
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
|
"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=="],
|
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
||||||
|
|
||||||
"link": ["link@2.1.1", "", { "bin": { "link": "dist/cli.js" } }, "sha512-NV3AUVYBovJ6eVQcTeRoPnZSxzt2LOijNd+ugEZKRy/XeQlpTRhVRkuDv5kOlXwMAUx30vfUc7asRFb9RT65yg=="],
|
|
||||||
|
|
||||||
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
||||||
|
|
||||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||||
|
|
@ -558,9 +609,9 @@
|
||||||
|
|
||||||
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
"lucide-svelte": ["lucide-svelte@0.475.0", "", { "peerDependencies": { "svelte": "^3 || ^4 || ^5.0.0-next.42" } }, "sha512-N5+hFTPHaZe9HhqJDxxxODfYuOmI6v+JIowzERcea/uxytN/JZlehVTcINBNp8wMo7l6ov1Jf5srrDbkI/WsJg=="],
|
"lucide-svelte": ["lucide-svelte@0.542.0", "", { "peerDependencies": { "svelte": "^3 || ^4 || ^5.0.0-next.42" } }, "sha512-KxqJycY4EWaGy1zk/7sqEcf48j4YaP9zEujYczzrsw5j9b9b5pjAJ1qGFKZvD7T6xz9reSYAfUAd6Bz62TdqGw=="],
|
||||||
|
|
||||||
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
"magic-string": ["magic-string@0.30.18", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ=="],
|
||||||
|
|
||||||
"mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="],
|
"mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="],
|
||||||
|
|
||||||
|
|
@ -580,11 +631,11 @@
|
||||||
|
|
||||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
"music-metadata": ["music-metadata@11.0.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "content-type": "^1.0.5", "debug": "^4.4.0", "file-type": "^19.6.0", "link": "^2.1.1", "media-typer": "^1.1.0", "strtok3": "^10.2.1", "token-types": "^6.0.0", "uint8array-extras": "^1.4.0" } }, "sha512-ZxppS3UuaV1xdWPDmXf4VX3M5+LdVng3xu1rXbZrZWlvtppdOfYrMCeMGDuOt31URTbkmbwuYaRYddkhY5DZMA=="],
|
"music-metadata": ["music-metadata@11.8.3", "", { "dependencies": { "@borewit/text-codec": "^0.2.0", "@tokenizer/token": "^0.3.0", "content-type": "^1.0.5", "debug": "^4.4.1", "file-type": "^21.0.0", "media-typer": "^1.1.0", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.1" } }, "sha512-Tgiv4MlCgDb6XzelziB1mmL2xeoHls0KTpCm3Z3qr+LfF4mBEpkuc5vNrc927IT5+S5fv+vzStfI+HYC0igDpA=="],
|
||||||
|
|
||||||
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
|
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
|
||||||
|
|
||||||
"nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
|
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||||
|
|
||||||
|
|
@ -604,6 +655,10 @@
|
||||||
|
|
||||||
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
||||||
|
|
||||||
|
"overlayscrollbars": ["overlayscrollbars@2.12.0", "", {}, "sha512-mWJ5MOkcZ/ljHwfLw8+bN0V9ziGCoNoqULcp994j5DTGNQvnkWKWkA7rnO29Kyew5AoHxUnJ4Ndqfcl0HSQjXg=="],
|
||||||
|
|
||||||
|
"overlayscrollbars-svelte": ["overlayscrollbars-svelte@0.5.5", "", { "peerDependencies": { "overlayscrollbars": "^2.0.0", "svelte": "^5.0.0" } }, "sha512-+dRW3YZSvFbKi5vDCpnUOHuoPLLSdu0BUVVMYZdmfVghu7XkafDRebG2y91/ImPqj6YDAUsz1rcWVYhCJSS/pQ=="],
|
||||||
|
|
||||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||||
|
|
||||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||||
|
|
@ -624,17 +679,15 @@
|
||||||
|
|
||||||
"path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
|
"path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
|
||||||
|
|
||||||
"peek-readable": ["peek-readable@6.1.1", "", {}, "sha512-7QmvgRKhxM0E2PGV4ocfROItVode+ELI27n4q+lpufZ+tRKBu/pBP8WOmw9HXn2ui/AUizqtvaVQhcJrOkRqYg=="],
|
|
||||||
|
|
||||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
"picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
|
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||||
|
|
||||||
"pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
|
"pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
|
||||||
|
|
||||||
"pirates": ["pirates@4.0.6", "", {}, "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg=="],
|
"pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="],
|
||||||
|
|
||||||
"postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
|
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
|
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
|
||||||
|
|
||||||
|
|
@ -654,11 +707,11 @@
|
||||||
|
|
||||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||||
|
|
||||||
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
|
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||||
|
|
||||||
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.3.3", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw=="],
|
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.4.0", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ=="],
|
||||||
|
|
||||||
"prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.6.11", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-import-sort": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-style-order": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-import-sort", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-style-order", "prettier-plugin-svelte"] }, "sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA=="],
|
"prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.6.14", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-hermes": "*", "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-import-sort": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-style-order": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-hermes", "@prettier/plugin-oxc", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-import-sort", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-style-order", "prettier-plugin-svelte"] }, "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg=="],
|
||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
|
|
@ -668,6 +721,8 @@
|
||||||
|
|
||||||
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
||||||
|
|
||||||
|
"repeat-string": ["repeat-string@1.6.1", "", {}, "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w=="],
|
||||||
|
|
||||||
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
|
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
|
||||||
|
|
||||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||||
|
|
@ -676,15 +731,15 @@
|
||||||
|
|
||||||
"riff-file": ["riff-file@1.0.3", "", { "dependencies": { "byte-data": "^18.0.3" } }, "sha512-Vv8wwGr0BCks7VMI3Lv0houZee4DaHFjjTT0LMhMJKio2YmLncLeIVpK63ydSverngNk8XQPU3fbeP3bWgSIig=="],
|
"riff-file": ["riff-file@1.0.3", "", { "dependencies": { "byte-data": "^18.0.3" } }, "sha512-Vv8wwGr0BCks7VMI3Lv0houZee4DaHFjjTT0LMhMJKio2YmLncLeIVpK63ydSverngNk8XQPU3fbeP3bWgSIig=="],
|
||||||
|
|
||||||
"rollup": ["rollup@4.34.9", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.34.9", "@rollup/rollup-android-arm64": "4.34.9", "@rollup/rollup-darwin-arm64": "4.34.9", "@rollup/rollup-darwin-x64": "4.34.9", "@rollup/rollup-freebsd-arm64": "4.34.9", "@rollup/rollup-freebsd-x64": "4.34.9", "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", "@rollup/rollup-linux-arm-musleabihf": "4.34.9", "@rollup/rollup-linux-arm64-gnu": "4.34.9", "@rollup/rollup-linux-arm64-musl": "4.34.9", "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", "@rollup/rollup-linux-riscv64-gnu": "4.34.9", "@rollup/rollup-linux-s390x-gnu": "4.34.9", "@rollup/rollup-linux-x64-gnu": "4.34.9", "@rollup/rollup-linux-x64-musl": "4.34.9", "@rollup/rollup-win32-arm64-msvc": "4.34.9", "@rollup/rollup-win32-ia32-msvc": "4.34.9", "@rollup/rollup-win32-x64-msvc": "4.34.9", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ=="],
|
"rollup": ["rollup@4.50.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.50.0", "@rollup/rollup-android-arm64": "4.50.0", "@rollup/rollup-darwin-arm64": "4.50.0", "@rollup/rollup-darwin-x64": "4.50.0", "@rollup/rollup-freebsd-arm64": "4.50.0", "@rollup/rollup-freebsd-x64": "4.50.0", "@rollup/rollup-linux-arm-gnueabihf": "4.50.0", "@rollup/rollup-linux-arm-musleabihf": "4.50.0", "@rollup/rollup-linux-arm64-gnu": "4.50.0", "@rollup/rollup-linux-arm64-musl": "4.50.0", "@rollup/rollup-linux-loongarch64-gnu": "4.50.0", "@rollup/rollup-linux-ppc64-gnu": "4.50.0", "@rollup/rollup-linux-riscv64-gnu": "4.50.0", "@rollup/rollup-linux-riscv64-musl": "4.50.0", "@rollup/rollup-linux-s390x-gnu": "4.50.0", "@rollup/rollup-linux-x64-gnu": "4.50.0", "@rollup/rollup-linux-x64-musl": "4.50.0", "@rollup/rollup-openharmony-arm64": "4.50.0", "@rollup/rollup-win32-arm64-msvc": "4.50.0", "@rollup/rollup-win32-ia32-msvc": "4.50.0", "@rollup/rollup-win32-x64-msvc": "4.50.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw=="],
|
||||||
|
|
||||||
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
||||||
|
|
||||||
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
||||||
|
|
||||||
"sass": ["sass@1.85.1", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag=="],
|
"sass": ["sass@1.91.0", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-aFOZHGf+ur+bp1bCHZ+u8otKGh77ZtmFyXDo4tlYvT7PWql41Kwd8wdkPqhhT+h2879IVblcHFglIMofsFd1EA=="],
|
||||||
|
|
||||||
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||||
|
|
||||||
"set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="],
|
"set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="],
|
||||||
|
|
||||||
|
|
@ -698,6 +753,8 @@
|
||||||
|
|
||||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
|
"sqlite-wasm-kysely": ["sqlite-wasm-kysely@0.3.0", "", { "dependencies": { "@sqlite.org/sqlite-wasm": "^3.48.0-build2" }, "peerDependencies": { "kysely": "*" } }, "sha512-TzjBNv7KwRw6E3pdKdlRyZiTmUIE0UttT/Sl56MVwVARl/u5gp978KepazCJZewFUnlWHz9i3NQd4kOtP/Afdg=="],
|
||||||
|
|
||||||
"string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
"string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
||||||
|
|
||||||
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
|
|
@ -708,7 +765,7 @@
|
||||||
|
|
||||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||||
|
|
||||||
"strtok3": ["strtok3@10.2.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^6.1.1" } }, "sha512-Q2dTnW3UXokAvXmXvrvMoUj/me3LyJI76HNHeuGMh2o0As/vzd7eHV3ncLOyvu928vQIDbE7Vf9ldEnC7cwy1w=="],
|
"strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
|
||||||
|
|
||||||
"sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="],
|
"sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="],
|
||||||
|
|
||||||
|
|
@ -716,9 +773,9 @@
|
||||||
|
|
||||||
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
||||||
|
|
||||||
"svelte": ["svelte@5.22.5", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^1.4.3", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-+2BDWVa/rqr34oM+5HFUSmCCPdBBeNqFv2Xc/SSB8kV4iQhWWBNvU9/nd5Dz3PkAGl7Bm/AndS1vY4fe1MgTKA=="],
|
"svelte": ["svelte@5.38.6", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-ltBPlkvqk3bgCK7/N323atUpP3O3Y+DrGV4dcULrsSn4fZaaNnOmdplNznwfdWclAgvSr5rxjtzn/zJhRm6TKg=="],
|
||||||
|
|
||||||
"svelte-check": ["svelte-check@4.1.5", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-Gb0T2IqBNe1tLB9EB1Qh+LOe+JB8wt2/rNBDGvkxQVvk8vNeAoG+vZgFB/3P5+zC7RWlyBlzm9dVjZFph/maIg=="],
|
"svelte-check": ["svelte-check@4.3.1", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg=="],
|
||||||
|
|
||||||
"svelte-eslint-parser": ["svelte-eslint-parser@0.43.0", "", { "dependencies": { "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "postcss": "^8.4.39", "postcss-scss": "^4.0.9" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA=="],
|
"svelte-eslint-parser": ["svelte-eslint-parser@0.43.0", "", { "dependencies": { "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "postcss": "^8.4.39", "postcss-scss": "^4.0.9" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA=="],
|
||||||
|
|
||||||
|
|
@ -734,26 +791,30 @@
|
||||||
|
|
||||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||||
|
|
||||||
"token-types": ["token-types@6.0.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA=="],
|
"token-types": ["token-types@6.1.1", "", { "dependencies": { "@borewit/text-codec": "^0.1.0", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ=="],
|
||||||
|
|
||||||
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
||||||
|
|
||||||
"ts-api-utils": ["ts-api-utils@2.0.1", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w=="],
|
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
||||||
|
|
||||||
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
|
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
|
||||||
|
|
||||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||||
|
|
||||||
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
|
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||||
|
|
||||||
"typescript-eslint": ["typescript-eslint@8.26.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.26.0", "@typescript-eslint/parser": "8.26.0", "@typescript-eslint/utils": "8.26.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA=="],
|
"typescript-eslint": ["typescript-eslint@8.42.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.42.0", "@typescript-eslint/parser": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/utils": "8.42.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg=="],
|
||||||
|
|
||||||
"uint8array-extras": ["uint8array-extras@1.4.0", "", {}, "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ=="],
|
"uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
|
||||||
|
|
||||||
|
"unplugin": ["unplugin@2.3.10", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw=="],
|
||||||
|
|
||||||
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
|
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
|
||||||
|
|
||||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||||
|
|
||||||
|
"urlpattern-polyfill": ["urlpattern-polyfill@10.1.0", "", {}, "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw=="],
|
||||||
|
|
||||||
"utf8-buffer": ["utf8-buffer@1.0.0", "", {}, "sha512-ueuhzvWnp5JU5CiGSY4WdKbiN/PO2AZ/lpeLiz2l38qwdLy/cW40XobgyuIWucNyum0B33bVB0owjFCeGBSLqg=="],
|
"utf8-buffer": ["utf8-buffer@1.0.0", "", {}, "sha512-ueuhzvWnp5JU5CiGSY4WdKbiN/PO2AZ/lpeLiz2l38qwdLy/cW40XobgyuIWucNyum0B33bVB0owjFCeGBSLqg=="],
|
||||||
|
|
||||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||||
|
|
@ -762,13 +823,15 @@
|
||||||
|
|
||||||
"vert-wasm": ["vert-wasm@0.0.2", "", {}, "sha512-QCkhkATZkWp3OPpIrlcLVd5S4DQXeDEWIPI1eV+Ku+sUVoCM4s9DQbNKtnJ8s4leMW3AD4E7cY/gXB/9TsI3WA=="],
|
"vert-wasm": ["vert-wasm@0.0.2", "", {}, "sha512-QCkhkATZkWp3OPpIrlcLVd5S4DQXeDEWIPI1eV+Ku+sUVoCM4s9DQbNKtnJ8s4leMW3AD4E7cY/gXB/9TsI3WA=="],
|
||||||
|
|
||||||
"vite": ["vite@5.4.14", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA=="],
|
"vite": ["vite@5.4.19", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA=="],
|
||||||
|
|
||||||
"vite-plugin-top-level-await": ["vite-plugin-top-level-await@1.5.0", "", { "dependencies": { "@rollup/plugin-virtual": "^3.0.2", "@swc/core": "^1.10.16", "uuid": "^10.0.0" }, "peerDependencies": { "vite": ">=2.8" } }, "sha512-r/DtuvHrSqUVk23XpG2cl8gjt1aATMG5cjExXL1BUTcSNab6CzkcPua9BPEc9fuTP5UpwClCxUe3+dNGL0yrgQ=="],
|
"vite-plugin-top-level-await": ["vite-plugin-top-level-await@1.6.0", "", { "dependencies": { "@rollup/plugin-virtual": "^3.0.2", "@swc/core": "^1.12.14", "@swc/wasm": "^1.12.14", "uuid": "10.0.0" }, "peerDependencies": { "vite": ">=2.8" } }, "sha512-bNhUreLamTIkoulCR9aDXbTbhLk6n1YE8NJUTTxl5RYskNRtzOR0ASzSjBVRtNdjIfngDXo11qOsybGLNsrdww=="],
|
||||||
|
|
||||||
"vite-plugin-wasm": ["vite-plugin-wasm@3.4.1", "", { "peerDependencies": { "vite": "^2 || ^3 || ^4 || ^5 || ^6" } }, "sha512-ja3nSo2UCkVeitltJGkS3pfQHAanHv/DqGatdI39ja6McgABlpsZ5hVgl6wuR8Qx5etY3T5qgDQhOWzc5RReZA=="],
|
"vite-plugin-wasm": ["vite-plugin-wasm@3.5.0", "", { "peerDependencies": { "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" } }, "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ=="],
|
||||||
|
|
||||||
"vitefu": ["vitefu@1.0.6", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["vite"] }, "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA=="],
|
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
|
||||||
|
|
||||||
|
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
|
||||||
|
|
||||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||||
|
|
||||||
|
|
@ -790,6 +853,8 @@
|
||||||
|
|
||||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
@ -798,8 +863,6 @@
|
||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
"file-type/strtok3": ["strtok3@9.1.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.3.1" } }, "sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw=="],
|
|
||||||
|
|
||||||
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
@ -822,23 +885,25 @@
|
||||||
|
|
||||||
"svelte-eslint-parser/espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="],
|
"svelte-eslint-parser/espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="],
|
||||||
|
|
||||||
|
"svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
||||||
|
|
||||||
"tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
|
"tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
|
||||||
|
|
||||||
"tailwindcss/postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="],
|
"tailwindcss/postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="],
|
||||||
|
|
||||||
|
"token-types/@borewit/text-codec": ["@borewit/text-codec@0.1.1", "", {}, "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA=="],
|
||||||
|
|
||||||
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
|
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
|
||||||
|
|
||||||
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
|
|
||||||
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||||
|
|
||||||
"csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
|
"csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
|
||||||
|
|
||||||
"file-type/strtok3/peek-readable": ["peek-readable@5.4.2", "", {}, "sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg=="],
|
"glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||||
|
|
||||||
"glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
|
||||||
|
|
||||||
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|
||||||
|
|
@ -846,7 +911,7 @@
|
||||||
|
|
||||||
"tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
"tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
||||||
|
|
||||||
"tailwindcss/postcss-load-config/yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
"tailwindcss/postcss-load-config/yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="],
|
||||||
|
|
||||||
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,205 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://inlang.com/schema/inlang-message-format",
|
||||||
|
"navbar": {
|
||||||
|
"upload": "Upload",
|
||||||
|
"convert": "Convert",
|
||||||
|
"settings": "Settings",
|
||||||
|
"about": "About",
|
||||||
|
"toggle_theme": "Toggle theme"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"copyright": "© {year} VERT.",
|
||||||
|
"source_code": "Source code",
|
||||||
|
"discord_server": "Discord server"
|
||||||
|
},
|
||||||
|
"upload": {
|
||||||
|
"title": "The file converter you'll love.",
|
||||||
|
"subtitle": "All image, audio, and document processing is done on your device. Videos are converted on our lightning-fast servers. No file size limit, no ads, and completely open source.",
|
||||||
|
"uploader": {
|
||||||
|
"text": "Drop or click to {action}",
|
||||||
|
"convert": "convert",
|
||||||
|
"jpegify": "jpegify"
|
||||||
|
},
|
||||||
|
"cards": {
|
||||||
|
"title": "VERT supports...",
|
||||||
|
"images": "Images",
|
||||||
|
"audio": "Audio",
|
||||||
|
"documents": "Documents",
|
||||||
|
"video": "Video",
|
||||||
|
"video_server_processing": "Server supported",
|
||||||
|
"local_supported": "Local supported",
|
||||||
|
"status": {
|
||||||
|
"text": "<b>Status:</b> {status}",
|
||||||
|
"ready": "ready",
|
||||||
|
"not_ready": "not ready"
|
||||||
|
},
|
||||||
|
"supported_formats": "Supported formats:"
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"partial_support": "This format can only be converted as {direction}.",
|
||||||
|
"direction_input": "input (from)",
|
||||||
|
"direction_output": "output (to)",
|
||||||
|
"video_server_processing": "Video uploads to a server for processing by default, learn how to set it up locally here."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"convert": {
|
||||||
|
"panel": {
|
||||||
|
"convert_all": "Convert all",
|
||||||
|
"download_all": "Download all as .zip",
|
||||||
|
"remove_all": "Remove all files",
|
||||||
|
"set_all_to": "Set all to",
|
||||||
|
"na": "N/A"
|
||||||
|
},
|
||||||
|
"dropdown": {
|
||||||
|
"audio": "Audio",
|
||||||
|
"video": "Video",
|
||||||
|
"doc": "Document",
|
||||||
|
"image": "Image",
|
||||||
|
"placeholder": "Search format"
|
||||||
|
},
|
||||||
|
"tooltips": {
|
||||||
|
"unknown_file": "Unknown file type",
|
||||||
|
"audio_file": "Audio file",
|
||||||
|
"video_file": "Video file",
|
||||||
|
"document_file": "Document file",
|
||||||
|
"image_file": "Image file",
|
||||||
|
"convert_file": "Convert this file",
|
||||||
|
"download_file": "Download this file"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"cant_convert": "We can't convert this file.",
|
||||||
|
"vertd_server": "what are you doing..? you're supposed to run the vertd server!",
|
||||||
|
"unsupported_format": "Only image, video, audio, and document files are supported",
|
||||||
|
"vertd_not_found": "Could not find the vertd instance to start video conversion. Are you sure the instance URL is set correctly?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"title": "Settings",
|
||||||
|
"errors": {
|
||||||
|
"save_failed": "Failed to save settings!"
|
||||||
|
},
|
||||||
|
"appearance": {
|
||||||
|
"title": "Appearance",
|
||||||
|
"brightness_theme": "Brightness theme",
|
||||||
|
"brightness_description": "Want a sunny flash-bang, or a quiet lonely night?",
|
||||||
|
"light": "Light",
|
||||||
|
"dark": "Dark",
|
||||||
|
"effect_settings": "Effect settings",
|
||||||
|
"effect_description": "Would you like fancy effects, or a more static experience?",
|
||||||
|
"enable": "Enable",
|
||||||
|
"disable": "Disable"
|
||||||
|
},
|
||||||
|
"conversion": {
|
||||||
|
"title": "Conversion",
|
||||||
|
"filename_format": "File name format",
|
||||||
|
"filename_description": "This will determine the name of the file on download, <b>not including the file extension.</b> You can put these following templates in the format, which will be replaced with the relevant information: <b>%name%</b> for the original file name, <b>%extension%</b> for the original file extension, and <b>%date%</b> for a date string of when the file was converted.",
|
||||||
|
"placeholder": "VERT_%name%",
|
||||||
|
"quality": "Conversion quality",
|
||||||
|
"quality_description": "This changes the default output quality of the converted files (in its category). Higher values may result in longer conversion times and file size.",
|
||||||
|
"quality_video": "This changes the default output quality of the converted video files. Higher values may result in longer conversion times and file size.",
|
||||||
|
"quality_audio": "Audio (kbps)",
|
||||||
|
"quality_images": "Image (%)",
|
||||||
|
"rate": "Sample rate (Hz)"
|
||||||
|
},
|
||||||
|
"vertd": {
|
||||||
|
"title": "Video conversion",
|
||||||
|
"status": "status:",
|
||||||
|
"loading": "loading...",
|
||||||
|
"available": "available, commit id {commitId}",
|
||||||
|
"unavailable": "unavailable (is the url right?)",
|
||||||
|
"description": "The <code>vertd</code> project is a server wrapper for FFmpeg. This allows you to convert videos through the convenience of VERT's web interface, while still being able to harness the power of your GPU to do it as quickly as possible.",
|
||||||
|
"hosting_info": "We host a public instance for your convenience, but it is quite easy to host your own on your PC or server if you know what you are doing. You can download the server binaries [vertd_link]here[/vertd_link] - the process of setting this up will become easier in the future, so stay tuned!",
|
||||||
|
"instance_url": "Instance URL",
|
||||||
|
"url_placeholder": "Example: http://localhost:24153",
|
||||||
|
"conversion_speed": "Conversion speed",
|
||||||
|
"speed_description": "This describes the tradeoff between speed and quality. Faster speeds will result in lower quality, but will get the job done quicker.",
|
||||||
|
"speeds": {
|
||||||
|
"very_slow": "Very Slow",
|
||||||
|
"slower": "Slower",
|
||||||
|
"slow": "Slow",
|
||||||
|
"medium": "Medium",
|
||||||
|
"fast": "Fast",
|
||||||
|
"ultra_fast": "Ultra Fast"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"privacy": {
|
||||||
|
"title": "Privacy",
|
||||||
|
"plausible_title": "Plausible analytics",
|
||||||
|
"plausible_description": "We use [plausible_link]Plausible[/plausible_link], a privacy-focused analytics tool, to gather completely anonymous statistics. All data is anonymized and aggregated, and no identifiable information is ever sent or stored. You can view the analytics [analytics_link]here[/analytics_link] and choose to opt out below.",
|
||||||
|
"opt_in": "Opt-in",
|
||||||
|
"opt_out": "Opt-out"
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"title": "Language",
|
||||||
|
"description": "Select your preferred language for the VERT interface."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"about": {
|
||||||
|
"title": "About",
|
||||||
|
"why": {
|
||||||
|
"title": "Why VERT?",
|
||||||
|
"description": "<b>File converters have always disappointed us.</b> They're ugly, riddled with ads, and most importantly; slow. We decided to solve this problem once and for all by making an alternative that solves all those problems, and more.<br/><br/>All non-video files are converted completely on-device; this means that there's no delay between sending and receiving the files from a server, and we never get to snoop on the files you convert.<br/><br/>Video files get uploaded to our lightning-fast RTX 4000 Ada server. Your videos stay on there for an hour if you do not convert them. If you do convert the file, the video will stay on the server for an hour, or until it is downloaded. The file will then be deleted from our server."
|
||||||
|
},
|
||||||
|
"sponsors": {
|
||||||
|
"title": "Sponsors",
|
||||||
|
"description": "Want to support us? Contact a developer in the [discord_link]Discord[/discord_link] server, or send an email to",
|
||||||
|
"email_copied": "Email copied to clipboard!"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"title": "Resources",
|
||||||
|
"discord": "Discord",
|
||||||
|
"source": "Source",
|
||||||
|
"email": "Email"
|
||||||
|
},
|
||||||
|
"donate": {
|
||||||
|
"title": "Donate to VERT",
|
||||||
|
"description": "With your support, we can keep maintaining and improving VERT.",
|
||||||
|
"one_time": "One-time",
|
||||||
|
"monthly": "Monthly",
|
||||||
|
"custom": "Custom",
|
||||||
|
"pay_now": "Pay now",
|
||||||
|
"donate_amount": "Donate ${amount} USD",
|
||||||
|
"thank_you": "Thank you for your donation!",
|
||||||
|
"payment_failed": "Payment failed: {message}{period} You have not been charged.",
|
||||||
|
"donation_error": "An error occurred while processing your donation. Please try again later.",
|
||||||
|
"payment_error": "Error fetching payment details. Please try again later."
|
||||||
|
},
|
||||||
|
"credits": {
|
||||||
|
"title": "Credits",
|
||||||
|
"contact_team": "If you would like to contact the development team, please use the email found on the \"Resources\" card.",
|
||||||
|
"notable_contributors": "Notable contributors",
|
||||||
|
"notable_description": "We'd like to thank these people for their major contributions to VERT.",
|
||||||
|
"github_contributors": "GitHub contributors",
|
||||||
|
"github_description": "Big [jpegify_link]thanks[/jpegify_link] to all these people for helping out! [github_link]Want to help too?[/github_link]",
|
||||||
|
"no_contributors": "Seems like no one has contributed yet... [contribute_link]be the first to contribute![/contribute_link]",
|
||||||
|
"libraries": "Libraries",
|
||||||
|
"libraries_description": "A big thanks to FFmpeg (audio, video), ImageMagick (images) and Pandoc (documents) for maintaining such excellent libraries for so many years. VERT relies on them to provide you with your conversions.",
|
||||||
|
"roles": {
|
||||||
|
"lead_developer": "Lead developer; conversion backend, UI implementation",
|
||||||
|
"developer": "Developer; UI implementation",
|
||||||
|
"designer": "Designer; UX, branding, marketing",
|
||||||
|
"docker_ci": "Maintaining Docker & CI support",
|
||||||
|
"former_cofounder": "Former co-founder & designer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"github_contributors": "Error fetching GitHub contributors"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workers": {
|
||||||
|
"errors": {
|
||||||
|
"general": "Error converting {file}: {message}",
|
||||||
|
"magick": "Error in Magick worker, image conversion may not work as expected.",
|
||||||
|
"ffmpeg": "Error loading ffmpeg, some features may not work.",
|
||||||
|
"no_audio": "No audio stream found.",
|
||||||
|
"invalid_rate": "Invalid sample rate specified: {rate}Hz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jpegify": {
|
||||||
|
"title": "SECRET JPEGIFY!!!",
|
||||||
|
"subtitle": "(shh... don't tell anyone!)",
|
||||||
|
"button": "JPEGIFY {compression}%!!!",
|
||||||
|
"download": "Download",
|
||||||
|
"delete": "Delete"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,205 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://inlang.com/schema/inlang-message-format",
|
||||||
|
"navbar": {
|
||||||
|
"upload": "Subir",
|
||||||
|
"convert": "Convertir",
|
||||||
|
"settings": "Ajustes",
|
||||||
|
"about": "Acerca de",
|
||||||
|
"toggle_theme": "Cambiar tema"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"copyright": "© {year} VERT.",
|
||||||
|
"source_code": "Código fuente",
|
||||||
|
"discord_server": "Servidor de Discord"
|
||||||
|
},
|
||||||
|
"upload": {
|
||||||
|
"title": "El convertidor de archivos que te encantará.",
|
||||||
|
"subtitle": "Todo el procesamiento de imágenes, audio y documentos es hecho en tu dispositivo. Los vídeos son convertidos en nuestros servidores ultra rápidos. Sin límite de tamaño de archivo, sin anuncios y de código abierto.",
|
||||||
|
"uploader": {
|
||||||
|
"text": "Arrastra o haz clic para {action}",
|
||||||
|
"convert": "convertir",
|
||||||
|
"jpegify": "jpegificar"
|
||||||
|
},
|
||||||
|
"cards": {
|
||||||
|
"title": "VERT soporta...",
|
||||||
|
"images": "Imágenes",
|
||||||
|
"audio": "Audio",
|
||||||
|
"documents": "Documentos",
|
||||||
|
"video": "Vídeo",
|
||||||
|
"video_server_processing": "Soportado por el servidor",
|
||||||
|
"local_supported": "Soportado localmente",
|
||||||
|
"status": {
|
||||||
|
"text": "<b>Estado:</b> {status}",
|
||||||
|
"ready": "listo",
|
||||||
|
"not_ready": "no listo"
|
||||||
|
},
|
||||||
|
"supported_formats": "Formatos soportados:"
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"partial_support": "Este formato solo se puede convertir a {direction}.",
|
||||||
|
"direction_input": "entrada (desde)",
|
||||||
|
"direction_output": "salida (hacia)",
|
||||||
|
"video_server_processing": "Por defecto, los vídeos se suben a un servidor para ser procesados. Aprende cómo instalarlo localmente aquí."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"convert": {
|
||||||
|
"panel": {
|
||||||
|
"convert_all": "Convertir todo",
|
||||||
|
"download_all": "Comprimir todo",
|
||||||
|
"remove_all": "Quitar todos los archivos",
|
||||||
|
"set_all_to": "Cambiar todos a",
|
||||||
|
"na": "N/A"
|
||||||
|
},
|
||||||
|
"dropdown": {
|
||||||
|
"audio": "Audio",
|
||||||
|
"video": "Vídeo",
|
||||||
|
"doc": "Documento",
|
||||||
|
"image": "Imagen",
|
||||||
|
"placeholder": "Buscar formato"
|
||||||
|
},
|
||||||
|
"tooltips": {
|
||||||
|
"unknown_file": "Formato de archivo desconocido",
|
||||||
|
"audio_file": "Audio",
|
||||||
|
"video_file": "Vídeo",
|
||||||
|
"document_file": "Documento",
|
||||||
|
"image_file": "Imagen",
|
||||||
|
"convert_file": "Convertir este archivo",
|
||||||
|
"download_file": "Descargar este archivo"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"cant_convert": "No podemos convertir este archivo.",
|
||||||
|
"vertd_server": "¿Qué estás haciendo..? ¡Debes ejecutar el servidor de vertd!",
|
||||||
|
"unsupported_format": "Solo aceptamos imágenes, vídeos, audios y documentos.",
|
||||||
|
"vertd_not_found": "No se encontró la instancia de vertd para iniciar la conversión de vídeos. ¿Estás seguro de que la URL es correcta?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"title": "Ajustes",
|
||||||
|
"errors": {
|
||||||
|
"save_failed": "¡No se han podido guardar los ajustes!"
|
||||||
|
},
|
||||||
|
"appearance": {
|
||||||
|
"title": "Apariencia",
|
||||||
|
"brightness_theme": "Tema",
|
||||||
|
"brightness_description": "¿Prefieres una flash-bang soleada o una silenciosa y solitaria noche?",
|
||||||
|
"light": "Claro",
|
||||||
|
"dark": "Oscuro",
|
||||||
|
"effect_settings": "Efectos",
|
||||||
|
"effect_description": "¿Prefieres efectos en la interfaz o una experiencia más estática?",
|
||||||
|
"enable": "Habilitar",
|
||||||
|
"disable": "Deshabilitar"
|
||||||
|
},
|
||||||
|
"conversion": {
|
||||||
|
"title": "Conversión",
|
||||||
|
"filename_format": "Formato del nombre de archivo",
|
||||||
|
"filename_description": "Esto va a determinar el nombre del archivo al ser descargado <b>sin incluir la extensión</b>. Puedes poner las siguientes plantillas en el formato, las cuales serán reemplazadas con la información que les corresponde: <b>%name%</b> para el nombre original, <b>%extension%</b> para la extensión original del archivo y <b>%date%</b> para la fecha de cuando el archivo fue convertido.",
|
||||||
|
"placeholder": "VERT_%name%",
|
||||||
|
"quality": "Calidad de la conversión",
|
||||||
|
"quality_description": "Esto cambia la calidad por defecto de los archivos convertidos (en su categoría). Valores más altos pueden resultar en tiempos de conversión y tamaños de archivo más largos.",
|
||||||
|
"quality_video": "Esto cambia la calidad por defecto de los vídeos convertidos. Valores más altos pueden resultar en tiempos de conversión y tamaños de archivo más largos.",
|
||||||
|
"quality_audio": "Audio (kbps)",
|
||||||
|
"quality_images": "Imagen (%)",
|
||||||
|
"rate": "Tasa de muestreo (Hz)"
|
||||||
|
},
|
||||||
|
"vertd": {
|
||||||
|
"title": "Conversión de vídeo",
|
||||||
|
"status": "estado:",
|
||||||
|
"loading": "cargando...",
|
||||||
|
"available": "disponible, id del commit {commitId}",
|
||||||
|
"unavailable": "no disponible (¿has comprobado la url?)",
|
||||||
|
"description": "<code>vertd</code> es un proyecto que actúa como un servidor intermediario (\"wrapper\") para FFmpeg. Permite convertir vídeos sin dejar de lado la conveniente interfaz web de VERT y, a la vez, aprovecha la potencia de tu GPU para hacerlo lo más rápido posible.",
|
||||||
|
"hosting_info": "Alojamos una instancia pública para tu conveniencia, pero es bastante fácil alojar una propia en tu PC o servidor si sabes lo que estás haciendo. Puedes descargar los binarios del servidor [vertd_link]aquí[/vertd_link]. ¡El proceso de instalación será más fácil en el futuro, así que mantente atento!",
|
||||||
|
"instance_url": "URL de la instancia",
|
||||||
|
"url_placeholder": "Ejemplo: http://localhost:24153",
|
||||||
|
"conversion_speed": "Velocidad de conversión",
|
||||||
|
"speed_description": "Esto describe el equilibrio entre velocidad y calidad. Velocidades más rápidas resultarán en una calidad más baja, pero harán el trabajo más rápido.",
|
||||||
|
"speeds": {
|
||||||
|
"very_slow": "Extremadamente lento",
|
||||||
|
"slower": "Muy lento",
|
||||||
|
"slow": "Lento",
|
||||||
|
"medium": "Medio",
|
||||||
|
"fast": "Rápido",
|
||||||
|
"ultra_fast": "Súper rápido"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"privacy": {
|
||||||
|
"title": "Privacidad",
|
||||||
|
"plausible_title": "Analíticas de Plausible",
|
||||||
|
"plausible_description": "Usamos [plausible_link]Plausible[/plausible_link], una herramienta de analíticas orientada a la privacidad para recopilar estadísticas completamente anónimas. Toda la información que recopilamos es anonimizada y agregada, y en ningún momento se envía ni se almacena información que permita identificarte. Puedes ver las estadísticas [analytics_link]aquí[/analytics_link] y excluirte de ellas a continuación:",
|
||||||
|
"opt_in": "Participar",
|
||||||
|
"opt_out": "No participar"
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"title": "Lenguaje",
|
||||||
|
"description": "Selecciona el lenguaje que prefieres usar para la interfaz de VERT."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"about": {
|
||||||
|
"title": "Acerca de",
|
||||||
|
"why": {
|
||||||
|
"title": "¿Por qué VERT?",
|
||||||
|
"description": "<b>Los conversores de archivos siempre nos han decepcionado.</b> Son feos, están llenos de anuncios y, lo más importante, son lentos. Decidimos solucionar este problema de una vez por todas creando una alternativa que resuelve todo eso, y más.<br/><br/>Todos los archivos (exceptuando vídeos) se convierten directamente en tu dispositivo; esto significa que no hay demoras por subir o bajar archivos de un servidor, y nunca tenemos acceso a los archivos que conviertes.<br/><br/>Los vídeos se suben a nuestro servidor ultra rápido equipado con una RTX 4000 Ada. Tus vídeos permanecen allí durante una hora si no los conviertes. Si los conviertes, el archivo se guarda durante una hora, o hasta que lo descargues. Luego, el archivo se elimina del servidor."
|
||||||
|
},
|
||||||
|
"sponsors": {
|
||||||
|
"title": "Patrocinadores",
|
||||||
|
"description": "¿Quieres apoyarnos? Contacta a un desarrollador en el servidor de [discord_link]Discord[/discord_link] o envía un correo a",
|
||||||
|
"email_copied": "¡Email copiado al portapapeles!"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"title": "Recursos",
|
||||||
|
"discord": "Discord",
|
||||||
|
"source": "Fuente",
|
||||||
|
"email": "Email"
|
||||||
|
},
|
||||||
|
"donate": {
|
||||||
|
"title": "Donar a VERT",
|
||||||
|
"description": "Con tu apoyo, podemos seguir manteniendo y mejorando VERT.",
|
||||||
|
"one_time": "Una sola vez",
|
||||||
|
"monthly": "Mensual",
|
||||||
|
"custom": "Personalizado",
|
||||||
|
"pay_now": "Pagar ahora",
|
||||||
|
"donate_amount": "Donar ${amount} USD",
|
||||||
|
"thank_you": "¡Gracias por tu donación!",
|
||||||
|
"payment_failed": "Pago fallido: {message}{period} No se ha efectuado ningún cargo.",
|
||||||
|
"donation_error": "Ha ocurrido un error al procesar tu donación. Por favor, inténtalo de nuevo más tarde.",
|
||||||
|
"payment_error": "Ha ocurrido un error al obtener los detalles del pago. Por favor, inténtalo de nuevo más tarde."
|
||||||
|
},
|
||||||
|
"credits": {
|
||||||
|
"title": "Créditos",
|
||||||
|
"contact_team": "Si te gustaría contactar al equipo de desarrollo, por favor usa el email que se encuentra en la tarjeta de \"Recursos\".",
|
||||||
|
"notable_contributors": "Colaboradores destacados",
|
||||||
|
"notable_description": "Queremos dar las gracias a las siguientes personas por sus importantes contribuciones a VERT.",
|
||||||
|
"github_contributors": "Contribuidores de GitHub",
|
||||||
|
"github_description": "¡Muchas [jpegify_link]gracias[/jpegify_link] a todos los que han contribuido! [github_link]¿Quieres contribuir también?[/github_link]",
|
||||||
|
"no_contributors": "Parece que nadie ha contribuido todavía... [contribute_link]¡Sé el primero en hacerlo![/contribute_link]",
|
||||||
|
"libraries": "Librerías",
|
||||||
|
"libraries_description": "Muchas gracias a FFmpeg (audio, vídeo), ImageMagick (imágenes) y Pandoc (documentos) por mantener librerías excelentes por tantos años. VERT depende de ellas para proporcionar tus conversiones.",
|
||||||
|
"roles": {
|
||||||
|
"lead_developer": "Líder de desarrollo; implementación del backend de conversión e interfaz",
|
||||||
|
"developer": "Desarrollador; implementación de la interfaz",
|
||||||
|
"designer": "Diseñador; UX, branding y marketing",
|
||||||
|
"docker_ci": "Mantenimiento del soporte para Docker y CI",
|
||||||
|
"former_cofounder": "Excofundador; diseñador"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"github_contributors": "Ocurrió un error mientras se obtenían los contribuidores de GitHub."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workers": {
|
||||||
|
"errors": {
|
||||||
|
"general": "Ocurrió un error mientras se convertía {file}: {message}",
|
||||||
|
"magick": "Ocurrió un error en el módulo de Magick, la conversión de imágenes puede que no funcione correctamente.",
|
||||||
|
"ffmpeg": "No se pudo cargar FFmpeg, algunas funciones podrían no funcionar.",
|
||||||
|
"no_audio": "No se encontró una pista de audio.",
|
||||||
|
"invalid_rate": "La tasa de muestreo especificada no es válida: {rate}Hz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jpegify": {
|
||||||
|
"title": "¡¡¡JPEGIFICADOR SECRETO!!!",
|
||||||
|
"subtitle": "(shh... ¡no se lo digas a nadie!)",
|
||||||
|
"button": "¡¡¡JPEGIFICAR {compression}%!!!",
|
||||||
|
"download": "Descargar",
|
||||||
|
"delete": "Eliminar"
|
||||||
|
}
|
||||||
|
}
|
||||||
63
package.json
63
package.json
|
|
@ -12,47 +12,54 @@
|
||||||
"lint": "prettier --check . && eslint ."
|
"lint": "prettier --check . && eslint ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@poppanator/sveltekit-svg": "^5.0.0",
|
"@poppanator/sveltekit-svg": "^5.0.1",
|
||||||
"@sveltejs/adapter-static": "^3.0.8",
|
"@sveltejs/adapter-static": "^3.0.9",
|
||||||
"@sveltejs/kit": "^2.16.0",
|
"@sveltejs/kit": "^2.37.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
||||||
"@types/eslint": "^9.6.1",
|
"@types/eslint": "^9.6.1",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.21",
|
||||||
"css-select": "5.1.0",
|
"css-select": "5.1.0",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.34.0",
|
||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-svelte": "^2.46.1",
|
"eslint-plugin-svelte": "^2.46.1",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.15.0",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.6.2",
|
||||||
"prettier-plugin-svelte": "^3.3.3",
|
"prettier-plugin-svelte": "^3.4.0",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.10",
|
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||||
"sass": "^1.83.4",
|
"sass": "^1.91.0",
|
||||||
"svelte": "^5.19.0",
|
"svelte": "^5.38.6",
|
||||||
"svelte-check": "^4.1.4",
|
"svelte-check": "^4.3.1",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.9.2",
|
||||||
"typescript-eslint": "^8.20.0",
|
"typescript-eslint": "^8.42.0",
|
||||||
"vite": "^5.4.11",
|
"vite": "^5.4.19",
|
||||||
"vite-plugin-top-level-await": "^1.5.0"
|
"vite-plugin-top-level-await": "^1.6.0",
|
||||||
|
"@inlang/paraglide-js": "2.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bjorn3/browser_wasi_shim": "^0.4.1",
|
"@bjorn3/browser_wasi_shim": "^0.4.2",
|
||||||
"@ffmpeg/ffmpeg": "^0.12.15",
|
"@ffmpeg/ffmpeg": "^0.12.15",
|
||||||
"@ffmpeg/util": "^0.12.2",
|
"@ffmpeg/util": "^0.12.2",
|
||||||
"@fontsource/azeret-mono": "^5.1.1",
|
"@fontsource/azeret-mono": "^5.2.9",
|
||||||
"@fontsource/lexend": "^5.1.2",
|
"@fontsource/lexend": "^5.2.9",
|
||||||
"@fontsource/radio-canada-big": "^5.1.1",
|
"@fontsource/radio-canada-big": "^5.2.6",
|
||||||
"@imagemagick/magick-wasm": "^0.0.34",
|
"@imagemagick/magick-wasm": "^0.0.35",
|
||||||
"@stripe/stripe-js": "^7.4.0",
|
"@stripe/stripe-js": "^7.9.0",
|
||||||
"byte-data": "^19.0.1",
|
"byte-data": "^19.0.1",
|
||||||
"client-zip": "^2.4.6",
|
"client-zip": "^2.5.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"lucide-svelte": "^0.475.0",
|
"lucide-svelte": "^0.542.0",
|
||||||
"music-metadata": "^11.0.0",
|
"music-metadata": "^11.8.3",
|
||||||
|
"overlayscrollbars": "^2.12.0",
|
||||||
|
"overlayscrollbars-svelte": "^0.5.5",
|
||||||
"p-queue": "^8.1.0",
|
"p-queue": "^8.1.0",
|
||||||
"riff-file": "^1.0.3",
|
"riff-file": "^1.0.3",
|
||||||
"svelte-stripe": "^1.4.0",
|
"svelte-stripe": "^1.4.0",
|
||||||
"vert-wasm": "^0.0.2",
|
"vert-wasm": "^0.0.2",
|
||||||
"vite-plugin-wasm": "^3.4.1"
|
"vite-plugin-wasm": "^3.5.0"
|
||||||
}
|
},
|
||||||
|
"trustedDependencies": [
|
||||||
|
"@parcel/watcher",
|
||||||
|
"@swc/core"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
cache
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ff77Td2rnvEqQyzBYT
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://inlang.com/schema/project-settings",
|
||||||
|
"baseLocale": "en",
|
||||||
|
"locales": [
|
||||||
|
"en",
|
||||||
|
"es"
|
||||||
|
],
|
||||||
|
"modules": [
|
||||||
|
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js",
|
||||||
|
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js"
|
||||||
|
],
|
||||||
|
"plugin.inlang.messageFormat": {
|
||||||
|
"pathPattern": "./messages/{locale}.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="%lang%">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import type { Handle } from '@sveltejs/kit';
|
||||||
|
import { paraglideMiddleware } from '$lib/paraglide/server';
|
||||||
|
|
||||||
|
// creating a handle to use the paraglide middleware
|
||||||
|
const paraglideHandle: Handle = ({ event, resolve }) =>
|
||||||
|
paraglideMiddleware(event.request, ({ request: localizedRequest, locale }) => {
|
||||||
|
event.request = localizedRequest;
|
||||||
|
return resolve(event, {
|
||||||
|
transformPageChunk: ({ html }) => {
|
||||||
|
return html.replace('%lang%', locale);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export const handle: Handle = paraglideHandle;
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
import type { Reroute } from '@sveltejs/kit';
|
||||||
|
import { deLocalizeUrl } from '$lib/paraglide/runtime';
|
||||||
|
|
||||||
|
export const reroute: Reroute = (request) => {
|
||||||
|
return deLocalizeUrl(request.url).pathname;
|
||||||
|
};
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
import ProgressBar from "../visual/ProgressBar.svelte";
|
import ProgressBar from "../visual/ProgressBar.svelte";
|
||||||
import FormatDropdown from "./FormatDropdown.svelte";
|
import FormatDropdown from "./FormatDropdown.svelte";
|
||||||
import { categories } from "$lib/converters";
|
import { categories } from "$lib/converters";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
const length = $derived(files.files.length);
|
const length = $derived(files.files.length);
|
||||||
const progress = $derived(files.files.filter((f) => f.result).length);
|
const progress = $derived(files.files.filter((f) => f.result).length);
|
||||||
|
|
@ -27,7 +28,7 @@
|
||||||
disabled={!files.ready}
|
disabled={!files.ready}
|
||||||
>
|
>
|
||||||
<RefreshCw size="24" />
|
<RefreshCw size="24" />
|
||||||
<p>Convert all</p>
|
<p>{m["convert.panel.convert_all"]()}</p>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn {$effects
|
class="btn {$effects
|
||||||
|
|
@ -37,7 +38,7 @@
|
||||||
onclick={() => files.downloadAll()}
|
onclick={() => files.downloadAll()}
|
||||||
>
|
>
|
||||||
<FolderArchiveIcon size="24" />
|
<FolderArchiveIcon size="24" />
|
||||||
<p>Download all as .zip</p>
|
<p>{m["convert.panel.download_all"]()}</p>
|
||||||
</button>
|
</button>
|
||||||
{#if $isMobile}
|
{#if $isMobile}
|
||||||
<button
|
<button
|
||||||
|
|
@ -48,10 +49,13 @@
|
||||||
onclick={() => (files.files = [])}
|
onclick={() => (files.files = [])}
|
||||||
>
|
>
|
||||||
<Trash2Icon size="24" />
|
<Trash2Icon size="24" />
|
||||||
<p>Remove all files</p>
|
<p>{m["convert.panel.remove_all"]()}</p>
|
||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<Tooltip text="Remove all files" position="right">
|
<Tooltip
|
||||||
|
text={m["convert.panel.remove_all"]()}
|
||||||
|
position="right"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
class="btn p-4 {$effects
|
class="btn p-4 {$effects
|
||||||
? ''
|
? ''
|
||||||
|
|
@ -66,8 +70,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full bg-separator h-0.5 flex md:hidden"></div>
|
<div class="w-full bg-separator h-0.5 flex md:hidden"></div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<p class="whitespace-nowrap text-xl">Set all to</p>
|
<p class="whitespace-nowrap text-xl">
|
||||||
{#if files.requiredConverters.length === 1}
|
{m["convert.panel.set_all_to"]()}
|
||||||
|
</p>
|
||||||
|
<!-- video and audio together still have this dropdown disabled because audio has just ffmpeg (video has vertd & ffmpeg), even tho it can convert between video and audio -->
|
||||||
|
{#if files.files.length > 0 && files.files.every((f) => JSON.stringify(f.converters) === JSON.stringify(files.files[0].converters))}
|
||||||
<FormatDropdown
|
<FormatDropdown
|
||||||
onselect={(r) =>
|
onselect={(r) =>
|
||||||
files.files.forEach((f) => {
|
files.files.forEach((f) => {
|
||||||
|
|
@ -77,9 +84,10 @@
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
{categories}
|
{categories}
|
||||||
|
dropdownSize={"large"}
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<Dropdown options={["N/A"]} disabled />
|
<Dropdown options={[m["convert.panel.na"]()]} disabled />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
class="w-4 h-4 ml-4 mt-0.5 flex-shrink-0"
|
class="w-4 h-4 ml-3 mt-0.5 flex-shrink-0"
|
||||||
style="transform: rotate({open
|
style="transform: rotate({open
|
||||||
? 180
|
? 180
|
||||||
: 0}deg); transition: transform {duration}ms {transition};"
|
: 0}deg); transition: transform {duration}ms {transition};"
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
extension?: string;
|
extension?: string;
|
||||||
prefix?: string;
|
prefix?: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
|
@ -17,29 +19,34 @@
|
||||||
extension,
|
extension,
|
||||||
prefix,
|
prefix,
|
||||||
type = "text",
|
type = "text",
|
||||||
|
min = 0,
|
||||||
|
max = 100,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative flex w-full {className}">
|
<div class="relative flex w-full {className}">
|
||||||
<input
|
<input
|
||||||
{type}
|
{type}
|
||||||
|
{min}
|
||||||
|
{max}
|
||||||
bind:value
|
bind:value
|
||||||
{placeholder}
|
{placeholder}
|
||||||
{disabled}
|
{disabled}
|
||||||
class="w-full p-3 rounded-lg bg-panel border-2 border-button
|
class="w-full p-3 rounded-lg bg-panel border-2 border-button
|
||||||
{prefix ? 'pl-[2rem]' : 'pl-3'}
|
{prefix ? 'pl-[2rem]' : 'pl-3'}
|
||||||
{extension ? 'pr-[4rem]' : 'pr-3'}"
|
{extension ? 'pr-[4rem]' : 'pr-3'}
|
||||||
|
{disabled && 'opacity-50 cursor-not-allowed'}"
|
||||||
/>
|
/>
|
||||||
{#if prefix}
|
{#if prefix}
|
||||||
<div class="absolute left-0 top-0 bottom-0 flex items-center px-2">
|
<div class="absolute left-0 top-0 bottom-0 flex items-center px-2">
|
||||||
<span class="text-sm text-gray-400 px-2 py-1 rounded"
|
<span class="text-sm text-gray-400 px-2 py-1 rounded">{prefix}</span
|
||||||
>{prefix}</span
|
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if extension}
|
{#if extension}
|
||||||
<div class="absolute right-0 top-0 bottom-0 flex items-center px-4">
|
<div class="absolute right-0 top-0 bottom-0 flex items-center px-4">
|
||||||
<span class="text-sm bg-button text-black dynadark:text-white px-2 py-1 rounded"
|
<span
|
||||||
|
class="text-sm bg-button text-black dynadark:text-white px-2 py-1 rounded"
|
||||||
>{extension}</span
|
>{extension}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { duration, fade, transition } from "$lib/animation";
|
import { duration, fade, transition } from "$lib/animation";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
import { isMobile, files } from "$lib/store/index.svelte";
|
import { isMobile, files } from "$lib/store/index.svelte";
|
||||||
import type { Categories } from "$lib/types";
|
import type { Categories } from "$lib/types";
|
||||||
|
import clsx from "clsx";
|
||||||
import { ChevronDown, SearchIcon } from "lucide-svelte";
|
import { ChevronDown, SearchIcon } from "lucide-svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
|
|
@ -12,6 +14,7 @@
|
||||||
selected?: string;
|
selected?: string;
|
||||||
onselect?: (option: string) => void;
|
onselect?: (option: string) => void;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
dropdownSize?: "default" | "large" | "small";
|
||||||
};
|
};
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
|
@ -20,76 +23,127 @@
|
||||||
selected = $bindable(""),
|
selected = $bindable(""),
|
||||||
onselect,
|
onselect,
|
||||||
disabled,
|
disabled,
|
||||||
|
dropdownSize = "default",
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
let open = $state(false);
|
let open = $state(false);
|
||||||
let hover = $state(false);
|
|
||||||
let dropdown = $state<HTMLDivElement>();
|
let dropdown = $state<HTMLDivElement>();
|
||||||
let currentCategory = $state<string | null>();
|
let currentCategory = $state<string | null>();
|
||||||
let searchQuery = $state("");
|
let searchQuery = $state("");
|
||||||
let dropdownMenu: HTMLElement | undefined = $state();
|
let dropdownMenu: HTMLElement | undefined = $state();
|
||||||
|
let rootCategory: string | null = null;
|
||||||
|
|
||||||
// initialize current category
|
// initialize current category
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!currentCategory) {
|
if (currentCategory) return;
|
||||||
if (selected) {
|
let foundCat: string | undefined;
|
||||||
const foundCat = Object.keys(categories).find((cat) =>
|
|
||||||
categories[cat].formats.includes(selected),
|
if (selected) {
|
||||||
);
|
foundCat = Object.keys(categories).find((cat) =>
|
||||||
currentCategory =
|
categories[cat].formats.includes(selected),
|
||||||
foundCat || Object.keys(categories)[0] || null;
|
);
|
||||||
} else {
|
} else {
|
||||||
// find category based on file types
|
// find category based on file types
|
||||||
const fileFormats = files.files.map((f) => f.from);
|
const fileFormats = files.files.map((f) => f.from);
|
||||||
const foundCat = Object.keys(categories).find((cat) =>
|
foundCat = Object.keys(categories).find((cat) =>
|
||||||
fileFormats.some((format) =>
|
fileFormats.some((format) =>
|
||||||
categories[cat].formats.includes(format),
|
categories[cat].formats.includes(format),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
currentCategory =
|
|
||||||
foundCat || Object.keys(categories)[0] || null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentCategory = foundCat || Object.keys(categories)[0] || null;
|
||||||
|
rootCategory = currentCategory;
|
||||||
});
|
});
|
||||||
|
|
||||||
// other available categories based on current category (e.g. converting between video and audio)
|
// other available categories based on current category (e.g. converting between video and audio)
|
||||||
const availableCategories = $derived.by(() => {
|
const availableCategories = $derived.by(() => {
|
||||||
if (!currentCategory) return Object.keys(categories);
|
if (!rootCategory) return Object.keys(categories);
|
||||||
|
|
||||||
return Object.keys(categories).filter(
|
let finalCategories = Object.keys(categories).filter(
|
||||||
(cat) =>
|
(cat) =>
|
||||||
cat === currentCategory ||
|
cat === rootCategory ||
|
||||||
categories[cat].canConvertTo?.includes(currentCategory || ""),
|
categories[rootCategory!]?.canConvertTo?.includes(cat),
|
||||||
);
|
);
|
||||||
|
if (from === ".gif") finalCategories.push("video");
|
||||||
|
|
||||||
|
return finalCategories;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const shouldInclude = (format: string, category: string): boolean => {
|
||||||
|
// if converting from audio to video, dont show gifs
|
||||||
|
if (
|
||||||
|
categories["audio"]?.formats.includes(from ?? "") &&
|
||||||
|
format === ".gif"
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const filteredData = $derived.by(() => {
|
const filteredData = $derived.by(() => {
|
||||||
|
const normalize = (str: string) => str.replace(/^\./, "").toLowerCase();
|
||||||
|
|
||||||
|
// if no query, return formats for current category
|
||||||
if (!searchQuery) {
|
if (!searchQuery) {
|
||||||
return {
|
return {
|
||||||
categories: availableCategories,
|
categories: availableCategories,
|
||||||
formats: currentCategory
|
formats: currentCategory
|
||||||
? categories[currentCategory].formats
|
? categories[currentCategory].formats.filter((format) =>
|
||||||
|
shouldInclude(format, currentCategory!),
|
||||||
|
)
|
||||||
: [],
|
: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
const searchLower = normalize(searchQuery);
|
||||||
|
|
||||||
// filter categories that have matching formats
|
// find all categories that have formats matching the search query
|
||||||
const matchingCategories = availableCategories.filter((cat) =>
|
const matchingCategories = availableCategories.filter((cat) =>
|
||||||
categories[cat].formats.some((format) =>
|
categories[cat].formats.some(
|
||||||
format.toLowerCase().includes(searchQuery.toLowerCase()),
|
(format) =>
|
||||||
|
normalize(format).includes(searchLower) &&
|
||||||
|
shouldInclude(format, cat),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
if (matchingCategories.length === 0) {
|
||||||
|
return {
|
||||||
|
categories: availableCategories,
|
||||||
|
formats: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// only show formats from the current category that match the search
|
// if current category has no matches, switch to first category that does
|
||||||
const filteredFormats =
|
const currentCategoryHasMatches =
|
||||||
currentCategory && categories[currentCategory]
|
currentCategory &&
|
||||||
? categories[currentCategory].formats.filter((format) =>
|
matchingCategories.some((cat) => cat === currentCategory);
|
||||||
format
|
if (!currentCategoryHasMatches && matchingCategories.length > 0) {
|
||||||
.toLowerCase()
|
const newCategory = matchingCategories[0];
|
||||||
.includes(searchQuery.toLowerCase()),
|
currentCategory = newCategory;
|
||||||
)
|
}
|
||||||
: [];
|
|
||||||
|
// return formats only from the current category that match the search
|
||||||
|
let filteredFormats = currentCategory
|
||||||
|
? categories[currentCategory].formats.filter(
|
||||||
|
(format) =>
|
||||||
|
normalize(format).includes(searchLower) &&
|
||||||
|
shouldInclude(format, currentCategory!),
|
||||||
|
)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
// sorting exact match first, then others
|
||||||
|
filteredFormats = filteredFormats.sort((a, b) => {
|
||||||
|
const aExact = normalize(a) === searchLower;
|
||||||
|
const bExact = normalize(b) === searchLower;
|
||||||
|
if (aExact && !bExact) return -1;
|
||||||
|
if (!aExact && bExact) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
categories: matchingCategories,
|
categories:
|
||||||
|
matchingCategories.length > 0
|
||||||
|
? matchingCategories
|
||||||
|
: availableCategories,
|
||||||
formats: filteredFormats,
|
formats: filteredFormats,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
@ -97,6 +151,21 @@
|
||||||
const selectOption = (option: string) => {
|
const selectOption = (option: string) => {
|
||||||
selected = option;
|
selected = option;
|
||||||
open = false;
|
open = false;
|
||||||
|
|
||||||
|
// find the category of this option if it's not in the current category
|
||||||
|
if (
|
||||||
|
currentCategory &&
|
||||||
|
!categories[currentCategory].formats.includes(option)
|
||||||
|
) {
|
||||||
|
const formatCategory = Object.keys(categories).find((cat) =>
|
||||||
|
categories[cat].formats.includes(option),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (formatCategory) {
|
||||||
|
currentCategory = formatCategory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onselect?.(option);
|
onselect?.(option);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -106,7 +175,39 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSearch = (event: Event) => {
|
const handleSearch = (event: Event) => {
|
||||||
searchQuery = (event.target as HTMLInputElement).value;
|
const query = (event.target as HTMLInputElement).value;
|
||||||
|
searchQuery = query;
|
||||||
|
|
||||||
|
// find which categories have matching formats & switch
|
||||||
|
if (query) {
|
||||||
|
const queryLower = query.toLowerCase();
|
||||||
|
const categoriesWithMatches = availableCategories.filter((cat) =>
|
||||||
|
categories[cat].formats.some((format) =>
|
||||||
|
format.toLowerCase().includes(queryLower),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (categoriesWithMatches.length > 0) {
|
||||||
|
const currentHasMatches =
|
||||||
|
currentCategory &&
|
||||||
|
categories[currentCategory].formats.some((format) =>
|
||||||
|
format.toLowerCase().includes(queryLower),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!currentHasMatches) {
|
||||||
|
currentCategory = categoriesWithMatches[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEnter = (event: KeyboardEvent) => {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
event.preventDefault();
|
||||||
|
if (filteredData.formats.length > 0) {
|
||||||
|
selectOption(filteredData.formats[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clickDropdown = () => {
|
const clickDropdown = () => {
|
||||||
|
|
@ -159,12 +260,12 @@
|
||||||
class="relative flex items-center justify-center w-full font-display px-3 py-3.5 bg-button rounded-full overflow-hidden cursor-pointer focus:!outline-none
|
class="relative flex items-center justify-center w-full font-display px-3 py-3.5 bg-button rounded-full overflow-hidden cursor-pointer focus:!outline-none
|
||||||
{disabled ? 'opacity-50 cursor-auto' : 'cursor-pointer'}"
|
{disabled ? 'opacity-50 cursor-auto' : 'cursor-pointer'}"
|
||||||
onclick={() => clickDropdown()}
|
onclick={() => clickDropdown()}
|
||||||
onmouseenter={() => (hover = true)}
|
|
||||||
onmouseleave={() => (hover = false)}
|
|
||||||
{disabled}
|
{disabled}
|
||||||
>
|
>
|
||||||
<!-- <p>{selected}</p> -->
|
<!-- <p>{selected}</p> -->
|
||||||
<div class="grid grid-cols-1 grid-rows-1 w-fit flex-grow-0">
|
<div
|
||||||
|
class="grid grid-cols-1 grid-rows-1 w-fit flex-grow-0 max-h-[2.5rem] overflow-hidden"
|
||||||
|
>
|
||||||
{#key selected}
|
{#key selected}
|
||||||
<p
|
<p
|
||||||
in:fade={{
|
in:fade={{
|
||||||
|
|
@ -175,7 +276,7 @@
|
||||||
duration,
|
duration,
|
||||||
easing: quintOut,
|
easing: quintOut,
|
||||||
}}
|
}}
|
||||||
class="col-start-1 row-start-1 text-center font-body font-medium"
|
class="col-start-1 row-start-1 text-center font-body font-medium truncate max-w-[4rem]"
|
||||||
>
|
>
|
||||||
{selected}
|
{selected}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -183,7 +284,7 @@
|
||||||
{#if currentCategory}
|
{#if currentCategory}
|
||||||
{#each categories[currentCategory].formats as option}
|
{#each categories[currentCategory].formats as option}
|
||||||
<p
|
<p
|
||||||
class="col-start-1 row-start-1 invisible pointer-events-none"
|
class="col-start-1 row-start-1 invisible pointer-events-none truncate max-w-[2.5rem]"
|
||||||
>
|
>
|
||||||
{option}
|
{option}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -191,7 +292,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
class="w-4 h-4 ml-4 mt-0.5 flex-shrink-0"
|
class="w-4 h-4 ml-3 mt-0.5 flex-shrink-0"
|
||||||
style="transform: rotate({open
|
style="transform: rotate({open
|
||||||
? 180
|
? 180
|
||||||
: 0}deg); transition: transform {duration}ms {transition};"
|
: 0}deg); transition: transform {duration}ms {transition};"
|
||||||
|
|
@ -200,24 +301,31 @@
|
||||||
{#if open}
|
{#if open}
|
||||||
<div
|
<div
|
||||||
bind:this={dropdownMenu}
|
bind:this={dropdownMenu}
|
||||||
style={hover ? "will-change: opacity, fade, transform" : ""}
|
|
||||||
transition:fade={{
|
transition:fade={{
|
||||||
duration,
|
duration,
|
||||||
easing: quintOut,
|
easing: quintOut,
|
||||||
}}
|
}}
|
||||||
class={$isMobile
|
class={clsx(
|
||||||
? "fixed inset-x-0 bottom-0 w-full z-[200] shadow-xl bg-panel-alt shadow-black/25 rounded-t-2xl overflow-hidden"
|
$isMobile
|
||||||
: "w-[250%] min-w-full shadow-xl bg-panel-alt shadow-black/25 absolute -translate-x-1/2 top-full mt-2 z-50 rounded-2xl overflow-hidden"}
|
? "fixed inset-x-0 bottom-0 w-full z-[200] shadow-xl bg-panel-alt shadow-black/25 rounded-t-2xl overflow-hidden"
|
||||||
|
: "min-w-full shadow-xl bg-panel-alt shadow-black/25 absolute -translate-x-1/2 top-full mt-2 z-50 rounded-2xl overflow-hidden",
|
||||||
|
!$isMobile && {
|
||||||
|
"w-[320%]": dropdownSize === "large",
|
||||||
|
"w-[250%]": dropdownSize === "default",
|
||||||
|
"w-[150%]": dropdownSize === "small",
|
||||||
|
},
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<!-- search box -->
|
<!-- search box -->
|
||||||
<div class="p-3 w-full">
|
<div class="p-3 w-full">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search format"
|
placeholder={m["convert.dropdown.placeholder"]()}
|
||||||
class="flex-grow w-full !pl-11 !pr-3 rounded-lg bg-panel text-foreground"
|
class="flex-grow w-full !pl-11 !pr-3 rounded-lg bg-panel text-foreground"
|
||||||
bind:value={searchQuery}
|
bind:value={searchQuery}
|
||||||
oninput={handleSearch}
|
oninput={handleSearch}
|
||||||
|
onkeydown={onEnter}
|
||||||
onfocus={() => {}}
|
onfocus={() => {}}
|
||||||
id="format-search"
|
id="format-search"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
|
|
@ -227,38 +335,56 @@
|
||||||
>
|
>
|
||||||
<SearchIcon class="w-4 h-4" />
|
<SearchIcon class="w-4 h-4" />
|
||||||
</span>
|
</span>
|
||||||
|
{#if searchQuery}
|
||||||
|
<span
|
||||||
|
class="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-muted"
|
||||||
|
style="font-size: 0.7rem;"
|
||||||
|
>
|
||||||
|
{filteredData.formats.length}
|
||||||
|
{filteredData.formats.length === 1
|
||||||
|
? "result"
|
||||||
|
: "results"}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- available categories -->
|
<!-- available categories -->
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
{#each filteredData.categories as category}
|
{#each filteredData.categories as category}
|
||||||
<button
|
<button
|
||||||
class="flex-grow text-lg hover:text-muted/20 border-b-[1px] pb-2 capitalize {currentCategory ===
|
class="flex-grow text-lg hover:text-muted/20 border-b-[1px] pb-2 capitalize
|
||||||
category
|
{currentCategory === category
|
||||||
? 'text-accent border-b-accent'
|
? 'text-accent border-b-accent'
|
||||||
: 'border-b-separator text-muted'}"
|
: 'border-b-separator text-muted'}"
|
||||||
onclick={() => selectCategory(category)}
|
onclick={() => selectCategory(category)}
|
||||||
>
|
>
|
||||||
{category}
|
{(m as any)[`convert.dropdown.${category}`]?.()}
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- available formats -->
|
<!-- available formats -->
|
||||||
<div class="max-h-80 overflow-y-auto grid grid-cols-3 gap-2 p-2">
|
<div class="max-h-80 overflow-y-auto grid grid-cols-3 gap-2 p-2">
|
||||||
{#each filteredData.formats as format}
|
{#if filteredData.formats.length > 0}
|
||||||
<button
|
{#each filteredData.formats as format}
|
||||||
class="w-full p-2 text-center rounded-xl
|
<button
|
||||||
{format === selected
|
class="w-full p-2 text-center rounded-xl
|
||||||
? 'bg-accent text-black'
|
{format === selected
|
||||||
: 'hover:bg-panel'}
|
? 'bg-accent text-black'
|
||||||
{format === from ? 'bg-separator' : ''}"
|
: format === from
|
||||||
onclick={() => selectOption(format)}
|
? 'bg-separator'
|
||||||
>
|
: 'hover:bg-panel'}"
|
||||||
{format}
|
onclick={() => selectOption(format)}
|
||||||
</button>
|
>
|
||||||
{/each}
|
{format}
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
{:else}
|
||||||
|
<div class="col-span-3 text-center p-4 text-muted">
|
||||||
|
{searchQuery
|
||||||
|
? "No formats match your search"
|
||||||
|
: "No formats available"}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
import { converters } from "$lib/converters";
|
import { converters } from "$lib/converters";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { page } from "$app/state";
|
import { page } from "$app/state";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
class?: string;
|
class?: string;
|
||||||
|
|
@ -98,7 +99,11 @@
|
||||||
<UploadIcon class="w-full h-full text-on-accent" />
|
<UploadIcon class="w-full h-full text-on-accent" />
|
||||||
</div>
|
</div>
|
||||||
<h2 class="text-center text-2xl font-semibold mt-4">
|
<h2 class="text-center text-2xl font-semibold mt-4">
|
||||||
Drop or click to {jpegify ? "JPEGIFY" : "convert"}
|
{m["upload.uploader.text"]({
|
||||||
|
action: jpegify
|
||||||
|
? m["upload.uploader.jpegify"]()
|
||||||
|
: m["upload.uploader.convert"]()
|
||||||
|
})}
|
||||||
</h2>
|
</h2>
|
||||||
</Panel>
|
</Panel>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { GITHUB_URL_VERT, DISCORD_URL } from "$lib/consts";
|
import { GITHUB_URL_VERT, DISCORD_URL } from "$lib/consts";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
const items = Object.entries({
|
const items = $derived([
|
||||||
//"Privacy policy": "#",
|
[m["footer.source_code"](), GITHUB_URL_VERT],
|
||||||
"Source code": GITHUB_URL_VERT,
|
[m["footer.discord_server"](), DISCORD_URL],
|
||||||
"Discord server": DISCORD_URL,
|
]);
|
||||||
});
|
|
||||||
|
|
||||||
const year = new Date().getFullYear();
|
const year = new Date().getFullYear();
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
<div
|
<div
|
||||||
class="w-full h-full flex items-center justify-center text-muted gap-3 relative"
|
class="w-full h-full flex items-center justify-center text-muted gap-3 relative"
|
||||||
>
|
>
|
||||||
<p>© {year} VERT.</p>
|
<p>{m["footer.copyright"]({ year })}</p>
|
||||||
{#each items as [name, url] (name)}
|
{#each items as [name, url] (name)}
|
||||||
<!-- bullet point -->
|
<!-- bullet point -->
|
||||||
<p>•</p>
|
<p>•</p>
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
import Logo from "../../visual/svg/Logo.svelte";
|
import Logo from "../../visual/svg/Logo.svelte";
|
||||||
import { beforeNavigate } from "$app/navigation";
|
import { beforeNavigate } from "$app/navigation";
|
||||||
import Tooltip from "$lib/components/visual/Tooltip.svelte";
|
import Tooltip from "$lib/components/visual/Tooltip.svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
const items = $derived<
|
const items = $derived<
|
||||||
{
|
{
|
||||||
|
|
@ -33,13 +34,13 @@
|
||||||
}[]
|
}[]
|
||||||
>([
|
>([
|
||||||
{
|
{
|
||||||
name: "Upload",
|
name: m["navbar.upload"](),
|
||||||
url: "/",
|
url: "/",
|
||||||
activeMatch: (pathname) => pathname === "/",
|
activeMatch: (pathname) => pathname === "/",
|
||||||
icon: UploadIcon,
|
icon: UploadIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Convert",
|
name: m["navbar.convert"](),
|
||||||
url: "/convert/",
|
url: "/convert/",
|
||||||
activeMatch: (pathname) =>
|
activeMatch: (pathname) =>
|
||||||
pathname === "/convert/" || pathname === "/convert",
|
pathname === "/convert/" || pathname === "/convert",
|
||||||
|
|
@ -47,13 +48,13 @@
|
||||||
badge: files.files.length,
|
badge: files.files.length,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Settings",
|
name: m["navbar.settings"](),
|
||||||
url: "/settings/",
|
url: "/settings/",
|
||||||
activeMatch: (pathname) => pathname.startsWith("/settings"),
|
activeMatch: (pathname) => pathname.startsWith("/settings"),
|
||||||
icon: SettingsIcon,
|
icon: SettingsIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "About",
|
name: m["navbar.about"](),
|
||||||
url: "/about/",
|
url: "/about/",
|
||||||
activeMatch: (pathname) => pathname.startsWith("/about"),
|
activeMatch: (pathname) => pathname.startsWith("/about"),
|
||||||
icon: InfoIcon,
|
icon: InfoIcon,
|
||||||
|
|
@ -63,6 +64,7 @@
|
||||||
let links = $state<HTMLAnchorElement[]>([]);
|
let links = $state<HTMLAnchorElement[]>([]);
|
||||||
let container = $state<HTMLDivElement>();
|
let container = $state<HTMLDivElement>();
|
||||||
let containerRect = $derived(container?.getBoundingClientRect());
|
let containerRect = $derived(container?.getBoundingClientRect());
|
||||||
|
let isInitialized = $state(false);
|
||||||
|
|
||||||
const linkRects = $derived(links.map((l) => l.getBoundingClientRect()));
|
const linkRects = $derived(links.map((l) => l.getBoundingClientRect()));
|
||||||
|
|
||||||
|
|
@ -72,6 +74,16 @@
|
||||||
|
|
||||||
const isSecretPage = $derived(selectedIndex === -1);
|
const isSecretPage = $derived(selectedIndex === -1);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (containerRect && linkRects.length > 0 && links.length > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
isInitialized = true;
|
||||||
|
}, 10);
|
||||||
|
} else {
|
||||||
|
isInitialized = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
beforeNavigate((e) => {
|
beforeNavigate((e) => {
|
||||||
const oldIndex = items.findIndex((i) =>
|
const oldIndex = items.findIndex((i) =>
|
||||||
i.activeMatch(e.from?.url.pathname || ""),
|
i.activeMatch(e.from?.url.pathname || ""),
|
||||||
|
|
@ -144,7 +156,7 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<p class="font-medium hidden md:flex">
|
<p class="font-medium hidden md:flex min-w-0">
|
||||||
{item.name}
|
{item.name}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -156,7 +168,7 @@
|
||||||
<div bind:this={container}>
|
<div bind:this={container}>
|
||||||
<Panel class="max-w-[778px] w-screen h-20 flex items-center gap-3 relative">
|
<Panel class="max-w-[778px] w-screen h-20 flex items-center gap-3 relative">
|
||||||
{@const linkRect = linkRects.at(selectedIndex) || linkRects[0]}
|
{@const linkRect = linkRects.at(selectedIndex) || linkRects[0]}
|
||||||
{#if linkRect}
|
{#if linkRect && isInitialized}
|
||||||
<div
|
<div
|
||||||
class="absolute bg-panel-highlight rounded-xl"
|
class="absolute bg-panel-highlight rounded-xl"
|
||||||
style="width: {linkRect.width}px; height: {linkRect.height}px; top: {linkRect.top -
|
style="width: {linkRect.width}px; height: {linkRect.height}px; top: {linkRect.top -
|
||||||
|
|
@ -180,7 +192,7 @@
|
||||||
{@render link(item, i)}
|
{@render link(item, i)}
|
||||||
{/each}
|
{/each}
|
||||||
<div class="w-0.5 bg-separator h-full hidden md:flex"></div>
|
<div class="w-0.5 bg-separator h-full hidden md:flex"></div>
|
||||||
<Tooltip text="Toggle theme" position="right">
|
<Tooltip text={m["navbar.toggle_theme"]()} position="right">
|
||||||
<button
|
<button
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
const isDark =
|
const isDark =
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex items-center justify-between max-w-sm p-4 gap-4 bg-accent-{color} border-accent-{color}-alt border-l-4 rounded-lg shadow-md"
|
class="flex items-center justify-between max-w-[100%] md:max-w-md p-4 gap-4 bg-accent-{color} border-accent-{color}-alt border-l-4 rounded-lg shadow-md"
|
||||||
in:fly={{
|
in:fly={{
|
||||||
duration: durations.enter,
|
duration: durations.enter,
|
||||||
easing: quintOut,
|
easing: quintOut,
|
||||||
|
|
@ -70,7 +70,9 @@
|
||||||
stroke="2"
|
stroke="2"
|
||||||
fill="none"
|
fill="none"
|
||||||
/>
|
/>
|
||||||
<p class="text-black font-normal whitespace-pre-wrap">{message}</p>
|
<p class="text-black font-normal whitespace-pre-wrap break-all">
|
||||||
|
{message}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="text-gray-600 hover:text-black flex-shrink-0"
|
class="text-gray-600 hover:text-black flex-shrink-0"
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,50 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fade } from "$lib/animation";
|
import { fade } from "$lib/animation";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: () => any;
|
children: () => any;
|
||||||
text: string;
|
text: string;
|
||||||
|
className?: string;
|
||||||
position?: "top" | "bottom" | "left" | "right";
|
position?: "top" | "bottom" | "left" | "right";
|
||||||
}
|
}
|
||||||
|
|
||||||
let { children, text, position = "top" }: Props = $props();
|
let { children, text, className, position = "top" }: Props = $props();
|
||||||
let showTooltip = $state(false);
|
let showTooltip = $state(false);
|
||||||
let timeout: number = 0;
|
let timeout: number = 0;
|
||||||
|
let triggerElement: HTMLElement;
|
||||||
|
let tooltipElement = $state<HTMLElement>();
|
||||||
|
let tooltipPosition = $state({ x: 0, y: 0 });
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
|
if (!triggerElement) return;
|
||||||
|
const rect = triggerElement.getBoundingClientRect();
|
||||||
|
|
||||||
|
switch (position) {
|
||||||
|
case "top":
|
||||||
|
tooltipPosition = {
|
||||||
|
x: rect.left + rect.width / 2,
|
||||||
|
y: rect.top - 10,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case "bottom":
|
||||||
|
tooltipPosition = {
|
||||||
|
x: rect.left + rect.width / 2,
|
||||||
|
y: rect.bottom + 10,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
tooltipPosition = {
|
||||||
|
x: rect.left - 10,
|
||||||
|
y: rect.top + rect.height / 2,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case "right":
|
||||||
|
tooltipPosition = {
|
||||||
|
x: rect.right + 10,
|
||||||
|
y: rect.top + rect.height / 2,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
showTooltip = true;
|
showTooltip = true;
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
@ -21,10 +53,23 @@
|
||||||
showTooltip = false;
|
showTooltip = false;
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (showTooltip && tooltipElement) {
|
||||||
|
document.body.appendChild(tooltipElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (tooltipElement && tooltipElement.parentNode === document.body) {
|
||||||
|
document.body.removeChild(tooltipElement);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<span
|
||||||
class="relative inline-block"
|
bind:this={triggerElement}
|
||||||
|
class="relative inline-block {className}"
|
||||||
onmouseenter={show}
|
onmouseenter={show}
|
||||||
onmouseleave={hide}
|
onmouseleave={hide}
|
||||||
onfocusin={show}
|
onfocusin={show}
|
||||||
|
|
@ -34,26 +79,30 @@
|
||||||
role="tooltip"
|
role="tooltip"
|
||||||
>
|
>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
{#if showTooltip}
|
</span>
|
||||||
<div
|
|
||||||
class="tooltip tooltip-{position}"
|
{#if showTooltip}
|
||||||
transition:fade={{
|
<span
|
||||||
duration: 100,
|
bind:this={tooltipElement}
|
||||||
}}
|
class="tooltip tooltip-{position}"
|
||||||
>
|
style="left: {tooltipPosition.x}px; top: {tooltipPosition.y}px;"
|
||||||
{text}
|
transition:fade={{
|
||||||
</div>
|
duration: 100,
|
||||||
{/if}
|
}}
|
||||||
</div>
|
>
|
||||||
|
{text}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.tooltip {
|
.tooltip {
|
||||||
--border-size: 1px;
|
--border-size: 1px;
|
||||||
@apply absolute z-10 bg-panel-alt text-foreground border border-stone-400 dynadark:border-white drop-shadow-lg text-xs px-4 py-2 rounded-full whitespace-nowrap pointer-events-none;
|
@apply fixed bg-panel-alt text-foreground border border-stone-400 dynadark:border-white drop-shadow-lg text-xs rounded-full pointer-events-none z-[999] max-w-xs break-words whitespace-normal;
|
||||||
|
@apply px-5 py-2.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-top {
|
.tooltip-top {
|
||||||
@apply bottom-full left-1/2 -translate-x-1/2 mb-3;
|
transform: translate(-50%, -100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-top::after {
|
.tooltip-top::after {
|
||||||
|
|
@ -67,7 +116,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-bottom {
|
.tooltip-bottom {
|
||||||
@apply top-full left-1/2 -translate-x-1/2 mt-3;
|
transform: translate(-50%, 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-bottom::after {
|
.tooltip-bottom::after {
|
||||||
|
|
@ -81,7 +130,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-left {
|
.tooltip-left {
|
||||||
@apply right-full top-1/2 -translate-y-1/2 mr-3;
|
transform: translate(-100%, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-left::after {
|
.tooltip-left::after {
|
||||||
|
|
@ -89,7 +138,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-right {
|
.tooltip-right {
|
||||||
@apply left-full top-1/2 -translate-y-1/2 ml-3;
|
transform: translate(0%, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-right::after {
|
.tooltip-right::after {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ export class FormatInfo {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
name: string,
|
name: string,
|
||||||
public fromSupported: boolean,
|
public fromSupported = true,
|
||||||
public toSupported: boolean,
|
public toSupported = true,
|
||||||
|
public isNative = true,
|
||||||
) {
|
) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
if (!this.name.startsWith(".")) {
|
if (!this.name.startsWith(".")) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,34 @@ import { FFmpeg } from "@ffmpeg/ffmpeg";
|
||||||
import { browser } from "$app/environment";
|
import { browser } from "$app/environment";
|
||||||
import { error, log } from "$lib/logger";
|
import { error, log } from "$lib/logger";
|
||||||
import { addToast } from "$lib/store/ToastProvider";
|
import { addToast } from "$lib/store/ToastProvider";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import { Settings } from "$lib/sections/settings/index.svelte";
|
||||||
|
|
||||||
|
// TODO: differentiate in UI? (not native formats)
|
||||||
|
const videoFormats = [
|
||||||
|
"mkv",
|
||||||
|
"mp4",
|
||||||
|
"avi",
|
||||||
|
"mov",
|
||||||
|
"webm",
|
||||||
|
"ts",
|
||||||
|
"mts",
|
||||||
|
"m2ts",
|
||||||
|
"wmv",
|
||||||
|
"mpg",
|
||||||
|
"mpeg",
|
||||||
|
"flv",
|
||||||
|
"f4v",
|
||||||
|
"vob",
|
||||||
|
"m4v",
|
||||||
|
"3gp",
|
||||||
|
"3g2",
|
||||||
|
"mxf",
|
||||||
|
"ogv",
|
||||||
|
"rm",
|
||||||
|
"rmvb",
|
||||||
|
"divx",
|
||||||
|
];
|
||||||
|
|
||||||
export class FFmpegConverter extends Converter {
|
export class FFmpegConverter extends Converter {
|
||||||
private ffmpeg: FFmpeg = null!;
|
private ffmpeg: FFmpeg = null!;
|
||||||
|
|
@ -15,6 +43,7 @@ export class FFmpegConverter extends Converter {
|
||||||
new FormatInfo("wav", true, true),
|
new FormatInfo("wav", true, true),
|
||||||
new FormatInfo("flac", true, true),
|
new FormatInfo("flac", true, true),
|
||||||
new FormatInfo("ogg", true, true),
|
new FormatInfo("ogg", true, true),
|
||||||
|
new FormatInfo("mogg", true, false),
|
||||||
new FormatInfo("oga", true, true),
|
new FormatInfo("oga", true, true),
|
||||||
new FormatInfo("opus", true, true),
|
new FormatInfo("opus", true, true),
|
||||||
new FormatInfo("aac", true, true),
|
new FormatInfo("aac", true, true),
|
||||||
|
|
@ -22,9 +51,24 @@ export class FFmpegConverter extends Converter {
|
||||||
new FormatInfo("wma", true, true),
|
new FormatInfo("wma", true, true),
|
||||||
new FormatInfo("amr", true, true),
|
new FormatInfo("amr", true, true),
|
||||||
new FormatInfo("ac3", true, true),
|
new FormatInfo("ac3", true, true),
|
||||||
new FormatInfo("alac", true, false),
|
new FormatInfo("alac", true, true),
|
||||||
new FormatInfo("aiff", true, true),
|
new FormatInfo("aiff", true, true),
|
||||||
|
new FormatInfo("aifc", true, true),
|
||||||
new FormatInfo("aif", true, true),
|
new FormatInfo("aif", true, true),
|
||||||
|
new FormatInfo("mp1", true, false),
|
||||||
|
new FormatInfo("mp2", true, true),
|
||||||
|
new FormatInfo("mpc", true, false), // unknown if it works, can't find sample file but ffmpeg should support i think?
|
||||||
|
//new FormatInfo("raw", true, false), // usually pcm
|
||||||
|
new FormatInfo("dsd", true, false), // dsd
|
||||||
|
new FormatInfo("dsf", true, false), // dsd
|
||||||
|
new FormatInfo("dff", true, false), // dsd
|
||||||
|
new FormatInfo("mqa", true, false),
|
||||||
|
new FormatInfo("au", true, true),
|
||||||
|
new FormatInfo("caf", true, true),
|
||||||
|
new FormatInfo("m4b", true, true),
|
||||||
|
new FormatInfo("voc", true, true),
|
||||||
|
new FormatInfo("weba", true, true),
|
||||||
|
...videoFormats.map((f) => new FormatInfo(f, true, true, false)),
|
||||||
];
|
];
|
||||||
|
|
||||||
public readonly reportsProgress = true;
|
public readonly reportsProgress = true;
|
||||||
|
|
@ -47,41 +91,542 @@ export class FFmpegConverter extends Converter {
|
||||||
})();
|
})();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error(["converters", this.name], `error loading ffmpeg: ${err}`);
|
error(["converters", this.name], `error loading ffmpeg: ${err}`);
|
||||||
addToast(
|
addToast("error", m["workers.errors.ffmpeg"]());
|
||||||
"error",
|
|
||||||
`Error loading ffmpeg, some features may not work.`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async convert(input: VertFile, to: string): Promise<VertFile> {
|
public async convert(input: VertFile, to: string): Promise<VertFile> {
|
||||||
if (!to.startsWith(".")) to = `.${to}`;
|
if (!to.startsWith(".")) to = `.${to}`;
|
||||||
const ffmpeg = new FFmpeg();
|
|
||||||
ffmpeg.on("progress", (progress) => {
|
let conversionError: string | null = null;
|
||||||
input.progress = progress.progress * 100;
|
const ffmpeg = await this.setupFFmpeg(input);
|
||||||
});
|
|
||||||
const baseURL =
|
// listen for errors during conversion
|
||||||
"https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.6/dist/esm";
|
const errorListener = (l: { message: string }) => {
|
||||||
await ffmpeg.load({
|
const msg = l.message;
|
||||||
coreURL: `${baseURL}/ffmpeg-core.js`,
|
if (
|
||||||
wasmURL: `${baseURL}/ffmpeg-core.wasm`,
|
msg.includes("Specified sample rate") &&
|
||||||
});
|
msg.includes("is not supported")
|
||||||
|
) {
|
||||||
|
const rate = Settings.instance.settings.ffmpegCustomSampleRate;
|
||||||
|
conversionError = m["workers.errors.invalid_rate"]({ rate });
|
||||||
|
} else if (msg.includes("Stream map '0:a:0' matches no streams.")) {
|
||||||
|
conversionError = m["workers.errors.no_audio"]();
|
||||||
|
} else if (
|
||||||
|
msg.includes("Error initializing output stream") ||
|
||||||
|
msg.includes("Error while opening encoder") ||
|
||||||
|
msg.includes("Error while opening decoder") ||
|
||||||
|
(msg.includes("Error") && msg.includes("stream")) ||
|
||||||
|
msg.includes("Conversion failed!")
|
||||||
|
) {
|
||||||
|
// other general errors
|
||||||
|
if (!conversionError) conversionError = msg;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ffmpeg.on("log", errorListener);
|
||||||
|
|
||||||
const buf = new Uint8Array(await input.file.arrayBuffer());
|
const buf = new Uint8Array(await input.file.arrayBuffer());
|
||||||
await ffmpeg.writeFile("input", buf);
|
await ffmpeg.writeFile("input", buf);
|
||||||
log(
|
log(
|
||||||
["converters", this.name],
|
["converters", this.name],
|
||||||
`wrote ${input.name} to ffmpeg virtual fs`,
|
`wrote ${input.name} to ffmpeg virtual fs`,
|
||||||
);
|
);
|
||||||
await ffmpeg.exec(["-i", "input", "output" + to]);
|
|
||||||
log(["converters", this.name], `executed ffmpeg command`);
|
const command = await this.buildConversionCommand(ffmpeg, input, to);
|
||||||
|
log(["converters", this.name], `FFmpeg command: ${command.join(" ")}`);
|
||||||
|
await ffmpeg.exec(command);
|
||||||
|
log(["converters", this.name], "executed ffmpeg command");
|
||||||
|
|
||||||
|
if (conversionError) {
|
||||||
|
ffmpeg.off("log", errorListener);
|
||||||
|
ffmpeg.terminate();
|
||||||
|
throw new Error(conversionError);
|
||||||
|
}
|
||||||
|
|
||||||
const output = (await ffmpeg.readFile(
|
const output = (await ffmpeg.readFile(
|
||||||
"output" + to,
|
"output" + to,
|
||||||
)) as unknown as Uint8Array;
|
)) as unknown as Uint8Array;
|
||||||
|
|
||||||
|
if (!output || output.length === 0) {
|
||||||
|
ffmpeg.off("log", errorListener);
|
||||||
|
ffmpeg.terminate();
|
||||||
|
throw new Error("empty file returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputFileName =
|
||||||
|
input.name.split(".").slice(0, -1).join(".") + to;
|
||||||
log(
|
log(
|
||||||
["converters", this.name],
|
["converters", this.name],
|
||||||
`read ${input.name.split(".").slice(0, -1).join(".") + to} from ffmpeg virtual fs`,
|
`read ${outputFileName} from ffmpeg virtual fs`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ffmpeg.off("log", errorListener);
|
||||||
ffmpeg.terminate();
|
ffmpeg.terminate();
|
||||||
return new VertFile(new File([output], input.name), to);
|
|
||||||
|
const outBuf = new Uint8Array(output).buffer.slice(0);
|
||||||
|
return new VertFile(new File([outBuf], outputFileName), to);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async setupFFmpeg(input: VertFile): Promise<FFmpeg> {
|
||||||
|
const ffmpeg = new FFmpeg();
|
||||||
|
|
||||||
|
ffmpeg.on("progress", (progress) => {
|
||||||
|
input.progress = progress.progress * 100;
|
||||||
|
});
|
||||||
|
|
||||||
|
ffmpeg.on("log", (l) => {
|
||||||
|
log(["converters", this.name], l.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
const baseURL =
|
||||||
|
"https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.10/dist/esm";
|
||||||
|
await ffmpeg.load({
|
||||||
|
coreURL: `${baseURL}/ffmpeg-core.js`,
|
||||||
|
wasmURL: `${baseURL}/ffmpeg-core.wasm`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return ffmpeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async detectAudioBitrate(ffmpeg: FFmpeg): Promise<number | null> {
|
||||||
|
const args = [
|
||||||
|
"-v",
|
||||||
|
"quiet",
|
||||||
|
"-select_streams",
|
||||||
|
"a:0",
|
||||||
|
"-show_entries",
|
||||||
|
"stream=bit_rate",
|
||||||
|
"-of",
|
||||||
|
"default=noprint_wrappers=1:nokey=1",
|
||||||
|
"input",
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
let bitrate: number | null = null;
|
||||||
|
|
||||||
|
const bitrateListener = (event: { message: string }) => {
|
||||||
|
if (bitrate !== null) return;
|
||||||
|
const n = parseInt(event.message.trim(), 10);
|
||||||
|
if (!n) return;
|
||||||
|
bitrate = Math.round(n / 1000);
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`Detected stream audio bitrate: ${bitrate} kbps`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ffmpeg.on("log", bitrateListener);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ffmpeg.ffprobe.call(ffmpeg, args);
|
||||||
|
return bitrate;
|
||||||
|
} finally {
|
||||||
|
ffmpeg.off("log", bitrateListener);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async detectAudioSampleRate(
|
||||||
|
ffmpeg: FFmpeg,
|
||||||
|
): Promise<number | null> {
|
||||||
|
const args = [
|
||||||
|
"-v",
|
||||||
|
"quiet",
|
||||||
|
"-select_streams",
|
||||||
|
"a:0",
|
||||||
|
"-show_entries",
|
||||||
|
"stream=sample_rate",
|
||||||
|
"-of",
|
||||||
|
"default=noprint_wrappers=1:nokey=1",
|
||||||
|
"input",
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
let sampleRate: number | null = null;
|
||||||
|
|
||||||
|
const sampleRateListener = (event: { message: string }) => {
|
||||||
|
if (sampleRate !== null) return;
|
||||||
|
const n = parseInt(event.message.trim(), 10);
|
||||||
|
if (!n) return;
|
||||||
|
sampleRate = n;
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`Detected stream audio sample rate: ${sampleRate} Hz`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ffmpeg.on("log", sampleRateListener);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ffmpeg.ffprobe.call(ffmpeg, args);
|
||||||
|
return sampleRate;
|
||||||
|
} finally {
|
||||||
|
ffmpeg.off("log", sampleRateListener);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async buildConversionCommand(
|
||||||
|
ffmpeg: FFmpeg,
|
||||||
|
input: VertFile,
|
||||||
|
to: string,
|
||||||
|
): Promise<string[]> {
|
||||||
|
const inputFormat = input.from.slice(1);
|
||||||
|
const outputFormat = to.slice(1);
|
||||||
|
|
||||||
|
const lossless = ["flac", "alac", "wav", "dsd", "dsf", "dff"];
|
||||||
|
const userSetting = Settings.instance.settings.ffmpegQuality;
|
||||||
|
const userSampleRate = Settings.instance.settings.ffmpegSampleRate;
|
||||||
|
const customSampleRate =
|
||||||
|
Settings.instance.settings.ffmpegCustomSampleRate ?? 44100;
|
||||||
|
let audioBitrateArgs: string[] = [];
|
||||||
|
let sampleRateArgs: string[] = [];
|
||||||
|
|
||||||
|
const isLosslessToLossy =
|
||||||
|
lossless.includes(inputFormat) && !lossless.includes(outputFormat);
|
||||||
|
if (userSetting !== "auto") {
|
||||||
|
// user's setting
|
||||||
|
audioBitrateArgs = ["-b:a", `${userSetting}k`];
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`using user setting for audio bitrate: ${userSetting}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// detect bitrate of original file and use
|
||||||
|
if (isLosslessToLossy) {
|
||||||
|
// use safe default
|
||||||
|
audioBitrateArgs = ["-b:a", "128k"];
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`converting from lossless to lossy, using default audio bitrate: 128k`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const inputBitrate = await this.detectAudioBitrate(ffmpeg);
|
||||||
|
audioBitrateArgs = inputBitrate
|
||||||
|
? ["-b:a", `${inputBitrate}k`]
|
||||||
|
: [];
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`using detected audio bitrate: ${inputBitrate}k`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sample rate setting
|
||||||
|
if (userSampleRate !== "auto") {
|
||||||
|
const rate =
|
||||||
|
userSampleRate === "custom"
|
||||||
|
? customSampleRate.toString()
|
||||||
|
: userSampleRate;
|
||||||
|
sampleRateArgs = ["-ar", rate];
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`using user setting for sample rate: ${rate}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// detect sample rate of original file and use
|
||||||
|
if (isLosslessToLossy) {
|
||||||
|
// use safe default
|
||||||
|
sampleRateArgs = ["-ar", "44100"];
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`converting from lossless to lossy, using default sample rate: 44100Hz`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const inputSampleRate =
|
||||||
|
await this.detectAudioSampleRate(ffmpeg);
|
||||||
|
sampleRateArgs = inputSampleRate
|
||||||
|
? ["-ar", inputSampleRate.toString()]
|
||||||
|
: [];
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`using detected audio sample rate: ${inputSampleRate}Hz`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// video to audio
|
||||||
|
if (videoFormats.includes(inputFormat)) {
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`Converting video ${input.from} to audio ${to}`,
|
||||||
|
);
|
||||||
|
return [
|
||||||
|
"-i",
|
||||||
|
"input",
|
||||||
|
"-map",
|
||||||
|
"0:a:0",
|
||||||
|
...audioBitrateArgs,
|
||||||
|
...sampleRateArgs,
|
||||||
|
"output" + to,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// audio to video
|
||||||
|
if (videoFormats.includes(outputFormat)) {
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`Converting audio ${input.from} to video ${to}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasAlbumArt = await this.extractAlbumArt(ffmpeg);
|
||||||
|
const codecArgs = toArgs(to);
|
||||||
|
|
||||||
|
if (hasAlbumArt) {
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
"Using album art as video background",
|
||||||
|
);
|
||||||
|
return [
|
||||||
|
"-loop",
|
||||||
|
"1",
|
||||||
|
"-i",
|
||||||
|
"cover.jpg",
|
||||||
|
"-i",
|
||||||
|
"input",
|
||||||
|
"-vf",
|
||||||
|
"scale=trunc(iw/2)*2:trunc(ih/2)*2",
|
||||||
|
"-shortest",
|
||||||
|
"-pix_fmt",
|
||||||
|
"yuv420p",
|
||||||
|
"-r",
|
||||||
|
"1",
|
||||||
|
...codecArgs,
|
||||||
|
...audioBitrateArgs,
|
||||||
|
...sampleRateArgs,
|
||||||
|
"output" + to,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
log(["converters", this.name], "Using solid color background");
|
||||||
|
return [
|
||||||
|
"-f",
|
||||||
|
"lavfi",
|
||||||
|
"-i",
|
||||||
|
"color=c=black:s=512x512:rate=1",
|
||||||
|
"-i",
|
||||||
|
"input",
|
||||||
|
"-shortest",
|
||||||
|
"-pix_fmt",
|
||||||
|
"yuv420p",
|
||||||
|
"-r",
|
||||||
|
"1",
|
||||||
|
...codecArgs,
|
||||||
|
...audioBitrateArgs,
|
||||||
|
...sampleRateArgs,
|
||||||
|
"output" + to,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// audio to audio
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
`Converting audio ${input.from} to audio ${to}`,
|
||||||
|
);
|
||||||
|
const { audio: audioCodec } = getCodecs(to);
|
||||||
|
return [
|
||||||
|
"-i",
|
||||||
|
"input",
|
||||||
|
"-c:a",
|
||||||
|
audioCodec,
|
||||||
|
...audioBitrateArgs,
|
||||||
|
...sampleRateArgs,
|
||||||
|
"output" + to,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private async extractAlbumArt(ffmpeg: FFmpeg): Promise<boolean> {
|
||||||
|
// extract using stream mapping (should work for most)
|
||||||
|
if (
|
||||||
|
await this.tryExtractAlbumArt(ffmpeg, [
|
||||||
|
"-i",
|
||||||
|
"input",
|
||||||
|
"-map",
|
||||||
|
"0:1",
|
||||||
|
"-c:v",
|
||||||
|
"copy",
|
||||||
|
"-update",
|
||||||
|
"1",
|
||||||
|
"cover.jpg",
|
||||||
|
])
|
||||||
|
) {
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
"Successfully extracted album art from stream 0:1",
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback: extract without stream mapping (this probably won't happen)
|
||||||
|
if (
|
||||||
|
await this.tryExtractAlbumArt(ffmpeg, [
|
||||||
|
"-i",
|
||||||
|
"input",
|
||||||
|
"-an",
|
||||||
|
"-c:v",
|
||||||
|
"copy",
|
||||||
|
"-update",
|
||||||
|
"1",
|
||||||
|
"cover.jpg",
|
||||||
|
])
|
||||||
|
) {
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
"Successfully extracted album art (fallback method)",
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(
|
||||||
|
["converters", this.name],
|
||||||
|
"No album art found, will create solid color background",
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async tryExtractAlbumArt(
|
||||||
|
ffmpeg: FFmpeg,
|
||||||
|
command: string[],
|
||||||
|
): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await ffmpeg.exec(command);
|
||||||
|
const coverData = await ffmpeg.readFile("cover.jpg");
|
||||||
|
return !!(coverData && (coverData as Uint8Array).length > 0);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// and here i was, thinking i'd be done with ffmpeg after finishing vertd
|
||||||
|
// but OH NO we just HAD to have someone suggest to allow album art video generation.
|
||||||
|
//
|
||||||
|
// i hate you SO much.
|
||||||
|
// - love, maddie
|
||||||
|
const toArgs = (ext: string): string[] => {
|
||||||
|
const codecs = getCodecs(ext);
|
||||||
|
const args = ["-c:v", codecs.video];
|
||||||
|
|
||||||
|
switch (codecs.video) {
|
||||||
|
case "libx264": {
|
||||||
|
args.push(
|
||||||
|
"-preset",
|
||||||
|
"ultrafast",
|
||||||
|
"-crf",
|
||||||
|
"18",
|
||||||
|
"-tune",
|
||||||
|
"stillimage",
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "libvpx": {
|
||||||
|
args.push("-c:v", "libvpx-vp9");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "mpeg2video": {
|
||||||
|
// for mpeg, mpg, vob, mxf
|
||||||
|
if (ext === ".mxf") args.push("-ar", "48000"); // force 48kHz sample rate
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push("-c:a", codecs.audio);
|
||||||
|
|
||||||
|
if (codecs.audio === "aac") args.push("-strict", "experimental");
|
||||||
|
|
||||||
|
if (ext === ".divx") args.unshift("-f", "avi");
|
||||||
|
if (ext === ".mxf") args.push("-strict", "unofficial");
|
||||||
|
|
||||||
|
return args;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCodecs = (ext: string): { video: string; audio: string } => {
|
||||||
|
switch (ext) {
|
||||||
|
// video <-> audio
|
||||||
|
case ".mp4":
|
||||||
|
case ".mkv":
|
||||||
|
case ".mov":
|
||||||
|
case ".mts":
|
||||||
|
case ".ts":
|
||||||
|
case ".m2ts":
|
||||||
|
case ".flv":
|
||||||
|
case ".f4v":
|
||||||
|
case ".m4v":
|
||||||
|
case ".3gp":
|
||||||
|
case ".3g2":
|
||||||
|
return { video: "libx264", audio: "aac" };
|
||||||
|
case ".wmv":
|
||||||
|
return { video: "wmv2", audio: "wmav2" };
|
||||||
|
case ".webm":
|
||||||
|
case ".ogv":
|
||||||
|
return {
|
||||||
|
video: ext === ".webm" ? "libvpx" : "libtheora",
|
||||||
|
audio: "libvorbis",
|
||||||
|
};
|
||||||
|
case ".avi":
|
||||||
|
case ".divx":
|
||||||
|
return { video: "mpeg4", audio: "libmp3lame" };
|
||||||
|
case ".mpg":
|
||||||
|
case ".mpeg":
|
||||||
|
case ".vob":
|
||||||
|
return { video: "mpeg2video", audio: "mp2" };
|
||||||
|
case ".mxf":
|
||||||
|
return { video: "mpeg2video", audio: "pcm_s16le" };
|
||||||
|
|
||||||
|
// audio
|
||||||
|
case ".mp3":
|
||||||
|
return { video: "libx264", audio: "libmp3lame" };
|
||||||
|
case ".flac":
|
||||||
|
return { video: "libx264", audio: "flac" };
|
||||||
|
case ".wav":
|
||||||
|
return { video: "libx264", audio: "pcm_s16le" };
|
||||||
|
case ".ogg":
|
||||||
|
case ".oga":
|
||||||
|
return { video: "libx264", audio: "libvorbis" };
|
||||||
|
case ".opus":
|
||||||
|
return { video: "libx264", audio: "libopus" };
|
||||||
|
case ".aac":
|
||||||
|
return { video: "libx264", audio: "aac" };
|
||||||
|
case ".m4a":
|
||||||
|
return { video: "libx264", audio: "aac" };
|
||||||
|
case ".alac":
|
||||||
|
return { video: "libx264", audio: "alac" };
|
||||||
|
case ".wma":
|
||||||
|
return { video: "libx264", audio: "wmav2" };
|
||||||
|
|
||||||
|
default:
|
||||||
|
return { video: "libx264", audio: "aac" };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONVERSION_BITRATES = [
|
||||||
|
"auto",
|
||||||
|
320,
|
||||||
|
256,
|
||||||
|
192,
|
||||||
|
128,
|
||||||
|
96,
|
||||||
|
64,
|
||||||
|
32,
|
||||||
|
] as const;
|
||||||
|
export type ConversionBitrate = (typeof CONVERSION_BITRATES)[number];
|
||||||
|
|
||||||
|
export const SAMPLE_RATES = [
|
||||||
|
"auto",
|
||||||
|
"custom",
|
||||||
|
"48000",
|
||||||
|
"44100",
|
||||||
|
"32000",
|
||||||
|
"22050",
|
||||||
|
"16000",
|
||||||
|
"11025",
|
||||||
|
"8000",
|
||||||
|
] as const;
|
||||||
|
export type SampleRate = (typeof SAMPLE_RATES)[number];
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import type { Categories } from "$lib/types";
|
import type { Categories } from "$lib/types";
|
||||||
|
import type { Converter } from "./converter.svelte";
|
||||||
import { FFmpegConverter } from "./ffmpeg.svelte";
|
import { FFmpegConverter } from "./ffmpeg.svelte";
|
||||||
import { PandocConverter } from "./pandoc.svelte";
|
import { PandocConverter } from "./pandoc.svelte";
|
||||||
import { VertdConverter } from "./vertd.svelte";
|
import { VertdConverter } from "./vertd.svelte";
|
||||||
|
|
@ -22,24 +23,40 @@ export function getConverterByFormat(format: string) {
|
||||||
|
|
||||||
export const categories: Categories = {
|
export const categories: Categories = {
|
||||||
image: { formats: [""], canConvertTo: [] },
|
image: { formats: [""], canConvertTo: [] },
|
||||||
video: { formats: [""], canConvertTo: [] }, // add "audio" when "nullptr/experimental-audio-to-video" is implemented
|
video: { formats: [""], canConvertTo: ["audio"] },
|
||||||
audio: { formats: [""], canConvertTo: [] }, // add "video" when "nullptr/experimental-audio-to-video" is implemented
|
audio: { formats: [""], canConvertTo: ["video"] },
|
||||||
docs: { formats: [""], canConvertTo: [] },
|
doc: { formats: [""], canConvertTo: [] },
|
||||||
};
|
};
|
||||||
|
|
||||||
categories.audio.formats =
|
categories.audio.formats =
|
||||||
converters
|
converters
|
||||||
.find((c) => c.name === "ffmpeg")
|
.find((c) => c.name === "ffmpeg")
|
||||||
?.formatStrings((f) => f.toSupported) || [];
|
?.supportedFormats.filter((f) => f.toSupported && f.isNative)
|
||||||
|
.map((f) => f.name) || [];
|
||||||
categories.video.formats =
|
categories.video.formats =
|
||||||
converters
|
converters
|
||||||
.find((c) => c.name === "vertd")
|
.find((c) => c.name === "vertd")
|
||||||
?.formatStrings((f) => f.toSupported) || [];
|
?.supportedFormats.filter((f) => f.toSupported && f.isNative)
|
||||||
|
.map((f) => f.name) || [];
|
||||||
categories.image.formats =
|
categories.image.formats =
|
||||||
converters
|
converters
|
||||||
.find((c) => c.name === "imagemagick")
|
.find((c) => c.name === "imagemagick")
|
||||||
?.formatStrings((f) => f.toSupported) || [];
|
?.formatStrings((f) => f.toSupported) || [];
|
||||||
categories.docs.formats =
|
categories.doc.formats =
|
||||||
converters
|
converters
|
||||||
.find((c) => c.name === "pandoc")
|
.find((c) => c.name === "pandoc")
|
||||||
?.formatStrings((f) => f.toSupported) || [];
|
?.supportedFormats.filter((f) => f.toSupported && f.isNative)
|
||||||
|
.map((f) => f.name) || [];
|
||||||
|
|
||||||
|
|
||||||
|
export const byNative = (format: string) => {
|
||||||
|
return (a: Converter, b: Converter) => {
|
||||||
|
const aFormat = a.supportedFormats.find((f) => f.name === format);
|
||||||
|
const bFormat = b.supportedFormats.find((f) => f.name === format);
|
||||||
|
|
||||||
|
if (aFormat && bFormat) {
|
||||||
|
return aFormat.isNative ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
import { FormatInfo } from "./converter.svelte";
|
||||||
|
|
||||||
|
// formats added from maya's somewhat automated testing
|
||||||
|
// placed into this file to easily differentiate (and also clean up the main magick file)
|
||||||
|
// some formats also have a comment from what i saw during testing
|
||||||
|
export const imageFormats = [
|
||||||
|
// TODO: yaml, json, txt - not sure when these are used (just contains image info seemingly?), probably will remove cause its not very useful for 99.99% of people
|
||||||
|
new FormatInfo("a", false, true),
|
||||||
|
new FormatInfo("aai", true, true),
|
||||||
|
new FormatInfo("ai", false, true),
|
||||||
|
new FormatInfo("art", false, true),
|
||||||
|
new FormatInfo("avs", true, true),
|
||||||
|
new FormatInfo("b", false, true),
|
||||||
|
new FormatInfo("bgr", false, true),
|
||||||
|
new FormatInfo("bgra", false, true),
|
||||||
|
new FormatInfo("bgro", false, true),
|
||||||
|
new FormatInfo("bmp2", true, true),
|
||||||
|
new FormatInfo("bmp3", true, true),
|
||||||
|
new FormatInfo("brf", false, true),
|
||||||
|
new FormatInfo("cal", false, true),
|
||||||
|
new FormatInfo("cals", false, true),
|
||||||
|
new FormatInfo("cin", true, true), // not ideal (made the image more "shadowy"?)
|
||||||
|
new FormatInfo("cip", false, true),
|
||||||
|
new FormatInfo("cmyk", false, true),
|
||||||
|
new FormatInfo("cmyka", false, true),
|
||||||
|
new FormatInfo("dcx", true, true),
|
||||||
|
new FormatInfo("dds", true, true),
|
||||||
|
new FormatInfo("dpx", true, true),
|
||||||
|
new FormatInfo("dxt1", true, true),
|
||||||
|
new FormatInfo("dxt5", true, true),
|
||||||
|
new FormatInfo("epdf", false, true),
|
||||||
|
new FormatInfo("epi", false, true),
|
||||||
|
new FormatInfo("eps2", false, true),
|
||||||
|
new FormatInfo("eps3", false, true),
|
||||||
|
new FormatInfo("epsf", false, true),
|
||||||
|
new FormatInfo("epsi", false, true),
|
||||||
|
new FormatInfo("ept", false, true),
|
||||||
|
new FormatInfo("ept2", false, true),
|
||||||
|
new FormatInfo("ept3", false, true),
|
||||||
|
new FormatInfo("exr", true, true),
|
||||||
|
new FormatInfo("farbfeld", true, true),
|
||||||
|
new FormatInfo("fax", true, true), // not ideal (image became super long for some reason)
|
||||||
|
new FormatInfo("ff", true, true),
|
||||||
|
new FormatInfo("fit", true, true), // not ideal (grayscale)
|
||||||
|
new FormatInfo("fits", true, true), // not ideal (grayscale)
|
||||||
|
new FormatInfo("fl32", true, true),
|
||||||
|
new FormatInfo("fts", true, true), // not ideal (grayscale)
|
||||||
|
new FormatInfo("ftxt", false, true),
|
||||||
|
new FormatInfo("g", false, true),
|
||||||
|
new FormatInfo("g3", true, true), // not ideal (image became super long for some reason)
|
||||||
|
new FormatInfo("g4", false, true),
|
||||||
|
new FormatInfo("gif87", true, true),
|
||||||
|
new FormatInfo("gray", false, true),
|
||||||
|
new FormatInfo("graya", false, true),
|
||||||
|
new FormatInfo("group4", false, true),
|
||||||
|
new FormatInfo("hrz", true, true),
|
||||||
|
new FormatInfo("icb", true, true),
|
||||||
|
new FormatInfo("icon", true, true),
|
||||||
|
new FormatInfo("info", false, true),
|
||||||
|
new FormatInfo("ipl", true, true),
|
||||||
|
new FormatInfo("isobrl", false, true),
|
||||||
|
new FormatInfo("isobrl6", false, true),
|
||||||
|
new FormatInfo("j2c", true, true),
|
||||||
|
new FormatInfo("j2k", true, true),
|
||||||
|
new FormatInfo("jng", true, true),
|
||||||
|
new FormatInfo("jp2", true, true),
|
||||||
|
new FormatInfo("jpc", true, true),
|
||||||
|
new FormatInfo("jpm", true, true),
|
||||||
|
new FormatInfo("jps", true, true),
|
||||||
|
//new FormatInfo("json", false, true),
|
||||||
|
new FormatInfo("map", false, true),
|
||||||
|
new FormatInfo("miff", true, true),
|
||||||
|
new FormatInfo("mng", true, true),
|
||||||
|
new FormatInfo("mono", false, true),
|
||||||
|
new FormatInfo("mtv", true, true),
|
||||||
|
new FormatInfo("o", false, true),
|
||||||
|
new FormatInfo("otb", true, true), // not ideal (completely black and white - maybe format is like that)
|
||||||
|
new FormatInfo("pal", false, true),
|
||||||
|
new FormatInfo("palm", true, true), // not ideal (screwed up colours)
|
||||||
|
new FormatInfo("pam", true, true),
|
||||||
|
new FormatInfo("pcd", true, true), // not ideal (turned big, bg orange, and colour just shifted? - maybe format)
|
||||||
|
new FormatInfo("pcds", true, true), // not ideal (turned big, bg orange, and colour just shifted? - maybe format)
|
||||||
|
new FormatInfo("pcl", false, true),
|
||||||
|
new FormatInfo("pct", true, true),
|
||||||
|
new FormatInfo("pcx", true, true),
|
||||||
|
new FormatInfo("pdb", true, true), // not ideal (completely black and white - maybe format is like that)
|
||||||
|
// new FormatInfo("pdf", false, true),
|
||||||
|
// new FormatInfo("pdfa", false, true),
|
||||||
|
new FormatInfo("pgx", true, true), // not ideal (grayscale - maybe format is like that)
|
||||||
|
new FormatInfo("phm", true, true),
|
||||||
|
new FormatInfo("picon", true, true), // not ideal (smudged out colours - format probably)
|
||||||
|
new FormatInfo("pict", true, true),
|
||||||
|
new FormatInfo("pjpeg", true, true),
|
||||||
|
new FormatInfo("png00", true, true),
|
||||||
|
new FormatInfo("png24", true, true),
|
||||||
|
new FormatInfo("png32", true, true),
|
||||||
|
new FormatInfo("png48", true, true),
|
||||||
|
new FormatInfo("png64", true, true),
|
||||||
|
new FormatInfo("png8", true, true),
|
||||||
|
new FormatInfo("ps", false, true),
|
||||||
|
new FormatInfo("ps1", false, true),
|
||||||
|
new FormatInfo("ps2", false, true),
|
||||||
|
new FormatInfo("ps3", false, true),
|
||||||
|
new FormatInfo("psb", true, true),
|
||||||
|
new FormatInfo("ptif", true, true),
|
||||||
|
new FormatInfo("qoi", true, true),
|
||||||
|
new FormatInfo("r", false, true),
|
||||||
|
new FormatInfo("ras", true, true),
|
||||||
|
new FormatInfo("rgb", false, true),
|
||||||
|
new FormatInfo("rgba", false, true),
|
||||||
|
new FormatInfo("rgbo", false, true),
|
||||||
|
new FormatInfo("rgf", true, true), // not ideal (completely black and white - maybe format is like that)
|
||||||
|
new FormatInfo("sgi", true, true),
|
||||||
|
new FormatInfo("six", true, true),
|
||||||
|
new FormatInfo("sixel", true, true),
|
||||||
|
new FormatInfo("sparse-color", false, true),
|
||||||
|
new FormatInfo("strimg", false, true),
|
||||||
|
new FormatInfo("sun", true, true),
|
||||||
|
new FormatInfo("svgz", false, true),
|
||||||
|
new FormatInfo("tga", true, true),
|
||||||
|
new FormatInfo("tiff64", true, true),
|
||||||
|
//new FormatInfo("txt", true, true),
|
||||||
|
new FormatInfo("ubrl", false, true),
|
||||||
|
new FormatInfo("ubrl6", false, true),
|
||||||
|
new FormatInfo("uil", false, true),
|
||||||
|
new FormatInfo("uyvy", false, true),
|
||||||
|
new FormatInfo("vda", true, true),
|
||||||
|
new FormatInfo("vicar", true, true), // not ideal (grayscale - maybe format is like that)
|
||||||
|
new FormatInfo("viff", true, true),
|
||||||
|
new FormatInfo("vips", true, true),
|
||||||
|
new FormatInfo("vst", true, true),
|
||||||
|
new FormatInfo("wbmp", true, true), // not ideal (completely black and white - maybe format is like that)
|
||||||
|
new FormatInfo("wpg", true, true),
|
||||||
|
new FormatInfo("xbm", true, true), // not ideal (completely black and white - maybe format is like that)
|
||||||
|
new FormatInfo("xpm", true, true),
|
||||||
|
new FormatInfo("xv", true, true),
|
||||||
|
//new FormatInfo("yaml", false, true),
|
||||||
|
new FormatInfo("ycbcr", false, true),
|
||||||
|
new FormatInfo("ycbcra", false, true),
|
||||||
|
new FormatInfo("yuv", false, true),
|
||||||
|
];
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { browser } from "$app/environment";
|
import { browser } from "$app/environment";
|
||||||
import { error, log } from "$lib/logger";
|
import { error, log } from "$lib/logger";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
import { addToast } from "$lib/store/ToastProvider";
|
import { addToast } from "$lib/store/ToastProvider";
|
||||||
import type { OmitBetterStrict, WorkerMessage } from "$lib/types";
|
import type { OmitBetterStrict, WorkerMessage } from "$lib/types";
|
||||||
import { VertFile } from "$lib/types";
|
import { VertFile } from "$lib/types";
|
||||||
import MagickWorker from "$lib/workers/magick?worker&url";
|
import MagickWorker from "$lib/workers/magick?worker&url";
|
||||||
import { Converter, FormatInfo } from "./converter.svelte";
|
import { Converter, FormatInfo } from "./converter.svelte";
|
||||||
|
import { imageFormats } from "./magick-automated";
|
||||||
|
import { Settings } from "$lib/sections/settings/index.svelte";
|
||||||
|
|
||||||
export class MagickConverter extends Converter {
|
export class MagickConverter extends Converter {
|
||||||
private worker: Worker = browser
|
private worker: Worker = browser
|
||||||
|
|
@ -17,33 +20,64 @@ export class MagickConverter extends Converter {
|
||||||
public ready = $state(false);
|
public ready = $state(false);
|
||||||
|
|
||||||
public supportedFormats = [
|
public supportedFormats = [
|
||||||
|
// manually tested formats
|
||||||
new FormatInfo("png", true, true),
|
new FormatInfo("png", true, true),
|
||||||
new FormatInfo("jpeg", true, true),
|
new FormatInfo("jpeg", true, true),
|
||||||
new FormatInfo("jpg", true, true),
|
new FormatInfo("jpg", true, true),
|
||||||
new FormatInfo("webp", true, true),
|
new FormatInfo("webp", true, true),
|
||||||
new FormatInfo("gif", true, true),
|
new FormatInfo("gif", true, true),
|
||||||
new FormatInfo("heic", true, false),
|
new FormatInfo("svg", true, true),
|
||||||
|
new FormatInfo("jxl", true, true),
|
||||||
|
new FormatInfo("avif", true, true),
|
||||||
|
new FormatInfo("heic", true, false), // seems to be unreliable? HEIC/HEIF is very weird if it will actually work
|
||||||
|
new FormatInfo("heif", true, false),
|
||||||
// TODO: .ico files can encode multiple images at various
|
// TODO: .ico files can encode multiple images at various
|
||||||
// sizes, bitdepths, etc. we should support that in future
|
// sizes, bitdepths, etc. we should support that in future
|
||||||
new FormatInfo("ico", true, true),
|
new FormatInfo("ico", true, true),
|
||||||
new FormatInfo("bmp", true, false),
|
new FormatInfo("bmp", true, true),
|
||||||
new FormatInfo("cur", true, false),
|
new FormatInfo("cur", true, true),
|
||||||
new FormatInfo("ani", true, false),
|
new FormatInfo("ani", true, false),
|
||||||
new FormatInfo("icns", true, false),
|
new FormatInfo("icns", true, false),
|
||||||
new FormatInfo("nef", true, false),
|
new FormatInfo("nef", true, false),
|
||||||
new FormatInfo("cr2", true, false),
|
new FormatInfo("cr2", true, false),
|
||||||
new FormatInfo("hdr", true, true),
|
new FormatInfo("hdr", true, true),
|
||||||
new FormatInfo("jpe", true, true),
|
new FormatInfo("jpe", true, true),
|
||||||
new FormatInfo("dng", true, false),
|
|
||||||
new FormatInfo("mat", true, true),
|
new FormatInfo("mat", true, true),
|
||||||
new FormatInfo("pbm", true, true),
|
new FormatInfo("pbm", true, true),
|
||||||
new FormatInfo("pfm", true, true),
|
new FormatInfo("pfm", true, true),
|
||||||
new FormatInfo("pgm", true, true),
|
new FormatInfo("pgm", true, true),
|
||||||
new FormatInfo("pnm", true, true),
|
new FormatInfo("pnm", true, true),
|
||||||
new FormatInfo("ppm", false, true),
|
new FormatInfo("ppm", true, true),
|
||||||
new FormatInfo("tif", true, true),
|
|
||||||
new FormatInfo("tiff", true, true),
|
new FormatInfo("tiff", true, true),
|
||||||
new FormatInfo("jfif", true, true),
|
new FormatInfo("jfif", true, true),
|
||||||
|
new FormatInfo("eps", false, true),
|
||||||
|
new FormatInfo("psd", true, true),
|
||||||
|
|
||||||
|
// raw camera formats
|
||||||
|
new FormatInfo("arw", true, false),
|
||||||
|
new FormatInfo("tif", true, true),
|
||||||
|
new FormatInfo("dng", true, false),
|
||||||
|
new FormatInfo("xcf", true, false),
|
||||||
|
new FormatInfo("rw2", true, false),
|
||||||
|
new FormatInfo("raf", true, false),
|
||||||
|
new FormatInfo("orf", true, false),
|
||||||
|
new FormatInfo("pef", true, false),
|
||||||
|
new FormatInfo("mos", true, false),
|
||||||
|
new FormatInfo("raw", true, false),
|
||||||
|
new FormatInfo("dcr", true, false),
|
||||||
|
new FormatInfo("crw", true, false),
|
||||||
|
new FormatInfo("cr3", true, false),
|
||||||
|
new FormatInfo("3fr", true, false),
|
||||||
|
new FormatInfo("erf", true, false),
|
||||||
|
new FormatInfo("mrw", true, false),
|
||||||
|
new FormatInfo("mef", true, false),
|
||||||
|
new FormatInfo("nrw", true, false),
|
||||||
|
new FormatInfo("srw", true, false),
|
||||||
|
new FormatInfo("sr2", true, false),
|
||||||
|
new FormatInfo("srf", true, false),
|
||||||
|
|
||||||
|
// formats added from maya's somewhat automated testing
|
||||||
|
...imageFormats,
|
||||||
];
|
];
|
||||||
|
|
||||||
public readonly reportsProgress = false;
|
public readonly reportsProgress = false;
|
||||||
|
|
@ -63,10 +97,7 @@ export class MagickConverter extends Converter {
|
||||||
["converters", this.name],
|
["converters", this.name],
|
||||||
`error in worker: ${message.error}`,
|
`error in worker: ${message.error}`,
|
||||||
);
|
);
|
||||||
addToast(
|
addToast("error", m["workers.errors.magick"]());
|
||||||
"error",
|
|
||||||
`Error in Magick worker, image conversion may not work as expected.`,
|
|
||||||
);
|
|
||||||
throw new Error(message.error);
|
throw new Error(message.error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -78,8 +109,33 @@ export class MagickConverter extends Converter {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
...args: any[]
|
...args: any[]
|
||||||
): Promise<VertFile> {
|
): Promise<VertFile> {
|
||||||
const compression: number | undefined = args.at(0);
|
let compression: number | undefined = args.at(0);
|
||||||
|
if (!compression) {
|
||||||
|
compression = Settings.instance.settings.magickQuality ?? 100;
|
||||||
|
log(["converters", this.name], `using user setting for quality: ${compression}%`);
|
||||||
|
}
|
||||||
log(["converters", this.name], `converting ${input.name} to ${to}`);
|
log(["converters", this.name], `converting ${input.name} to ${to}`);
|
||||||
|
|
||||||
|
// handle converting from SVG manually because magick-wasm doesn't support it
|
||||||
|
if (input.from === ".svg") {
|
||||||
|
try {
|
||||||
|
const blob = await this.svgToImage(input);
|
||||||
|
const pngFile = new VertFile(
|
||||||
|
new File([blob], input.name.replace(/\.svg$/i, ".png")),
|
||||||
|
input.to,
|
||||||
|
);
|
||||||
|
if (to === ".png") return pngFile; // if target is png, return it directly
|
||||||
|
return await this.convert(pngFile, to, ...args); // otherwise, recursively convert png to user's target format
|
||||||
|
} catch (err) {
|
||||||
|
error(
|
||||||
|
["converters", this.name],
|
||||||
|
`SVG conversion failed: ${err}`,
|
||||||
|
);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// every other format handled by magick worker
|
||||||
const msg = {
|
const msg = {
|
||||||
type: "convert",
|
type: "convert",
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -138,4 +194,67 @@ export class MagickConverter extends Converter {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async svgToImage(input: VertFile): Promise<Blob> {
|
||||||
|
log(["converters", this.name], `converting SVG to image (PNG)`);
|
||||||
|
|
||||||
|
const svgText = await input.file.text();
|
||||||
|
const svgBlob = new Blob([svgText], { type: "image/svg+xml" });
|
||||||
|
const svgUrl = URL.createObjectURL(svgBlob);
|
||||||
|
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
if (!ctx) throw new Error("Failed to get canvas context");
|
||||||
|
|
||||||
|
const img = new Image();
|
||||||
|
|
||||||
|
// try to extract dimensions from SVG, and if not fallback to default
|
||||||
|
let width = 512;
|
||||||
|
let height = 512;
|
||||||
|
const widthMatch = svgText.match(/width=["'](\d+)["']/);
|
||||||
|
const heightMatch = svgText.match(/height=["'](\d+)["']/);
|
||||||
|
const viewBoxMatch = svgText.match(
|
||||||
|
/viewBox=["'][^"']*\s+(\d+)\s+(\d+)["']/,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (widthMatch && heightMatch) {
|
||||||
|
width = parseInt(widthMatch[1]);
|
||||||
|
height = parseInt(heightMatch[1]);
|
||||||
|
} else if (viewBoxMatch) {
|
||||||
|
width = parseInt(viewBoxMatch[1]);
|
||||||
|
height = parseInt(viewBoxMatch[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
img.onload = () => {
|
||||||
|
try {
|
||||||
|
canvas.width = img.naturalWidth || width;
|
||||||
|
canvas.height = img.naturalHeight || height;
|
||||||
|
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
URL.revokeObjectURL(svgUrl);
|
||||||
|
if (blob) {
|
||||||
|
resolve(blob);
|
||||||
|
} else {
|
||||||
|
reject(
|
||||||
|
new Error("Failed to convert canvas to Blob"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, "image/png");
|
||||||
|
} catch (err) {
|
||||||
|
URL.revokeObjectURL(svgUrl);
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
img.onerror = () => {
|
||||||
|
URL.revokeObjectURL(svgUrl);
|
||||||
|
reject(new Error("Failed to load SVG image"));
|
||||||
|
};
|
||||||
|
|
||||||
|
img.src = svgUrl;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,21 @@ export class VertdConverter extends Converter {
|
||||||
new FormatInfo("mts", true, true),
|
new FormatInfo("mts", true, true),
|
||||||
new FormatInfo("ts", true, true),
|
new FormatInfo("ts", true, true),
|
||||||
new FormatInfo("m2ts", true, true),
|
new FormatInfo("m2ts", true, true),
|
||||||
|
new FormatInfo("mpg", true, true),
|
||||||
|
new FormatInfo("mpeg", true, true),
|
||||||
|
new FormatInfo("flv", true, true),
|
||||||
|
new FormatInfo("f4v", true, true),
|
||||||
|
new FormatInfo("vob", true, true),
|
||||||
|
new FormatInfo("m4v", true, true),
|
||||||
|
new FormatInfo("3gp", true, true),
|
||||||
|
new FormatInfo("3g2", true, true),
|
||||||
|
new FormatInfo("mxf", true, true),
|
||||||
|
new FormatInfo("ogv", true, true),
|
||||||
|
new FormatInfo("rm", true, false),
|
||||||
|
new FormatInfo("rmvb", true, false),
|
||||||
|
new FormatInfo("h264", true, true),
|
||||||
|
new FormatInfo("divx", true, true),
|
||||||
|
new FormatInfo("swf", true, true),
|
||||||
];
|
];
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,17 @@ body {
|
||||||
@apply w-full p-3 rounded-lg bg-panel border-2 border-button pl-3 pr-[4rem];
|
@apply w-full p-3 rounded-lg bg-panel border-2 border-button pl-3 pr-[4rem];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type="number"]::-webkit-inner-spin-button,
|
||||||
|
input[type="number"]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
appearance: textfield;
|
||||||
|
}
|
||||||
|
|
||||||
input[type="text"]::placeholder {
|
input[type="text"]::placeholder {
|
||||||
@apply text-muted font-normal;
|
@apply text-muted font-normal;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import { HeartHandshakeIcon } from "lucide-svelte";
|
import { HeartHandshakeIcon } from "lucide-svelte";
|
||||||
import { GITHUB_URL_VERT } from "$lib/consts";
|
import { GITHUB_URL_VERT } from "$lib/consts";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import { link } from "$lib/store/index.svelte";
|
||||||
|
|
||||||
let { mainContribs, notableContribs, ghContribs } = $props();
|
let { mainContribs, notableContribs, ghContribs } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -51,12 +53,11 @@
|
||||||
<div class="rounded-full bg-blue-300 p-2 inline-block mr-3 w-10 h-10">
|
<div class="rounded-full bg-blue-300 p-2 inline-block mr-3 w-10 h-10">
|
||||||
<HeartHandshakeIcon color="black" />
|
<HeartHandshakeIcon color="black" />
|
||||||
</div>
|
</div>
|
||||||
Credits
|
{m["about.credits.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="-mt-4 -mb-3 font-black text-lg">
|
<p class="-mt-4 -mb-3 font-black text-lg">
|
||||||
If you would like to contact the development team, please use the email
|
{m["about.credits.contact_team"]()}
|
||||||
found on the "Resources" card.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Main contributors -->
|
<!-- Main contributors -->
|
||||||
|
|
@ -72,11 +73,12 @@
|
||||||
<!-- Notable contributors -->
|
<!-- Notable contributors -->
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<h2 class="text-base font-bold">Notable contributors</h2>
|
<h2 class="text-base font-bold">
|
||||||
|
{m["about.credits.notable_contributors"]()}
|
||||||
|
</h2>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base text-muted font-normal">
|
<p class="text-base text-muted font-normal">
|
||||||
We'd like to thank these people for their major
|
{m["about.credits.notable_description"]()}
|
||||||
contributions to VERT.
|
|
||||||
</p>
|
</p>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
{#each notableContribs as contrib}
|
{#each notableContribs as contrib}
|
||||||
|
|
@ -90,34 +92,26 @@
|
||||||
<!-- GitHub contributors -->
|
<!-- GitHub contributors -->
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<h2 class="text-base font-bold">GitHub contributors</h2>
|
<h2 class="text-base font-bold">
|
||||||
|
{m["about.credits.github_contributors"]()}
|
||||||
|
</h2>
|
||||||
{#if ghContribs && ghContribs.length > 0}
|
{#if ghContribs && ghContribs.length > 0}
|
||||||
<p class="text-base text-muted font-normal">
|
<p class="text-base text-muted font-normal">
|
||||||
Big <a
|
{@html link(
|
||||||
class="text-black dynadark:text-white"
|
["jpegify_link", "github_link"],
|
||||||
href="/jpegify">thanks</a
|
m["about.credits.github_description"](),
|
||||||
>
|
["/jpegify", GITHUB_URL_VERT],
|
||||||
to all these people for helping out!
|
[false, true],
|
||||||
<a
|
["text-black dynadark:text-white", "text-blue-500 font-normal hover:underline"]
|
||||||
class="text-blue-500 font-normal hover:underline"
|
)}
|
||||||
href={GITHUB_URL_VERT}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Want to help too?
|
|
||||||
</a>
|
|
||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-base text-muted font-normal italic">
|
<p class="text-base text-muted font-normal italic">
|
||||||
Seems like no one has contributed yet...
|
{@html link(
|
||||||
<a
|
"contribute_link",
|
||||||
class="text-blue-500 font-normal hover:underline"
|
m["about.credits.no_contributors"](),
|
||||||
href={GITHUB_URL_VERT}
|
GITHUB_URL_VERT,
|
||||||
target="_blank"
|
)}
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
be the first to contribute!
|
|
||||||
</a>
|
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -131,12 +125,9 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<h2 class="mt-2 -mb-2">Libraries</h2>
|
<h2 class="mt-2 -mb-2">{m["about.credits.libraries"]()}</h2>
|
||||||
<p class="font-normal">
|
<p class="font-normal">
|
||||||
A big thanks to FFmpeg (audio, video), Imagemagick (images) and
|
{m["about.credits.libraries_description"]()}
|
||||||
Pandoc (documents) for maintaining such excellent libraries for
|
|
||||||
so many years. VERT relies on them to provide you with your
|
|
||||||
conversions.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div></Panel
|
</div></Panel
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,8 @@
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import { effects } from "$lib/store/index.svelte";
|
import { effects } from "$lib/store/index.svelte";
|
||||||
import { addToast } from "$lib/store/ToastProvider";
|
import { addToast } from "$lib/store/ToastProvider";
|
||||||
import {
|
import { loadStripe } from "@stripe/stripe-js/pure";
|
||||||
loadStripe,
|
import { type Stripe, type StripeElements } from "@stripe/stripe-js";
|
||||||
type Stripe,
|
|
||||||
type StripeElements,
|
|
||||||
} from "@stripe/stripe-js";
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {
|
import {
|
||||||
CalendarHeartIcon,
|
CalendarHeartIcon,
|
||||||
|
|
@ -35,9 +32,10 @@
|
||||||
HeartIcon,
|
HeartIcon,
|
||||||
WalletIcon,
|
WalletIcon,
|
||||||
} from "lucide-svelte";
|
} from "lucide-svelte";
|
||||||
import { onMount, tick } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { Elements, PaymentElement } from "svelte-stripe";
|
import { Elements, PaymentElement } from "svelte-stripe";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
let amount = $state(1);
|
let amount = $state(1);
|
||||||
let customAmount = $state("");
|
let customAmount = $state("");
|
||||||
|
|
@ -66,10 +64,7 @@
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
paymentState = "prepay";
|
paymentState = "prepay";
|
||||||
addToast(
|
addToast("error", m["about.donate.payment_error"]());
|
||||||
"error",
|
|
||||||
"Error fetching payment details. Please try again later.",
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,10 +82,6 @@
|
||||||
const payDuration = 400;
|
const payDuration = 400;
|
||||||
const transition = "cubic-bezier(0.23, 1, 0.320, 1)";
|
const transition = "cubic-bezier(0.23, 1, 0.320, 1)";
|
||||||
|
|
||||||
onMount(async () => {
|
|
||||||
stripe = await loadStripe(PUB_STRIPE_KEY);
|
|
||||||
});
|
|
||||||
|
|
||||||
const donate = async () => {
|
const donate = async () => {
|
||||||
if (!stripe || !clientSecret || !elements) return;
|
if (!stripe || !clientSecret || !elements) return;
|
||||||
|
|
||||||
|
|
@ -98,9 +89,13 @@
|
||||||
|
|
||||||
const submitResult = await elements.submit();
|
const submitResult = await elements.submit();
|
||||||
if (submitResult.error) {
|
if (submitResult.error) {
|
||||||
|
const period = submitResult.error.message?.endsWith(".") ? "" : ".";
|
||||||
addToast(
|
addToast(
|
||||||
"error",
|
"error",
|
||||||
`Payment failed: ${submitResult.error.message}${submitResult.error.message?.endsWith(".") ? "" : "."} You have not been charged.`,
|
m["about.donate.payment_failed"]({
|
||||||
|
message: submitResult.error.message || "",
|
||||||
|
period,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
enablePay = true;
|
enablePay = true;
|
||||||
return;
|
return;
|
||||||
|
|
@ -116,12 +111,16 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
|
const period = res.error.message?.endsWith(".") ? "" : ".";
|
||||||
addToast(
|
addToast(
|
||||||
"error",
|
"error",
|
||||||
`Payment failed: ${res.error.message}${res.error.message?.endsWith(".") ? "" : "."} You have not been charged.`,
|
m["about.donate.payment_failed"]({
|
||||||
|
message: res.error.message || "",
|
||||||
|
period,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
addToast("success", "Thank you for your donation!");
|
addToast("success", m["about.donate.thank_you"]());
|
||||||
}
|
}
|
||||||
|
|
||||||
paymentState = "prepay";
|
paymentState = "prepay";
|
||||||
|
|
@ -140,13 +139,10 @@
|
||||||
if (status) {
|
if (status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "succeeded":
|
case "succeeded":
|
||||||
addToast("success", "Thank you for your donation!");
|
addToast("success", m["about.donate.thank_you"]());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
addToast(
|
addToast("error", m["about.donate.donation_error"]());
|
||||||
"error",
|
|
||||||
"An error occurred while processing your donation. Please try again later.",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto("/about");
|
goto("/about");
|
||||||
|
|
@ -162,10 +158,10 @@
|
||||||
>
|
>
|
||||||
<HeartIcon color="black" />
|
<HeartIcon color="black" />
|
||||||
</div>
|
</div>
|
||||||
Donate to VERT
|
{m["about.donate.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-base font-normal">
|
<p class="text-base font-normal">
|
||||||
With your support, we can keep maintaining and improving VERT.
|
{m["about.donate.description"]()}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -192,7 +188,7 @@
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<HandCoinsIcon size="24" class="inline-block mr-2" />
|
<HandCoinsIcon size="24" class="inline-block mr-2" />
|
||||||
One-time
|
{m["about.donate.one_time"]()}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -207,7 +203,7 @@
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<CalendarHeartIcon size="24" class="inline-block mr-2" />
|
<CalendarHeartIcon size="24" class="inline-block mr-2" />
|
||||||
Monthly
|
{m["about.donate.monthly"]()}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-4 gap-3 w-full">
|
<div class="grid grid-cols-4 gap-3 w-full">
|
||||||
|
|
@ -229,9 +225,10 @@
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<FancyInput
|
<FancyInput
|
||||||
bind:value={customAmount}
|
bind:value={customAmount}
|
||||||
placeholder="Custom"
|
placeholder={m["about.donate.custom"]()}
|
||||||
prefix="$"
|
prefix="$"
|
||||||
type="number"
|
type="number"
|
||||||
|
class="h-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -288,7 +285,9 @@
|
||||||
class="btn w-full h-12 bg-accent-red text-black rounded-full mt-4"
|
class="btn w-full h-12 bg-accent-red text-black rounded-full mt-4"
|
||||||
onclick={donate}
|
onclick={donate}
|
||||||
>
|
>
|
||||||
Donate ${amount.toFixed(2)} USD
|
{m["about.donate.donate_amount"]({
|
||||||
|
amount: amount.toFixed(2),
|
||||||
|
})}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -304,7 +303,7 @@
|
||||||
class="row-start-1 col-start-1 flex justify-center items-center"
|
class="row-start-1 col-start-1 flex justify-center items-center"
|
||||||
>
|
>
|
||||||
<WalletIcon size="24" class="inline-block mr-2" />
|
<WalletIcon size="24" class="inline-block mr-2" />
|
||||||
Pay now
|
{m["about.donate.pay_now"]()}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
MailIcon,
|
MailIcon,
|
||||||
MessageCircleMoreIcon,
|
MessageCircleMoreIcon,
|
||||||
} from "lucide-svelte";
|
} from "lucide-svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Panel class="flex flex-col gap-4 p-6">
|
<Panel class="flex flex-col gap-4 p-6">
|
||||||
|
|
@ -17,7 +18,7 @@
|
||||||
>
|
>
|
||||||
<LinkIcon color="black" />
|
<LinkIcon color="black" />
|
||||||
</div>
|
</div>
|
||||||
Resources
|
{m["about.resources.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex gap-3">
|
<div class="flex gap-3">
|
||||||
<a
|
<a
|
||||||
|
|
@ -29,7 +30,7 @@
|
||||||
: '!scale-100'} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
: '!scale-100'} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<MessageCircleMoreIcon size="24" class="inline-block mr-2" />
|
<MessageCircleMoreIcon size="24" class="inline-block mr-2" />
|
||||||
Discord
|
{m["about.resources.discord"]()}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href={GITHUB_URL_VERT}
|
href={GITHUB_URL_VERT}
|
||||||
|
|
@ -40,7 +41,7 @@
|
||||||
: '!scale-100'} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
: '!scale-100'} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<GithubIcon size="24" class="inline-block mr-2" />
|
<GithubIcon size="24" class="inline-block mr-2" />
|
||||||
Source
|
{m["about.resources.source"]()}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="mailto:{CONTACT_EMAIL}"
|
href="mailto:{CONTACT_EMAIL}"
|
||||||
|
|
@ -51,7 +52,7 @@
|
||||||
: '!scale-100'} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
: '!scale-100'} flex-1 gap-2 p-4 rounded-full bg-button text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<MailIcon size="24" class="inline-block mr-2" />
|
<MailIcon size="24" class="inline-block mr-2" />
|
||||||
Email
|
{m["about.resources.email"]()}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
import { DISCORD_URL } from "$lib/consts";
|
import { DISCORD_URL } from "$lib/consts";
|
||||||
import { error } from "$lib/logger";
|
import { error } from "$lib/logger";
|
||||||
import { addToast } from "$lib/store/ToastProvider";
|
import { addToast } from "$lib/store/ToastProvider";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import { link } from "$lib/store/index.svelte";
|
||||||
|
|
||||||
let copied = false;
|
let copied = false;
|
||||||
let timeoutId: number | undefined;
|
let timeoutId: number | undefined;
|
||||||
|
|
@ -13,7 +15,7 @@
|
||||||
try {
|
try {
|
||||||
navigator.clipboard.writeText("hello@vert.sh");
|
navigator.clipboard.writeText("hello@vert.sh");
|
||||||
copied = true;
|
copied = true;
|
||||||
addToast("success", "Email copied to clipboard!");
|
addToast("success", m["about.sponsors.email_copied"]());
|
||||||
|
|
||||||
if (timeoutId) clearTimeout(timeoutId);
|
if (timeoutId) clearTimeout(timeoutId);
|
||||||
timeoutId = setTimeout(() => (copied = false), 2000);
|
timeoutId = setTimeout(() => (copied = false), 2000);
|
||||||
|
|
@ -30,7 +32,7 @@
|
||||||
>
|
>
|
||||||
<PiggyBankIcon color="black" />
|
<PiggyBankIcon color="black" />
|
||||||
</div>
|
</div>
|
||||||
Sponsors
|
{m["about.sponsors.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="mt-2 [&>*]:font-normal h-full flex justify-between flex-col">
|
<div class="mt-2 [&>*]:font-normal h-full flex justify-between flex-col">
|
||||||
<div class="flex gap-3 justify-center text-lg">
|
<div class="flex gap-3 justify-center text-lg">
|
||||||
|
|
@ -43,11 +45,11 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-muted">
|
<p class="text-muted">
|
||||||
Want to support us? Contact a developer in the <a
|
{@html link(
|
||||||
href={DISCORD_URL}
|
"discord_link",
|
||||||
target="_blank">Discord</a
|
m["about.sponsors.description"](),
|
||||||
>
|
DISCORD_URL,
|
||||||
server, or send an email to
|
)}
|
||||||
<span class="inline-block mx-[2px] relative top-[2px]">
|
<span class="inline-block mx-[2px] relative top-[2px]">
|
||||||
<button
|
<button
|
||||||
id="email"
|
id="email"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import { MessageCircleQuestionIcon } from "lucide-svelte";
|
import { MessageCircleQuestionIcon } from "lucide-svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Panel class="flex flex-col gap-3 p-6">
|
<Panel class="flex flex-col gap-3 p-6">
|
||||||
|
|
@ -10,22 +11,9 @@
|
||||||
>
|
>
|
||||||
<MessageCircleQuestionIcon color="black" />
|
<MessageCircleQuestionIcon color="black" />
|
||||||
</div>
|
</div>
|
||||||
Why VERT?
|
{m["about.why.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-lg font-normal">
|
<p class="text-lg font-normal">
|
||||||
<b>File converters have always disappointed us.</b> They're ugly,
|
{@html m["about.why.description"]()}
|
||||||
riddled with ads, and most importantly; slow. We decided to solve this
|
|
||||||
problem once and for all by making an alternative that solves all those
|
|
||||||
problems, and more.<br />
|
|
||||||
<br />
|
|
||||||
All non-video files are converted completely on-device; this means that there's
|
|
||||||
no delay between sending and receiving the files from a server, and we never
|
|
||||||
get to snoop on the files you convert.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
Video files get uploaded to our lightning-fast RTX 4000 Ada server. Your
|
|
||||||
videos stay on there for an hour if you do not convert them. If you do convert
|
|
||||||
the file, the video will stay on the server for an hour, or until it is downloaded.
|
|
||||||
The file will then be deleted from our server.
|
|
||||||
</p>
|
</p>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
effects,
|
effects,
|
||||||
setEffects,
|
setEffects,
|
||||||
setTheme,
|
setTheme,
|
||||||
|
updateLocale,
|
||||||
|
availableLocales,
|
||||||
} from "$lib/store/index.svelte";
|
} from "$lib/store/index.svelte";
|
||||||
import {
|
import {
|
||||||
MoonIcon,
|
MoonIcon,
|
||||||
|
|
@ -14,6 +16,23 @@
|
||||||
SunIcon,
|
SunIcon,
|
||||||
} from "lucide-svelte";
|
} from "lucide-svelte";
|
||||||
import { onMount, onDestroy } from "svelte";
|
import { onMount, onDestroy } from "svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import { getLocale } from "$lib/paraglide/runtime";
|
||||||
|
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
||||||
|
|
||||||
|
let currentLocale = $state("en");
|
||||||
|
|
||||||
|
const getLanguageDisplayName = (locale: string) => {
|
||||||
|
try {
|
||||||
|
return availableLocales[locale as keyof typeof availableLocales];
|
||||||
|
} catch {
|
||||||
|
return locale.toUpperCase();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const languageOptions = Object.keys(availableLocales).map((locale) =>
|
||||||
|
getLanguageDisplayName(locale),
|
||||||
|
);
|
||||||
|
|
||||||
let lightElement: HTMLButtonElement;
|
let lightElement: HTMLButtonElement;
|
||||||
let darkElement: HTMLButtonElement;
|
let darkElement: HTMLButtonElement;
|
||||||
|
|
@ -49,6 +68,8 @@
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
effectsUnsubscribe = effects.subscribe(updateEffectsClasses);
|
effectsUnsubscribe = effects.subscribe(updateEffectsClasses);
|
||||||
themeUnsubscribe = theme.subscribe(updateThemeClasses);
|
themeUnsubscribe = theme.subscribe(updateThemeClasses);
|
||||||
|
|
||||||
|
currentLocale = localStorage.getItem("locale") || getLocale();
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
|
|
@ -57,9 +78,20 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
updateEffectsClasses($effects);
|
updateEffectsClasses($effects);
|
||||||
updateThemeClasses($theme);
|
updateThemeClasses($theme);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function handleLanguageChange(selectedLanguage: string) {
|
||||||
|
const selectedLocale = Object.keys(availableLocales).find(
|
||||||
|
(locale) => getLanguageDisplayName(locale) === selectedLanguage,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (selectedLocale && selectedLocale !== currentLocale) {
|
||||||
|
currentLocale = selectedLocale;
|
||||||
|
updateLocale(selectedLocale);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Panel class="flex flex-col gap-8 p-6">
|
<Panel class="flex flex-col gap-8 p-6">
|
||||||
|
|
@ -70,14 +102,16 @@
|
||||||
class="inline-block -mt-1 mr-2 bg-accent-purple p-2 rounded-full"
|
class="inline-block -mt-1 mr-2 bg-accent-purple p-2 rounded-full"
|
||||||
color="black"
|
color="black"
|
||||||
/>
|
/>
|
||||||
Appearance
|
{m["settings.appearance.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-8">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base font-bold">Brightness theme</p>
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.appearance.brightness_theme"]()}
|
||||||
|
</p>
|
||||||
<p class="text-sm text-muted font-normal italic">
|
<p class="text-sm text-muted font-normal italic">
|
||||||
Want a sunny flash-bang, or a quiet lonely night?
|
{m["settings.appearance.brightness_description"]()}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-3 w-full">
|
<div class="flex flex-col gap-3 w-full">
|
||||||
|
|
@ -85,29 +119,34 @@
|
||||||
<button
|
<button
|
||||||
bind:this={lightElement}
|
bind:this={lightElement}
|
||||||
onclick={() => setTheme("light")}
|
onclick={() => setTheme("light")}
|
||||||
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<SunIcon size="24" class="inline-block mr-2" />
|
<SunIcon size="24" class="inline-block mr-2" />
|
||||||
Light
|
{m["settings.appearance.light"]()}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
bind:this={darkElement}
|
bind:this={darkElement}
|
||||||
onclick={() => setTheme("dark")}
|
onclick={() => setTheme("dark")}
|
||||||
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black flex items-center justify-center"
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} flex-1 p-4 rounded-lg text-black flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<MoonIcon size="24" class="inline-block mr-2" />
|
<MoonIcon size="24" class="inline-block mr-2" />
|
||||||
Dark
|
{m["settings.appearance.dark"]()}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base font-bold">Effect settings</p>
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.appearance.effect_settings"]()}
|
||||||
|
</p>
|
||||||
<p class="text-sm text-muted font-normal italic">
|
<p class="text-sm text-muted font-normal italic">
|
||||||
Would you like fancy effects, or a more static
|
{m["settings.appearance.effect_description"]()}
|
||||||
experience?
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-3 w-full">
|
<div class="flex flex-col gap-3 w-full">
|
||||||
|
|
@ -115,23 +154,45 @@
|
||||||
<button
|
<button
|
||||||
bind:this={enableEffectsElement}
|
bind:this={enableEffectsElement}
|
||||||
onclick={() => setEffects(true)}
|
onclick={() => setEffects(true)}
|
||||||
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<PlayIcon size="24" class="inline-block mr-2" />
|
<PlayIcon size="24" class="inline-block mr-2" />
|
||||||
Enable
|
{m["settings.appearance.enable"]()}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
bind:this={disableEffectsElement}
|
bind:this={disableEffectsElement}
|
||||||
onclick={() => setEffects(false)}
|
onclick={() => setEffects(false)}
|
||||||
class="btn {$effects ? "" : "!scale-100"} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<PauseIcon size="24" class="inline-block mr-2" />
|
<PauseIcon size="24" class="inline-block mr-2" />
|
||||||
Disable
|
{m["settings.appearance.disable"]()}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.language.title"]()}
|
||||||
|
</p>
|
||||||
|
<p class="text-sm text-muted font-normal italic">
|
||||||
|
{m["settings.language.description"]()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-3 w-full">
|
||||||
|
<Dropdown
|
||||||
|
options={languageOptions}
|
||||||
|
settingsStyle
|
||||||
|
selected={getLanguageDisplayName(currentLocale)}
|
||||||
|
onselect={handleLanguageChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,15 @@
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import { RefreshCwIcon } from "lucide-svelte";
|
import { RefreshCwIcon } from "lucide-svelte";
|
||||||
import type { ISettings } from "./index.svelte";
|
import type { ISettings } from "./index.svelte";
|
||||||
|
import {
|
||||||
|
CONVERSION_BITRATES,
|
||||||
|
type ConversionBitrate,
|
||||||
|
SAMPLE_RATES,
|
||||||
|
type SampleRate,
|
||||||
|
} from "$lib/converters/ffmpeg.svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
||||||
|
import FancyInput from "$lib/components/functional/FancyInput.svelte";
|
||||||
|
|
||||||
const { settings }: { settings: ISettings } = $props();
|
const { settings }: { settings: ISettings } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -15,34 +24,96 @@
|
||||||
class="inline-block -mt-1 mr-2 bg-accent p-2 rounded-full"
|
class="inline-block -mt-1 mr-2 bg-accent p-2 rounded-full"
|
||||||
color="black"
|
color="black"
|
||||||
/>
|
/>
|
||||||
Conversion
|
{m["settings.conversion.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-8">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base font-bold">File name format</p>
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.conversion.filename_format"]()}
|
||||||
|
</p>
|
||||||
<p class="text-sm text-muted font-normal">
|
<p class="text-sm text-muted font-normal">
|
||||||
This will determine the name of the file on download, <span
|
{@html m["settings.conversion.filename_description"]()}
|
||||||
class="font-bold italic"
|
|
||||||
>not including the file extension.</span
|
|
||||||
>
|
|
||||||
You can put these following templates in the format, which
|
|
||||||
will be replaced with the relevant information:
|
|
||||||
<span class="font-bold">%name%</span>
|
|
||||||
for the original file name,
|
|
||||||
<span class="font-bold">%extension%</span>
|
|
||||||
for the original file extension, and
|
|
||||||
<span class="font-bold">%date%</span>
|
|
||||||
for a date string of when the file was converted.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<FancyTextInput
|
<FancyTextInput
|
||||||
placeholder="VERT_%name%"
|
placeholder="VERT_%name%"
|
||||||
bind:value={settings.filenameFormat}
|
bind:value={settings.filenameFormat}
|
||||||
extension=".ext"
|
extension={".ext"}
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.conversion.quality"]()}
|
||||||
|
</p>
|
||||||
|
<p class="text-sm text-muted font-normal">
|
||||||
|
{m["settings.conversion.quality_description"]()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold">
|
||||||
|
{m["settings.conversion.quality_images"]()}
|
||||||
|
</p>
|
||||||
|
<FancyInput
|
||||||
|
bind:value={
|
||||||
|
settings.magickQuality as unknown as string
|
||||||
|
}
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
max={100}
|
||||||
|
placeholder={"100"}
|
||||||
|
extension={"%"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold">
|
||||||
|
{m["settings.conversion.quality_audio"]()}
|
||||||
|
</p>
|
||||||
|
<Dropdown
|
||||||
|
options={CONVERSION_BITRATES.map((b) =>
|
||||||
|
b.toString(),
|
||||||
|
)}
|
||||||
|
selected={settings.ffmpegQuality.toString()}
|
||||||
|
onselect={(option: string) =>
|
||||||
|
(settings.ffmpegQuality =
|
||||||
|
option as ConversionBitrate)}
|
||||||
|
settingsStyle
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold">
|
||||||
|
{m["settings.conversion.rate"]()}
|
||||||
|
</p>
|
||||||
|
<Dropdown
|
||||||
|
options={SAMPLE_RATES.map((r) => r.toString())}
|
||||||
|
selected={settings.ffmpegSampleRate.toString()}
|
||||||
|
onselect={(option: string) => {
|
||||||
|
settings.ffmpegSampleRate =
|
||||||
|
option as SampleRate;
|
||||||
|
}}
|
||||||
|
settingsStyle
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold select-none"> </p>
|
||||||
|
<FancyInput
|
||||||
|
bind:value={
|
||||||
|
settings.ffmpegCustomSampleRate as unknown as string
|
||||||
|
}
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
placeholder={"44100"}
|
||||||
|
extension={"Hz"}
|
||||||
|
disabled={settings.ffmpegSampleRate !== "custom"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div></Panel
|
||||||
</Panel>
|
>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
import { ChartColumnIcon, PauseIcon, PlayIcon } from "lucide-svelte";
|
import { ChartColumnIcon, PauseIcon, PlayIcon } from "lucide-svelte";
|
||||||
import type { ISettings } from "./index.svelte";
|
import type { ISettings } from "./index.svelte";
|
||||||
import { effects } from "$lib/store/index.svelte";
|
import { effects } from "$lib/store/index.svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import { link } from "$lib/store/index.svelte";
|
||||||
|
|
||||||
const { settings }: { settings: ISettings } = $props();
|
const { settings }: { settings: ISettings } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -15,26 +17,23 @@
|
||||||
class="inline-block -mt-1 mr-2 bg-accent-blue p-2 rounded-full"
|
class="inline-block -mt-1 mr-2 bg-accent-blue p-2 rounded-full"
|
||||||
color="black"
|
color="black"
|
||||||
/>
|
/>
|
||||||
Privacy
|
{m["settings.privacy.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-8">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base font-bold">Plausible analytics</p>
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.privacy.plausible_title"]()}
|
||||||
|
</p>
|
||||||
<p class="text-sm text-muted font-normal">
|
<p class="text-sm text-muted font-normal">
|
||||||
We use <a
|
{@html link(
|
||||||
href="https://plausible.io/privacy-focused-web-analytics"
|
["plausible_link", "analytics_link"],
|
||||||
target="_blank"
|
m["settings.privacy.plausible_description"](),
|
||||||
rel="noopener noreferrer">Plausible</a
|
[
|
||||||
>, a privacy-focused analytics tool, to gather
|
"https://plausible.io/privacy-focused-web-analytics",
|
||||||
completely anonymous statistics. All data is anonymized
|
"https://ats.vert.sh/vert.sh",
|
||||||
and aggregated, and no identifiable information is ever
|
],
|
||||||
sent or stored. You can view the analytics
|
)}
|
||||||
<a
|
|
||||||
href="https://ats.vert.sh/vert.sh"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer">here</a
|
|
||||||
> and choose to opt out below.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-3 w-full">
|
<div class="flex flex-col gap-3 w-full">
|
||||||
|
|
@ -48,7 +47,7 @@
|
||||||
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<PlayIcon size="24" class="inline-block mr-2" />
|
<PlayIcon size="24" class="inline-block mr-2" />
|
||||||
Opt-in
|
{m["settings.privacy.opt_in"]()}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
@ -60,7 +59,7 @@
|
||||||
: 'selected'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
: 'selected'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<PauseIcon size="24" class="inline-block mr-2" />
|
<PauseIcon size="24" class="inline-block mr-2" />
|
||||||
Opt-out
|
{m["settings.privacy.opt_out"]()}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
||||||
import { vertdLoaded } from "$lib/store/index.svelte";
|
import { vertdLoaded } from "$lib/store/index.svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import { link } from "$lib/store/index.svelte";
|
||||||
|
|
||||||
let vertdCommit = $state<string | null>(null);
|
let vertdCommit = $state<string | null>(null);
|
||||||
let abortController: AbortController | null = null;
|
let abortController: AbortController | null = null;
|
||||||
|
|
@ -55,7 +57,7 @@
|
||||||
class="inline-block -mt-1 mr-2 bg-accent-red p-2 rounded-full overflow-visible"
|
class="inline-block -mt-1 mr-2 bg-accent-red p-2 rounded-full overflow-visible"
|
||||||
color="black"
|
color="black"
|
||||||
/>
|
/>
|
||||||
Video conversion
|
{m["settings.vertd.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
class={clsx("text-sm font-normal", {
|
class={clsx("text-sm font-normal", {
|
||||||
|
|
@ -64,90 +66,79 @@
|
||||||
"!text-muted": vertdCommit === "loading",
|
"!text-muted": vertdCommit === "loading",
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
status: {vertdCommit
|
{m["settings.vertd.status"]()} {vertdCommit
|
||||||
? vertdCommit === "loading"
|
? vertdCommit === "loading"
|
||||||
? "loading..."
|
? m["settings.vertd.loading"]()
|
||||||
: `available, commit id ${vertdCommit}`
|
: m["settings.vertd.available"]({ commitId: vertdCommit })
|
||||||
: "unavailable (is the url right?)"}
|
: m["settings.vertd.unavailable"]()}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-8">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<p class="text-sm text-muted font-normal">
|
<p class="text-sm text-muted font-normal">
|
||||||
The <code>vertd</code> project is a server wrapper for FFmpeg.
|
{@html m["settings.vertd.description"]()}
|
||||||
This allows you to convert videos through the convenience of
|
|
||||||
VERT's web interface, while still being able to harness the power
|
|
||||||
of your GPU to do it as quickly as possible.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-muted font-normal">
|
<p class="text-sm text-muted font-normal">
|
||||||
We host a public instance for your convenience, but it is
|
{@html link("vertd_link", m["settings.vertd.hosting_info"](), GITHUB_URL_VERTD)}
|
||||||
quite easy to host your own on your PC or server if you know
|
|
||||||
what you are doing. You can download the server binaries <a
|
|
||||||
href={GITHUB_URL_VERTD}
|
|
||||||
target="_blank">here</a
|
|
||||||
> - the process of setting this up will become easier in the
|
|
||||||
future, so stay tuned!
|
|
||||||
</p>
|
</p>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base font-bold">Instance URL</p>
|
<p class="text-base font-bold">{m["settings.vertd.instance_url"]()}</p>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Example: http://localhost:24153"
|
placeholder={m["settings.vertd.url_placeholder"]()}
|
||||||
bind:value={settings.vertdURL}
|
bind:value={settings.vertdURL}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base font-bold">Conversion speed</p>
|
<p class="text-base font-bold">{m["settings.vertd.conversion_speed"]()}</p>
|
||||||
<p class="text-sm text-muted font-normal">
|
<p class="text-sm text-muted font-normal">
|
||||||
This describes the tradeoff between speed and
|
{m["settings.vertd.speed_description"]()}
|
||||||
quality. Faster speeds will result in lower quality,
|
|
||||||
but will get the job done quicker.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
options={[
|
options={[
|
||||||
"Very Slow",
|
m["settings.vertd.speeds.very_slow"](),
|
||||||
"Slower",
|
m["settings.vertd.speeds.slower"](),
|
||||||
"Slow",
|
m["settings.vertd.speeds.slow"](),
|
||||||
"Medium",
|
m["settings.vertd.speeds.medium"](),
|
||||||
"Fast",
|
m["settings.vertd.speeds.fast"](),
|
||||||
"Ultra Fast",
|
m["settings.vertd.speeds.ultra_fast"](),
|
||||||
]}
|
]}
|
||||||
settingsStyle
|
settingsStyle
|
||||||
selected={(() => {
|
selected={(() => {
|
||||||
switch (settings.vertdSpeed) {
|
switch (settings.vertdSpeed) {
|
||||||
case "verySlow":
|
case "verySlow":
|
||||||
return "Very Slow";
|
return m["settings.vertd.speeds.very_slow"]();
|
||||||
case "slower":
|
case "slower":
|
||||||
return "Slower";
|
return m["settings.vertd.speeds.slower"]();
|
||||||
case "slow":
|
case "slow":
|
||||||
return "Slow";
|
return m["settings.vertd.speeds.slow"]();
|
||||||
case "medium":
|
case "medium":
|
||||||
return "Medium";
|
return m["settings.vertd.speeds.medium"]();
|
||||||
case "fast":
|
case "fast":
|
||||||
return "Fast";
|
return m["settings.vertd.speeds.fast"]();
|
||||||
case "ultraFast":
|
case "ultraFast":
|
||||||
return "Ultra Fast";
|
return m["settings.vertd.speeds.ultra_fast"]();
|
||||||
}
|
}
|
||||||
})()}
|
})()}
|
||||||
onselect={(selected) => {
|
onselect={(selected) => {
|
||||||
switch (selected) {
|
switch (selected) {
|
||||||
case "Very Slow":
|
case m["settings.vertd.speeds.very_slow"]():
|
||||||
settings.vertdSpeed = "verySlow";
|
settings.vertdSpeed = "verySlow";
|
||||||
break;
|
break;
|
||||||
case "Slower":
|
case m["settings.vertd.speeds.slower"]():
|
||||||
settings.vertdSpeed = "slower";
|
settings.vertdSpeed = "slower";
|
||||||
break;
|
break;
|
||||||
case "Slow":
|
case m["settings.vertd.speeds.slow"]():
|
||||||
settings.vertdSpeed = "slow";
|
settings.vertdSpeed = "slow";
|
||||||
break;
|
break;
|
||||||
case "Medium":
|
case m["settings.vertd.speeds.medium"]():
|
||||||
settings.vertdSpeed = "medium";
|
settings.vertdSpeed = "medium";
|
||||||
break;
|
break;
|
||||||
case "Fast":
|
case m["settings.vertd.speeds.fast"]():
|
||||||
settings.vertdSpeed = "fast";
|
settings.vertdSpeed = "fast";
|
||||||
break;
|
break;
|
||||||
case "Ultra Fast":
|
case m["settings.vertd.speeds.ultra_fast"]():
|
||||||
settings.vertdSpeed = "ultraFast";
|
settings.vertdSpeed = "ultraFast";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { PUB_VERTD_URL } from "$env/static/public";
|
import { PUB_VERTD_URL } from "$env/static/public";
|
||||||
|
import type { ConversionBitrate } from "$lib/converters/ffmpeg.svelte";
|
||||||
import type { ConversionSpeed } from "$lib/converters/vertd.svelte";
|
import type { ConversionSpeed } from "$lib/converters/vertd.svelte";
|
||||||
|
|
||||||
export { default as Appearance } from "./Appearance.svelte";
|
export { default as Appearance } from "./Appearance.svelte";
|
||||||
|
|
@ -10,7 +11,11 @@ export interface ISettings {
|
||||||
filenameFormat: string;
|
filenameFormat: string;
|
||||||
plausible: boolean;
|
plausible: boolean;
|
||||||
vertdURL: string;
|
vertdURL: string;
|
||||||
vertdSpeed: ConversionSpeed;
|
vertdSpeed: ConversionSpeed; // videos
|
||||||
|
magickQuality: number; // images
|
||||||
|
ffmpegQuality: ConversionBitrate; // audio (or audio <-> video)
|
||||||
|
ffmpegSampleRate: string; // audio (or audio <-> video)
|
||||||
|
ffmpegCustomSampleRate: number; // audio (or audio <-> video) - only used when ffmpegSampleRate is "custom"
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Settings {
|
export class Settings {
|
||||||
|
|
@ -21,6 +26,10 @@ export class Settings {
|
||||||
plausible: true,
|
plausible: true,
|
||||||
vertdURL: PUB_VERTD_URL,
|
vertdURL: PUB_VERTD_URL,
|
||||||
vertdSpeed: "slow",
|
vertdSpeed: "slow",
|
||||||
|
magickQuality: 100,
|
||||||
|
ffmpegQuality: "auto",
|
||||||
|
ffmpegSampleRate: "auto",
|
||||||
|
ffmpegCustomSampleRate: 44100,
|
||||||
});
|
});
|
||||||
|
|
||||||
public save() {
|
public save() {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import { browser } from "$app/environment";
|
import { browser } from "$app/environment";
|
||||||
import { converters } from "$lib/converters";
|
import { byNative, converters } from "$lib/converters";
|
||||||
import { error, log } from "$lib/logger";
|
import { error, log } from "$lib/logger";
|
||||||
import { VertFile } from "$lib/types";
|
import { VertFile } from "$lib/types";
|
||||||
import { parseBlob, selectCover } from "music-metadata";
|
import { parseBlob, selectCover } from "music-metadata";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
import { addDialog } from "./DialogProvider";
|
import { addDialog } from "./DialogProvider";
|
||||||
import PQueue from "p-queue";
|
import PQueue from "p-queue";
|
||||||
|
import { getLocale, setLocale } from "$lib/paraglide/runtime";
|
||||||
|
|
||||||
class Files {
|
class Files {
|
||||||
public files = $state<VertFile[]>([]);
|
public files = $state<VertFile[]>([]);
|
||||||
|
|
@ -32,11 +33,13 @@ class Files {
|
||||||
this.thumbnailQueue.add(async () => {
|
this.thumbnailQueue.add(async () => {
|
||||||
const isAudio = converters
|
const isAudio = converters
|
||||||
.find((c) => c.name === "ffmpeg")
|
.find((c) => c.name === "ffmpeg")
|
||||||
?.formatStrings()
|
?.supportedFormats.filter((f) => f.isNative)
|
||||||
|
.map((f) => f.name)
|
||||||
?.includes(file.from.toLowerCase());
|
?.includes(file.from.toLowerCase());
|
||||||
const isVideo = converters
|
const isVideo = converters
|
||||||
.find((c) => c.name === "vertd")
|
.find((c) => c.name === "vertd")
|
||||||
?.formatStrings()
|
?.supportedFormats.filter((f) => f.isNative)
|
||||||
|
.map((f) => f.name)
|
||||||
?.includes(file.from.toLowerCase());
|
?.includes(file.from.toLowerCase());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -120,11 +123,11 @@ class Files {
|
||||||
log(["files"], `no extension found for ${file.name}`);
|
log(["files"], `no extension found for ${file.name}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const converter = converters.find((c) =>
|
const converter = converters
|
||||||
c
|
.sort(byNative(format))
|
||||||
.formatStrings()
|
.find((converter) =>
|
||||||
.includes(format || ".somenonexistentextension"),
|
converter.formatStrings().includes(format),
|
||||||
);
|
);
|
||||||
if (!converter) {
|
if (!converter) {
|
||||||
log(["files"], `no converter found for ${file.name}`);
|
log(["files"], `no converter found for ${file.name}`);
|
||||||
this.files.push(new VertFile(file, format));
|
this.files.push(new VertFile(file, format));
|
||||||
|
|
@ -292,3 +295,47 @@ export const vertdLoaded = writable(false);
|
||||||
export const isMobile = writable(false);
|
export const isMobile = writable(false);
|
||||||
export const effects = writable(true);
|
export const effects = writable(true);
|
||||||
export const theme = writable<"light" | "dark">("light");
|
export const theme = writable<"light" | "dark">("light");
|
||||||
|
export const locale = writable(getLocale());
|
||||||
|
export const availableLocales = {
|
||||||
|
"en": "English",
|
||||||
|
"es": "Español",
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateLocale(newLocale: string) {
|
||||||
|
log(["locale"], `set to ${newLocale}`);
|
||||||
|
localStorage.setItem("locale", newLocale);
|
||||||
|
// @ts-expect-error shush
|
||||||
|
setLocale(newLocale, { reload: false });
|
||||||
|
// @ts-expect-error shush
|
||||||
|
locale.set(newLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function link(
|
||||||
|
tag: string | string[],
|
||||||
|
text: string,
|
||||||
|
links: string | string[],
|
||||||
|
newTab?: boolean | boolean[],
|
||||||
|
className?: string | string[]
|
||||||
|
) {
|
||||||
|
if (!text) return "";
|
||||||
|
|
||||||
|
const tags = Array.isArray(tag) ? tag : [tag];
|
||||||
|
const linksArr = Array.isArray(links) ? links : [links];
|
||||||
|
const newTabArr = Array.isArray(newTab) ? newTab : [newTab];
|
||||||
|
const classArr = Array.isArray(className) ? className : [className];
|
||||||
|
|
||||||
|
let result = text;
|
||||||
|
|
||||||
|
tags.forEach((t, i) => {
|
||||||
|
const link = linksArr[i] ?? "#";
|
||||||
|
const target = newTabArr[i] ? 'target="_blank" rel="noopener noreferrer"' : "";
|
||||||
|
const cls = classArr[i] ? `class="${classArr[i]}"` : "";
|
||||||
|
|
||||||
|
const regex = new RegExp(`\\[${t}\\](.*?)\\[\\/${t}\\]`, "g");
|
||||||
|
result = result.replace(regex, (_, inner) =>
|
||||||
|
`<a href="${link}" ${target} ${cls} >${inner}</a>`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { converters } from "$lib/converters";
|
import { byNative, converters } from "$lib/converters";
|
||||||
import type { Converter } from "$lib/converters/converter.svelte";
|
import type { Converter } from "$lib/converters/converter.svelte";
|
||||||
import { error } from "$lib/logger";
|
import { error } from "$lib/logger";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
import { addToast } from "$lib/store/ToastProvider";
|
import { addToast } from "$lib/store/ToastProvider";
|
||||||
|
|
||||||
export class VertFile {
|
export class VertFile {
|
||||||
|
|
@ -27,18 +28,35 @@ export class VertFile {
|
||||||
public converters: Converter[] = [];
|
public converters: Converter[] = [];
|
||||||
|
|
||||||
public findConverters(supportedFormats: string[] = [this.from]) {
|
public findConverters(supportedFormats: string[] = [this.from]) {
|
||||||
const converter = this.converters.filter((converter) =>
|
const converter = this.converters
|
||||||
converter.formatStrings().map((f) => supportedFormats.includes(f)),
|
.filter((converter) =>
|
||||||
);
|
converter
|
||||||
|
.formatStrings()
|
||||||
|
.map((f) => supportedFormats.includes(f)),
|
||||||
|
)
|
||||||
|
.sort(byNative(this.from));
|
||||||
return converter;
|
return converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public findConverter() {
|
public findConverter() {
|
||||||
const converter = this.converters.find(
|
const converter = this.converters.find((converter) => {
|
||||||
(converter) =>
|
if (
|
||||||
converter.formatStrings().includes(this.from) &&
|
!converter.formatStrings().includes(this.from) ||
|
||||||
converter.formatStrings().includes(this.to),
|
!converter.formatStrings().includes(this.to)
|
||||||
);
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const theirFrom = converter.supportedFormats.find(
|
||||||
|
(f) => f.name === this.from,
|
||||||
|
);
|
||||||
|
const theirTo = converter.supportedFormats.find(
|
||||||
|
(f) => f.name === this.to,
|
||||||
|
);
|
||||||
|
if (!theirFrom || !theirTo) return false;
|
||||||
|
if (!theirFrom.isNative && !theirTo.isNative) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
return converter;
|
return converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +93,10 @@ export class VertFile {
|
||||||
error(["files"], castedErr.message);
|
error(["files"], castedErr.message);
|
||||||
addToast(
|
addToast(
|
||||||
"error",
|
"error",
|
||||||
`Error converting file ${this.file.name}: ${castedErr.message || castedErr}`,
|
m["workers.errors.general"]({
|
||||||
|
file: this.file.name,
|
||||||
|
message: castedErr.message || castedErr,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +126,8 @@ export class VertFile {
|
||||||
|
|
||||||
const blob = URL.createObjectURL(
|
const blob = URL.createObjectURL(
|
||||||
new Blob([await this.result.file.arrayBuffer()], {
|
new Blob([await this.result.file.arrayBuffer()], {
|
||||||
type: to.slice(1),
|
// type: to.slice(1),
|
||||||
|
type: "application/octet-stream", // use generic type to prevent browsers changing extension
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,12 @@ magickPromise
|
||||||
const handleMessage = async (message: any): Promise<any> => {
|
const handleMessage = async (message: any): Promise<any> => {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case "convert": {
|
case "convert": {
|
||||||
|
const compression: number | undefined = message.compression;
|
||||||
if (!message.to.startsWith(".")) message.to = `.${message.to}`;
|
if (!message.to.startsWith(".")) message.to = `.${message.to}`;
|
||||||
message.to = message.to.toLowerCase();
|
message.to = message.to.toLowerCase();
|
||||||
if (message.to === ".jfif") {
|
if (message.to === ".jfif") message.to = ".jpeg";
|
||||||
message.to = ".jpeg";
|
if (message.input.from === ".jfif") message.input.from = ".jpeg";
|
||||||
}
|
if (message.input.from === ".fit") message.input.from = ".fits";
|
||||||
|
|
||||||
if (message.input.from === ".jfif") {
|
|
||||||
message.input.from = ".jpeg";
|
|
||||||
}
|
|
||||||
|
|
||||||
const buffer = await message.input.file.arrayBuffer();
|
const buffer = await message.input.file.arrayBuffer();
|
||||||
// only wait when we need to
|
// only wait when we need to
|
||||||
|
|
@ -70,7 +67,7 @@ const handleMessage = async (message: any): Promise<any> => {
|
||||||
const convertedImgs: Uint8Array[] = [];
|
const convertedImgs: Uint8Array[] = [];
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
imgs.map(async (img, i) => {
|
imgs.map(async (img, i) => {
|
||||||
const output = await magickConvert(img, message.to);
|
const output = await magickConvert(img, message.to, compression);
|
||||||
convertedImgs[i] = output;
|
convertedImgs[i] = output;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
@ -78,7 +75,10 @@ const handleMessage = async (message: any): Promise<any> => {
|
||||||
const zip = makeZip(
|
const zip = makeZip(
|
||||||
convertedImgs.map(
|
convertedImgs.map(
|
||||||
(img, i) =>
|
(img, i) =>
|
||||||
new File([img], `image${i}.${message.to.slice(1)}`),
|
new File(
|
||||||
|
[new Uint8Array(img)],
|
||||||
|
`image${i}.${message.to.slice(1)}`,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
"images.zip",
|
"images.zip",
|
||||||
);
|
);
|
||||||
|
|
@ -108,9 +108,13 @@ const handleMessage = async (message: any): Promise<any> => {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
message.to,
|
message.to,
|
||||||
|
compression
|
||||||
);
|
);
|
||||||
files.push(
|
files.push(
|
||||||
new File([blob], `image${i}${message.to}`),
|
new File(
|
||||||
|
[new Uint8Array(blob)],
|
||||||
|
`image${i}${message.to}`,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
@ -154,6 +158,7 @@ const handleMessage = async (message: any): Promise<any> => {
|
||||||
const converted = await magickConvert(
|
const converted = await magickConvert(
|
||||||
img,
|
img,
|
||||||
message.to,
|
message.to,
|
||||||
|
compression
|
||||||
);
|
);
|
||||||
outputs.push(converted);
|
outputs.push(converted);
|
||||||
break;
|
break;
|
||||||
|
|
@ -167,7 +172,10 @@ const handleMessage = async (message: any): Promise<any> => {
|
||||||
const zip = makeZip(
|
const zip = makeZip(
|
||||||
outputs.map(
|
outputs.map(
|
||||||
(img, i) =>
|
(img, i) =>
|
||||||
new File([img], `image${i}.${message.to.slice(1)}`),
|
new File(
|
||||||
|
[new Uint8Array(img)],
|
||||||
|
`image${i}.${message.to.slice(1)}`,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
"images.zip",
|
"images.zip",
|
||||||
);
|
);
|
||||||
|
|
@ -179,6 +187,32 @@ const handleMessage = async (message: any): Promise<any> => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build frames of animated formats (webp/gif)
|
||||||
|
// APNG does not work on magick-wasm since it needs ffmpeg built-in (not in magick-wasm) - handle in ffmpeg
|
||||||
|
if (
|
||||||
|
(message.input.from === ".webp" ||
|
||||||
|
message.input.from === ".gif") &&
|
||||||
|
(message.to === ".gif" || message.to === ".webp")
|
||||||
|
) {
|
||||||
|
const collection = MagickImageCollection.create(
|
||||||
|
new Uint8Array(buffer),
|
||||||
|
);
|
||||||
|
const format =
|
||||||
|
message.to === ".gif"
|
||||||
|
? MagickFormat.Gif
|
||||||
|
: MagickFormat.WebP;
|
||||||
|
const result = await new Promise<Uint8Array>((resolve) => {
|
||||||
|
collection.write(format, (output) => {
|
||||||
|
resolve(structuredClone(output));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
collection.dispose();
|
||||||
|
return {
|
||||||
|
type: "finished",
|
||||||
|
output: result,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const img = MagickImage.create(
|
const img = MagickImage.create(
|
||||||
new Uint8Array(buffer),
|
new Uint8Array(buffer),
|
||||||
new MagickReadSettings({
|
new MagickReadSettings({
|
||||||
|
|
@ -188,7 +222,7 @@ const handleMessage = async (message: any): Promise<any> => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const converted = await magickConvert(img, message.to);
|
const converted = await magickConvert(img, message.to, compression);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "finished",
|
type: "finished",
|
||||||
|
|
@ -206,7 +240,10 @@ const readToEnd = async (reader: ReadableStreamDefaultReader<Uint8Array>) => {
|
||||||
if (value) chunks.push(value);
|
if (value) chunks.push(value);
|
||||||
done = d;
|
done = d;
|
||||||
}
|
}
|
||||||
const blob = new Blob(chunks, { type: "application/zip" });
|
const blob = new Blob(
|
||||||
|
chunks.map((chunk) => new Uint8Array(chunk)),
|
||||||
|
{ type: "application/zip" },
|
||||||
|
);
|
||||||
const arrayBuffer = await blob.arrayBuffer();
|
const arrayBuffer = await blob.arrayBuffer();
|
||||||
return new Uint8Array(arrayBuffer);
|
return new Uint8Array(arrayBuffer);
|
||||||
};
|
};
|
||||||
|
|
@ -250,8 +287,12 @@ const magickToBlob = async (img: IMagickImage): Promise<Blob> => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
reject(new Error("Pixel data is null"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
const imageData = new ImageData(
|
const imageData = new ImageData(
|
||||||
new Uint8ClampedArray(data?.buffer || new ArrayBuffer(0)),
|
new Uint8ClampedArray(data),
|
||||||
img.width,
|
img.width,
|
||||||
img.height,
|
img.height,
|
||||||
);
|
);
|
||||||
|
|
@ -266,7 +307,11 @@ const magickToBlob = async (img: IMagickImage): Promise<Blob> => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const magickConvert = async (img: IMagickImage, to: string) => {
|
const magickConvert = async (
|
||||||
|
img: IMagickImage,
|
||||||
|
to: string,
|
||||||
|
compression?: number,
|
||||||
|
) => {
|
||||||
const intermediary = await magickToBlob(img);
|
const intermediary = await magickToBlob(img);
|
||||||
const buf = new Uint8Array(await intermediary.arrayBuffer());
|
const buf = new Uint8Array(await intermediary.arrayBuffer());
|
||||||
let fmt = to.slice(1).toUpperCase();
|
let fmt = to.slice(1).toUpperCase();
|
||||||
|
|
@ -274,6 +319,8 @@ const magickConvert = async (img: IMagickImage, to: string) => {
|
||||||
|
|
||||||
const result = await new Promise<Uint8Array>((resolve) => {
|
const result = await new Promise<Uint8Array>((resolve) => {
|
||||||
ImageMagick.read(buf, MagickFormat.Png, (image) => {
|
ImageMagick.read(buf, MagickFormat.Png, (image) => {
|
||||||
|
// magick-wasm automatically clamps (https://github.com/dlemstra/magick-wasm/blob/76fc6f2b0c0497d2ddc251bbf6174b4dc92ac3ea/src/magick-image.ts#L2480)
|
||||||
|
if (compression) image.quality = compression;
|
||||||
image.write(fmt as unknown as MagickFormat, (o) => {
|
image.write(fmt as unknown as MagickFormat, (o) => {
|
||||||
resolve(structuredClone(o));
|
resolve(structuredClone(o));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,6 @@ const formatToReader = (format: Format): string => {
|
||||||
return "rtf";
|
return "rtf";
|
||||||
case ".rst":
|
case ".rst":
|
||||||
return "rst";
|
return "rst";
|
||||||
case ".xml":
|
|
||||||
return "xml";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`Unsupported format: ${format}`);
|
throw new Error(`Unsupported format: ${format}`);
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,7 @@
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { goto, beforeNavigate, afterNavigate } from "$app/navigation";
|
import { goto, beforeNavigate, afterNavigate } from "$app/navigation";
|
||||||
|
|
||||||
import {
|
import { PUB_PLAUSIBLE_URL, PUB_HOSTNAME } from "$env/static/public";
|
||||||
PUB_PLAUSIBLE_URL,
|
|
||||||
PUB_HOSTNAME,
|
|
||||||
PUB_DONATION_URL,
|
|
||||||
} from "$env/static/public";
|
|
||||||
import { VERT_NAME } from "$lib/consts";
|
import { VERT_NAME } from "$lib/consts";
|
||||||
import * as Layout from "$lib/components/layout";
|
import * as Layout from "$lib/components/layout";
|
||||||
import * as Navbar from "$lib/components/layout/Navbar";
|
import * as Navbar from "$lib/components/layout/Navbar";
|
||||||
|
|
@ -19,11 +15,13 @@
|
||||||
theme,
|
theme,
|
||||||
dropping,
|
dropping,
|
||||||
vertdLoaded,
|
vertdLoaded,
|
||||||
|
locale,
|
||||||
} from "$lib/store/index.svelte";
|
} from "$lib/store/index.svelte";
|
||||||
import "$lib/css/app.scss";
|
import "$lib/css/app.scss";
|
||||||
import { browser } from "$app/environment";
|
import { browser } from "$app/environment";
|
||||||
import { page } from "$app/state";
|
import { page } from "$app/state";
|
||||||
import { initStores as initAnimStores } from "$lib/animation/index.js";
|
import { initStores as initAnimStores } from "$lib/animation/index.js";
|
||||||
|
import { locales, localizeHref } from "$lib/paraglide/runtime";
|
||||||
|
|
||||||
let { children, data } = $props();
|
let { children, data } = $props();
|
||||||
let enablePlausible = $state(false);
|
let enablePlausible = $state(false);
|
||||||
|
|
@ -72,7 +70,6 @@
|
||||||
theme.set(
|
theme.set(
|
||||||
(localStorage.getItem("theme") as "light" | "dark") || "light",
|
(localStorage.getItem("theme") as "light" | "dark") || "light",
|
||||||
);
|
);
|
||||||
|
|
||||||
Settings.instance.load();
|
Settings.instance.load();
|
||||||
|
|
||||||
fetch(`${Settings.instance.settings.vertdURL}/api/version`).then(
|
fetch(`${Settings.instance.settings.vertdURL}/api/version`).then(
|
||||||
|
|
@ -83,7 +80,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
// Enable plausible if enabled
|
|
||||||
enablePlausible =
|
enablePlausible =
|
||||||
!!PUB_PLAUSIBLE_URL && Settings.instance.settings.plausible;
|
!!PUB_PLAUSIBLE_URL && Settings.instance.settings.plausible;
|
||||||
if (!enablePlausible && browser) {
|
if (!enablePlausible && browser) {
|
||||||
|
|
@ -142,35 +138,44 @@
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<!-- FIXME: if user resizes between desktop/mobile, highlight of page disappears (only shows on original size) -->
|
<!-- FIXME: if user resizes between desktop/mobile, highlight of page disappears (only shows on original size) -->
|
||||||
<div
|
{#key $locale}
|
||||||
class="flex flex-col min-h-screen h-full w-full overflow-x-hidden"
|
<div
|
||||||
ondrop={dropFiles}
|
class="flex flex-col min-h-screen h-full w-full overflow-x-hidden"
|
||||||
ondragenter={(e) => handleDrag(e, true)}
|
ondrop={dropFiles}
|
||||||
ondragover={(e) => handleDrag(e, true)}
|
ondragenter={(e) => handleDrag(e, true)}
|
||||||
ondragleave={(e) => handleDrag(e, false)}
|
ondragover={(e) => handleDrag(e, true)}
|
||||||
role="region"
|
ondragleave={(e) => handleDrag(e, false)}
|
||||||
>
|
role="region"
|
||||||
<Layout.UploadRegion />
|
>
|
||||||
|
<Layout.UploadRegion />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Layout.MobileLogo />
|
<Layout.MobileLogo />
|
||||||
<Navbar.Desktop />
|
<Navbar.Desktop />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
SvelteKit throws the following warning when developing - safe to ignore as we render the children in this component:
|
SvelteKit throws the following warning when developing - safe to ignore as we render the children in this component:
|
||||||
`<slot />` or `{@render ...}` tag missing — inner content will not be rendered
|
`<slot />` or `{@render ...}` tag missing — inner content will not be rendered
|
||||||
-->
|
-->
|
||||||
<Layout.PageContent {children} />
|
<Layout.PageContent {children} />
|
||||||
|
<div style="display:none">
|
||||||
|
{#each locales as locale}
|
||||||
|
<a href={localizeHref(page.url.pathname, { locale })}
|
||||||
|
>{locale}</a
|
||||||
|
>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Layout.Toasts />
|
<Layout.Toasts />
|
||||||
<Layout.Dialogs />
|
<Layout.Dialogs />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Layout.Footer />
|
<Layout.Footer />
|
||||||
<Navbar.Mobile />
|
<Navbar.Mobile />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/key}
|
||||||
|
|
||||||
<!-- Gradients placed here to prevent it overlapping in transitions -->
|
<!-- Gradients placed here to prevent it overlapping in transitions -->
|
||||||
<Layout.Gradients />
|
<Layout.Gradients />
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,11 @@
|
||||||
import { vertdLoaded } from "$lib/store/index.svelte";
|
import { vertdLoaded } from "$lib/store/index.svelte";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { AudioLines, BookText, Check, Film, Image } from "lucide-svelte";
|
import { AudioLines, BookText, Check, Film, Image } from "lucide-svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import { OverlayScrollbarsComponent } from "overlayscrollbars-svelte";
|
||||||
|
import { browser } from "$app/environment";
|
||||||
|
import "overlayscrollbars/overlayscrollbars.css";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
const getSupportedFormats = (name: string) =>
|
const getSupportedFormats = (name: string) =>
|
||||||
converters
|
converters
|
||||||
|
|
@ -20,6 +25,7 @@
|
||||||
ready: boolean;
|
ready: boolean;
|
||||||
formats: string;
|
formats: string;
|
||||||
icon: typeof Image;
|
icon: typeof Image;
|
||||||
|
title: string;
|
||||||
};
|
};
|
||||||
} = $derived({
|
} = $derived({
|
||||||
Images: {
|
Images: {
|
||||||
|
|
@ -28,16 +34,19 @@
|
||||||
false,
|
false,
|
||||||
formats: getSupportedFormats("imagemagick"),
|
formats: getSupportedFormats("imagemagick"),
|
||||||
icon: Image,
|
icon: Image,
|
||||||
|
title: m["upload.cards.images"](),
|
||||||
},
|
},
|
||||||
Audio: {
|
Audio: {
|
||||||
ready: converters.find((c) => c.name === "ffmpeg")?.ready || false,
|
ready: converters.find((c) => c.name === "ffmpeg")?.ready || false,
|
||||||
formats: getSupportedFormats("ffmpeg"),
|
formats: getSupportedFormats("ffmpeg"),
|
||||||
icon: AudioLines,
|
icon: AudioLines,
|
||||||
|
title: m["upload.cards.audio"](),
|
||||||
},
|
},
|
||||||
Documents: {
|
Documents: {
|
||||||
ready: converters.find((c) => c.name === "pandoc")?.ready || false,
|
ready: converters.find((c) => c.name === "pandoc")?.ready || false,
|
||||||
formats: getSupportedFormats("pandoc"),
|
formats: getSupportedFormats("pandoc"),
|
||||||
icon: BookText,
|
icon: BookText,
|
||||||
|
title: m["upload.cards.documents"](),
|
||||||
},
|
},
|
||||||
Video: {
|
Video: {
|
||||||
ready:
|
ready:
|
||||||
|
|
@ -45,6 +54,7 @@
|
||||||
(false && $vertdLoaded),
|
(false && $vertdLoaded),
|
||||||
formats: getSupportedFormats("vertd"),
|
formats: getSupportedFormats("vertd"),
|
||||||
icon: Film,
|
icon: Film,
|
||||||
|
title: m["upload.cards.video"](),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -58,12 +68,35 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
if (formatInfo) {
|
if (formatInfo) {
|
||||||
return `This format can only be converted as ${
|
const direction = formatInfo.fromSupported
|
||||||
formatInfo.fromSupported ? "input (from)" : "output (to)"
|
? m["upload.tooltip.direction_input"]()
|
||||||
}.`;
|
: m["upload.tooltip.direction_output"]();
|
||||||
|
return m["upload.tooltip.partial_support"]({ direction });
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let scrollContainers: HTMLElement[] = $state([]);
|
||||||
|
// svelte-ignore state_referenced_locally
|
||||||
|
let showBlur = $state(Array(Object.keys(status).length).fill(false));
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const handleResize = () => {
|
||||||
|
for (let i = 0; i < scrollContainers.length; i++) {
|
||||||
|
// show bottom blur if scrollable
|
||||||
|
const container = scrollContainers[i];
|
||||||
|
if (!container) return;
|
||||||
|
showBlur[i] = container.scrollHeight > container.clientHeight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleResize();
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("resize", handleResize);
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="max-w-6xl w-full mx-auto px-6 md:px-8">
|
<div class="max-w-6xl w-full mx-auto px-6 md:px-8">
|
||||||
|
|
@ -75,14 +108,12 @@
|
||||||
<h1
|
<h1
|
||||||
class="text-4xl px-12 md:p-0 md:text-6xl flex-wrap tracking-tight leading-tight md:leading-[72px] mb-4 md:mb-6"
|
class="text-4xl px-12 md:p-0 md:text-6xl flex-wrap tracking-tight leading-tight md:leading-[72px] mb-4 md:mb-6"
|
||||||
>
|
>
|
||||||
The file converter you'll love.
|
{m["upload.title"]()}
|
||||||
</h1>
|
</h1>
|
||||||
<p
|
<p
|
||||||
class="font-normal px-5 md:p-0 text-lg md:text-xl text-black text-muted dynadark:text-muted"
|
class="font-normal px-5 md:p-0 text-lg md:text-xl text-black text-muted dynadark:text-muted"
|
||||||
>
|
>
|
||||||
All image, audio, and document processing is done on your
|
{m["upload.subtitle"]()}
|
||||||
device. Videos are converted on our lightning-fast servers.
|
|
||||||
No file size limit, no ads, and completely open source.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow w-full h-72">
|
<div class="flex-grow w-full h-72">
|
||||||
|
|
@ -94,84 +125,150 @@
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="mt-10 md:mt-16">
|
<div class="mt-10 md:mt-16">
|
||||||
<h2 class="text-center text-4xl">VERT supports...</h2>
|
<h2 class="text-center text-4xl">{m["upload.cards.title"]()}</h2>
|
||||||
|
|
||||||
<div class="flex gap-4 mt-8 md:flex-row flex-col">
|
<div class="flex gap-4 mt-8 md:flex-row flex-col">
|
||||||
{#each Object.entries(status) as [key, s]}
|
{#if browser}
|
||||||
{@const Icon = s.icon}
|
{#each Object.entries(status) as [key, s], i}
|
||||||
<div class="file-category-card w-full flex flex-col gap-4">
|
{@const Icon = s.icon}
|
||||||
<div class="file-category-card-inner">
|
<div class="file-category-card w-full flex flex-col gap-4">
|
||||||
<div
|
<div class="file-category-card-inner">
|
||||||
class={clsx("icon-container", {
|
<div
|
||||||
"bg-accent-blue": key === "Images",
|
class={clsx("icon-container", {
|
||||||
"bg-accent-purple": key === "Audio",
|
"bg-accent-blue": key === "Images",
|
||||||
"bg-accent-green": key === "Documents",
|
"bg-accent-purple": key === "Audio",
|
||||||
"bg-accent-red": key === "Video",
|
"bg-accent-green": key === "Documents",
|
||||||
})}
|
"bg-accent-red": key === "Video",
|
||||||
>
|
})}
|
||||||
<Icon size="20" />
|
>
|
||||||
|
<Icon size="20" />
|
||||||
|
</div>
|
||||||
|
<span>{s.title}</span>
|
||||||
</div>
|
</div>
|
||||||
<span>{key}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="file-category-card-content flex-grow gap-4">
|
<div
|
||||||
{#if key === "Video"}
|
class="file-category-card-content flex-grow relative"
|
||||||
<p>
|
>
|
||||||
Video uploads to a server for processing by
|
<OverlayScrollbarsComponent
|
||||||
default, learn how to set it up locally <a
|
options={{
|
||||||
target="_blank"
|
scrollbars: {
|
||||||
href="https://github.com/VERT-sh/VERT/wiki/How-to-convert-video-with-VERT"
|
autoHide: "move",
|
||||||
>here</a
|
autoHideDelay: 1500,
|
||||||
>.
|
},
|
||||||
</p>
|
}}
|
||||||
{:else}
|
defer
|
||||||
<p class="flex tems-center justify-center gap-2">
|
>
|
||||||
<Check size="20" /> Local fully supported
|
<div
|
||||||
</p>
|
class="flex flex-col gap-4 h-[12.25rem] relative"
|
||||||
{/if}
|
bind:this={scrollContainers[i]}
|
||||||
<p>
|
>
|
||||||
<b>Status: </b>
|
{#if key === "Video"}
|
||||||
{s.ready ? "ready" : "not ready"}
|
<p
|
||||||
</p>
|
class="flex tems-center justify-center gap-2"
|
||||||
<div>
|
>
|
||||||
<span class="flex flex-wrap justify-center">
|
<Check size="20" />
|
||||||
<b>Supported formats: </b>
|
|
||||||
{#each s.formats.split(", ") as format, index}
|
|
||||||
{@const isPartial = format.endsWith("*")}
|
|
||||||
{@const formatName = isPartial
|
|
||||||
? format.slice(0, -1)
|
|
||||||
: format}
|
|
||||||
<span
|
|
||||||
class="text-sm font-normal flex items-center"
|
|
||||||
>
|
|
||||||
{#if isPartial}
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
text={getTooltip(formatName)}
|
text={m[
|
||||||
|
"upload.tooltip.video_server_processing"
|
||||||
|
]()}
|
||||||
>
|
>
|
||||||
{formatName}<span
|
<span>
|
||||||
class="text-red-500">*</span
|
<a
|
||||||
>
|
href="https://github.com/VERT-sh/VERT/blob/main/docs/VIDEO_CONVERSION.md"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{m[
|
||||||
|
"upload.cards.video_server_processing"
|
||||||
|
]()}
|
||||||
|
</a>
|
||||||
|
<span
|
||||||
|
class="text-red-500 -ml-0.5"
|
||||||
|
>*</span
|
||||||
|
>
|
||||||
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{:else}
|
</p>
|
||||||
{formatName}
|
{:else}
|
||||||
{/if}
|
<p
|
||||||
{#if index < s.formats.split(", ").length - 1}
|
class="flex tems-center justify-center gap-2"
|
||||||
<span>, </span>
|
>
|
||||||
{/if}
|
<Check size="20" />
|
||||||
</span>
|
{m[
|
||||||
{/each}
|
"upload.cards.local_supported"
|
||||||
</span>
|
]()}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
<p>
|
||||||
|
{@html m["upload.cards.status.text"]({
|
||||||
|
status: s.ready
|
||||||
|
? m[
|
||||||
|
"upload.cards.status.ready"
|
||||||
|
]()
|
||||||
|
: m[
|
||||||
|
"upload.cards.status.not_ready"
|
||||||
|
](),
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-col items-center relative">
|
||||||
|
<b
|
||||||
|
>{m[
|
||||||
|
"upload.cards.supported_formats"
|
||||||
|
]()} </b
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="flex flex-wrap justify-center leading-tight px-2"
|
||||||
|
>
|
||||||
|
{#each s.formats.split(", ") as format, index}
|
||||||
|
{@const isPartial =
|
||||||
|
format.endsWith("*")}
|
||||||
|
{@const formatName = isPartial
|
||||||
|
? format.slice(0, -1)
|
||||||
|
: format}
|
||||||
|
<span
|
||||||
|
class="text-sm font-normal flex items-center relative"
|
||||||
|
>
|
||||||
|
{#if isPartial}
|
||||||
|
<Tooltip
|
||||||
|
text={getTooltip(
|
||||||
|
formatName,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{formatName}<span
|
||||||
|
class="text-red-500"
|
||||||
|
>*</span
|
||||||
|
>
|
||||||
|
</Tooltip>
|
||||||
|
{:else}
|
||||||
|
{formatName}
|
||||||
|
{/if}
|
||||||
|
{#if index < s.formats.split(", ").length - 1}
|
||||||
|
<span>, </span>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{/each}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</OverlayScrollbarsComponent>
|
||||||
|
<!-- blur at bottom if scrollable - positioned relative to the card container -->
|
||||||
|
{#if showBlur[i]}
|
||||||
|
<div
|
||||||
|
class="absolute left-0 bottom-0 w-full h-10 pointer-events-none"
|
||||||
|
style={`background: linear-gradient(to top, var(--bg-panel), transparent 100%);`}
|
||||||
|
></div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/each}
|
||||||
{/each}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.file-category-card {
|
.file-category-card {
|
||||||
@apply bg-panel rounded-2xl p-5 shadow-panel;
|
@apply bg-panel rounded-2xl p-5 shadow-panel relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-category-card p {
|
.file-category-card p {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
import { addToast } from "$lib/store/ToastProvider";
|
import { addToast } from "$lib/store/ToastProvider";
|
||||||
import { dev } from "$app/environment";
|
import { dev } from "$app/environment";
|
||||||
import { page } from "$app/state";
|
import { page } from "$app/state";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
// import { dev } from "$app/environment";
|
// import { dev } from "$app/environment";
|
||||||
// import { page } from "$app/state";
|
// import { page } from "$app/state";
|
||||||
|
|
||||||
|
|
@ -34,19 +35,19 @@
|
||||||
{
|
{
|
||||||
name: "nullptr",
|
name: "nullptr",
|
||||||
github: "https://github.com/not-nullptr",
|
github: "https://github.com/not-nullptr",
|
||||||
role: "Lead developer; conversion backend, UI implementation",
|
role: m["about.credits.roles.lead_developer"](),
|
||||||
avatar: avatarNullptr,
|
avatar: avatarNullptr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "JovannMC",
|
name: "JovannMC",
|
||||||
github: "https://github.com/JovannMC",
|
github: "https://github.com/JovannMC",
|
||||||
role: "Developer; UI implementation",
|
role: m["about.credits.roles.developer"](),
|
||||||
avatar: avatarJovannMC,
|
avatar: avatarJovannMC,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Liam",
|
name: "Liam",
|
||||||
github: "https://x.com/z2rMC",
|
github: "https://x.com/z2rMC",
|
||||||
role: "Designer; UX, branding, marketing",
|
role: m["about.credits.roles.designer"](),
|
||||||
avatar: avatarLiam,
|
avatar: avatarLiam,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -55,13 +56,13 @@
|
||||||
{
|
{
|
||||||
name: "azurejelly",
|
name: "azurejelly",
|
||||||
github: "https://github.com/azurejelly",
|
github: "https://github.com/azurejelly",
|
||||||
role: "Maintaining Docker & CI support",
|
role: m["about.credits.roles.docker_ci"](),
|
||||||
avatar: avatarAzurejelly,
|
avatar: avatarAzurejelly,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Realmy",
|
name: "Realmy",
|
||||||
github: "https://github.com/RealmyTheMan",
|
github: "https://github.com/RealmyTheMan",
|
||||||
role: "Former co-founder & designer",
|
role: m["about.credits.roles.former_cofounder"](),
|
||||||
avatar: avatarRealmy,
|
avatar: avatarRealmy,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -80,7 +81,7 @@
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${GITHUB_API_URL}/contributors`);
|
const response = await fetch(`${GITHUB_API_URL}/contributors`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
addToast("error", "Error fetching GitHub contributors");
|
addToast("error", m["about.errors.github_contributors"]());
|
||||||
throw new Error(`HTTP error, status: ${response.status}`);
|
throw new Error(`HTTP error, status: ${response.status}`);
|
||||||
}
|
}
|
||||||
const allContribs = await response.json();
|
const allContribs = await response.json();
|
||||||
|
|
@ -89,6 +90,7 @@
|
||||||
const excludedNames = new Set([
|
const excludedNames = new Set([
|
||||||
...mainContribs.map((c) => c.github.split("/").pop()),
|
...mainContribs.map((c) => c.github.split("/").pop()),
|
||||||
...notableContribs.map((c) => c.github.split("/").pop()),
|
...notableContribs.map((c) => c.github.split("/").pop()),
|
||||||
|
"Z2r-YT"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const filteredContribs = allContribs.filter(
|
const filteredContribs = allContribs.filter(
|
||||||
|
|
@ -135,7 +137,7 @@
|
||||||
<div class="flex flex-col h-full items-center">
|
<div class="flex flex-col h-full items-center">
|
||||||
<h1 class="hidden md:block text-[40px] tracking-tight leading-[72px] mb-6">
|
<h1 class="hidden md:block text-[40px] tracking-tight leading-[72px] mb-6">
|
||||||
<InfoIcon size="40" class="inline-block -mt-2 mr-2" />
|
<InfoIcon size="40" class="inline-block -mt-2 mr-2" />
|
||||||
About
|
{m["about.title"]()}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import ProgressBar from "$lib/components/visual/ProgressBar.svelte";
|
import ProgressBar from "$lib/components/visual/ProgressBar.svelte";
|
||||||
import Tooltip from "$lib/components/visual/Tooltip.svelte";
|
import Tooltip from "$lib/components/visual/Tooltip.svelte";
|
||||||
import { categories, converters } from "$lib/converters";
|
import { categories, converters, byNative } from "$lib/converters";
|
||||||
import {
|
import {
|
||||||
effects,
|
effects,
|
||||||
files,
|
files,
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
XIcon,
|
XIcon,
|
||||||
} from "lucide-svelte";
|
} from "lucide-svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// depending on format, select right category and format
|
// depending on format, select right category and format
|
||||||
|
|
@ -51,21 +52,30 @@
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
// Set gradient color depending on the file types
|
// Set gradient color depending on the file types
|
||||||
// TODO: if more file types added, add a "fileType" property to the file object
|
// TODO: if more file types added, add a "fileType" property to the file object
|
||||||
const allAudio = files.files.every(
|
const allAudio = files.files.every((file) => {
|
||||||
(file) => file.findConverter()?.name === "ffmpeg",
|
const converter = file
|
||||||
);
|
.findConverters()
|
||||||
const allImages = files.files.every(
|
.sort(byNative(file.from))[0];
|
||||||
(file) =>
|
return converter?.name === "ffmpeg";
|
||||||
file.findConverter()?.name !== "ffmpeg" &&
|
});
|
||||||
file.findConverter()?.name !== "vertd",
|
const allImages = files.files.every((file) => {
|
||||||
);
|
const converter = file
|
||||||
const allVideos = files.files.every(
|
.findConverters()
|
||||||
(file) => file.findConverter()?.name === "vertd",
|
.sort(byNative(file.from))[0];
|
||||||
);
|
return converter?.name === "libvips";
|
||||||
|
});
|
||||||
const allDocuments = files.files.every(
|
const allVideos = files.files.every((file) => {
|
||||||
(file) => file.findConverter()?.name === "pandoc",
|
const converter = file
|
||||||
);
|
.findConverters()
|
||||||
|
.sort(byNative(file.from))[0];
|
||||||
|
return converter?.name === "vertd";
|
||||||
|
});
|
||||||
|
const allDocuments = files.files.every((file) => {
|
||||||
|
const converter = file
|
||||||
|
.findConverters()
|
||||||
|
.sort(byNative(file.from))[0];
|
||||||
|
return converter?.name === "pandoc";
|
||||||
|
});
|
||||||
|
|
||||||
if (files.files.length === 1 && files.files[0].blobUrl && !allVideos) {
|
if (files.files.length === 1 && files.files[0].blobUrl && !allVideos) {
|
||||||
showGradient.set(false);
|
showGradient.set(false);
|
||||||
|
|
@ -75,7 +85,7 @@
|
||||||
|
|
||||||
if (
|
if (
|
||||||
files.files.length === 0 ||
|
files.files.length === 0 ||
|
||||||
(!allAudio && !allImages && !allVideos)
|
(!allAudio && !allImages && !allVideos && !allDocuments)
|
||||||
) {
|
) {
|
||||||
gradientColor.set("");
|
gradientColor.set("");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -95,7 +105,6 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet fileItem(file: VertFile, index: number)}
|
{#snippet fileItem(file: VertFile, index: number)}
|
||||||
{@const availableConverters = file.findConverters()}
|
|
||||||
{@const currentConverter = converters.find(
|
{@const currentConverter = converters.find(
|
||||||
(c) =>
|
(c) =>
|
||||||
c.formatStrings((f) => f.fromSupported).includes(file.from) &&
|
c.formatStrings((f) => f.fromSupported).includes(file.from) &&
|
||||||
|
|
@ -103,11 +112,13 @@
|
||||||
)}
|
)}
|
||||||
{@const isAudio = converters
|
{@const isAudio = converters
|
||||||
.find((c) => c.name === "ffmpeg")
|
.find((c) => c.name === "ffmpeg")
|
||||||
?.formatStrings((f) => f.fromSupported)
|
?.supportedFormats.filter((f) => f.isNative)
|
||||||
|
.map((f) => f.name)
|
||||||
.includes(file.from)}
|
.includes(file.from)}
|
||||||
{@const isVideo = converters
|
{@const isVideo = converters
|
||||||
.find((c) => c.name === "vertd")
|
.find((c) => c.name === "vertd")
|
||||||
?.formatStrings((f) => f.fromSupported)
|
?.supportedFormats.filter((f) => f.isNative)
|
||||||
|
.map((f) => f.name)
|
||||||
.includes(file.from)}
|
.includes(file.from)}
|
||||||
{@const isImage = converters
|
{@const isImage = converters
|
||||||
.find((c) => c.name === "imagemagick")
|
.find((c) => c.name === "imagemagick")
|
||||||
|
|
@ -115,28 +126,29 @@
|
||||||
.includes(file.from)}
|
.includes(file.from)}
|
||||||
{@const isDocument = converters
|
{@const isDocument = converters
|
||||||
.find((c) => c.name === "pandoc")
|
.find((c) => c.name === "pandoc")
|
||||||
?.formatStrings((f) => f.fromSupported)
|
?.supportedFormats.filter((f) => f.isNative)
|
||||||
|
.map((f) => f.name)
|
||||||
.includes(file.from)}
|
.includes(file.from)}
|
||||||
<Panel class="p-5 flex flex-col min-w-0 gap-4 relative">
|
<Panel class="p-5 flex flex-col min-w-0 gap-4 relative">
|
||||||
<div class="flex-shrink-0 h-8 w-full flex items-center gap-2">
|
<div class="flex-shrink-0 h-8 w-full flex items-center gap-2">
|
||||||
{#if !converters.length}
|
{#if !converters.length}
|
||||||
<Tooltip text="Unknown file type" position="bottom">
|
<Tooltip text={m["convert.tooltips.unknown_file"]()} position="bottom">
|
||||||
<FileQuestionIcon size="24" class="flex-shrink-0" />
|
<FileQuestionIcon size="24" class="flex-shrink-0" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{:else if isAudio}
|
{:else if isAudio}
|
||||||
<Tooltip text="Audio file" position="bottom">
|
<Tooltip text={m["convert.tooltips.audio_file"]()} position="bottom">
|
||||||
<AudioLines size="24" class="flex-shrink-0" />
|
<AudioLines size="24" class="flex-shrink-0" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{:else if isVideo}
|
{:else if isVideo}
|
||||||
<Tooltip text="Video file" position="bottom">
|
<Tooltip text={m["convert.tooltips.video_file"]()} position="bottom">
|
||||||
<FilmIcon size="24" class="flex-shrink-0" />
|
<FilmIcon size="24" class="flex-shrink-0" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{:else if isDocument}
|
{:else if isDocument}
|
||||||
<Tooltip text="Document file" position="bottom">
|
<Tooltip text={m["convert.tooltips.document_file"]()} position="bottom">
|
||||||
<BookText size="24" class="flex-shrink-0" />
|
<BookText size="24" class="flex-shrink-0" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{:else}
|
{:else}
|
||||||
<Tooltip text="Image file" position="bottom">
|
<Tooltip text={m["convert.tooltips.image_file"]()} position="bottom">
|
||||||
<ImageIcon size="24" class="flex-shrink-0" />
|
<ImageIcon size="24" class="flex-shrink-0" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -172,11 +184,10 @@
|
||||||
class="h-full flex flex-col text-center justify-center text-failure"
|
class="h-full flex flex-col text-center justify-center text-failure"
|
||||||
>
|
>
|
||||||
<p class="font-body font-bold">
|
<p class="font-body font-bold">
|
||||||
We can't convert this file.
|
{m["convert.errors.cant_convert"]()}
|
||||||
</p>
|
</p>
|
||||||
<p class="font-normal">
|
<p class="font-normal">
|
||||||
what are you doing..? you're supposed to run the vertd
|
{m["convert.errors.vertd_server"]()}
|
||||||
server!
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
@ -184,11 +195,10 @@
|
||||||
class="h-full flex flex-col text-center justify-center text-failure"
|
class="h-full flex flex-col text-center justify-center text-failure"
|
||||||
>
|
>
|
||||||
<p class="font-body font-bold">
|
<p class="font-body font-bold">
|
||||||
We can't convert this file.
|
{m["convert.errors.cant_convert"]()}
|
||||||
</p>
|
</p>
|
||||||
<p class="font-normal">
|
<p class="font-normal">
|
||||||
Only image, video, audio, and document files are
|
{m["convert.errors.unsupported_format"]()}
|
||||||
supported
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -196,10 +206,9 @@
|
||||||
<div
|
<div
|
||||||
class="h-full flex flex-col text-center justify-center text-failure"
|
class="h-full flex flex-col text-center justify-center text-failure"
|
||||||
>
|
>
|
||||||
<p class="font-body font-bold">We can't convert this file.</p>
|
<p class="font-body font-bold">{m["convert.errors.cant_convert"]()}</p>
|
||||||
<p class="font-normal">
|
<p class="font-normal">
|
||||||
Could not find the vertd instance to start video conversion.
|
{m["convert.errors.vertd_not_found"]()}
|
||||||
Are you sure the instance URL is set correctly?
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
@ -251,7 +260,7 @@
|
||||||
onselect={(option) => handleSelect(option, file)}
|
onselect={(option) => handleSelect(option, file)}
|
||||||
/>
|
/>
|
||||||
<div class="w-full flex items-center justify-between">
|
<div class="w-full flex items-center justify-between">
|
||||||
<Tooltip text="Convert this file" position="bottom">
|
<Tooltip text={m["convert.tooltips.convert_file"]()} position="bottom">
|
||||||
<button
|
<button
|
||||||
class="btn {$effects
|
class="btn {$effects
|
||||||
? ''
|
? ''
|
||||||
|
|
@ -269,7 +278,7 @@
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
text="Download this file"
|
text={m["convert.tooltips.download_file"]()}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
import { files } from "$lib/store/index.svelte";
|
import { files } from "$lib/store/index.svelte";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
import { blur } from "svelte/transition";
|
import { blur } from "svelte/transition";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
const images = $derived(
|
const images = $derived(
|
||||||
files.files.filter((f) =>
|
files.files.filter((f) =>
|
||||||
|
|
@ -31,9 +32,9 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mx-auto w-full max-w-[778px] flex flex-col gap-8">
|
<div class="mx-auto w-full max-w-[778px] flex flex-col gap-8">
|
||||||
<h1 class="text-5xl text-center">SECRET JPEGIFY!!!</h1>
|
<h1 class="text-5xl text-center">{m["jpegify.title"]()}</h1>
|
||||||
<p class="text-muted text-center -mt-4 font-normal italic">
|
<p class="text-muted text-center -mt-4 font-normal italic">
|
||||||
(shh... don't tell anyone!)
|
{m["jpegify.subtitle"]()}
|
||||||
</p>
|
</p>
|
||||||
<Uploader class="w-full h-64" jpegify={true} />
|
<Uploader class="w-full h-64" jpegify={true} />
|
||||||
<input
|
<input
|
||||||
|
|
@ -49,7 +50,7 @@
|
||||||
onclick={jpegify}
|
onclick={jpegify}
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
class="btn bg-accent text-black rounded-2xl text-2xl w-full mx-auto"
|
class="btn bg-accent text-black rounded-2xl text-2xl w-full mx-auto"
|
||||||
>JPEGIFY {compressionInverted}%!!!</button
|
>{m["jpegify.button"]({ compression: compressionInverted })}</button
|
||||||
>
|
>
|
||||||
<div class="flex flex-wrap flex-row justify-center gap-4">
|
<div class="flex flex-wrap flex-row justify-center gap-4">
|
||||||
{#each images as file, i (file.id)}
|
{#each images as file, i (file.id)}
|
||||||
|
|
@ -89,7 +90,7 @@
|
||||||
disabled={!!!file.result}
|
disabled={!!!file.result}
|
||||||
class="btn bg-accent text-black rounded-2xl text-2xl w-full mx-auto"
|
class="btn bg-accent text-black rounded-2xl text-2xl w-full mx-auto"
|
||||||
>
|
>
|
||||||
Download
|
{m["jpegify.download"]()}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
|
|
@ -103,7 +104,7 @@
|
||||||
}}
|
}}
|
||||||
class="btn border-accent-red border-2 bg-transparent text-black dynadark:text-white rounded-2xl text-2xl w-full mx-auto"
|
class="btn border-accent-red border-2 bg-transparent text-black dynadark:text-white rounded-2xl text-2xl w-full mx-auto"
|
||||||
>
|
>
|
||||||
Delete
|
{m["jpegify.delete"]()}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
import { PUB_PLAUSIBLE_URL } from "$env/static/public";
|
import { PUB_PLAUSIBLE_URL } from "$env/static/public";
|
||||||
import { SettingsIcon } from "lucide-svelte";
|
import { SettingsIcon } from "lucide-svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
|
||||||
let settings = $state(Settings.Settings.instance.settings);
|
let settings = $state(Settings.Settings.instance.settings);
|
||||||
|
|
||||||
|
|
@ -31,7 +32,7 @@
|
||||||
log(["settings"], "saving settings");
|
log(["settings"], "saving settings");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log(["settings", "error"], `failed to save settings: ${error}`);
|
log(["settings", "error"], `failed to save settings: ${error}`);
|
||||||
addToast("error", "Failed to save settings!");
|
addToast("error", m["settings.errors.save_failed"]());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -51,7 +52,7 @@
|
||||||
<div class="flex flex-col h-full items-center">
|
<div class="flex flex-col h-full items-center">
|
||||||
<h1 class="hidden md:block text-[40px] tracking-tight leading-[72px] mb-6">
|
<h1 class="hidden md:block text-[40px] tracking-tight leading-[72px] mb-6">
|
||||||
<SettingsIcon size="40" class="inline-block -mt-2 mr-2" />
|
<SettingsIcon size="40" class="inline-block -mt-2 mr-2" />
|
||||||
Settings
|
{m["settings.title"]()}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { paraglideVitePlugin } from "@inlang/paraglide-js";
|
||||||
import { sveltekit } from "@sveltejs/kit/vite";
|
import { sveltekit } from "@sveltejs/kit/vite";
|
||||||
import { defineConfig, type PluginOption } from "vite";
|
import { defineConfig, type PluginOption } from "vite";
|
||||||
import svg from "@poppanator/sveltekit-svg";
|
import svg from "@poppanator/sveltekit-svg";
|
||||||
|
|
@ -6,6 +7,11 @@ import wasm from "vite-plugin-wasm";
|
||||||
export default defineConfig(({ command }) => {
|
export default defineConfig(({ command }) => {
|
||||||
const plugins: PluginOption[] = [
|
const plugins: PluginOption[] = [
|
||||||
sveltekit(),
|
sveltekit(),
|
||||||
|
paraglideVitePlugin({
|
||||||
|
project: "./project.inlang",
|
||||||
|
outdir: "./src/lib/paraglide",
|
||||||
|
strategy: ["localStorage", "preferredLanguage", "baseLocale"],
|
||||||
|
}),
|
||||||
svg({
|
svg({
|
||||||
includePaths: ["./src/lib/assets"],
|
includePaths: ["./src/lib/assets"],
|
||||||
svgoOptions: {
|
svgoOptions: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue