From 8cc11367ef38bab47415c3ab98dffcbd0694a632 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 13 Jun 2024 15:32:17 +0600 Subject: [PATCH 001/775] web: project skeleton --- web/.gitignore | 10 + web/.npmrc | 1 + web/README.md | 2 + web/package-lock.json | 1959 +++++++++++++++++++++++++++++++++++ web/package.json | 32 + web/src/app.d.ts | 13 + web/src/app.html | 12 + web/src/lib/index.ts | 1 + web/src/routes/+page.svelte | 1 + web/static/favicon.png | Bin 0 -> 1391 bytes web/svelte.config.js | 18 + web/tsconfig.json | 19 + web/vite.config.ts | 6 + 13 files changed, 2074 insertions(+) create mode 100644 web/.gitignore create mode 100644 web/.npmrc create mode 100644 web/README.md create mode 100644 web/package-lock.json create mode 100644 web/package.json create mode 100644 web/src/app.d.ts create mode 100644 web/src/app.html create mode 100644 web/src/lib/index.ts create mode 100644 web/src/routes/+page.svelte create mode 100644 web/static/favicon.png create mode 100644 web/svelte.config.js create mode 100644 web/tsconfig.json create mode 100644 web/vite.config.ts diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 00000000..6635cf55 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/web/.npmrc b/web/.npmrc new file mode 100644 index 00000000..b6f27f13 --- /dev/null +++ b/web/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/web/README.md b/web/README.md new file mode 100644 index 00000000..930f5029 --- /dev/null +++ b/web/README.md @@ -0,0 +1,2 @@ +# cobalt web +wip diff --git a/web/package-lock.json b/web/package-lock.json new file mode 100644 index 00000000..614fe446 --- /dev/null +++ b/web/package-lock.json @@ -0,0 +1,1959 @@ +{ + "name": "cobalt-web", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cobalt-web", + "version": "0.0.1", + "license": "AGPL-3.0", + "devDependencies": { + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "svelte-check": "^3.6.0", + "tslib": "^2.4.1", + "typescript": "^5.0.0", + "vite": "^5.0.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.25", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", + "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.1.tgz", + "integrity": "sha512-/3xx8ZFCD5UBc/7AbyXkFF3HNCzWAp2xncH8HA4doGjoGQEN7PmwiRx4Y9nOzi4mqDqYYUic0gaIAE2khWWU4Q==", + "dev": true, + "dependencies": { + "import-meta-resolve": "^4.1.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.5.10", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.10.tgz", + "integrity": "sha512-OqoyTmFG2cYmCFAdBfW+Qxbg8m23H4dv6KqwEt7ofr/ROcfcIl3Z/VT56L22H9f0uNZyr+9Bs1eh2gedOCK9kA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^5.0.0", + "esm-env": "^1.0.0", + "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": "^2.0.4", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", + "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", + "dev": true, + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.10", + "svelte-hmr": "^0.16.0", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", + "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/pug": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", + "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", + "dev": true + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/esm-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", + "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", + "dev": true + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "dependencies": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", + "dev": true + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sorcery": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", + "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.14", + "buffer-crc32": "^1.0.0", + "minimist": "^1.2.0", + "sander": "^0.5.0" + }, + "bin": { + "sorcery": "bin/sorcery" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svelte": { + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", + "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-check": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.0.tgz", + "integrity": "sha512-7Nxn+3X97oIvMzYJ7t27w00qUf1Y52irE2RU2dQAd5PyvfGp4E7NLhFKVhb6PV2fx7dCRMpNKDIuazmGthjpSQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "chokidar": "^3.4.1", + "fast-glob": "^3.2.7", + "import-fresh": "^3.2.1", + "picocolors": "^1.0.0", + "sade": "^1.7.4", + "svelte-preprocess": "^5.1.3", + "typescript": "^5.0.3" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "peerDependencies": { + "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" + } + }, + "node_modules/svelte-hmr": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", + "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", + "dev": true, + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/svelte-preprocess": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", + "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/pug": "^2.0.6", + "detect-indent": "^6.1.0", + "magic-string": "^0.30.5", + "sorcery": "^0.11.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.10.2", + "coffeescript": "^2.5.1", + "less": "^3.11.3 || ^4.0.0", + "postcss": "^7 || ^8", + "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "pug": "^3.0.0", + "sass": "^1.26.8", + "stylus": "^0.55.0", + "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", + "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "coffeescript": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "postcss-load-config": { + "optional": true + }, + "pug": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "5.2.13", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", + "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "dev": true, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + } +} diff --git a/web/package.json b/web/package.json new file mode 100644 index 00000000..1762262f --- /dev/null +++ b/web/package.json @@ -0,0 +1,32 @@ +{ + "name": "cobalt-web", + "version": "0.0.1", + "type": "module", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "license": "AGPL-3.0", + "repository": { + "type": "git", + "url": "git+https://github.com/imputnet/cobalt.git" + }, + "bugs": { + "url": "https://github.com/imputnet/cobalt/issues" + }, + "homepage": "https://cobalt.tools/", + "devDependencies": { + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "svelte-check": "^3.6.0", + "tslib": "^2.4.1", + "typescript": "^5.0.0", + "vite": "^5.0.3" + } +} diff --git a/web/src/app.d.ts b/web/src/app.d.ts new file mode 100644 index 00000000..c7c0ed1d --- /dev/null +++ b/web/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/web/src/app.html b/web/src/app.html new file mode 100644 index 00000000..88592f7a --- /dev/null +++ b/web/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/web/src/lib/index.ts b/web/src/lib/index.ts new file mode 100644 index 00000000..856f2b6c --- /dev/null +++ b/web/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte new file mode 100644 index 00000000..b4488011 --- /dev/null +++ b/web/src/routes/+page.svelte @@ -0,0 +1 @@ +

hello world

diff --git a/web/static/favicon.png b/web/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c94ccce2e435172cf392a64433c2aa2c80f7f7f9 GIT binary patch literal 1391 zcmb7EdpOez822BJk5f7)mlHz5HV!t_S%3E5Ie)z0`@Qc!-}8Lm^M0%VKW}ZgJ{$l5ZC@YH zKsD391GZLOpSe;bYSK#b38n%70{I;vP*#Cen;$mdv98PKE`_=73T+XKMn{UU63yf zOuDl-Q)97?>=B)JZz9D$ImF^T!+Ck=T*q$8T)uQ{b;e4{19uTYX+KwEew{6Pmtp?E zOg%h6i*TX_l8(ygG2^b8IA>$?C0ua_(nkzWGlQzvw_XFd0-<|=Z319807xTV^kc# znqr)5@21vR@HAR=3?u=jISZLQWB1R*O1%2!3z_G1alZ&eaQ?({S?~C7`q%MaG@pn> zwaYrx*tg#Faiw-l754V?+|H_*{dbA+w5fkuW^zC6=K4_`Uo`-B@GbkH+^mH$h2q|* zlCXkl)H8aULtuY&ohvFLn&nKA6YNV%43Zn+b&nvW zY1EjKe%8@;FH! zg3xQbCrn5uKvI8wJm?W#Sb1$^n3_@G49j=TbAQoJg4uG!%SfCTWf^8G6ff)IPEbTJTd8;)gY%~N>jIu21@Q^`-TZ|>WtNXB}dtNUbrN5B*c{-RJ z{c>9SX2Qzhyt1b{0ZUIV|IeiSm@99MRCO3{z-2gSp?YKx41ehe-O}jJhlx6hYTB#( zQ~t0_=c9+S)`|)A>X54Ij#9H1a%^wb(p~m!x!G6d66RyB4wRPld)lNM?PtQ`!<~CN z{hiuK3bXEPWW19ePm77sWUpL2sc^8f8q>BXUptlk=uDJBgb_;6C$<@F>q*?+wNv{L wV+k8!eBA!L$0Bv>Xl#5~O3Lh5HsazpPy$B2ABqFS>i-D%diit91@)$4EdT%j literal 0 HcmV?d00001 diff --git a/web/svelte.config.js b/web/svelte.config.js new file mode 100644 index 00000000..6599b78a --- /dev/null +++ b/web/svelte.config.js @@ -0,0 +1,18 @@ +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://kit.svelte.dev/docs/integrations#preprocessors + // for more information about preprocessors + preprocess: vitePreprocess(), + + kit: { + // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. + // If your environment is not supported, or you settled on a specific environment, switch out the adapter. + // See https://kit.svelte.dev/docs/adapters for more information about adapters. + adapter: adapter() + } +}; + +export default config; diff --git a/web/tsconfig.json b/web/tsconfig.json new file mode 100644 index 00000000..471ad319 --- /dev/null +++ b/web/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/web/vite.config.ts b/web/vite.config.ts new file mode 100644 index 00000000..4a79a4b1 --- /dev/null +++ b/web/vite.config.ts @@ -0,0 +1,6 @@ +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [sveltekit()], +}); From c5c0d44a2ebaec5a4ad956ab93f9b99342a218e7 Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 29 Jul 2024 15:26:04 +0600 Subject: [PATCH 002/775] web: add license --- web/LICENSE | 437 ++++++++++++++++++++++++++++++++++++++++++ web/package-lock.json | 2 +- web/package.json | 2 +- 3 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 web/LICENSE diff --git a/web/LICENSE b/web/LICENSE new file mode 100644 index 00000000..bfef380b --- /dev/null +++ b/web/LICENSE @@ -0,0 +1,437 @@ +Attribution-NonCommercial-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International +Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-NonCommercial-ShareAlike 4.0 International Public License +("Public License"). To the extent this Public License may be +interpreted as a contract, You are granted the Licensed Rights in +consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the +Licensor receives from making the Licensed Material available under +these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-NC-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution, NonCommercial, and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. NonCommercial means not primarily intended for or directed towards + commercial advantage or monetary compensation. For purposes of + this Public License, the exchange of the Licensed Material for + other material subject to Copyright and Similar Rights by digital + file-sharing or similar means is NonCommercial provided there is + no payment of monetary compensation in connection with the + exchange. + + l. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + m. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + n. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part, for NonCommercial purposes only; and + + b. produce, reproduce, and Share Adapted Material for + NonCommercial purposes only. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties, including when + the Licensed Material is used other than for NonCommercial + purposes. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-NC-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database for NonCommercial purposes + only; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. \ No newline at end of file diff --git a/web/package-lock.json b/web/package-lock.json index 614fe446..a6857de2 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "cobalt-web", "version": "0.0.1", - "license": "AGPL-3.0", + "license": "CC-BY-NC-SA-4.0", "devDependencies": { "@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/kit": "^2.0.0", diff --git a/web/package.json b/web/package.json index 1762262f..1c319ab2 100644 --- a/web/package.json +++ b/web/package.json @@ -10,7 +10,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, - "license": "AGPL-3.0", + "license": "CC-BY-NC-SA-4.0", "repository": { "type": "git", "url": "git+https://github.com/imputnet/cobalt.git" From fa85a4c75cef234906cfda5be54f328c44d20529 Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 29 Jul 2024 15:29:13 +0600 Subject: [PATCH 003/775] readme: update license info --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d5fe8164..518e89e8 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,9 @@ cobalt is a tool for easing content downloads from internet and takes ***zero li cobalt is ***NOT*** a piracy tool and cannot be used as such. it can only download free, publicly accessible content. such content can be easily downloaded through any browser's dev tools. pressing one button is easier, so i made a convenient, ad-less tool for such repeated actions. ## cobalt license -cobalt code is licensed under [AGPL-3.0](/LICENSE). +cobalt api code is licensed under [AGPL-3.0](/LICENSE). cobalt web code is licensed under [CC-BY-NC-SA-4.0](/web/LICENSE). -cobalt branding, mascots, and other related assets included in the repo are ***copyrighted*** and not covered by the AGPL-3.0 license. you ***cannot*** use them under same terms. +cobalt branding, mascots, and other related assets included in the repo are ***copyrighted*** and not covered by the license. you ***cannot*** use them under same terms. you are allowed to host an ***unmodified*** instance of cobalt with branding, but this ***does not*** give you permission to use it anywhere else, or make derivatives of it in any way. From 38d7add0a929b3d82cb019ce9dd8d99f8bc4307c Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 16:33:01 +0600 Subject: [PATCH 004/775] web: navigation & sidebar --- web/package-lock.json | 62 ++++++++++------- web/package.json | 4 ++ web/src/components/sidebar/CobaltLogo.svelte | 15 ++++ web/src/components/sidebar/Sidebar.svelte | 72 ++++++++++++++++++++ web/src/components/sidebar/SidebarTab.svelte | 40 +++++++++++ web/src/routes/+layout.svelte | 41 +++++++++++ web/src/routes/+page.svelte | 3 +- web/src/routes/about/+page.svelte | 2 + web/src/routes/convert/+page.svelte | 2 + web/src/routes/crop/+page.svelte | 2 + web/src/routes/donate/+page.svelte | 2 + web/src/routes/settings/+page.svelte | 2 + web/src/routes/trim/+page.svelte | 2 + web/src/routes/updates/+page.svelte | 2 + 14 files changed, 225 insertions(+), 26 deletions(-) create mode 100644 web/src/components/sidebar/CobaltLogo.svelte create mode 100644 web/src/components/sidebar/Sidebar.svelte create mode 100644 web/src/components/sidebar/SidebarTab.svelte create mode 100644 web/src/routes/+layout.svelte create mode 100644 web/src/routes/about/+page.svelte create mode 100644 web/src/routes/convert/+page.svelte create mode 100644 web/src/routes/crop/+page.svelte create mode 100644 web/src/routes/donate/+page.svelte create mode 100644 web/src/routes/settings/+page.svelte create mode 100644 web/src/routes/trim/+page.svelte create mode 100644 web/src/routes/updates/+page.svelte diff --git a/web/package-lock.json b/web/package-lock.json index a6857de2..318aedaa 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,6 +8,10 @@ "name": "cobalt-web", "version": "0.0.1", "license": "CC-BY-NC-SA-4.0", + "dependencies": { + "@fontsource/ibm-plex-mono": "^5.0.13", + "@tabler/icons-svelte": "^3.6.0" + }, "devDependencies": { "@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/kit": "^2.0.0", @@ -23,7 +27,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -400,11 +403,15 @@ "node": ">=12" } }, + "node_modules/@fontsource/ibm-plex-mono": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", + "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -418,7 +425,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -427,7 +433,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -435,14 +440,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -780,6 +783,30 @@ "vite": "^5.0.0" } }, + "node_modules/@tabler/icons": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.6.0.tgz", + "integrity": "sha512-Zv0Ofc64RCMpZ2F8CvsWAphrSjerx5hEErt/RMmE+W8r4E5l5Lizi+My9KbbZQ4NyAtrtrOX80OY1oROZrRzEA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-svelte": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-svelte/-/icons-svelte-3.6.0.tgz", + "integrity": "sha512-phI61t81MlWhodATjvQQdqw8vTL0srSW6GsHzJmuhIMJGB4rwFzAXB2Ec4Pkz0vWFzVQgkeSE/AsiOLIUKWkxA==", + "dependencies": { + "@tabler/icons": "3.6.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "svelte": ">=3 <5" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -789,8 +816,7 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/pug": { "version": "2.0.10", @@ -802,7 +828,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -827,7 +852,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -836,7 +860,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", - "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -927,7 +950,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", @@ -955,7 +977,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -994,7 +1015,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "engines": { "node": ">=6" } @@ -1068,7 +1088,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -1270,7 +1289,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dev": true, "dependencies": { "@types/estree": "*" } @@ -1287,14 +1305,12 @@ "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "dev": true + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } @@ -1302,8 +1318,7 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, "node_modules/merge2": { "version": "1.4.1", @@ -1454,7 +1469,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -1692,7 +1706,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1713,7 +1726,6 @@ "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", - "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", diff --git a/web/package.json b/web/package.json index 1c319ab2..a675b11d 100644 --- a/web/package.json +++ b/web/package.json @@ -28,5 +28,9 @@ "tslib": "^2.4.1", "typescript": "^5.0.0", "vite": "^5.0.3" + }, + "dependencies": { + "@fontsource/ibm-plex-mono": "^5.0.13", + "@tabler/icons-svelte": "^3.6.0" } } diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte new file mode 100644 index 00000000..26d58efb --- /dev/null +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -0,0 +1,15 @@ + + + diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte new file mode 100644 index 00000000..ce5e6a7b --- /dev/null +++ b/web/src/components/sidebar/Sidebar.svelte @@ -0,0 +1,72 @@ + + + + + diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte new file mode 100644 index 00000000..9dfa051a --- /dev/null +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -0,0 +1,40 @@ + + + + + {tabName} + + + diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte new file mode 100644 index 00000000..b2917a1d --- /dev/null +++ b/web/src/routes/+layout.svelte @@ -0,0 +1,41 @@ + + +
+ +
+ +
+
+ + diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index b4488011..1b1b69e5 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -1 +1,2 @@ -

hello world

+ +
home
diff --git a/web/src/routes/about/+page.svelte b/web/src/routes/about/+page.svelte new file mode 100644 index 00000000..e6a55ff1 --- /dev/null +++ b/web/src/routes/about/+page.svelte @@ -0,0 +1,2 @@ + +
about
diff --git a/web/src/routes/convert/+page.svelte b/web/src/routes/convert/+page.svelte new file mode 100644 index 00000000..804a21ff --- /dev/null +++ b/web/src/routes/convert/+page.svelte @@ -0,0 +1,2 @@ + +
convert
diff --git a/web/src/routes/crop/+page.svelte b/web/src/routes/crop/+page.svelte new file mode 100644 index 00000000..3cb79e88 --- /dev/null +++ b/web/src/routes/crop/+page.svelte @@ -0,0 +1,2 @@ + +
crop
diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte new file mode 100644 index 00000000..49f8a142 --- /dev/null +++ b/web/src/routes/donate/+page.svelte @@ -0,0 +1,2 @@ + +
donate
diff --git a/web/src/routes/settings/+page.svelte b/web/src/routes/settings/+page.svelte new file mode 100644 index 00000000..51f4f6c2 --- /dev/null +++ b/web/src/routes/settings/+page.svelte @@ -0,0 +1,2 @@ + +
settings
diff --git a/web/src/routes/trim/+page.svelte b/web/src/routes/trim/+page.svelte new file mode 100644 index 00000000..7dbcf323 --- /dev/null +++ b/web/src/routes/trim/+page.svelte @@ -0,0 +1,2 @@ + +
trim
diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte new file mode 100644 index 00000000..ff1b2d95 --- /dev/null +++ b/web/src/routes/updates/+page.svelte @@ -0,0 +1,2 @@ + +
updates
From b831dc82361aa9ae7a663a440c019d76130cce1c Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 16:38:10 +0600 Subject: [PATCH 005/775] web: space out css --- web/src/components/sidebar/Sidebar.svelte | 2 ++ web/src/components/sidebar/SidebarTab.svelte | 2 ++ web/src/routes/+layout.svelte | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index ce5e6a7b..a76ad5cb 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -58,12 +58,14 @@ display: flex; flex-direction: column; } + #sidebar { background: black; height: 100vh; position: sticky; width: var(--sidebar-width); } + #sidebar-tabs { height: 100%; justify-content: space-between; diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 9dfa051a..27676df0 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -29,11 +29,13 @@ font-size: var(--sidebar-font-size); opacity: 0.8; } + .sidebar-tab.active { color: var(--background); background: var(--accent); opacity: 1; } + .sidebar-tab:hover { opacity: 1; } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index b2917a1d..f91c7a01 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -19,21 +19,25 @@ --sidebar-font-size: 11px; --sidebar-padding: 12px; } + :global(html), :global(body) { font-family: "IBM Plex Mono", "Noto Sans Mono", monospace; margin: 0; } + :global(a) { text-decoration: none; text-decoration-line: none; } + #cobalt { height: 100vh; display: grid; grid-template-columns: var(--sidebar-width) 1fr; overflow: hidden; } + #content { display: flex; overflow: scroll; From 5399ee9a4cf76846dc29b12c7c1828e8d6fad060 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 16:47:13 +0600 Subject: [PATCH 006/775] web: make sidebar scrollable on vertical overflow --- web/src/components/sidebar/Sidebar.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index a76ad5cb..368eaac0 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -70,5 +70,6 @@ height: 100%; justify-content: space-between; padding-bottom: var(--sidebar-padding); + overflow: scroll; } From 92cccd720dedf97cb3b7100f631b6eb94556a804 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 17:33:33 +0600 Subject: [PATCH 007/775] web: mobile navigation --- web/src/components/sidebar/CobaltLogo.svelte | 5 +++ web/src/components/sidebar/Sidebar.svelte | 35 ++++++++++++++++++++ web/src/components/sidebar/SidebarTab.svelte | 10 ++++++ web/src/routes/+layout.svelte | 10 ++++++ 4 files changed, 60 insertions(+) diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte index 26d58efb..aa269f20 100644 --- a/web/src/components/sidebar/CobaltLogo.svelte +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -12,4 +12,9 @@ align-items: center; padding: calc(var(--sidebar-padding) * 2 - 2px); } + @media screen and (max-width: 535px) { + #cobalt-logo { + display: none; + } + } diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 368eaac0..43b4cf58 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -72,4 +72,39 @@ padding-bottom: var(--sidebar-padding); overflow: scroll; } + + @media screen and (max-width: 535px) { + #sidebar, + #sidebar-tabs, + .sidebar-inner-container { + flex-direction: row; + } + #sidebar { + width: 100%; + height: auto; + overflow: scroll; + position: fixed; + bottom: 0; + } + #sidebar::before { + content: ''; + z-index: 1; + width: 100%; + height: 100%; + display: block; + position: absolute; + pointer-events: none; + background: linear-gradient(90deg, + rgba(0, 0, 0, 0.9) 0%, + rgba(0, 0, 0, 0) 4%, + rgba(0, 0, 0, 0) 50%, + rgba(0, 0, 0, 0) 96%, + rgba(0, 0, 0, 0.9) 100% + ); + } + #sidebar-tabs { + justify-content: space-around; + padding-bottom: 0; + } + } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 27676df0..cd86711e 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -39,4 +39,14 @@ .sidebar-tab:hover { opacity: 1; } + + @media screen and (max-width: 535px) { + .sidebar-tab { + padding: 5px var(--sidebar-padding); + min-width: calc(var(--sidebar-width) / 2); + } + .sidebar-tab.active { + z-index: 2; + } + } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index f91c7a01..56bed2d2 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -42,4 +42,14 @@ display: flex; overflow: scroll; } + @media screen and (max-width: 535px) { + #cobalt { + display: grid; + grid-template-columns: unset; + grid-template-rows: 1fr var(--sidebar-width); + } + #content { + order: -1; + } + } From 7cab37fc304ba9ee2a83952c493c9c89aeb763d6 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 17:34:14 +0600 Subject: [PATCH 008/775] web: disable tap highlighting & user selection --- web/src/routes/+layout.svelte | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 56bed2d2..0ef57b2a 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -24,6 +24,9 @@ :global(body) { font-family: "IBM Plex Mono", "Noto Sans Mono", monospace; margin: 0; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + user-select: none; + -webkit-user-select: none; } :global(a) { From e6ffa4864c51d69fb87044aeef5603c31a6fd612 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 21:48:57 +0600 Subject: [PATCH 009/775] web: omnibox base with meowbalt --- web/package-lock.json | 6 + web/package.json | 1 + web/src/components/save/Omnibox.svelte | 111 ++++++++++++++++++ .../save/buttons/ClearButton.svelte | 15 +++ .../save/buttons/DownloadButton.svelte | 54 +++++++++ web/src/components/sidebar/CobaltLogo.svelte | 2 +- web/src/components/sidebar/Sidebar.svelte | 7 +- web/src/components/sidebar/SidebarTab.svelte | 10 +- web/src/routes/+layout.svelte | 44 ++++++- web/src/routes/+page.svelte | 52 +++++++- web/static/meowbalt/smile.png | Bin 0 -> 16660 bytes 11 files changed, 286 insertions(+), 16 deletions(-) create mode 100644 web/src/components/save/Omnibox.svelte create mode 100644 web/src/components/save/buttons/ClearButton.svelte create mode 100644 web/src/components/save/buttons/DownloadButton.svelte create mode 100644 web/static/meowbalt/smile.png diff --git a/web/package-lock.json b/web/package-lock.json index 318aedaa..fa609f93 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "license": "CC-BY-NC-SA-4.0", "dependencies": { + "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", "@tabler/icons-svelte": "^3.6.0" }, @@ -403,6 +404,11 @@ "node": ">=12" } }, + "node_modules/@fontsource-variable/noto-sans-mono": { + "version": "5.0.20", + "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz", + "integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==" + }, "node_modules/@fontsource/ibm-plex-mono": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", diff --git a/web/package.json b/web/package.json index a675b11d..ad8cc3f1 100644 --- a/web/package.json +++ b/web/package.json @@ -30,6 +30,7 @@ "vite": "^5.0.3" }, "dependencies": { + "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", "@tabler/icons-svelte": "^3.6.0" } diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte new file mode 100644 index 00000000..5926135b --- /dev/null +++ b/web/src/components/save/Omnibox.svelte @@ -0,0 +1,111 @@ + + +
+
+ + + isFocused = true} + on:focus={() => isFocused = true} + on:blur={() => isFocused = false} + + spellcheck="false" + autocomplete="off" + autocapitalize="off" + maxlength="256" + + placeholder="paste the link here" + aria-label="link input area" + > + + {#if link.length > 0} + link = ""} /> + {/if} + {#if validLink(link)} + + {/if} +
+
+ + diff --git a/web/src/components/save/buttons/ClearButton.svelte b/web/src/components/save/buttons/ClearButton.svelte new file mode 100644 index 00000000..76f20d3e --- /dev/null +++ b/web/src/components/save/buttons/ClearButton.svelte @@ -0,0 +1,15 @@ + + + + + diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte new file mode 100644 index 00000000..a9b09945 --- /dev/null +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -0,0 +1,54 @@ + + + + + diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte index aa269f20..9cb25ff2 100644 --- a/web/src/components/sidebar/CobaltLogo.svelte +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -10,7 +10,7 @@ display: flex; justify-content: center; align-items: center; - padding: calc(var(--sidebar-padding) * 2 - 2px); + padding: calc(var(--padding) * 2 - 2px); } @media screen and (max-width: 535px) { #cobalt-logo { diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 43b4cf58..64671620 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -60,7 +60,7 @@ } #sidebar { - background: black; + background: var(--secondary); height: 100vh; position: sticky; width: var(--sidebar-width); @@ -69,7 +69,7 @@ #sidebar-tabs { height: 100%; justify-content: space-between; - padding-bottom: var(--sidebar-padding); + padding-bottom: var(--padding); overflow: scroll; } @@ -94,7 +94,8 @@ display: block; position: absolute; pointer-events: none; - background: linear-gradient(90deg, + background: linear-gradient( + 90deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 4%, rgba(0, 0, 0, 0) 50%, diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index cd86711e..c868295e 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -24,15 +24,15 @@ align-items: center; text-align: center; gap: 5px; - padding: var(--sidebar-padding) 5px; - color: var(--accent); + padding: var(--padding) 5px; + color: var(--primary); font-size: var(--sidebar-font-size); opacity: 0.8; } .sidebar-tab.active { - color: var(--background); - background: var(--accent); + color: var(--secondary); + background: var(--primary); opacity: 1; } @@ -42,7 +42,7 @@ @media screen and (max-width: 535px) { .sidebar-tab { - padding: 5px var(--sidebar-padding); + padding: 5px var(--padding); min-width: calc(var(--sidebar-width) / 2); } .sidebar-tab.active { diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 0ef57b2a..48bb34bd 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -13,20 +13,32 @@ diff --git a/web/static/meowbalt/smile.png b/web/static/meowbalt/smile.png new file mode 100644 index 0000000000000000000000000000000000000000..e4b1824e0eaddd9f358fdc50fb82e7fd5ac19e19 GIT binary patch literal 16660 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 literal 0 HcmV?d00001 From bf26988cde771e1b4c41a3cfac71cc9b85b6cb72 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 15 Jun 2024 20:39:34 +0600 Subject: [PATCH 010/775] web/save: add paste button & dummy mode buttons tuned default button look, moved custom icons to lib for easy access --- .../components/buttons/ActionButton.svelte | 10 ++++ web/src/components/save/Omnibox.svelte | 46 +++++++++++++++++++ .../save/buttons/DownloadButton.svelte | 3 ++ web/src/components/sidebar/CobaltLogo.svelte | 9 ++-- web/src/lib/icons/Clipboard.svelte | 11 +++++ web/src/lib/icons/Cobalt.svelte | 4 ++ web/src/lib/icons/Music.svelte | 5 ++ web/src/lib/icons/Sparkles.svelte | 5 ++ web/src/routes/+layout.svelte | 18 +++++--- 9 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 web/src/components/buttons/ActionButton.svelte create mode 100644 web/src/lib/icons/Clipboard.svelte create mode 100644 web/src/lib/icons/Cobalt.svelte create mode 100644 web/src/lib/icons/Music.svelte create mode 100644 web/src/lib/icons/Sparkles.svelte diff --git a/web/src/components/buttons/ActionButton.svelte b/web/src/components/buttons/ActionButton.svelte new file mode 100644 index 00000000..13c126bf --- /dev/null +++ b/web/src/components/buttons/ActionButton.svelte @@ -0,0 +1,10 @@ + + + diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 5926135b..7ec197e4 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -3,6 +3,11 @@ import DownloadButton from './buttons/DownloadButton.svelte'; import ClearButton from './buttons/ClearButton.svelte'; + import ActionButton from '../buttons/ActionButton.svelte'; + + import IconClipboard from '$lib/icons/Clipboard.svelte'; + import IconMusic from '$lib/icons/Music.svelte'; + import IconSparkles from '$lib/icons/Sparkles.svelte'; let link: string = ""; let isFocused = false; @@ -14,6 +19,15 @@ return false } } + + const pasteClipboard = () => { + navigator.clipboard.readText().then(text => { + let matchLink = text.match(/https:\/\/[^\s]+/g); + if (matchLink) { + link = matchLink[0]; + } + }); + }
@@ -44,6 +58,29 @@ {/if}
+
+
+ + + + + + +
+ + + +
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index a9b09945..6e2f004c 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -17,7 +17,10 @@ border-radius: 0; padding: 0 12px; + background: none; + box-shadow: none; + transform: none; border-left: 1px var(--gray) solid; border-top-right-radius: 11px; diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte index 9cb25ff2..891da1da 100644 --- a/web/src/components/sidebar/CobaltLogo.svelte +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -1,8 +1,9 @@ + + diff --git a/web/src/components/buttons/Switcher.svelte b/web/src/components/buttons/Switcher.svelte new file mode 100644 index 00000000..dd457177 --- /dev/null +++ b/web/src/components/buttons/Switcher.svelte @@ -0,0 +1,35 @@ + + +
+ +
+ + diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 7ec197e4..dabec6cb 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -1,13 +1,17 @@
-
+
isFocused = true} - on:focus={() => isFocused = true} - on:blur={() => isFocused = false} - + on:input={() => (isFocused = true)} + on:focus={() => (isFocused = true)} + on:blur={() => (isFocused = false)} spellcheck="false" autocomplete="off" autocapitalize="off" maxlength="256" - placeholder="paste the link here" aria-label="link input area" - > + /> {#if link.length > 0} - link = ""} /> + (link = "")} /> {/if} {#if validLink(link)} {/if}
+
-
- - + + + - + -
- + + + + +
@@ -100,7 +99,7 @@ align-items: center; gap: 10px; font-size: 14px; - flex: 1 + flex: 1; } #input-container.downloadable { @@ -143,14 +142,14 @@ } #link-area::placeholder { - color: var(--gray) + color: var(--gray); } - #action-container, - #mode-switcher { + #action-container { display: flex; flex-direction: row; } + #action-container { justify-content: space-between; } diff --git a/web/src/lib/icons/Mute.svelte b/web/src/lib/icons/Mute.svelte new file mode 100644 index 00000000..5b2644b1 --- /dev/null +++ b/web/src/lib/icons/Mute.svelte @@ -0,0 +1,5 @@ + + + + + From 1f2c28bd029ab7e989465ba53d6933a74fa0e809 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 18:22:44 +0600 Subject: [PATCH 012/775] web: basic api interaction & downloading download button now acts the way it should with various states --- web/src/components/save/Omnibox.svelte | 2 +- .../save/buttons/DownloadButton.svelte | 75 ++++++++++++++++++- web/src/lib/api.ts | 31 ++++++++ web/src/lib/index.ts | 1 - 4 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 web/src/lib/api.ts delete mode 100644 web/src/lib/index.ts diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index dabec6cb..cabff743 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -60,7 +60,7 @@ (link = "")} /> {/if} {#if validLink(link)} - + {/if}
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 6e2f004c..9ebb2234 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -1,9 +1,78 @@ - - diff --git a/web/src/components/misc/Placeholder.svelte b/web/src/components/misc/Placeholder.svelte new file mode 100644 index 00000000..01dd78f1 --- /dev/null +++ b/web/src/components/misc/Placeholder.svelte @@ -0,0 +1,16 @@ + + +
+ +
{pageName} page is not ready yet!
+
+ + diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 5dd708fc..55040fea 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -80,6 +80,14 @@ background-color: var(--button-hover); } + :global(.center-column-container) { + display: flex; + width: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + } + #cobalt { height: 100vh; display: grid; diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 654698ef..bd364ec1 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -1,15 +1,11 @@ -
+
- black and white cat smiling and loafing +
@@ -18,12 +14,6 @@
From 2080a3e1ae31bac8d3908c783cbdf017b2173f09 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 20:39:23 +0600 Subject: [PATCH 025/775] web/sidebar: fix grid on mobile --- web/src/components/sidebar/Sidebar.svelte | 2 +- web/src/routes/+layout.svelte | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index e7b753bf..5ea169b2 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -81,7 +81,7 @@ #sidebar { width: 100%; - height: auto; + height: var(--sidebar-height-mobile); position: fixed; bottom: 0; } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 55040fea..d83aea9a 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -26,6 +26,7 @@ --border-radius: 11px; --sidebar-width: 80px; + --sidebar-height-mobile: 50px; --sidebar-font-size: 11px; } @@ -105,7 +106,7 @@ #cobalt { display: grid; grid-template-columns: unset; - grid-template-rows: 1fr var(--sidebar-width); + grid-template-rows: 1fr var(--sidebar-height-mobile); } #content { order: -1; From f8f248f399a04a681bacf46e09b77efe405ed507 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 21:45:24 +0600 Subject: [PATCH 026/775] web: dark theme & coloring, border, focus fixes --- web/src/components/save/Omnibox.svelte | 2 +- .../save/buttons/DownloadButton.svelte | 2 +- web/src/components/sidebar/Sidebar.svelte | 11 +--- web/src/components/sidebar/SidebarTab.svelte | 16 ++++-- web/src/routes/+layout.svelte | 53 +++++++++++++++++++ 5 files changed, 70 insertions(+), 14 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 78368e93..d876b208 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -93,7 +93,7 @@ #input-container { display: flex; - box-shadow: 0 0 0 1.5px var(--gray) inset; + box-shadow: 0 0 0 1.5px var(--input-border) inset; border-radius: var(--border-radius); padding: 0 12px; align-items: center; diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 62ef1e00..e4379c84 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -100,7 +100,7 @@ box-shadow: none; transform: none; - border-left: 1px var(--gray) solid; + border-left: 1.5px var(--input-border) solid; border-top-right-radius: var(--border-radius); border-bottom-right-radius: var(--border-radius); } diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 5ea169b2..b73e392e 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -59,7 +59,7 @@ } #sidebar { - background: var(--secondary); + background: var(--sidebar-bg); height: 100vh; width: var(--sidebar-width); position: sticky; @@ -94,14 +94,7 @@ display: block; position: absolute; pointer-events: none; - background: linear-gradient( - 90deg, - rgba(0, 0, 0, 0.9) 0%, - rgba(0, 0, 0, 0) 4%, - rgba(0, 0, 0, 0) 50%, - rgba(0, 0, 0, 0) 96%, - rgba(0, 0, 0, 0.9) 100% - ); + background: var(--sidebar-mobile-gradient); } #sidebar-tabs { diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index c868295e..e2f8c9b8 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -25,14 +25,14 @@ text-align: center; gap: 5px; padding: var(--padding) 5px; - color: var(--primary); + color: var(--sidebar-highlight); font-size: var(--sidebar-font-size); opacity: 0.8; } .sidebar-tab.active { - color: var(--secondary); - background: var(--primary); + color: var(--sidebar-bg); + background: var(--sidebar-highlight); opacity: 1; } @@ -40,6 +40,16 @@ opacity: 1; } + .sidebar-tab:focus-visible { + box-shadow: 0 0 0 1.5px var(--sidebar-highlight) inset; + outline: none; + z-index: 1; + } + + .sidebar-tab.active:focus-visible { + box-shadow: 0 0 0 1.5px var(--sidebar-bg) inset; + } + @media screen and (max-width: 535px) { .sidebar-tab { padding: 5px var(--padding); diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index d83aea9a..25080a22 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -22,17 +22,62 @@ --button-hover-transparent: rgba(0, 0, 0, 0.03); --button-stroke: rgba(0, 0, 0, 0.08); + --sidebar-bg: #000000; + --sidebar-highlight: #ffffff; + + --input-border: #8d8d95; + --padding: 12px; --border-radius: 11px; --sidebar-width: 80px; --sidebar-height-mobile: 50px; --sidebar-font-size: 11px; + + --sidebar-mobile-gradient: linear-gradient( + 90deg, + rgba(0, 0, 0, 0.9) 0%, + rgba(0, 0, 0, 0) 4%, + rgba(0, 0, 0, 0) 50%, + rgba(0, 0, 0, 0) 96%, + rgba(0, 0, 0, 0.9) 100% + ); + } + + /* temporary switcher until theming is implemented, */ + /* just so my eyes don't burn at night */ + @media (prefers-color-scheme: dark) { + :global(:root) { + --primary: #000000; + --secondary: #e1e1e1; + --gray: #6e6e6e; + + --button: #191919; + --button-hover: #2a2a2a; + --button-hover-transparent: rgba(225, 225, 225, 0.04); + --button-stroke: rgba(255, 255, 255, 0.08); + + --sidebar-bg: #101010; + --sidebar-highlight: #f2f2f2; + + --input-border: #383838; + + --sidebar-mobile-gradient: linear-gradient( + 90deg, + rgba(16, 16, 16, 0.9) 0%, + rgba(16, 16, 16, 0) 4%, + rgba(16, 16, 16, 0) 50%, + rgba(16, 16, 16, 0) 96%, + rgba(16, 16, 16, 0.9) 100% + ); + } } :global(html), :global(body) { margin: 0; + background-color: var(--primary); + color: var(--secondary); } :global(*) { @@ -73,12 +118,19 @@ box-shadow: 0 0 0 1.5px var(--button-stroke) inset; } + :global(button:focus-visible) { + box-shadow: 0 0 0 1.5px var(--secondary) inset; + outline: none; + z-index: 1; + } + :global(button:active) { transform: scale(0.95); } :global(button:hover) { background-color: var(--button-hover); + z-index: 1; } :global(.center-column-container) { @@ -100,6 +152,7 @@ display: flex; overflow: scroll; padding: var(--padding); + background-color: var(--primary); } @media screen and (max-width: 535px) { From 66a1e9e953af000350e68611f99e1ec6d5384fcb Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 21:54:02 +0600 Subject: [PATCH 027/775] web/omnibox: prevent password manager autofill --- web/src/components/save/Omnibox.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index d876b208..f969590b 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -54,6 +54,7 @@ maxlength="256" placeholder="paste the link here" aria-label="link input area" + data-form-type="other" /> {#if link.length > 0} From 3fc7b99d05064ed477130510365e716caf60f1a1 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 22:00:26 +0600 Subject: [PATCH 028/775] web: add manifest, more icons, and some metadata --- web/src/app.html | 13 +++- web/static/icons/android-chrome-192x192.png | Bin 0 -> 3580 bytes web/static/icons/android-chrome-512x512.png | Bin 0 -> 9818 bytes web/static/icons/apple-touch-icon.png | Bin 0 -> 3278 bytes web/static/icons/generic.png | Bin 0 -> 9818 bytes web/static/icons/maskable/128.png | Bin 0 -> 815 bytes web/static/icons/maskable/192.png | Bin 0 -> 1014 bytes web/static/icons/maskable/384.png | Bin 0 -> 1856 bytes web/static/icons/maskable/48.png | Bin 0 -> 390 bytes web/static/icons/maskable/512.png | Bin 0 -> 2828 bytes web/static/icons/maskable/72.png | Bin 0 -> 569 bytes web/static/icons/maskable/96.png | Bin 0 -> 617 bytes web/static/manifest.json | 75 ++++++++++++++++++++ 13 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 web/static/icons/android-chrome-192x192.png create mode 100644 web/static/icons/android-chrome-512x512.png create mode 100644 web/static/icons/apple-touch-icon.png create mode 100644 web/static/icons/generic.png create mode 100644 web/static/icons/maskable/128.png create mode 100644 web/static/icons/maskable/192.png create mode 100644 web/static/icons/maskable/384.png create mode 100644 web/static/icons/maskable/48.png create mode 100644 web/static/icons/maskable/512.png create mode 100644 web/static/icons/maskable/72.png create mode 100644 web/static/icons/maskable/96.png create mode 100644 web/static/manifest.json diff --git a/web/src/app.html b/web/src/app.html index 8f8e1666..e4d684a2 100644 --- a/web/src/app.html +++ b/web/src/app.html @@ -2,8 +2,19 @@ - + + cobalt + + + + + + + + + + %sveltekit.head% diff --git a/web/static/icons/android-chrome-192x192.png b/web/static/icons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3ac83a24696f6d2e99ffe51177a583e01a6533 GIT binary patch literal 3580 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 literal 0 HcmV?d00001 diff --git a/web/static/icons/apple-touch-icon.png b/web/static/icons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b2abfa63d553dc474982d8b3d36dee71f9ceb0ce GIT binary patch literal 3278 zcmeHK`8$+t8@3H*ERm%#QBi%iEMuw0k{V?ULn3CFtb?&+dF@hJhp~(-F_uOqQiG5g zQ$k1v8BDyg6?!f4A|xtB-}8R|!uR9%{qWrPaXiO;U)Oz|&v{<=`J~&~q9hY(L*vB^RhkK5W4Bcg< zh%2aU;jDap2Jh-wyph`1O_3^2%PH>7K@d`}QBGcv8!PM9yoKKBio*?#%x+kS-3 z%DuK7#3$!(EmrD*^;@+=TmJaCwWfE2$|~(CBq0;!oMdEN9y+Q^s+=d=sVN{kSrgHy zFIyrRb14BCS6~~JiX7pu7q#=NAMP8p^D~;2w2{F_+R>n`ij%4Y-K5KTZV&TmbY4Wq|4#67t0e&t#FCCA%`fy*zwG^t zmP_YBnUDr&A%@k`i^!EXlTCpO++zL4;15R4v0J{w%rR*Au=$>O!rv+9ZhmjLtL^GC z-5#&AwK$M}DO0|0tlmBUw1|`oo{JV6QPC|xQq>(e5o^Hfypj@)eyR@jI4ZlBNgO)$ zLUBeznr_&w=#C7Iw`t-@%eue3nag4s6vGLribfH=TJ(e`d)lnjBEcvGof@YcVUZ*v zsh9&2lka_KO`V^576K+^9v!k;^3FzlZa`$TJL?c_!l1Xj)&PuRR`{sNZme-IIV~j!>Vtmua6&_ zVh82-+&S7~2zm>liNky3a^{Zq%OjH~?i@9n@5@)!3x0ogqA3vjK2`ZCgw|W6WGp|n z*ht|?S3{!|jib1jZJJS}mF_7pQ%KtA3Oudv_$u2G?8>k|iAJMyVTJ)hi(huu@QC>R zR?Pi#uG-h0OHC@_3Eaew|7zfOL?+9;3&RxaUE2M+eB7tMP$Em))bvBEtvmaAvB}Nv zx_24pC~y(s(sJQH!4kI3VGDUBhJjY~Zf)MY@(cEj-hCb4KYwUZZHZnl1dvMoGW!_5 z*kLEbOR%ErhiSOKY^}Z4Y!7@`)z~ld;4G;Xq(v4~8UHL;?tNRA8jK*BYz_^oJ_NH1 zo9|T)nqbQ~{pWh>#+i$lin#9;mx5mm;He>2Xq0DemWrHOWPg?uO z)+ee_B?8woG<38Ii$s;r_fs$L?yPBcrAp-A z*!~-IB*UXRq`y$B@y2#Q^UWV&YWimm5Ae1hT96yOmY z15fs;28dJ$lqnpn!xT2)C_>24!`m)PqWP~#V*RhvWqf8k675@K{?NBRSb6jNMkm*O z&T)6-(dA@=f`ulaP|(G@6kjp=am)s?%Dw%zo_DX*@u-|6Pf^ZT4y-HpkdB*>zjlA1 zArM)#--21d^GKQ?C4t1=0C-mthsyGdql2xl7Gt}HuZo)qA2@Q|?P1y#;2gptrKg!R zp0t`&Gaw4Rh$TDyL2dg=vPAupp{KW3W4 zQBkYoo^Cs{3HNj}I7MBv9%Z?qu=6-dVDO>2(apJ@(nuxTuM`pHF_5uO=(iq|9Y7N1 z&UMxB#bX%#mO|w3M70xjPESe{GQO_QxHmjjv+RUPb5lHw$EVxk%wy*O+8x6n=E;d} zgZB^v{x(eCfjoXeVWF4!xfoInw!WnMYEi#rg$rLDbpf$ zyS;|+2=i%>wg7M{aq`DhH;k~4zu&kU4N($Av=%X3TiBS=(>9aOLXMh?{cfB8t2@(T zDMrz=3ciTzuwTMG-dl%ZN+Va^4V=3Ds&UkB#)#vvWO)X_&n81H!hog6$W+Jy#9X?q zj1z#_pi_9{%LFd_nmS91A-=uQLBcM?1f2_C|nQw*mpc$`2A-%aBB*3{y@E&%O&Ma4Z3Z z2!;rgf4v46;4@n7*m&z_RCDA?;RwhYMu<`mtJH$f5;fSSp6kkN?8k02?}>{atY&rN zFQFOdPQm%TpWkSUR|s5N{$KB)BzbAew{3CJ%;blTHBMJ9xBC>7qwX9j2L1lIvlf1i z#e;?ysccDVc^z2|)g8z?X)Tnd@j~P5kYFGkZnn0|gaR46N2_SpW79awcU)Vd3~QEP zXM(SH^;JtsI?c4lw<9c8Ih4arW8+T4P-f7~wRinaNP;k5;JxD_Ci`1MX12J$)RLRS zKb3SHfxAUD8v{MTwwyCg{)U`uU(#@_wxnvidVgJd>#OiMQ^5b}VGwb~^9+R3Uk6as zb=%a>*iDS0b#?sY@QcVmh8;aA-&u^W{nk%*?)Rm)6^rZInZU9gGe7(^nBsX6=#AVG zpV}sJRHvQO`OVNY)5Mr@{8KN|?AH@mAamXB=NC#LDXFq&i51c7)5A{*s7{4H>L5|n z>(i~yJF63f=`YP1K+U7y8YVZ9eu`9*F%h8g>(S&R3GFww->mL)uDCxpZ~2w*2vATS z&!;7Tr0rB&Bn>Ua!a<+@`g%Ko#KIY*TyFn}k)Tdh7;skY*)gn#wtlMtoWrKI%#LWM zhNfP}&i9*tG8`7ZE{`m3T*A7S0WDRtYBLyBz>690dR10sQ))Dq^6UmqjrGTzMR+S; z_LnecAXek=&0y;Sp7uE}1^%p-^$8|%fbmQ9a+!g9u>_zigt+8pfc_Mil4hKhxtZ?G zb(!6u>Sl`3=aj;WOkM>WPl+lannVx8Nh!GJQBYu&hzDNTBGiW4$MK>RLJ%rj(f{1& z&W|nPqmht!YfLRtRd2CNa$&gmaeS68=i<*!_keF4jqHI1$O|4D0De&T N(3fm4)*(HT{tc`e{yYEx literal 0 HcmV?d00001 diff --git a/web/static/icons/generic.png b/web/static/icons/generic.png new file mode 100644 index 0000000000000000000000000000000000000000..d1777d489d3824d04f6d6db9f1d7e167b5f4dbc7 GIT binary patch literal 9818 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 literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/128.png b/web/static/icons/maskable/128.png new file mode 100644 index 0000000000000000000000000000000000000000..e8213cfe5828cc4435d15e4da25d5e57b3f2c472 GIT binary patch literal 815 zcmV+~1JL}5P)C0002YP)t-s00030 z|Ns5{{T3D$`T6gwv<-QBdbw3CyQgoK2BeSJ7MIN;#m$jHdIx3{aStB{b8 ziHV7HbaZ89Wll~`OG`^dMMVh-3GD3b=H}+)SUnwoKOaadSbR8&+y zKR-J=J2EmdBqSvB^YiWP?Y+IdsHmuwm6d^kfm&KxK|w*<+S%6WNt=~O%#0006W zNkl~PJx+&|Ey*O!vMtM z0l3frw1Tc_06Oak7&-Xg;QW2S#V`+SP;tw7(*UgV-4J)bEL6tXHm_6jcfe)WL#2`C z^pvCxYQZOPnYnmjEe_e1R;e}afJxF`qSEYw&U<>KR%V+}`GZQW7=tcuQS(b4F!4$* zDxC`GqGF9MM9MbdR7Pdl&bDKpT4M}c!j*R4%@WWZmegL32{75OQCUy3Z4yxH&w)uY z_33g45$FmNq*kl|mydf?-m|GNtW)~{E|o1R*Dc>xsS14TfCgL(FF%k2Y<5N8IAGFq zmQjR!I-$qjFb%Erf4HCZ}!tI^jGABIgZQgf~3>jWYa&{Am z)r<5N26}69JOE|`)Ren=`+P;>w>VzNx{WH5lAQyxuj}pI0}e=@2iX(aNa~vycsO{` ziUCXmI(Z;01Kd&!U>NZ7^Zo literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/192.png b/web/static/icons/maskable/192.png new file mode 100644 index 0000000000000000000000000000000000000000..8268d89a58c3c6334d887d403c4a9a615343c5f3 GIT binary patch literal 1014 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE8Azrw%`pX1#{zspT!Hle|Np;z`=+g}{rB%* zUS3`n78VW;4rys=At9kppFTZ!@IXaHML|K~*RNkce*Ad#>ecDfr`N1mvtq@H{{H@k zhK7=olGxZ-J3G6tU%$4tw&v&Oi;Ihkii*B?@#5OGYy0=_PfkvL`t<3eM~`mZx;1Cc zoN3dhO`bfts;VkIJ>AgI@ZGz2Z{EDQc=6)# zGPZ5(zyVI|4|iX-iE;W5i{cGZ{0{;Z@{O5qygM}CVbk9Uq8qNSJUshAzTfOf#_I3_ zwGX=kmGv8rvaDnIXK<412Dh<=(2rol(_A-h>pgILkUy<^O~YPe^XjYz@@@P;9r|)*!yQERNyS=Y7W;e%Yk3nZ#TD;m--1 zd7WXFaJ&4%Yu3jmY}==Fm-R}2CeP)^`I6dw0UNJH9=zdc{5hieym!dz>a64MzfAa` zW%#d<`|7Uu7bHq27X0WrR?(ZKEA+U2m15%8DaW46ttzeXdi+a>^D<+vyKhMLz9ogh z&7t!z-T(3R_?C6MH&i`W*=yUKn|9`o|E^@IqY_td*({n^_xZZ?MTrpGy4P)PhE7iT z9*gZAw??^d>6=&}nc*9__FksrV_)WLcNWO(%$NDE`R3NT4^KeG?O#o!{lf4c$T~xGJ8d{<+W0CT?(v@wVlkAA$mMjFpVH z)jvF`cCcXo#5C`x#g4zKGm4+@XVt0Qc5L}-BO*@5Y*ZU%)ktuu6{1-oD!MF$n zGiZlt`p{--9cikaltY7dY-wnuL4~}`dw<5mXvV-@9f({Rk2t*_jot&H) z8yoBB=m>?v?(S|23k!iju(7ex+S-ajp}1V`hYuenCnx*+`w<8P91iF4cpMIAadDB! zWX{gcwzs$E*C_#;NYOCskytmJ3l`^ zK0e;n)m2tjmYSLx92{(5V8CXx>2!KtULF>Ub#rrDT3TW-7`3&vMMXu4iHQjb34wuu z!^6Xkjg3?)wW6Ye&*xWFRgp-ff`Wp~%uIiO|1T?QB>(_Hcw<~I=PhvA(>{9NE8kqX z{#x#?_DeaRdFfMuS1_l}-IvkW5jW2-&+}7TL-^;O>;?@TNJ%d9{{?X_F~Mc(lk^%m zYv7)#FqV(fMzm~O{$2&nTH5lpwi*4k7&`=7PRhr`fE9R0Qvi8!J35j$mXJUkTS{Rn zP-wnjg^+r32yxJ%SDvC@Pm**8I1S_{f$M2>fjNwlB2nxPgEf%J$50%IHP`(J*xZR? z%2Tez1%p`MNmgjSmPk(V5U&PZ4-jiVUm`W{-;!z@8fZC%oIQE~Bph2yXpO`!^pwDy zZmG7lStNLHre4yi?O`DCjY<0wT4c?RtoH6#{e~&t@eDf;g{*IXxA^2pY3a>V-IY1J zyx5&*^=h&tQ=*XZv$W?Oy$d)S<2zTI-a7Tt#bWn}vX$YTq)op<=hjrJ-PYzSuKF#e z25Pk>N6GEox0oAiPFX+brc;x@WzS~EgJ$>85%q!FG%`~|>%McA*4t(_O0IRfgW;iHT5VAw>_FOG zUquF%SRR^PGdY;9+xCf^DROTpR3ETCU|@F5E&X+vAA8&f|0piwt@%b?@L}2~Pbc-^ zN@#*JmcPX@6>At=!4#9)xw`r-Y>DnC;4P)Jc3);NBIHN1k=Nqt$h>Eoh0|-{Gc|q6 zBb{iyJc|v&Vqbbeyy(jdS228Kc*q34z%;UAFk)3k>W55(*WEX^UamfvZfjK8d$>TN zow0nXyWzHIgW9NXNpr@lWwoGgsP3(az>hwVf9ayT=f)u(kUNzht$IbyEHJ6beg*v` zT9mTZ8=0(R)LtQ_gtrwGDbQi|_PA#S+#D~26xNbyF^C6r3}S>DG3*e&k@9Ie$?AMf z5u{LYsr<)7XH&G+@~zvs8yP}#_Fi)u2w~w=+H#;6z0pCLQK@LbVvC)L8_J5z zdVEvhtzVbn8b22iz<+E{z*RmI-Lnm_$;nw8l$r7f4I6{j&8H#L|L7%W)g zG<`jLAiB+`@R{gz06~{UjY!i0eUqTu^z_B@f^55!a!7zbiGOXtG&MY+Xs(pH+<_i` zyh9^Er*?zF%8VT^{$y3$FC918AkGghLiPH1#f?semf5EeGcD3{aiF-nnjvv;p97=x zvvjFWmR8U%)c+N)z>y9%I;>R=5;suqzxm?&8DIJaUt){*oylM47&eUiTpg8rshW$R zL>=e1PP%dL!9OWCl{Zq171KoQhWFhE9D-8m;5*W#>f`5~ zjiAj%HC7k=cL(8Fn$Vonre8YLOwLp}+Ft(^mNuSSo_L{0)Hbf!G;q-XQT*zomDh~l z9GfpzVR6;kJh`1c9mvn(Z2ik<^LKYHN;O@@#$!WHCcx}G)oft)uC@(v5A8?*tQ=M+ zA)NQnN~M-7XBU135t?9?N=UUMsuBX7@=x)~#BWCrAX^#6zTl^!M7wfj{*_NhByP-mKQYsv?5Pz+$*psMG1jBYr3*qkLBR(^%JX1NKs79YbFGl zXrAu~I7~4dZtYzAClFzkG!2S!XX$aAB!ioEcCu{U6f@ahXe@4Kzo0#7z#Fwc`?oJz nv_N+M?+@W;^HqDlV&cz;Xd literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/48.png b/web/static/icons/maskable/48.png new file mode 100644 index 0000000000000000000000000000000000000000..02a5bca0fb8b6cf17cd1327fab8f337e61c79489 GIT binary patch literal 390 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 literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/72.png b/web/static/icons/maskable/72.png new file mode 100644 index 0000000000000000000000000000000000000000..903f6bd500691990bc32f79d2192de30a594dbac GIT binary patch literal 569 zcmV-90>=G`P)U1D4i4kv<4{mg+}zyK($d1h!nwJ*b8~YFMdNuC9rRiG+lN zczAdage<5vZq|SJIvoDZf)%Lvw2I#ZK=M#Qy;1d0m_2sQ#amIqLvuF=xisi6$UIuz; zb6ur&hh5M0l9dq)!pXaUZ^FLHW>XW;P5BP`aN`?s&5l?Pn9ZZe+0xgV$Q#-C<2SNj z3;m;=H+pQcu@HK-A3tRDYEO~S*LK?Rog}FBlPt2w6wIbv9YG6rk|gmb8~ZEUS3jCQtRvM z=jZ3-z?PPllarH=kB?<#Wkp3rKtMne5)uy&58B$=&CSij!^6VD!n?b>y1Kff zqoag`giA|HIyyQyI5;36AhcV!LI3~(b4f%&RA}Dq)<>IyFc5&@45AbfM5WogYu#S| z{}0 Date: Sun, 16 Jun 2024 22:26:06 +0600 Subject: [PATCH 029/775] web/sidebar: optimize tab bar for mobile --- web/src/components/sidebar/Sidebar.svelte | 9 +++++++++ web/src/components/sidebar/SidebarTab.svelte | 4 ++++ web/src/routes/+layout.svelte | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index b73e392e..11691748 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -84,6 +84,7 @@ height: var(--sidebar-height-mobile); position: fixed; bottom: 0; + padding: 4px 0; } #sidebar::before { @@ -103,5 +104,13 @@ overflow-x: scroll; padding-bottom: 0; } + + #sidebar :global(.sidebar-inner-container:first-child) { + padding-left: var(--padding); + } + + #sidebar :global(.sidebar-inner-container:last-child) { + padding-right: var(--padding); + } } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index e2f8c9b8..13593f60 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -28,6 +28,8 @@ color: var(--sidebar-highlight); font-size: var(--sidebar-font-size); opacity: 0.8; + height: fit-content; + -webkit-touch-callout: none; } .sidebar-tab.active { @@ -55,8 +57,10 @@ padding: 5px var(--padding); min-width: calc(var(--sidebar-width) / 2); } + .sidebar-tab.active { z-index: 2; + border-radius: var(--border-radius); } } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 25080a22..f3c34353 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -31,7 +31,7 @@ --border-radius: 11px; --sidebar-width: 80px; - --sidebar-height-mobile: 50px; + --sidebar-height-mobile: calc(52px + env(safe-area-inset-bottom)); --sidebar-font-size: 11px; --sidebar-mobile-gradient: linear-gradient( From 5ba3231a1e847ff999593d5fde2fd69ba4d5203b Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 22:59:16 +0600 Subject: [PATCH 030/775] web: consistent tab bar style with rounded corners --- web/src/components/sidebar/Sidebar.svelte | 7 ++++--- web/src/components/sidebar/SidebarTab.svelte | 2 +- web/src/routes/+layout.svelte | 14 +++++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 11691748..c54c316d 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -63,6 +63,7 @@ height: 100vh; width: var(--sidebar-width); position: sticky; + padding: 0 var(--sidebar-inner-padding); } #sidebar-tabs { @@ -84,7 +85,7 @@ height: var(--sidebar-height-mobile); position: fixed; bottom: 0; - padding: 4px 0; + padding: var(--sidebar-inner-padding) 0; } #sidebar::before { @@ -106,11 +107,11 @@ } #sidebar :global(.sidebar-inner-container:first-child) { - padding-left: var(--padding); + padding-left: calc(var(--border-radius) * 2); } #sidebar :global(.sidebar-inner-container:last-child) { - padding-right: var(--padding); + padding-right: calc(var(--border-radius) * 2); } } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 13593f60..d6a2f5fc 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -29,6 +29,7 @@ font-size: var(--sidebar-font-size); opacity: 0.8; height: fit-content; + border-radius: var(--border-radius); -webkit-touch-callout: none; } @@ -60,7 +61,6 @@ .sidebar-tab.active { z-index: 2; - border-radius: var(--border-radius); } } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index f3c34353..70f4b214 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -33,6 +33,7 @@ --sidebar-width: 80px; --sidebar-height-mobile: calc(52px + env(safe-area-inset-bottom)); --sidebar-font-size: 11px; + --sidebar-inner-padding: 4px; --sidebar-mobile-gradient: linear-gradient( 90deg, @@ -76,7 +77,7 @@ :global(html), :global(body) { margin: 0; - background-color: var(--primary); + background-color: var(--sidebar-bg); color: var(--secondary); } @@ -144,7 +145,7 @@ #cobalt { height: 100vh; display: grid; - grid-template-columns: var(--sidebar-width) 1fr; + grid-template-columns: calc(var(--sidebar-width) + 8px) 1fr; overflow: hidden; } @@ -153,16 +154,23 @@ overflow: scroll; padding: var(--padding); background-color: var(--primary); + + border-top-left-radius: var(--border-radius); + border-bottom-left-radius: var(--border-radius); } @media screen and (max-width: 535px) { #cobalt { display: grid; grid-template-columns: unset; - grid-template-rows: 1fr var(--sidebar-height-mobile); + grid-template-rows: 1fr calc(var(--sidebar-height-mobile) + 8px); } #content { + padding-top: env(safe-area-inset-top); order: -1; + border-top-left-radius: 0; + border-bottom-left-radius: calc(var(--border-radius) * 2); + border-bottom-right-radius: calc(var(--border-radius) * 2); } } From ea830974b6309c226cb5aad2fa1f34b63a16922e Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 23:06:30 +0600 Subject: [PATCH 031/775] web: fix DownloadButton tab focus glow --- web/src/components/save/buttons/DownloadButton.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index e4379c84..86b56b15 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -105,6 +105,10 @@ border-bottom-right-radius: var(--border-radius); } + #download-button:focus-visible { + box-shadow: 0 0 0 1.5px var(--secondary) inset; + } + #download-state { font-size: 24px; font-family: "Noto Sans Mono Variable", "Noto Sans Mono", "IBM Plex Mono", monospace; From 65c14d41fa2acbd64c7a42085cf445fd71e7a88a Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 23:30:10 +0600 Subject: [PATCH 032/775] web: make tab focus blue for better visibility --- web/src/components/save/Omnibox.svelte | 1 + web/src/components/save/buttons/DownloadButton.svelte | 2 +- web/src/components/sidebar/SidebarTab.svelte | 5 +++-- web/src/routes/+layout.svelte | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index f969590b..e986100b 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -115,6 +115,7 @@ #input-container.focused :global(#input-link-icon) { stroke: var(--secondary); } + #input-container.downloadable :global(#input-link-icon) { stroke: var(--secondary); } diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 86b56b15..2e0838cb 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -106,7 +106,7 @@ } #download-button:focus-visible { - box-shadow: 0 0 0 1.5px var(--secondary) inset; + box-shadow: 0 0 0 2px var(--blue) inset; } #download-state { diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index d6a2f5fc..36b50f6c 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -44,13 +44,14 @@ } .sidebar-tab:focus-visible { - box-shadow: 0 0 0 1.5px var(--sidebar-highlight) inset; + box-shadow: 0 0 0 3px var(--blue) inset; outline: none; z-index: 1; } .sidebar-tab.active:focus-visible { - box-shadow: 0 0 0 1.5px var(--sidebar-bg) inset; + background: var(--blue); + color: var(--sidebar-highlight); } @media screen and (max-width: 535px) { diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 70f4b214..bfc6deff 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -16,6 +16,7 @@ --primary: #ffffff; --secondary: #000000; --gray: #8d8d95; + --blue: #2f8af9; --button: #eeeeee; --button-hover: #e8e8e8; @@ -120,7 +121,7 @@ } :global(button:focus-visible) { - box-shadow: 0 0 0 1.5px var(--secondary) inset; + box-shadow: 0 0 0 2px var(--blue) inset; outline: none; z-index: 1; } From 2ea3ca1a07cff46f00e662c236d54c7d1f4ec61b Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 00:31:07 +0600 Subject: [PATCH 033/775] web/sidebar: automatically scroll to active tab --- web/src/components/sidebar/SidebarTab.svelte | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 36b50f6c..87bf8cd0 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -4,7 +4,19 @@ export let tabName: string; export let tabLink: string; + let tab: HTMLElement; + $: isTabActive = $page.url.pathname === tabLink; + + const showTab = (e: HTMLElement | undefined) => { + if (e) { + e.scrollIntoView({}); + } + } + + $: if (isTabActive) { + showTab(tab) + } showTab(tab)} > {tabName} From 95aeec3380f17f3361a136cc55752a7c4b8f3740 Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 01:00:18 +0600 Subject: [PATCH 034/775] web: tab bar pagination effect & smooth scroll --- web/src/components/sidebar/SidebarTab.svelte | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 87bf8cd0..563564f0 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -4,13 +4,23 @@ export let tabName: string; export let tabLink: string; + const firstTabs = [ + "save", + "trim", + "crop", + "convert" + ]; + let tab: HTMLElement; $: isTabActive = $page.url.pathname === tabLink; const showTab = (e: HTMLElement | undefined) => { if (e) { - e.scrollIntoView({}); + e.scrollIntoView({ + inline: firstTabs.includes(tabName) ? 'end' : 'start', + behavior: 'smooth' + }); } } From 5390415aa7d55e3c402753fa57f06d395cfdbe2d Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 01:12:59 +0600 Subject: [PATCH 035/775] web: use hover effects only when supported --- .../save/buttons/DownloadButton.svelte | 17 +++++++++-------- web/src/components/sidebar/SidebarTab.svelte | 10 ++++++---- web/src/routes/+layout.svelte | 8 +++++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 2e0838cb..655ea4b1 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -121,19 +121,20 @@ margin-bottom: 0.1rem; } - #download-button:hover { - background: var(--button-hover-transparent); - } - #download-button:disabled { cursor: unset; } - #download-button:disabled:hover { - background: none; - } - :global(#input-container.focused) #download-button { border-left: 2px var(--secondary) solid; } + + @media (hover: hover) { + #download-button:hover { + background: var(--button-hover-transparent); + } + #download-button:disabled:hover { + background: none; + } + } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 563564f0..36e8db53 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -63,10 +63,6 @@ opacity: 1; } - .sidebar-tab:hover { - opacity: 1; - } - .sidebar-tab:focus-visible { box-shadow: 0 0 0 3px var(--blue) inset; outline: none; @@ -78,6 +74,12 @@ color: var(--sidebar-highlight); } + @media (hover: hover) { + .sidebar-tab:hover { + opacity: 1; + } + } + @media screen and (max-width: 535px) { .sidebar-tab { padding: 5px var(--padding); diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index bfc6deff..fc5609ce 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -130,9 +130,11 @@ transform: scale(0.95); } - :global(button:hover) { - background-color: var(--button-hover); - z-index: 1; + @media (hover: hover) { + :global(button:hover) { + background-color: var(--button-hover); + z-index: 1; + } } :global(.center-column-container) { From f2bacc703a351c9df3190f00ac341d9772ccec8b Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 01:18:39 +0600 Subject: [PATCH 036/775] web/omnibox: import only one tabler icon --- web/src/components/save/Omnibox.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index e986100b..defeedd3 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -1,5 +1,5 @@ From 838cc508de52df4a45f0a8f30b6d6a99bc6dec6b Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 19:10:10 +0600 Subject: [PATCH 041/775] web/save: reduce meowbalt padding --- web/src/routes/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 63f3fbda..050bce55 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -21,7 +21,7 @@ justify-content: center; width: 100%; height: 100%; - gap: 24px; + gap: 15px; } #terms-note { From 8ec4a528ef74d419aee353d36758aae362e5a5fc Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 19:41:45 +0600 Subject: [PATCH 042/775] web/save: fix terms note padding on mobile --- web/src/routes/+page.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 050bce55..15fa7416 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -35,6 +35,7 @@ @media screen and (max-width: 535px) { #terms-note { font-size: 11px; + padding-bottom: 0; } } From 068af6a965650006e269a3f7e3cc27438e4eb8dc Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 15:28:36 +0600 Subject: [PATCH 043/775] web/types/api: add trailing commas --- web/src/lib/types/api.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/web/src/lib/types/api.ts b/web/src/lib/types/api.ts index 2a739f60..f3b81851 100644 --- a/web/src/lib/types/api.ts +++ b/web/src/lib/types/api.ts @@ -3,19 +3,21 @@ enum CobaltResponseType { RateLimit = 'rate-limit', Picker = 'picker', Redirect = 'redirect', - Stream = 'stream' + Stream = 'stream', } type CobaltErrorResponse = { status: CobaltResponseType.Error | CobaltResponseType.RateLimit, - text: string + text: string, }; -type CobaltPartialURLResponse = { url: string } +type CobaltPartialURLResponse = { + url: string, +} type CobaltPartialImagesPickerResponse = { pickerType: 'images', - picker: CobaltPartialURLResponse[] + picker: CobaltPartialURLResponse[], } type CobaltPartialVariousPickerResponse = { @@ -23,7 +25,7 @@ type CobaltPartialVariousPickerResponse = { picker: { type: 'photo' | 'video', url: string, - thumb: string + thumb: string, }[]; } @@ -33,11 +35,11 @@ type CobaltPickerResponse = { } & (CobaltPartialImagesPickerResponse | CobaltPartialVariousPickerResponse); type CobaltRedirectResponse = { - status: CobaltResponseType.Redirect + status: CobaltResponseType.Redirect, } & CobaltPartialURLResponse; type CobaltStreamResponse = { - status: CobaltResponseType.Stream + status: CobaltResponseType.Stream, } & CobaltPartialURLResponse; export type CobaltAPIResponse = CobaltErrorResponse From 21e03a407c66f1dc13b50be3ee1e8be6743db011 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 17:55:06 +0600 Subject: [PATCH 044/775] web: add eslint --- web/eslint.config.js | 9 + web/package-lock.json | 1276 ++++++++++++++++++++++++++++++++++++++++- web/package.json | 6 +- 3 files changed, 1289 insertions(+), 2 deletions(-) create mode 100644 web/eslint.config.js diff --git a/web/eslint.config.js b/web/eslint.config.js new file mode 100644 index 00000000..7d683070 --- /dev/null +++ b/web/eslint.config.js @@ -0,0 +1,9 @@ +// @ts-check + +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, +); diff --git a/web/package-lock.json b/web/package-lock.json index e4509d63..6907bcb2 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -14,13 +14,17 @@ "@tabler/icons-svelte": "^3.6.0" }, "devDependencies": { + "@eslint/js": "^9.5.0", "@sveltejs/adapter-static": "^3.0.2", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", + "@types/eslint__js": "^8.42.3", + "eslint": "^8.57.0", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", - "typescript": "^5.0.0", + "typescript": "^5.4.5", + "typescript-eslint": "^7.13.1", "vite": "^5.0.3" } }, @@ -404,6 +408,66 @@ "node": ">=12" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz", + "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@fontsource-variable/noto-sans-mono": { "version": "5.0.20", "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz", @@ -414,6 +478,44 @@ "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==" }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -817,17 +919,271 @@ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", "dev": true }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint__js": { + "version": "8.42.3", + "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", + "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", + "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/type-utils": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", + "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", + "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", + "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", + "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", + "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", + "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true, + "license": "ISC" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -839,6 +1195,59 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -852,6 +1261,13 @@ "node": ">= 8" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -860,6 +1276,16 @@ "dequal": "^2.0.3" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/axobject-query": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", @@ -926,6 +1352,23 @@ "node": ">=6" } }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -962,6 +1405,26 @@ "periscopic": "^3.1.0" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -977,6 +1440,21 @@ "node": ">= 0.6" } }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -1006,6 +1484,13 @@ } } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -1038,6 +1523,32 @@ "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", "dev": true }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", @@ -1082,12 +1593,188 @@ "@esbuild/win32-x64": "0.20.2" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/esm-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", "dev": true }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -1096,6 +1783,23 @@ "@types/estree": "^1.0.0" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -1112,6 +1816,20 @@ "node": ">=8.6.0" } }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -1121,6 +1839,19 @@ "reusify": "^1.0.4" } }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1133,6 +1864,62 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1186,12 +1973,49 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalyzer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", "dev": true }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", @@ -1204,6 +2028,33 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -1230,6 +2081,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1289,6 +2150,16 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-reference": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", @@ -1297,6 +2168,57 @@ "@types/estree": "*" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -1306,11 +2228,48 @@ "node": ">=6" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", @@ -1430,6 +2389,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1448,6 +2414,56 @@ "wrappy": "1" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1460,6 +2476,16 @@ "node": ">=6" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1469,6 +2495,26 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/periscopic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", @@ -1525,6 +2571,26 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -1671,12 +2737,48 @@ "rimraf": "^2.5.2" } }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/set-cookie-parser": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", "dev": true }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/sirv": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", @@ -1691,6 +2793,16 @@ "node": ">= 10" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/sorcery": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", @@ -1714,6 +2826,19 @@ "node": ">=0.10.0" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -1726,6 +2851,32 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/svelte": { "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", @@ -1846,6 +2997,13 @@ } } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, "node_modules/tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", @@ -1877,17 +3035,57 @@ "node": ">=6" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1896,6 +3094,43 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", + "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.13.1", + "@typescript-eslint/parser": "7.13.1", + "@typescript-eslint/utils": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/vite": { "version": "5.2.13", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", @@ -1965,11 +3200,50 @@ } } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/web/package.json b/web/package.json index 32a8f969..af5ab742 100644 --- a/web/package.json +++ b/web/package.json @@ -20,13 +20,17 @@ }, "homepage": "https://cobalt.tools/", "devDependencies": { + "@eslint/js": "^9.5.0", "@sveltejs/adapter-static": "^3.0.2", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", + "@types/eslint__js": "^8.42.3", + "eslint": "^8.57.0", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", - "typescript": "^5.0.0", + "typescript": "^5.4.5", + "typescript-eslint": "^7.13.1", "vite": "^5.0.3" }, "dependencies": { From 009a2cc8633564cd540b006d8c78f039376b910f Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:12:51 +0600 Subject: [PATCH 045/775] web: implement settings core this was a torture --- web/package-lock.json | 12 ++++++++- web/package.json | 3 ++- web/src/lib/settings.ts | 42 ++++++++++++++++++++++++++++++++ web/src/lib/settings/defaults.ts | 35 ++++++++++++++++++++++++++ web/src/lib/types/generic.ts | 8 ++++++ web/src/lib/types/settings.ts | 41 +++++++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 web/src/lib/settings.ts create mode 100644 web/src/lib/settings/defaults.ts create mode 100644 web/src/lib/types/generic.ts create mode 100644 web/src/lib/types/settings.ts diff --git a/web/package-lock.json b/web/package-lock.json index 6907bcb2..23441713 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -11,7 +11,8 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0" + "@tabler/icons-svelte": "^3.6.0", + "ts-deepmerge": "^7.0.0" }, "devDependencies": { "@eslint/js": "^9.5.0", @@ -3048,6 +3049,15 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-deepmerge": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.0.tgz", + "integrity": "sha512-WZ/iAJrKDhdINv1WG6KZIGHrZDar6VfhftG1QJFpVbOYZMYJLJOvZOo1amictRXVdBXZIgBHKswMTXzElngprA==", + "license": "ISC", + "engines": { + "node": ">=14.13.1" + } + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", diff --git a/web/package.json b/web/package.json index af5ab742..eda7e04a 100644 --- a/web/package.json +++ b/web/package.json @@ -36,6 +36,7 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0" + "@tabler/icons-svelte": "^3.6.0", + "ts-deepmerge": "^7.0.0" } } diff --git a/web/src/lib/settings.ts b/web/src/lib/settings.ts new file mode 100644 index 00000000..cdbf607b --- /dev/null +++ b/web/src/lib/settings.ts @@ -0,0 +1,42 @@ +import { readable, type Updater } from 'svelte/store'; +import { merge } from 'ts-deepmerge'; + +import type { RecursivePartial } from './types/generic'; +import type { CobaltSettings } from './types/settings'; + +import defaultSettings from "$lib/settings/defaults"; + +const writeToStorage = (settings: CobaltSettings) => { + localStorage.setItem( + "settings", + JSON.stringify(settings) + ); + + return settings; +} + +const loadFromStorage = () => { + const settings = localStorage.getItem('settings'); + if (!settings) { + return writeToStorage(defaultSettings); + } + + return JSON.parse(settings) as CobaltSettings; +} + +let update: (_: Updater) => void; + +export default readable( + loadFromStorage(), + (_, _update) => { update = _update } +); + +// update settings from outside +export function updateSetting(settings: RecursivePartial) { + update((current) => { + // deep merge partial type into full CobaltSettings type + current = merge(current, settings) as CobaltSettings; + + return writeToStorage(current); + }); +} diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts new file mode 100644 index 00000000..ddaa83be --- /dev/null +++ b/web/src/lib/settings/defaults.ts @@ -0,0 +1,35 @@ +import type { CobaltSettings } from "$lib/types/settings"; + +const defaultSettings: CobaltSettings = { + schemaVersion: 1, + accessibility: { + reduceAnimations: false, + reduceTransparency: false + }, + appearance: { + theme: "auto" + }, + general: { + customProcessingEndpoint: "", + seenOnboarding: false, + seenSafetyWarning: false + }, + save: { + audioFormat: "mp3", + disableMetadata: false, + downloadMode: "auto", + downloadPopup: true, + filenameStyle: "classic", + tiktokH265: false, + tiktokFullAudio: false, + twitterGif: false, + videoQuality: "720", + youtubeVideoCodec: "h264", + youtubeDubBrowserLang: false + }, + privacy: { + trafficAnalytics: true + } +} + +export default defaultSettings; diff --git a/web/src/lib/types/generic.ts b/web/src/lib/types/generic.ts new file mode 100644 index 00000000..c2927964 --- /dev/null +++ b/web/src/lib/types/generic.ts @@ -0,0 +1,8 @@ +// more readable version of recursive partial taken from stackoverflow: +// https://stackoverflow.com/a/51365037 +export type RecursivePartial = { + [Key in keyof Type]?: + Type[Key] extends (infer ElementType)[] ? RecursivePartial[] : + Type[Key] extends object | undefined ? RecursivePartial : + Type[Key]; +}; diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts new file mode 100644 index 00000000..a65e7843 --- /dev/null +++ b/web/src/lib/types/settings.ts @@ -0,0 +1,41 @@ +type CobaltSettingsAccessibility = { + reduceAnimations: boolean, + reduceTransparency: boolean, +}; + +type CobaltSettingsAppearance = { + theme: "auto" | "light" | "dark", +}; + +type CobaltSettingsGeneral = { + customProcessingEndpoint: string, + seenOnboarding: boolean, + seenSafetyWarning: boolean, +}; + +type CobaltSettingsSave = { + audioFormat: "best" | "mp3" | "ogg" | "wav" | "opus", + disableMetadata: boolean, + downloadMode: "auto" | "audio" | "mute", + downloadPopup: boolean, + filenameStyle: "classic" | "basic" | "pretty" | "nerdy", + tiktokH265: boolean, + tiktokFullAudio: boolean, + twitterGif: boolean, + videoQuality: "max" | "2160" | "1440" | "1080" | "720" | "360" | "240" | "144", + youtubeVideoCodec: "h264" | "av1" | "vp9", + youtubeDubBrowserLang: boolean, +}; + +type CobaltSettingsPrivacy = { + trafficAnalytics: boolean, +}; + +export type CobaltSettings = { + schemaVersion: number, + accessibility: CobaltSettingsAccessibility, + appearance: CobaltSettingsAppearance, + general: CobaltSettingsGeneral, + save: CobaltSettingsSave, + privacy: CobaltSettingsPrivacy, +}; From b15b108fa93ca1d0ae39a6be43c6c1eafaee2957 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:20:18 +0600 Subject: [PATCH 046/775] web/package: add min engine versions --- web/package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/package.json b/web/package.json index eda7e04a..aa2eeeee 100644 --- a/web/package.json +++ b/web/package.json @@ -11,6 +11,10 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "license": "CC-BY-NC-SA-4.0", + "engines": { + "node": ">=20.10.0", + "npm": ">=10.0.0" + }, "repository": { "type": "git", "url": "git+https://github.com/imputnet/cobalt.git" From 1cac70f79545f1d6a8af7044024385f373a748c3 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:26:13 +0600 Subject: [PATCH 047/775] web/package: lowball engine requirements --- web/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/package.json b/web/package.json index aa2eeeee..51a4ff45 100644 --- a/web/package.json +++ b/web/package.json @@ -12,8 +12,8 @@ }, "license": "CC-BY-NC-SA-4.0", "engines": { - "node": ">=20.10.0", - "npm": ">=10.0.0" + "node": ">=20", + "npm": ">=9" }, "repository": { "type": "git", From 0ce73e03d3aed2c2b57efb41b2200bedde978a28 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:30:56 +0600 Subject: [PATCH 048/775] web/package: update required node version to 20.9 --- web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/package.json b/web/package.json index 51a4ff45..6d2d17e2 100644 --- a/web/package.json +++ b/web/package.json @@ -12,7 +12,7 @@ }, "license": "CC-BY-NC-SA-4.0", "engines": { - "node": ">=20", + "node": ">=20.9", "npm": ">=9" }, "repository": { From 00cdb2121d7e7f06dc9b9808e867b69b6a36188c Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 23:04:09 +0600 Subject: [PATCH 049/775] web: data-driven switcher & save mode switcher also: - disabled ssr to enable localstorage - removed the workaround for hover, as it looks bad --- .../components/buttons/ActionButton.svelte | 9 +----- .../buttons/SettingsContextButton.svelte | 32 +++++++++++++++++++ web/src/components/buttons/Switcher.svelte | 9 ++---- web/src/components/save/Omnibox.svelte | 17 +++++----- web/src/lib/settings.ts | 2 +- web/src/routes/+layout.svelte | 6 +++- web/src/routes/+layout.ts | 1 + 7 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 web/src/components/buttons/SettingsContextButton.svelte diff --git a/web/src/components/buttons/ActionButton.svelte b/web/src/components/buttons/ActionButton.svelte index 022e6784..3c2a4433 100644 --- a/web/src/components/buttons/ActionButton.svelte +++ b/web/src/components/buttons/ActionButton.svelte @@ -3,13 +3,6 @@ export let click = () => { alert('no function assigned') }; - - - diff --git a/web/src/components/buttons/SettingsContextButton.svelte b/web/src/components/buttons/SettingsContextButton.svelte new file mode 100644 index 00000000..a0a29e12 --- /dev/null +++ b/web/src/components/buttons/SettingsContextButton.svelte @@ -0,0 +1,32 @@ + + + diff --git a/web/src/components/buttons/Switcher.svelte b/web/src/components/buttons/Switcher.svelte index 06e794a5..afcfeba3 100644 --- a/web/src/components/buttons/Switcher.svelte +++ b/web/src/components/buttons/Switcher.svelte @@ -1,8 +1,4 @@ - - -
+
@@ -31,7 +27,8 @@ border-radius: 0; } + /* clumsy hack to get rid of double border in a list of switches */ .switcher > :global(:not(.button:first-child)) { - margin-left: -1.5px; /* hack to get rid of double border in a list of switches */ + margin-left: -1.5px; } diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 8cebdcad..5686764d 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -12,6 +12,7 @@ import IconMute from "$lib/icons/Mute.svelte"; import IconClipboard from "$lib/icons/Clipboard.svelte"; + import SettingsContextButton from "../buttons/SettingsContextButton.svelte"; let link: string = ""; let isFocused = false; @@ -66,18 +67,18 @@
- - + + auto - - + + audio - - + + mute - + - + paste paste and download diff --git a/web/src/lib/settings.ts b/web/src/lib/settings.ts index cdbf607b..f005ced4 100644 --- a/web/src/lib/settings.ts +++ b/web/src/lib/settings.ts @@ -18,7 +18,7 @@ const writeToStorage = (settings: CobaltSettings) => { const loadFromStorage = () => { const settings = localStorage.getItem('settings'); if (!settings) { - return writeToStorage(defaultSettings); + return defaultSettings; } return JSON.parse(settings) as CobaltSettings; diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 7d6ca8a0..34f362b1 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -133,10 +133,14 @@ transform: scale(0.95); } + :global(.button.selected) { + background: var(--secondary); + color: var(--primary); + } + @media (hover: hover) { :global(button:hover) { background-color: var(--button-hover); - z-index: 1; } } diff --git a/web/src/routes/+layout.ts b/web/src/routes/+layout.ts index 189f71e2..ceccaaf6 100644 --- a/web/src/routes/+layout.ts +++ b/web/src/routes/+layout.ts @@ -1 +1,2 @@ export const prerender = true; +export const ssr = false; From 3b2178fd1aaab77a7c4e2c7b16738537b132559b Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 23:29:26 +0600 Subject: [PATCH 050/775] web/api: full api request with user preferences --- web/src/lib/api.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index 3719080c..7892dc8e 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -1,10 +1,29 @@ +import { get } from 'svelte/store'; +import settings from "$lib/settings"; import type { CobaltAPIResponse } from "$lib/types/api"; const apiURL = "https://api.cobalt.tools"; const request = async (url: string) => { + const saveSettings = get(settings).save; + const request = { - url + url, + + isAudioOnly: saveSettings.downloadMode === "audio", + isAudioMuted: saveSettings.downloadMode === "mute", + aFormat: saveSettings.audioFormat, + isTTFullAudio: saveSettings.tiktokFullAudio, + dubLang: saveSettings.youtubeDubBrowserLang, + + vCodec: saveSettings.youtubeVideoCodec, + vQuality: saveSettings.videoQuality, + + filenamePattern: saveSettings.filenameStyle, + disableMetadata: saveSettings.disableMetadata, + + twitterGif: saveSettings.twitterGif, + tiktokH265: saveSettings.tiktokH265, } const response: CobaltAPIResponse | undefined = await fetch(`${apiURL}/api/json`, { From 4564f409aa61c82faf314a31a2dd07db908057fa Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 23:42:52 +0600 Subject: [PATCH 051/775] web/types/settings: add missing 480p video quality --- web/src/lib/types/settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts index a65e7843..c17e65a1 100644 --- a/web/src/lib/types/settings.ts +++ b/web/src/lib/types/settings.ts @@ -22,7 +22,7 @@ type CobaltSettingsSave = { tiktokH265: boolean, tiktokFullAudio: boolean, twitterGif: boolean, - videoQuality: "max" | "2160" | "1440" | "1080" | "720" | "360" | "240" | "144", + videoQuality: "max" | "2160" | "1440" | "1080" | "720" | "480" | "360" | "240" | "144", youtubeVideoCodec: "h264" | "av1" | "vp9", youtubeDubBrowserLang: boolean, }; From f2e74b681b7d02742d07888b7524e019289fa797 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 20 Jun 2024 13:46:01 +0600 Subject: [PATCH 052/775] web/sidebar: align tabbar to center on mobile --- web/src/components/sidebar/Sidebar.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index c54c316d..5888a32d 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -86,6 +86,7 @@ position: fixed; bottom: 0; padding: var(--sidebar-inner-padding) 0; + justify-content: center; } #sidebar::before { From b9e7661b6d0a5a8861c6a46bffd66f57766955f2 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 20 Jun 2024 18:05:17 +0600 Subject: [PATCH 053/775] web: basic settings page needed for testing typescript cries about types but i don't care at this point --- ...extButton.svelte => SettingsButton.svelte} | 0 .../buttons/SettingsCheckbox.svelte | 31 ++++++++++++++ web/src/components/save/Omnibox.svelte | 14 +++---- web/src/lib/settings/defaults.ts | 13 +++++- web/src/routes/settings/+page.svelte | 42 +++++++++++++++++-- 5 files changed, 89 insertions(+), 11 deletions(-) rename web/src/components/buttons/{SettingsContextButton.svelte => SettingsButton.svelte} (100%) create mode 100644 web/src/components/buttons/SettingsCheckbox.svelte diff --git a/web/src/components/buttons/SettingsContextButton.svelte b/web/src/components/buttons/SettingsButton.svelte similarity index 100% rename from web/src/components/buttons/SettingsContextButton.svelte rename to web/src/components/buttons/SettingsButton.svelte diff --git a/web/src/components/buttons/SettingsCheckbox.svelte b/web/src/components/buttons/SettingsCheckbox.svelte new file mode 100644 index 00000000..81c8c00a --- /dev/null +++ b/web/src/components/buttons/SettingsCheckbox.svelte @@ -0,0 +1,31 @@ + + +
+ + updateSetting({ + [settingContext]: { + [settingId]: isChecked, + }, + })} + /> + +
diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 5686764d..3a4e6d58 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -12,7 +12,7 @@ import IconMute from "$lib/icons/Mute.svelte"; import IconClipboard from "$lib/icons/Clipboard.svelte"; - import SettingsContextButton from "../buttons/SettingsContextButton.svelte"; + import SettingsButton from "../buttons/SettingsButton.svelte"; let link: string = ""; let isFocused = false; @@ -68,15 +68,15 @@
- + auto - - + + audio - - + + mute - + diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts index ddaa83be..124e8751 100644 --- a/web/src/lib/settings/defaults.ts +++ b/web/src/lib/settings/defaults.ts @@ -31,5 +31,16 @@ const defaultSettings: CobaltSettings = { trafficAnalytics: true } } - export default defaultSettings; + +export const settingArrays = { + appearance: { + theme: ["auto", "light", "dark"] + }, + save: { + audioFormat: ["best", "mp3", "ogg", "wav", "opus"], + filenameStyle: ["classic", "basic", "pretty", "nerdy"], + videoQuality: ["max", "2160", "1440", "1080", "720", "480", "360", "240", "144"], + youtubeVideoCodec: ["h264", "av1", "vp9"], + }, +} diff --git a/web/src/routes/settings/+page.svelte b/web/src/routes/settings/+page.svelte index d6a792fb..5f94bc32 100644 --- a/web/src/routes/settings/+page.svelte +++ b/web/src/routes/settings/+page.svelte @@ -1,5 +1,41 @@ - - +
+
settings (placeholder)
+
+ {#each Object.entries(switchers) as [context, settingIdParent]} +
+
{context} context:
+
+
+ {#each Object.entries(settingIdParent) as [settingId, settingValue]} + {#if settingValue instanceof Array} +
{settingId}
+ + {#each settingValue as value} + + {value} + + {/each} + +
+ {/if} + + {#if typeof settingValue === "boolean"} + + {settingId} + +
+ {/if} + {/each} + {/each} +
From 7e39bd78d7ef5e5abb993170f4b4e02334e05e48 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 20 Jun 2024 19:19:57 +0600 Subject: [PATCH 054/775] web/settings: fix setting value name --- web/src/components/buttons/SettingsButton.svelte | 10 +++++----- web/src/components/save/Omnibox.svelte | 6 +++--- web/src/routes/settings/+page.svelte | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/web/src/components/buttons/SettingsButton.svelte b/web/src/components/buttons/SettingsButton.svelte index a0a29e12..bb2a6f13 100644 --- a/web/src/components/buttons/SettingsButton.svelte +++ b/web/src/components/buttons/SettingsButton.svelte @@ -3,7 +3,7 @@ generics=" Context extends Exclude, Id extends keyof CobaltSettings[Context], - Key extends CobaltSettings[Context][Id] + Value extends CobaltSettings[Context][Id] " > import settings, { updateSetting } from "$lib/settings"; @@ -11,20 +11,20 @@ export let settingContext: Context; export let settingId: Id; - export let settingKey: Key; + export let settingValue: Value; $: setting = $settings[settingContext][settingId]; - $: isSelected = setting === settingKey; + $: isSelected = setting === settingValue;
+ \ No newline at end of file + From 49e2df425dd275119bb94de955d4b521615d3829 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 19:41:38 +0600 Subject: [PATCH 078/775] web: remove future feature placeholders --- web/src/components/sidebar/Sidebar.svelte | 12 ------------ web/src/components/sidebar/SidebarTab.svelte | 9 ++++----- web/src/routes/convert/+page.svelte | 5 ----- web/src/routes/crop/+page.svelte | 5 ----- web/src/routes/trim/+page.svelte | 5 ----- 5 files changed, 4 insertions(+), 32 deletions(-) delete mode 100644 web/src/routes/convert/+page.svelte delete mode 100644 web/src/routes/crop/+page.svelte delete mode 100644 web/src/routes/trim/+page.svelte diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index e6c7824d..e075da07 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -3,9 +3,6 @@ import SidebarTab from "$components/sidebar/SidebarTab.svelte"; import IconDownload from "@tabler/icons-svelte/IconDownload.svelte"; - import IconCut from "@tabler/icons-svelte/IconCut.svelte"; - import IconCrop from "@tabler/icons-svelte/IconCrop.svelte"; - import IconTransform from "@tabler/icons-svelte/IconTransform.svelte"; import IconSettings from "@tabler/icons-svelte/IconSettings.svelte"; import IconComet from "@tabler/icons-svelte/IconComet.svelte"; @@ -33,15 +30,6 @@ - - - - - - - - - diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 67275a6b..c9657288 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -4,11 +4,10 @@ export let tabName: string; export let tabLink: string; - const firstTabs = [ + const firstTabPage = [ "save", - "trim", - "crop", - "convert" + "settings", + "updates" ]; let tab: HTMLElement; @@ -21,7 +20,7 @@ const showTab = (e: HTMLElement | undefined) => { if (e) { e.scrollIntoView({ - inline: firstTabs.includes(tabName) ? 'end' : 'start', + inline: firstTabPage.includes(tabName) ? 'end' : 'start', behavior: 'smooth' }); } diff --git a/web/src/routes/convert/+page.svelte b/web/src/routes/convert/+page.svelte deleted file mode 100644 index a26a5d64..00000000 --- a/web/src/routes/convert/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/web/src/routes/crop/+page.svelte b/web/src/routes/crop/+page.svelte deleted file mode 100644 index 1e39a5b6..00000000 --- a/web/src/routes/crop/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/web/src/routes/trim/+page.svelte b/web/src/routes/trim/+page.svelte deleted file mode 100644 index fbee1685..00000000 --- a/web/src/routes/trim/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - From 7b289bfb1611ddc42000aa7fabcd00ccd24b1268 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 20:59:25 +0600 Subject: [PATCH 079/775] web: mobile improvements - all buttons now reflect that they're pressed or hovered - settings feel way better on mobile - settings header has been completely remade --- .../buttons/SettingsCheckbox.svelte | 2 +- .../settings/SettingsSection.svelte | 12 ++++++ .../components/settings/SettingsTab.svelte | 1 + web/src/components/sidebar/SidebarTab.svelte | 8 +++- web/src/routes/+layout.svelte | 6 ++- web/src/routes/settings/+layout.svelte | 43 +++++++++++++------ 6 files changed, 54 insertions(+), 18 deletions(-) diff --git a/web/src/components/buttons/SettingsCheckbox.svelte b/web/src/components/buttons/SettingsCheckbox.svelte index b8f98afd..9cea6fa0 100644 --- a/web/src/components/buttons/SettingsCheckbox.svelte +++ b/web/src/components/buttons/SettingsCheckbox.svelte @@ -52,10 +52,10 @@ flex-direction: row; align-items: center; gap: 12px; - justify-content: start; text-align: left; transform: none; + padding: 6px 12px; } .checkbox-text { diff --git a/web/src/components/settings/SettingsSection.svelte b/web/src/components/settings/SettingsSection.svelte index ad5674fb..2c0abf0b 100644 --- a/web/src/components/settings/SettingsSection.svelte +++ b/web/src/components/settings/SettingsSection.svelte @@ -30,6 +30,18 @@ #settings-section-categories { background: var(--button); border-radius: var(--border-radius); + box-shadow: var(--button-box-shadow); + } + + #settings-section-categories > :global(:not(.settings-tab:last-child)) { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + box-shadow: 0 3px 0px -1.2px var(--button-stroke); + } + + #settings-section-categories > :global(:not(.settings-tab:first-child)) { + border-top-left-radius: 0; + border-top-right-radius: 0; } } diff --git a/web/src/components/settings/SettingsTab.svelte b/web/src/components/settings/SettingsTab.svelte index 28fc621c..607977b2 100644 --- a/web/src/components/settings/SettingsTab.svelte +++ b/web/src/components/settings/SettingsTab.svelte @@ -95,6 +95,7 @@ @media screen and (max-width: 750px) { .settings-tab { background: none; + padding: 9px; --small-padding: 5px; } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index c9657288..9fd76c07 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -70,9 +70,15 @@ opacity: 1; } + .sidebar-tab:active:not(.active) { + opacity: 1; + background-color: var(--sidebar-hover); + } + @media (hover: hover) { - .sidebar-tab:hover { + .sidebar-tab:hover:not(.active) { opacity: 1; + background-color: var(--sidebar-hover); } } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 6a54a4f4..e66775a3 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -26,9 +26,11 @@ --button-hover-transparent: rgba(0, 0, 0, 0.06); --button-stroke: rgba(0, 0, 0, 0.05); --button-text: #282828; + --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; --sidebar-bg: #000000; --sidebar-highlight: #ffffff; + --sidebar-hover: rgba(255, 255, 255, 0.1); --input-border: #8d8d95; @@ -129,7 +131,7 @@ cursor: pointer; background-color: var(--button); color: var(--button-text); - box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + box-shadow: var(--button-box-shadow); } :global(:focus-visible) { @@ -139,7 +141,7 @@ } :global(button:active) { - transform: scale(0.95); + background-color: var(--button-hover); } :global(.button.active) { diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index d58cb825..dfa96938 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -14,6 +14,8 @@ let screenWidth: number; + $: currentPageTitle = $page.url.pathname.split("/").at(-1); + $: isMobile = screenWidth <= 750; $: isHome = $page.url.pathname === `/settings`; @@ -23,11 +25,19 @@
- {#if !isHome && isMobile} - - -

settings

-
+ {#if isMobile} + {#if !isHome} + + + + {/if} +

+ settings + {#if !isHome} + / + {currentPageTitle} + {/if} +

{:else}

settings

{/if} @@ -77,7 +87,9 @@ #settings-page { --settings-nav-width: 250px; --settings-padding: 30px; - --settings-padding-small: calc(var(--settings-padding) - var(--padding)); + --settings-padding-small: calc( + var(--settings-padding) - var(--padding) + ); display: grid; width: 100%; grid-template-columns: var(--settings-nav-width) 1fr; @@ -110,11 +122,11 @@ } #settings-navigation { - gap: 12px; + gap: var(--padding); } #settings-header { - --back-padding: 6px; + --back-padding: calc(var(--padding) / 2); } .back-button { @@ -123,7 +135,9 @@ color: var(--secondary); gap: var(--back-padding); padding: var(--back-padding); - padding-right: calc(var(--back-padding) * 2); + + position: absolute; + left: var(--back-padding); } .back-button:active { @@ -166,10 +180,7 @@ position: sticky; padding: var(--padding); gap: 4px; - } - - #settings-header.back-visible { - padding: calc(var(--padding) - var(--back-padding)); + justify-content: center; } #settings-sidebar { @@ -178,7 +189,11 @@ #settings-page-title { text-align: center; - font-size: 16px; + letter-spacing: -0.3px; + } + + .title-slash { + color: var(--gray); } #settings-navigation { From 635561394cb3cd2e72cc41ec78da3a723a407064 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 21:01:08 +0600 Subject: [PATCH 080/775] web: add dynamic page titles --- web/src/routes/+page.svelte | 4 ++++ web/src/routes/about/+page.svelte | 6 ++++++ web/src/routes/donate/+page.svelte | 6 ++++++ web/src/routes/settings/+layout.svelte | 8 ++++++++ web/src/routes/updates/+page.svelte | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index a91c5c69..5d076ad2 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -3,6 +3,10 @@ import MeowbaltLoaf from "$components/meowbalt/MeowbaltLoaf.svelte"; + + cobalt + +
diff --git a/web/src/routes/about/+page.svelte b/web/src/routes/about/+page.svelte index 89a7710a..5d70e6dd 100644 --- a/web/src/routes/about/+page.svelte +++ b/web/src/routes/about/+page.svelte @@ -2,4 +2,10 @@ import Placeholder from "$components/misc/Placeholder.svelte"; + + + cobalt: about + + + diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index 1ce2815e..9959ebe0 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -2,4 +2,10 @@ import Placeholder from "$components/misc/Placeholder.svelte"; + + + cobalt: donate + + + diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index dfa96938..6ac82241 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -15,11 +15,19 @@ let screenWidth: number; $: currentPageTitle = $page.url.pathname.split("/").at(-1); + $: stringPageTitle = + currentPageTitle !== "settings" ? `/ ${currentPageTitle}` : ""; $: isMobile = screenWidth <= 750; $: isHome = $page.url.pathname === `/settings`; + + + cobalt: settings {stringPageTitle} + + +
diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 8140bcd2..e3cf1e20 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -2,4 +2,10 @@ import Placeholder from "$components/misc/Placeholder.svelte"; + + + cobalt: updates + + + From 98b0a2f10a95731d165a4c2236f2ba5a4452ab03 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 21:06:07 +0600 Subject: [PATCH 081/775] web/SettingsCheckbox: remove yassing --- web/src/components/buttons/SettingsCheckbox.svelte | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/web/src/components/buttons/SettingsCheckbox.svelte b/web/src/components/buttons/SettingsCheckbox.svelte index 9cea6fa0..568bc41b 100644 --- a/web/src/components/buttons/SettingsCheckbox.svelte +++ b/web/src/components/buttons/SettingsCheckbox.svelte @@ -23,14 +23,13 @@ - - diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte new file mode 100644 index 00000000..ef253ac2 --- /dev/null +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -0,0 +1,72 @@ + + +
+ + + {#if description} +
{description}
+ {/if} +
+ + diff --git a/web/src/components/buttons/Switcher.svelte b/web/src/components/buttons/Switcher.svelte index b836105e..4b0cb333 100644 --- a/web/src/components/buttons/Switcher.svelte +++ b/web/src/components/buttons/Switcher.svelte @@ -28,16 +28,15 @@ } .switcher.big { - --switcher-inner-padding: 4px; - border-radius: calc(var(--border-radius) + var(--switcher-inner-padding)); background: var(--button); box-shadow: var(--button-box-shadow); - padding: var(--switcher-inner-padding); + padding: var(--sidebar-inner-padding); } .switcher.big :global(.button) { width: 100%; - height: calc(40px - var(--switcher-inner-padding)); + height: calc(40px - var(--sidebar-inner-padding)); + border-radius: calc(var(--border-radius) - var(--sidebar-inner-padding));; } .switcher.big :global(.button:not(:focus-visible)) { diff --git a/web/src/components/misc/Toggle.svelte b/web/src/components/misc/Toggle.svelte new file mode 100644 index 00000000..ed0dbb31 --- /dev/null +++ b/web/src/components/misc/Toggle.svelte @@ -0,0 +1,42 @@ + + +
+
+
+ + diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 719fb173..163600ec 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -2,11 +2,10 @@ import "@fontsource/ibm-plex-mono/400.css"; import "@fontsource/ibm-plex-mono/500.css"; + import device from "$lib/device"; import currentTheme, { statusBarColors } from "$lib/state/theme"; import Sidebar from "$components/sidebar/Sidebar.svelte"; - - import device from "$lib/device"; @@ -45,7 +44,10 @@ --sidebar-highlight: #ffffff; --sidebar-hover: rgba(255, 255, 255, 0.1); - --input-border: #8d8d95; + --input-border: var(--gray); + + --toggle-bg: var(--input-border); + --toggle-bg-enabled: var(--secondary); --padding: 12px; --border-radius: 11px; @@ -85,6 +87,9 @@ --input-border: #383838; + --toggle-bg: var(--input-border); + --toggle-bg-enabled: #777777; + --sidebar-mobile-gradient: linear-gradient( 90deg, rgba(16, 16, 16, 0.9) 0%, @@ -217,9 +222,10 @@ } :global(.subtext) { - font-size: 13px; + font-size: 12px; color: var(--gray); line-height: 1.4; + padding: 0 var(--padding); } #cobalt { diff --git a/web/src/routes/settings/general/appearance/+page.svelte b/web/src/routes/settings/general/appearance/+page.svelte index 68022510..dd4b679b 100644 --- a/web/src/routes/settings/general/appearance/+page.svelte +++ b/web/src/routes/settings/general/appearance/+page.svelte @@ -2,7 +2,7 @@ import SettingsCategory from "$components/settings/SettingsCategory.svelte"; import Switcher from "$components/buttons/Switcher.svelte"; import SettingsButton from "$components/buttons/SettingsButton.svelte"; - import SettingsCheckbox from "$components/buttons/SettingsCheckbox.svelte"; + import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; import { themeOptions } from "$lib/types/settings"; @@ -18,13 +18,13 @@ - - - - @@ -22,7 +22,7 @@ - - - - Date: Sat, 29 Jun 2024 22:53:09 +0600 Subject: [PATCH 090/775] web/SettingsToggle: clean up --- web/src/components/buttons/SettingsToggle.svelte | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte index ef253ac2..ccbc1b2c 100644 --- a/web/src/components/buttons/SettingsToggle.svelte +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -31,9 +31,7 @@ }) } > -
-

{title}

-
+

{title}

+

{$page.status}: {$page.error?.message}

\ No newline at end of file From 157b687ab5fbd7f9213d47fb33afa3a9ee6284ec Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 4 Jul 2024 22:25:22 +0000 Subject: [PATCH 112/775] web/settings: redirect to full page if base page is opened on desktop --- web/src/routes/settings/+layout.svelte | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index 819938a6..65c1fb4e 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -13,6 +13,8 @@ import IconFileSettings from "@tabler/icons-svelte/IconFileSettings.svelte"; import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; + import { goto } from "$app/navigation"; + import { defaultSettingsPage } from "$lib/settings/defaults"; let screenWidth: number; @@ -21,7 +23,13 @@ currentPageTitle !== "settings" ? ` / ${$t(`settings.page.${currentPageTitle}`)}` : ""; $: isMobile = screenWidth <= 750; - $: isHome = $page.url.pathname === `/settings`; + $: isHome = $page.url.pathname === '/settings'; + $: { + if (!isMobile && isHome) { + goto(defaultSettingsPage(), { replaceState: true }); + } + } + From 9ae0473f80732df4499cfd6bf6ebd02340c0e4f0 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 4 Jul 2024 22:25:47 +0000 Subject: [PATCH 113/775] web/sidebar: simplify settings link logic --- web/src/components/sidebar/Sidebar.svelte | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 9eef6cc8..e76be484 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -12,17 +12,12 @@ import IconComet from "@tabler/icons-svelte/IconComet.svelte"; import IconHeart from "@tabler/icons-svelte/IconHeart.svelte"; import IconInfoCircle from "@tabler/icons-svelte/IconInfoCircle.svelte"; + import { defaultSettingsPage } from "$lib/settings/defaults"; - let screenWidth: number, - settingsLink: string; + let screenWidth: number; + let settingsLink = defaultSettingsPage(); - $: isMobile = screenWidth <= 750; - - $: if (isMobile) { - settingsLink = "/settings"; - } else { - settingsLink = "/settings/general/appearance"; - } + $: screenWidth, settingsLink = defaultSettingsPage(); From a6a51b850a7ebb4b16f1aece2d7dbce4c08a61e0 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 4 Jul 2024 22:27:38 +0000 Subject: [PATCH 114/775] web/chore: tabs to spaces idk how this happened :-3 --- web/src/routes/+error.svelte | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/web/src/routes/+error.svelte b/web/src/routes/+error.svelte index ba0b6166..abcd6efe 100644 --- a/web/src/routes/+error.svelte +++ b/web/src/routes/+error.svelte @@ -1,16 +1,16 @@ From 9b3f289b0e3665c349790dc2562b3df5d1f99bbc Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 7 Jul 2024 18:52:06 +0600 Subject: [PATCH 115/775] web/lib/api: don't follow redirects away from api --- web/src/lib/api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index 7892dc8e..d1008377 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -28,6 +28,7 @@ const request = async (url: string) => { const response: CobaltAPIResponse | undefined = await fetch(`${apiURL}/api/json`, { method: "POST", + redirect: "manual", body: JSON.stringify(request), headers: { 'Accept': 'application/json', From 430bfaca43fafa9b9da05f80033a4eb22be3510a Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 7 Jul 2024 19:14:49 +0600 Subject: [PATCH 116/775] web/settings: add section ids --- .../components/settings/SettingsCategory.svelte | 5 +++-- .../components/settings/SettingsSection.svelte | 4 ++-- .../settings/general/appearance/+page.svelte | 8 ++++++-- web/src/routes/settings/save/audio/+page.svelte | 15 +++++++++++---- .../routes/settings/save/metadata/+page.svelte | 15 +++++++++++---- web/src/routes/settings/save/video/+page.svelte | 10 ++++++++-- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/web/src/components/settings/SettingsCategory.svelte b/web/src/components/settings/SettingsCategory.svelte index 8ccd1cf5..3ec3c895 100644 --- a/web/src/components/settings/SettingsCategory.svelte +++ b/web/src/components/settings/SettingsCategory.svelte @@ -1,16 +1,17 @@ -
+

{title}

{#if description.length > 0}
{description}
{/if} -
+ diff --git a/web/src/components/settings/SettingsSection.svelte b/web/src/components/settings/SettingsNavSection.svelte similarity index 100% rename from web/src/components/settings/SettingsSection.svelte rename to web/src/components/settings/SettingsNavSection.svelte diff --git a/web/src/components/settings/SettingsTab.svelte b/web/src/components/settings/SettingsNavTab.svelte similarity index 100% rename from web/src/components/settings/SettingsTab.svelte rename to web/src/components/settings/SettingsNavTab.svelte diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index 65c1fb4e..5ad31ef9 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -3,8 +3,8 @@ import { t } from "$lib/i18n/translations"; - import SettingsTab from "$components/settings/SettingsTab.svelte"; - import SettingsSection from "$components/settings/SettingsSection.svelte"; + import SettingsNavTab from "$components/settings/SettingsNavTab.svelte"; + import SettingsNavSection from "$components/settings/SettingsNavSection.svelte"; import IconSunHigh from "@tabler/icons-svelte/IconSunHigh.svelte"; @@ -68,38 +68,38 @@ {/if}
@@ -120,15 +120,13 @@ grid-template-columns: var(--settings-nav-width) 1fr; overflow: hidden; padding-left: var(--settings-padding); - padding-top: var(--settings-padding); } #settings-page-content { display: flex; flex-direction: column; - gap: var(--settings-padding); max-width: 600px; - padding: 0 var(--settings-padding); + padding: calc(var(--settings-padding) / 2); overflow-y: scroll; } @@ -140,6 +138,7 @@ #settings-sidebar { width: var(--settings-nav-width); + padding-top: var(--settings-padding); } #settings-sidebar { @@ -189,14 +188,18 @@ padding: 0; } - #settings-page-content, #settings-navigation { padding: var(--padding); + padding-bottom: calc(var(--padding) * 2); + } + + #settings-page-content { + padding: var(--padding) 0; + padding-top: 0; } #settings-page-content { max-width: unset; - gap: calc(var(--padding) * 2); } #settings-header { @@ -210,6 +213,7 @@ #settings-sidebar { gap: 0px; + padding: 0; } #settings-page-title { From da1a11b5ce5822c68cec876030c5888765c32a54 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 7 Jul 2024 16:10:12 +0000 Subject: [PATCH 118/775] svelte: don't use relative paths for bundle links in html this prevents a blank page from showing up when a user visits a non-existing page on a static build --- web/svelte.config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/svelte.config.js b/web/svelte.config.js index aac39830..b4751daa 100644 --- a/web/svelte.config.js +++ b/web/svelte.config.js @@ -17,6 +17,9 @@ const config = { precompress: false, strict: true }), + paths: { + relative: false + }, alias: { $components: 'src/components', $i18n: 'i18n', From 35a8628cc177dde458047f3ffe39093dc2f0c4b1 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 7 Jul 2024 22:45:35 +0600 Subject: [PATCH 119/775] web/SettingsToggle: change aria role to switch --- web/src/components/buttons/SettingsToggle.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte index 1bbb59fb..d310ca39 100644 --- a/web/src/components/buttons/SettingsToggle.svelte +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -23,7 +23,8 @@
+ {/each} +
+ + + diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 96510462..718a9041 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -3,14 +3,30 @@ import API from "$lib/api"; import { device } from "$lib/device"; + import { t } from "$lib/i18n/translations"; + import { createDialog } from "$lib/dialogs"; + import type { DialogInfo } from "$lib/types/dialog"; + export let url: string; $: buttonText = ">>"; $: buttonAltText = $t('a11y.save.download'); $: isDisabled = false; + let defaultErrorPopup = { + id: "save-error", + type: "small", + title: "", + bodySubText: "", + buttons: [{ + text: $t("general.gotit"), + color: "gray", + action: () => {}, + }] + } + const changeDownloadButton = (state: string) => { isDisabled = true; switch (state) { @@ -59,14 +75,20 @@ changeDownloadButton("error"); restoreDownloadButton(); - return alert("couldn't access the api"); + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: "couldn't access the api" + }) } if (response.status === "error" || response.status === "rate-limit") { changeDownloadButton("error"); restoreDownloadButton(); - return alert(`error from api: ${response.text}`); + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: response.text + }) } if (response.status === "redirect") { @@ -90,7 +112,10 @@ changeDownloadButton("error"); restoreDownloadButton(); - return alert("couldn't probe the stream"); + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: "couldn't probe the stream" + }) } } }; diff --git a/web/src/lib/dialogs.ts b/web/src/lib/dialogs.ts new file mode 100644 index 00000000..a186be04 --- /dev/null +++ b/web/src/lib/dialogs.ts @@ -0,0 +1,23 @@ +import { readable, type Updater } from "svelte/store"; +import type { DialogInfo } from "$lib/types/dialog"; + +let update: (_: Updater) => void; + +export default readable( + [], + (_, _update) => { update = _update } +); + +export function createDialog(newData: DialogInfo) { + update((popups) => { + popups.push(newData); + return popups; + }); +} + +export function killDialog() { + update((popups) => { + popups.pop() + return popups; + }); +} diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts new file mode 100644 index 00000000..b473acd1 --- /dev/null +++ b/web/src/lib/types/dialog.ts @@ -0,0 +1,14 @@ +export type DialogButton = { + text: string, + color: string, + action: () => unknown | Promise +} + +export type DialogInfo = { + id: string, + type: "small", + title: string, + bodyText: string, + bodySubText: string, + buttons: DialogButton[] +} diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 2ba680c5..35306b81 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -8,6 +8,7 @@ import Sidebar from "$components/sidebar/Sidebar.svelte"; import NotchSticker from "$components/misc/NotchSticker.svelte"; + import DialogHolder from "$components/dialog/DialogHolder.svelte"; $: reduceMotion = $settings.appearance.reduceMotion @@ -33,6 +34,7 @@ {#if device.is.iPhone && app.is.installed} {/if} +
@@ -302,6 +304,15 @@ font-size: 11px; } + :global(dialog) { + max-height: 100%; + max-width: 100%; + padding: var(--padding); + border-radius: var(--border-radius); + border: none; + pointer-events: all; + } + :global(.subtext) { font-size: 12.5px; font-weight: 500; From 1f0958a0d1922f10d55deb6bb033b618a46ca12b Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 13 Jul 2024 13:17:03 +0000 Subject: [PATCH 170/775] web/settings: move to state folder --- web/src/components/buttons/SettingsButton.svelte | 2 +- web/src/components/buttons/SettingsToggle.svelte | 2 +- web/src/components/save/Omnibox.svelte | 2 +- web/src/components/settings/LanguageAutoToggle.svelte | 4 ++-- web/src/components/settings/LanguageDropdown.svelte | 2 +- web/src/lib/api.ts | 2 +- web/src/lib/{ => state}/settings.ts | 6 +++--- web/src/lib/state/theme.ts | 2 +- web/src/routes/+layout.svelte | 2 +- web/src/routes/+layout.ts | 2 +- web/src/routes/settings/+layout.svelte | 2 +- web/src/routes/settings/advanced/debug/+page.svelte | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) rename web/src/lib/{ => state}/settings.ts (92%) diff --git a/web/src/components/buttons/SettingsButton.svelte b/web/src/components/buttons/SettingsButton.svelte index ca3be280..871c2fa0 100644 --- a/web/src/components/buttons/SettingsButton.svelte +++ b/web/src/components/buttons/SettingsButton.svelte @@ -6,7 +6,7 @@ Value extends CobaltSettings[Context][Id] " > - import settings, { updateSetting } from "$lib/settings"; + import settings, { updateSetting } from "$lib/state/settings"; import type { CobaltSettings } from "$lib/types/settings"; export let settingContext: Context; diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte index 8995da90..1e37aa3e 100644 --- a/web/src/components/buttons/SettingsToggle.svelte +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -5,7 +5,7 @@ Id extends keyof CobaltSettings[Context] " > - import settings, { updateSetting } from "$lib/settings"; + import settings, { updateSetting } from "$lib/state/settings"; import type { CobaltSettings } from "$lib/types/settings"; import Toggle from "$components/misc/Toggle.svelte"; diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index bbe98070..b8ba01b1 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -12,7 +12,7 @@ import ActionButton from "$components/buttons/ActionButton.svelte"; import SettingsButton from "$components/buttons/SettingsButton.svelte"; - import { updateSetting } from "$lib/settings"; + import { updateSetting } from "$lib/state/settings"; import type { DownloadModeOption } from "$lib/types/settings"; import IconSparkles from "$lib/icons/Sparkles.svelte"; diff --git a/web/src/components/settings/LanguageAutoToggle.svelte b/web/src/components/settings/LanguageAutoToggle.svelte index 0de00d62..aa896c9f 100644 --- a/web/src/components/settings/LanguageAutoToggle.svelte +++ b/web/src/components/settings/LanguageAutoToggle.svelte @@ -1,7 +1,7 @@ + + + + \ No newline at end of file From f582be5d440a0e345607a18bcdf6c10b4a8bd0f9 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 14 Jul 2024 21:27:34 +0600 Subject: [PATCH 177/775] web/i18n/save: remove "the" from terms note --- web/i18n/en/save.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/i18n/en/save.json b/web/i18n/en/save.json index ef676658..83d260d2 100644 --- a/web/i18n/en/save.json +++ b/web/i18n/en/save.json @@ -6,5 +6,5 @@ "mute": "mute", "input.placeholder": "paste the link here", "terms.note.agreement": "by continuing, you agree to", - "terms.note.link": "the terms and ethics of use" + "terms.note.link": "terms and ethics of use" } From 9f649ff1db62395588fa9fdc4aa9cd746a984526 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 14 Jul 2024 21:51:56 +0600 Subject: [PATCH 178/775] web/settings: update analytics text & add a link to more info --- web/i18n/en/settings.json | 7 ++++--- web/src/components/misc/OuterLink.svelte | 7 +++++++ .../settings/general/privacy/+page.svelte | 20 +++++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 web/src/components/misc/OuterLink.svelte diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 3b0195e5..6a299974 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -85,9 +85,10 @@ "language.preferred.title": "preferred language", "language.preferred.description": "language used for interface and content. if any text isn’t translated to this language, it will be displayed in english.", - "privacy": "anonymous traffic analytics", - "privacy.disableAnalytics.title": "opt out of private analytics", - "privacy.disableAnalytics.description": "enable if you don't want to be included in anonymous traffic stats. read more about this in about > privacy policy (tl;dr: nothing about you is ever stored or tracked, no cookies are used).", + "privacy.analytics": "anonymous traffic analytics", + "privacy.analytics.title": "don't contribute to analytics", + "privacy.analytics.description": "we use a self-hosted plausible instance for getting an approximate number of active cobalt users. no identifiable informaton about you is ever stored. all processed data is anonymized and aggregated.\n\nplausible does not use any cookies and is fully compliant with GDPR, CCPA, and PECR.", + "privacy.analytics.learnmore": "learn more about plausible's dedication to privacy.", "advanced.debug": "debug", "advanced.debug.title": "enable debug features", diff --git a/web/src/components/misc/OuterLink.svelte b/web/src/components/misc/OuterLink.svelte new file mode 100644 index 00000000..b8f97dc1 --- /dev/null +++ b/web/src/components/misc/OuterLink.svelte @@ -0,0 +1,7 @@ + + + + + diff --git a/web/src/routes/settings/general/privacy/+page.svelte b/web/src/routes/settings/general/privacy/+page.svelte index 1512ee04..c6f65a7f 100644 --- a/web/src/routes/settings/general/privacy/+page.svelte +++ b/web/src/routes/settings/general/privacy/+page.svelte @@ -3,13 +3,25 @@ import SettingsCategory from "$components/settings/SettingsCategory.svelte"; import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; + import OuterLink from "$components/misc/OuterLink.svelte"; - + - \ No newline at end of file +
+ + {$t("settings.privacy.analytics.learnmore")} + +
+
+ + From 5a630c2320b8d146efed3e88b38aec6dd858fb21 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 13 Jul 2024 20:37:38 +0000 Subject: [PATCH 179/775] web/migrate: set up migration from old settings format --- web/src/lib/settings/migrate.ts | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 web/src/lib/settings/migrate.ts diff --git a/web/src/lib/settings/migrate.ts b/web/src/lib/settings/migrate.ts new file mode 100644 index 00000000..64c9ae53 --- /dev/null +++ b/web/src/lib/settings/migrate.ts @@ -0,0 +1,115 @@ +import type { RecursivePartial } from "$lib/types/generic"; +import type { CobaltSettings } from "$lib/types/settings"; +import defaultSettings from "./defaults"; + +const oldSwitcherValues = { + theme: ['auto', 'light', 'dark'], + vCodec: ['h264', 'av1', 'vp9'], + vQuality: ['720', 'max', '2160', '1440', '1080', '480', '360', '240', '144'], + aFormat: ['mp3', 'best', 'ogg', 'wav', 'opus'], + filenamePattern: ['classic', 'pretty', 'basic', 'nerdy'] +} as const; + +const oldCheckboxes = [ + 'audioMode', + 'downloadPopup', + 'fullTikTokAudio', + 'muteAudio', + 'reduceTransparency', + 'disableAnimations', + 'disableMetadata', + 'twitterGif', + 'plausible_ignore', + 'ytDub', + 'tiktokH265' +] as const; + +type LegacySwitchers = keyof typeof oldSwitcherValues; +type LegacyCheckboxes = typeof oldCheckboxes[number]; + +const _get = (name: LegacyCheckboxes | LegacySwitchers) => { + const value = localStorage.getItem(name); + if (value !== null) { + return value; + } +} + +const getBool = (name: LegacyCheckboxes) => { + const value = _get(name); + + if (value !== undefined) { + return value === 'true'; + } +} + +const getLiteral = (name: T) => { + const value = _get(name); + if (value === undefined) { + return; + } + + const values = oldSwitcherValues[name] as readonly string[]; + if (values.includes(value)) { + type SwitcherOptions = typeof oldSwitcherValues[T][number]; + return value as SwitcherOptions; + } +} + +const getDownloadMode = () => { + if (getBool('muteAudio')) { + return 'mute'; + } + + if (getBool('audioMode')) { + return 'audio'; + } + + return 'auto'; +} + +const cleanup = () => { + for (const key of Object.keys(localStorage)) { + // plausible script needs this value, so we keep it if migrating + if (key !== 'plausible_ignore') { + localStorage.removeItem(key); + } + } +} + +export const migrateOldSettings = () => { + if (getLiteral('vCodec') === undefined) { + /* on the old frontend, preferences such as "vCodec" are set right + * when you open it. so, if this preference does not exist, we can + * assume that the user never used the old frontend, and abort the + * migration early. */ + return; + } + + const migrated: RecursivePartial = { + schemaVersion: defaultSettings.schemaVersion, + appearance: { + theme: getLiteral('theme'), + reduceTransparency: getBool('reduceTransparency'), + reduceMotion: getBool('disableAnimations'), + }, + privacy: { + disableAnalytics: getBool('plausible_ignore') + }, + save: { + youtubeVideoCodec: getLiteral('vCodec'), + videoQuality: getLiteral('vQuality'), + audioFormat: getLiteral('aFormat'), + downloadMode: getDownloadMode(), + filenameStyle: getLiteral('filenamePattern'), + tiktokFullAudio: getBool('fullTikTokAudio'), + tiktokH265: getBool('tiktokH265'), + downloadPopup: getBool('downloadPopup'), + disableMetadata: getBool('disableMetadata'), + twitterGif: getBool('twitterGif'), + youtubeDubBrowserLang: getBool('ytDub'), + } + }; + + cleanup(); + return migrated; +} From 436b735d2ab879257c779027a9acde5c97ed1724 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 13 Jul 2024 20:39:40 +0000 Subject: [PATCH 180/775] web/settings: try to migrate settings if new format is not used yet --- web/src/lib/state/settings.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/src/lib/state/settings.ts b/web/src/lib/state/settings.ts index 1b62b750..555c45a9 100644 --- a/web/src/lib/state/settings.ts +++ b/web/src/lib/state/settings.ts @@ -4,6 +4,7 @@ import { merge } from 'ts-deepmerge'; import type { RecursivePartial } from '../types/generic'; import type { CobaltSettings } from '../types/settings'; +import { migrateOldSettings } from '../settings/migrate'; import defaultSettings from '../settings/defaults'; type PartialSettings = RecursivePartial; @@ -43,6 +44,11 @@ const migrate = (settings: PartialSettingsWithSchema) => { const loadFromStorage = () => { const settings = localStorage.getItem('settings'); if (!settings) { + const migrated = migrateOldSettings(); + if (migrated) { + return writeToStorage(migrated); + } + return {}; } From 128ab388f3128f2b94fcaccf3f5c489188df66b5 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 14 Jul 2024 22:50:18 +0600 Subject: [PATCH 181/775] web: add env variable & plausible functionality --- web/src/lib/env.ts | 9 ++++++ web/src/routes/+layout.svelte | 10 +++++++ .../settings/general/privacy/+page.svelte | 29 ++++++++++--------- 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 web/src/lib/env.ts diff --git a/web/src/lib/env.ts b/web/src/lib/env.ts new file mode 100644 index 00000000..a5f08382 --- /dev/null +++ b/web/src/lib/env.ts @@ -0,0 +1,9 @@ +import { env } from "$env/dynamic/public"; + +const variables = { + HOST: env.PUBLIC_HOST, + PLAUSIBLE_HOST: env.PUBLIC_PLAUSIBLE_HOST, + PLAUSIBLE_ENABLED: env.PUBLIC_HOST && env.PUBLIC_PLAUSIBLE_HOST, +} + +export default variables; diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index e203f1de..20eeabbc 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -2,6 +2,7 @@ import "@fontsource/ibm-plex-mono/400.css"; import "@fontsource/ibm-plex-mono/500.css"; + import env from "$lib/env"; import settings from "$lib/state/settings"; import { device, app } from "$lib/device"; import { locale } from "$lib/i18n/translations"; @@ -23,6 +24,15 @@ {#if device.is.mobile} {/if} + + {#if env.PLAUSIBLE_ENABLED} + + {/if}
diff --git a/web/src/routes/settings/general/privacy/+page.svelte b/web/src/routes/settings/general/privacy/+page.svelte index c6f65a7f..00eacbca 100644 --- a/web/src/routes/settings/general/privacy/+page.svelte +++ b/web/src/routes/settings/general/privacy/+page.svelte @@ -1,4 +1,5 @@ - - -
- - {$t("settings.privacy.analytics.learnmore")} - -
-
+{#if env.PLAUSIBLE_ENABLED} + + +
+ + {$t("settings.privacy.analytics.learnmore")} + +
+
+{/if} diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 8ee30862..3ca087a1 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -2,7 +2,10 @@ import { killDialog } from "$lib/dialogs"; import type { DialogButton } from "$lib/types/dialog"; + import MeowbaltError from "$components/meowbalt/MeowbaltError.svelte"; + export let id: string; + export let meowbalt: string = ""; export let title: string = ""; export let bodyText: string = ""; export let bodySubText: string = ""; @@ -10,46 +13,227 @@ let dialogParent: HTMLDialogElement; + let closing = false; + const close = () => { if (dialogParent) { - dialogParent.close(); - killDialog(); + closing = true; + setTimeout(() => { + dialogParent.close(); + killDialog(); + }, 150) } - } + }; $: if (dialogParent) { dialogParent.showModal(); } - - - + + diff --git a/web/src/components/meowbalt/MeowbaltError.svelte b/web/src/components/meowbalt/MeowbaltError.svelte new file mode 100644 index 00000000..34ec570e --- /dev/null +++ b/web/src/components/meowbalt/MeowbaltError.svelte @@ -0,0 +1,19 @@ + + +{$t("a11y.meowbalt.error")} + + diff --git a/web/src/components/meowbalt/MeowbaltLoaf.svelte b/web/src/components/meowbalt/MeowbaltLoaf.svelte index 908b1ec8..3e8533e3 100644 --- a/web/src/components/meowbalt/MeowbaltLoaf.svelte +++ b/web/src/components/meowbalt/MeowbaltLoaf.svelte @@ -6,7 +6,6 @@ id="meowbalt-loaf" src="/meowbalt/smile.png" height="152" - width="141" alt={$t("a11y.meowbalt.smile")} /> diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 718a9041..5201b3bc 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -18,11 +18,13 @@ let defaultErrorPopup = { id: "save-error", type: "small", + meowbalt: "error", title: "", bodySubText: "", buttons: [{ text: $t("general.gotit"), color: "gray", + main: true, action: () => {}, }] } diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index b473acd1..20bea678 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -1,14 +1,16 @@ export type DialogButton = { text: string, color: string, + main: boolean, action: () => unknown | Promise } export type DialogInfo = { id: string, type: "small", + meowbalt: "error", title: string, bodyText: string, bodySubText: string, - buttons: DialogButton[] + buttons: DialogButton[], } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 01f025fe..4af2d963 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -66,10 +66,14 @@ --button: #f4f4f4; --button-hover: #e8e8e8; --button-hover-transparent: rgba(0, 0, 0, 0.06); - --button-stroke: rgba(0, 0, 0, 0.05); + --button-stroke: rgba(0, 0, 0, 0.06); --button-text: #282828; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --popup-bg: #f1f1f1; + --popup-backdrop: var(--primary); + --popup-stroke: rgba(0, 0, 0, 0.08); + --sidebar-bg: #000000; --sidebar-highlight: #ffffff; --sidebar-hover: rgba(255, 255, 255, 0.1); @@ -120,6 +124,10 @@ --button-text: #e1e1e1; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --popup-bg: #191919; + --popup-backdrop: var(--primary); + --popup-stroke: rgba(255, 255, 255, 0.08); + --sidebar-bg: #101010; --sidebar-highlight: #f2f2f2; @@ -319,15 +327,6 @@ font-size: 11px; } - :global(dialog) { - max-height: 100%; - max-width: 100%; - padding: var(--padding); - border-radius: var(--border-radius); - border: none; - pointer-events: all; - } - :global(.subtext) { font-size: 12.5px; font-weight: 500; diff --git a/web/static/meowbalt/checking.png b/web/static/meowbalt/checking.png new file mode 100644 index 0000000000000000000000000000000000000000..0d6a51c2bb32c9a246b79ebc13bb2753129af4dd GIT binary patch literal 15440 zcmWk#cQ72z7bnUQ7avWPKxIg7b{hgJTUFNk1|sey_xwxEq=T%OtC9>{TnJ@m z-qN&?0e^##Qx4En^-)#g=Hd)gRVvEuHkITKwuHwT7}tO7D{>1)SvsUz+E-T%m*g~+ z6}Hw_kN9aDwKPt@QF{JT>DlMn=?^KNti<@6>P8LuIU|g;UFBr#W%&Mc@Q$%}{@%J= z;O0KpLATzAq|?iqjPZ#X9@C8p7NRWa0e065P!Cf}&~m zUVaw#g8X8B9;j0Py+pcG$u?wqJt2PyiZoNuYgIi+b?eojbrey*Ob?RYPTXh-whtmbH6R9F3=xtc~^ zZl{TX4c{|9H|KC37V7+@L}zpRAUjQCIpu5}dxSBhw_`mg0+DWSW~^l-ApnVyl9m#e zO!0@uLX>N>sy=$ZRD&AC7(lZ4rR}T`xk@G(a;m6^gc4I%U+*9nJJ&25tu!%lEtqkH zlkUaEMLfc!lv`AUg&aD zSvLLx&yetodPOrW=qe+IKYw=k8>AnI=~rQZR5S@*FFZe5!XpI@Dtb<=yyTF7 z^HwSP1lklkn-sme{C4haaq5NpONk>)A4bdl?dh{y@i%Sc-w{`ymMu^74}I3lzSP~f zUb6WEQHirG)VH$-p}fq0x8dUv2!7-sN=Ey|%af6BkLhroWuhaLp*8L&s0#?|&BA{a zXhbDn-6STGtU7b4$~uk!8q!mEMtNu}(_VGg{0dQUR%h4PApgjg^+lg;bU)@1=+EGl zhNT=%F*PF#38EPioxg#%o-N+4v{hWwvo#U?&48JOfzb!d4GzP?dei~AmAQE!Utgzh z{1X#@*lQv_kbh%suy*-KfPyIih(W$OPT$geE}FCg!!VG^wIy9(0{T07J}RQPs>g7i z3Y~NA;~_=Yvtg?W&a9?yuzn^J0O^9?PG2+|qKnB9MD*reRI0IeTl zQ5bKa98`IU>zl<*0st5EL+(mg96BTku8v7$2Od5JU-xkWE69Ky^@;15MaNVuU}$(n zqLV5pX}xeykOAZv`7`Kutd^wKZrp@#b^;^%4$HGifi{#S4eKbzQ~xzS3R442oY^{q zeL$?>_Z~S?6eMT0Og;)xn6jm)?Bxy0ZQBIcRl7J^8KOivJb^m}nPj=IISge4`fe$* zXQD*LEIg{oE6(Tlb|bt{#YH%Y>)47zoHL%STIDYg;V;t6k*AQKGOviya!p!4jejAe zAXdyPV!%)_pBT)$s}t+zZ&@GX3I8>pE*lb)x)ES*(zu93pmI2 zuj!qsAMOrv08K#(^uXAyFn-OXhBJZ>3jjLu3mlwNWtT|h=7OeFp}M_@{|X91gk15ka;D#n%*^{K)iuz7h(@$EXSh)bwP%P z4|sa3QO@jX5S-x88GgGdNS-)HLc6-IOye9#w~*H(txa2**LozjEL!zn3)%d!6B*=> z9CfV||ITO=B;hdm?^&e4^yBssz2~8MfHfUQHduG^-!e^b_cE(1{?@vGOieJ+i-PdbBo4HiPl=|S%+Y=BH)QMapcCd^{|6M3f%pd2Z8o66Pa1&fe^!H-RF z=}jC{M!)Ork>ca+u6vKkE|VA6Qg1Cx22n?87;D(X%=LhyE;C&d7aAiB}E%OP!TvblF+H3fL7V%wH=$(oHg;4%2Hixt^N+Z*Ax zr!0bF<#`dmrn@9{Ql$*)j%1kqd(i?PLFn=m=OwqfxwX}N-9KnEMZlGwxLDPZX)7Bz zX3taXBnaU?cX)jFb8n>&77Zxw8RH-VQ1;yv%pxgzluedGtP+$ZeYXOF-+f#7;6S_Q zk8=WL_qaJ8ivncy7N6eF+&IGQm#pP%P7vC^3Y0(z-yI?r%FBTk)W9>+&wdZ1NKw+B z#DT5L9Y?V#92x{pos7TSOk8VFjwaXu%3Il^e=0A+?JZ>Yu|A<^dy3O0~ z9N6rfq1wLOJAaJdLP`ZEPa2H5)FD1KW+~;}N$s^li zDnTc)3c6gNxDpA`}(F<`UnJ+gVlMDm;9&ITBc?!l8u;ZSpt#O1Gi8nm<3 zr)<|+rH1_Usku6Qo#mFv1C9AA&3T${xA^49;pZqUcRvXYz|4SwiM#_N97Iy|;2hcE zQw`?bPZffWH02{R8Nicftki{URiE;IiRo!fP6}U0(W=dutuv`g#5DANC#y;n=#Nx? zS}J;$^re}37Z<`RnJ|5|yE!`d=b>RW^##BP@4mt!UC1TLvmqqmY#l$CNu{GF0^1!e zo8R#j>3w7aop_=F2vJZB5}$qqd=D-X2h&W}rFc0Awc-4wz|OaS4LU!4N21Dq`6(|^ zX66S54Y)?-RXzeb%Y=j1Hv(u}@mKgS&DL%MH@Zt2(&=6-`^j-b7`M0BbTD+M2dhbF zlsL#9+`p?epjCO9y!QQi^cMzwfBZBmu_J?fXtS6cDMjiIxsDElSCIk_^0{RoHJ>z# z8Ac?&nJ#7^_5Jx>&csaKlPyNrBb}&02sS{JH1!<+ zc2rLdo*AM-kB++gmYg|Jl)QR!yXE*H1Tsd?O~$G+H|t9T+<%{_L_}!V?=crWx739q z%vt$dRNVf4-YXP!G5kzsz(d<-je$Qu(PB$Py7EoV2XTcT&|widT<|gr!fd!o*!@2( zPHiSR#;sDVtZD*KXT(Pepu489!VXbL(Xt%-qg2?bKs8%1sC5AqH5^t=l7`(WFG+Aw?%@8z>5CzcZ5 zAV0P0Jr$b&?G2hze{p`hEVo|A7X>g)4&##xtR@5NJ&Y8KLOKb!%G}wS==0<-?_-C) z08c2G1=Gt=*JE72DQ#@J_D&@(BfZw~9FA)u1C3hkwQm>RxM4%>C-mtcW5VYH4GxPR zJ}$Ej+SELfia!H?b`FAU#?b~rZSsG(ZwhTI-MYT@e$wTjGp6zGL&4v(3MTMm6p10z zMViG*Wd;fW07WZ%hp|X-v9}`@Gp|H0N6)5CcfG;`W8{3y*JcTF6(BA%+o_7M<1>Zb z35mf03ZED>jrr-qe@a7LOFG^mHUS|}G6nVGw4g|(7OS_Z4rK;N^^k$5#TV5p5`qlK z>F*x4HC-jNGYf+t17Wj;`^!#gCCKS>uHVHX>x!YhlOoNi%HpTuS;JA1etzwA*ovQs z^3*7R-!@Ww8W-rnRv)HS0C#bUPyJXxBaJGH+tVpKv0HO;&7;nFjhx?=3Ft1gLf);O zT+2VMgf$YJzoP;YL%07!1wp3Wnw^Ao$hbPzQv1}#7gJoGqsskHLo2^6$;&WuK=Gy2 zf+eOrUhG>R)vP2XVAkaGQo~^a<#Z0?`iI@BI!Gc!3?n0>=Gxl*Eox{0NwC#g-dFnA z?+o-+n|ob9Uf<*WM2y@ckOY1vl1H+wuAL(a)r%MzbpAN&dvz;?UC-)_W<*Oom+RdZ zmGFLddIFSBA71XL98``NERDtZubwn6g<c4Ejyp+0p*|Z@kI)8|-WL-XNV!FhyQazyJlWAlBw;1xN+7;c2 zzF8FZ7Z0J_uLag8@}ODP=Gu97Yhlw1O5WDJkef1I7g)k~VrfyJ6_Q&)bOa)kDi$NK z^Gh>{F!lLxaXvWz=Z^K*E^vp7{P<&VbB0uK+6f!Z7oGSZ~L_3bz4PT?hN{~Z2!oCil zzf_@9jD(XQ|duF>^yaXgh)9ixqV`#<{+b1523kTo=ctZj6`v4G;Ko9V!OyC~p zs7KtCe-Vf1V!)A)`pHY}1@>#Rj+U#|yFqLywFYWAhua1d0dN2xQIX=u?}q|t1Rd7d zCO3RJ7KE$Bs~Nxav1h>wB5`Fp)&8mk%8v91I*}kdp}!?m=yQ%KvtixSG(!%yV3yC) zx%FpycSX}fC)oyLkN$ar9njHjB`KI;1-8es`j=ssO)bOxW8;EPXEdSxMYo(L?YQSF z5GmR+&38VVkm4nksuU5fK`jl{Rh}Ny4}QJ76J@cE%j@tZt+&HzXQOM-N+YH>0$*x6 z8}E96a}a_rx z6o%KGPV+lwbc5oBq0wIn>A~;c$}dOwqdG#@MYC3xtu1e`J@5LrR0JtxEu>iA%WH+W zCig2#9=uu&J2Lw8h7A`T$098C=|sz%tif#}tC3>jOxlHZpRXXSOPo~X^i?iU6B^sp zj(05_1@M;irKLsenMPgvJ;qA8$P{pN7jL{kN+}Sg6{5@*eYvLs{j~VH7UI5`U=<4; zEa9tajp5sPh}!Kf?_F?j^Z+KqiN#k_C+@vnx0;exaD!gf7QmDCSNAQ@bf%mD&4I$J zq6FEwCX3l<749e~8%DK#+o2H!^6fiG7&wU($8$;bj-=fJI&WeN&$zf)IIgNUzVgb0 zkP65fHxD$FpSzd-lz7FgWTfZdx6t~8hq~so{GGR-2^i?Rm0c@=WYwkDCux=T*$%tO zuaT^0tWeEItfdC)=Qv_OeGWUX*zsS`4ciC`tIp^jrdU7Lre!NLsn375)7JH2;@j_> z4IZ!x{cN%86r=FUPVB2})N|GMl??Ss^vrEs&s+uG6~R^btt)tE9}4CZK2RfZNTXqk z?<9iYp8h|tcE+YQ!Rc$PTpONJP3o`9Y*O80s(~V%opLF%@_4{5$V;~|V9^#Ew(FBJ z31k48lr1VqVS*h2P9ctQa>nW2(B^lH15}C*5F1Ck3FVsuVd;PiOK(>!8!A+zG`;8*tM-cd)9Yo6SFgs<2l30-~5IU zwDdQ~=Q$1@wY_-H(gzg^QV5Wp&)1oHI4)Rxv0W|}bxyoD8=wg#M2I7|*H!e_z<2U; zGv*VS1k8Ws4f-}GuqwN3l9xBzspTq#0^CF-I#XreN~!l>!Ms>6iS#{e5oQ5hgv)pc zC%lJ9jKI7apat;p&7j=4-q&0G$!c#lY0S?fZnfD9|XFG zL)Td(EVmovLIG|mPrT5Qm<%dE z<881|+qT-Uc**-Wo3!(=kF*Ar9_d&kQNW$;zf>lq=%4+Or+BFV>&`D|YYf(B`3~pK z)>fOvxZQXBzVom(CIk;z&#~Rh@!|n>1;IR4DyIc*UJMxl2;DBZlZpYk0SJZVre`yt z?2Rf^c;A*+9})H%L5jvcSU0f8ycU>}e#9wq!h#A@nL1yGJ9@SWxBlHJUefj1LGmCM zUKpPq+{_h$ij>th9?2Ata_@x#8ti{A60&^xVh>g$8(dy=aW-~7>!kSI<4OqT;Qx+w z-OO-jsq@oAinO`^dU+P`*_w$3twxL<2tXj-y$jhNz1GD858Vjb-y#P3l_NRetkPrB zq79P>CnxF2_Tz5-5+cEcuJ17@wI$8-Ms_fLEn3jzTY*Q{k=7jkkQH)J0f1;KF5f%; z^15yHOdY}9!YpE|ug8D8n&WN~54fh|-FGy(jK!=Wl6_3B@<$_bNz)4B9%mNT)eTe& zr=ZPU0=At+H5rsQ6? z%@v8g5j!l4Jl6kJ?>%Gw92{#d7V;YvU>b)aJ*POMcmk9O9K%+2DV%g+=ZVT+fjjYb zlSy!sOuqC#BEfxPhb$acDpL&At}RvcG~l70ByEouAyNp%*im=&T@=V(VI>^5n>EkY z|5PzFNnRg!?Io1Bo0L&ZVg zd<6F#BvFn|bYUJGoT{Q*V{7~U>(!h6N7Wh?O7MQx?f|*R;h>_pSyhO7jF9+e;CU^i+HJby zMwi6!JT4SoggV8(WP-Vd1-i;*bsR&4YG~d_O(2=&L1Z(NY%D;`IUy?1js)vr|KSlx zE6Q@|nPl2%-2jznkE}&lbY0!x%=C1;9GMWKbwFkwk>WiE#W-|jsp8$9%dqhe<0GVA zHZFi_n$LSHS$q*Jc2x}+Bxpw6IsFq3rg-S|W+MyA!OxuLvp=@+s!qaZk9wny6k=6L z{jYq3S_gY1s=*Dty}jf12;ync06Jeu@oq&5^M-}{cnED z`0b0K;~`YH)C_?4pkT`0v%hT? z-hb6m2mcYTPRxB3&$rS_BtOEumGx=$p4plxpoUPt0&nvBuADjLK;RzZUEWgZde=wN z&nM~{m>GzddDG=8(=btPQ$&Ih)oR5g9-#@QpXh{MerTg7{a5LgA&tZ;{G6zmvzht2 z&mb_L=++^M%A2>d5pRoJpZsd`p(6-v@xX#!tY}BXbgbf@W(A#)+K(TIesuYj*wFUi z9sF4{|5>?#xlRmLSac8B^>`0S5Q!haDgZyB)Xc|JK ztJ$DO$*OeZ@Bh5a+q;f2Ap}AnpkT%3+Ha!W5DAOmS>B<=)WNWp)dl27FE#y<`Axaj zkW*E$1CJzk3R{(3&*R1CPm-FD?tsG^>swp&sApxh05kciT(gfDl0LPP(vHN(trZb4 zUH%i=<_Ix)z`*-b(uEWi*7`W;FP>OX5z7kY)!e;pq8=hSKacZvB{EDCTdE-+o@ZZ% zFSQ=CDv4?m4ke6SjE%kVE9jXG*>4VvkC;j||FNn?jv>apuk}03TWOhAw|ILc75vpm zM(*Uiaye*b2zTyj2%y%z>iv63kL3g0EOBt(12?3kbzp7hAoY{w5KCsQMdv2 zvRTi=UemQ1ES#wqRv^%m2VWdrCuVHA@q+J4Z2v3MshBa4zv$XAK*#WP$v$}CQPR}C z$_aV1DH6Cv?7?cwvR?PHE;*#2$%i}ueh(rC!@2pFz>FRkLISWeM~1d?rK_1R4pB2_lR{Yf{eojFXQdxDQ4q?J6#G|fzs zEo!wiwSa1*_z;h!w_THKs|^{Lx`{Zm?7gbAQJrPE<`j!CI&0;GY1@fpshbwZ*|@V9<;^$%Ro8{L*tP5n(!m>g<2m|$M0$nI={pW0fUFI( zu`p$3%J~urqm|_7;YK+@d}~TmVcYAE7OGP-?-jH*ZZ9^MkB0rRNC~lXR_evjk!ARU z1YoQ#wL$qpQv|3&GnIEL)5ivWgcjc@Eys|t!LgLGq62D%MZ<=7r6$u4he+{Btwk$a z7oSTDu0{xW5^AJrxz^jC(Y?{rf6=`;d^>k8=h#dV9 z%t&Zj09P7!#y~v+^ZWPV92GiDPhDF$>jam@zHGzCZNrV0NtFcQF>$5d-w79vE!Z+b zr_m#%sp3}KgRbWn6bhDJxK4;$+uZs7=ke%U*O%p)OQ-bduWo2oSNy&+1t3e4wvJ8$ z75?KX?{T)}9%-?y5-(ix6ky$p5v_o#NG@iBmwoUvf zpZ&B41p38M14Da?8urlF>mcWdPAWbUiRE#&=mKQi z`Zz9$w3?5ZcXhdZQ={E)T=>1hOlvTzug`x3u8jG}Frqvj=8vS|6$&-eRtV)7X_L!m zX6ltA<=~#2QFG; zeafCDqeAWK*}ws{z!#tQvwxKdsF6xY$!I=$1g^`3Iw;^Z$)0p6I+uK?|LE zTz<1sr28lcrQLpHXvpNxMY40y^4n^8>r7OE&j2VwhYCcNzQLAzB$y;;1@0>z z(9<|OOAp=(VcEnCzi$yC2c~8?l< zrX~;)K=2VUDcjEslPX$~`^W*A?~r=dFw|UcPa6TmtVYKXK-j6wjAKZBg$q7)_=yV+ zP||Wz?C3B*t5}r#FFBz!fA0?;1$7coQ^jMdv*7gu4OzGs;E_#Cgj zE*_&P`fO;JvDN%kUCVgp^`+^NuwA^*PTwjERUDOSV_b%AD-57I43Xorv>BB z?~Skg8J8F+kkl(hUhm6d1h%p;qi^|MA>;#)1v{^ipDxOB|LGYct;wIvt-~_sq+GkI zwVKU`i%+5q0)~|k0UrV8p9z*0s4ivdM$y_VBu{mQNi-LOzvxDR$Dm&rrl2lrgc?!{ z{AxMQCI-Z2(X+^p2d{60!Ng}-%p>0YnjWgk!w|Yw&Z(si&knBQj7&+2nql=AWP2Q9m0T3kvyxgB+OLxx1Wp zTfNta<)V8hoV@<-E&^$E`$=Lp+)7S+`UT)FC>Hlx-GhZ{h_itU!u{p;WmA=9fHMDH z55Oslt_23E=|mkHSk++s=QXlk=LBdYCWm*9LXohRmA8^)Q-tJ6q zmTbVm_q~twS6``bwZNYlX0bDiI6lX{I?~+*0N&)EKImvc<&Sy~9s7-=a>muhHtU|~ zqaGT{pqP1fs8f6A!XP5?Zi@&u6OQ`iI!Cm(PR`OKbrPm4>`n%r$0$gwB_H$C#+|I- z>6RO+(Y1mrlT*9pxOuGhzg3dzK`j=^jl7#(Z@5j!?k*mliTdzq99| zDm)MfA5IEpuPxSFk3S!Ru*a$EnNp!0-wAE6(bu&9jGFxkUO!82^A6Mz zCEr3KLhDDB%lfp;{v+h8XI4K{@y@j>7LfqOSq)l#dOoDYX#cHNLuZ+Broypd#@K+e ziW#dn5fX79F*maj0PH9$7VM%CSS;|3d?w|4$Jzr>s~ONA~MN zw~S@}7&WWuYR)&y27LWR1NwHswMU&$0^hoPK=!W0Ch)Qf1HX<5=7GpO4fHadcgXqZ?Kg=IZTYoVso(Yaac1q&p_D=q|+I|xNLxSGaf5Q8~E&8UVq zx80PQb|Xn*O=r&#JP;`kRAA(B;q&V*xLv)J*txI$Dh|HRi~AtsE!(`|3Z2i7Wvcoj zsw2r!7Z-Rrl5UI39+5jwb7u4neiuvX{PW-XO~CZPqg{b~K4}h^uM4pZ(BGHJ;!Z`z z6?ybuuIIpU%hlju<=&~I?j=6^Sa;wPEBh>&uF~_-^XpTJP#nPSnbRVXpnRK$ z$dbbqw}}A42(i6QZ)7TA`3P8Tk66pj(W?d4g1i_#)JTdwRci1@S(asG|VF zzD)Pl?|XO`kfgUh`uN!4oB|?4ELdAuRpxO0$}U2t6dl-XRW}cPJ@Rh(iA>cY+xOz? z(w(5CE+Z-GN9e2D!QPQ&tCtAx-RG3M1~f<`9aM`ui3N|?L|tuJ-e^jYo>ZIP=aN_! zr=@54rZ-M@ga`Yt?t{M>=@?H?%Z$^K;DxU%=Z;|@c4I#4VM=#u)dDqTY%J5%;M|t? z@8|rxwzz$zLWZKQw1xArFq^tv+$J7mcD@TwiW=utN$`RK-?b&dl8L~c6bcrv!aLB+j0=`TwGi$qRz9XPOl?i16yZe zp`Qe3`sK{#XuaFo9@a(lW`}cbb0pnEyyNw)vFrEpgD@^o<2Qgmpy+I~plZy@P{@Pl zxj#viSZ0^9C@_WWqZEdGsdl-kQ}VfAVihb->;xa^3A|Akc|-&0k4&`sZ~YOtH~mFW zOnV$`^zVmv)aZW_=#NkqG+*Xe@`?Pf^2q#}0g24vshWzF_cr*7>D+o8N8@OsgmTML z{3#*M&sg8LrR@3C<6>V4HgJ-e9U1L^K@<06qSxxrV&faUd==VybtJ#Q;b(>g13u7Y zmva47wD(7f=a+6dBwvSB>$bg4Z|zcr&~xU?3g>=tkWZk{VgRxlxWHSx;%Sm4sypqk^+V`(qc5))Yzn48!ULX~|vYzB~+;jO-#a{8{ zn$yNx8|3|CI;2_k@DMInq7UhN|D(StI^#-R*F+yJAo)6gpU5?o&86j0?)8|Hh=W*D@Z`;ek~sOOBLCg4o5F5 z1Myl=zY^6`=VU`15#vOH>Jw~dT=Vo_lRV9$qvxw@MtXicAtcW`403@Vh))o3SyqByq^8VM!@K|)}tVB_rfJ9K>K^x%*Bii4`^24)k_J*+>pt zCZlWzo=HxO9kfG{NhcD4mT$b(M(`wL*g@N1*QX!U<&jM*T>qLSJSU2-Y}ZcIGHIkz z0o2TMjW2c;0|iT7m&HB?!WW9haT4=;dX@niBL$^28qT1z^)xFJAGbR4w~;Q*34S=L zoQo5b=Bw1l>f~1oEb|&V5ks>4iad1|6yLN75|JbXKJa&0wB$A~D*H%Ix~5Vm?lp8+ z_WI<8l2u2xlyc8*a!y~}njal1!J-0%%}Ec55G)G?BgGty32H?;2sf_hm-8&HejDHf zlN-HVMc4PIF-!X`__=N(@6fY&PlQv5Uz;^L!NJy3m)hK7DV=io=r@GS(RshA!GCXW zvRMc~mp(uP0|p3Y;tfOmk)c+G(-VZc$3~E)sGIyiG;0e_{P(S?RswNfJr>K|_{NEk zjc>rRLG}jOwb7ysx#fFBFSQHiZr^;Vx7QEC-uYh(KZF&pRX#qgcnVfRDNAq+PYXqN zc+3G;DZAu4dn9En=sQTjRyQ0y_0>Z&Yp~qdumNf?5fuZU{>)K%nACG ziCp;c)#0R`l{8e2ovNDxWf8G*({I%ZFPmzc%(SL82l|IXiNeh&{3fI1hpx327Z;xi ze$o|p|F7`N!OxA`_S6r(p+iJLnZP%JGo$W-o9O9xHJt_Cyw0_`vn-VQ1mwCM&0)vksHku_ABqj zuc)TPqQ*w_RsL!RPGAz$iF@PN+t+JqaHirZlaNiKVTCf6KYozJdVKOk@Ef2QhKN`#ZEY1iJ2NJ`-=vMPAc zx4O_ryXoNo(_Sk}8;_F-FQP2e&I@Tjk|)yw7OWJ8N30ZQG0wVuCSA~C0< z!k|s*7H!gn)rh|(Xf^pB9Y8TkcT&r*3RUBfJ`G*Z}vsaJ)WbWjMK7xvC zs4^=kAqtx5d8AHR(KT{+)v!p+P&!)@CP~i8;m<|8TmzSvD`-L_Cr>8=J#sMQV<~Me zAG4^Wtw;XUah=2?{M4{MMk_1BCzuSNSPmW6oeE+k(J$p&4E$Hwl6%XoCl)u=@^$hKmE|C)3F&uQG4`Ae7~&kxC$(YG8(?I(=$KNykr&u~HBz`ZI0*woEV-`zs> zSufjs1c7ooPLf3|FD|R7AwAsu#gOL39YK1OSWn1xspg59Dvg8G-<_bE5G5tdxJE?X z>p#AI*YIya{-I=EsIWShpZ%$K#P5lD1c}AV+crh}Xv&X&g_6@^3vqyv*0!X-oFsGL z4QFe**N0Cdkp)i^*nqXRMtvAOgpsxKxwxvo*S3>E`i|5>1Tl`vdL^|a=-VO>a$WhT zTk&gToCvvp^RW!9q+`u3`i_{jUoqT+%gJj(ulB$O8woDYjWjlVRgAv`nOq3qKw)qA*kC zk$@Bpyu^M~xS}g-<8a)LS78w6@S9duS1DZ3z}{FjIZfuOS@f_Ky)B2u@Kta(JDLrW z=kr3dVq{bjYGj>Hj!iCF43D~^`f(UgkVxeMWYB z7ZEpRuW#0hN+&sp4V@X9V1$+8i{y>P%_F=;Jwrc|Ag-7T*Cnyh6at^|1c}D!yCA=` zgs}Yhj7c=NN~uHh^}G-C{7*z7Zy6dej@61wobB;(>v^YCZsc*|nA;=eGrusHvdpDq)-R^@av{a|}OCq7lU z;GgC%8nxD77Wd1L&tozOpG5qG(c+JXFdqXUo-NfU6l-e8%b>ChjaWtjLG<-j*d2lD zR&^mD6y@18jcMyHpr{O&=>E7Tb}Pl})*uBTpO(lw6J&ZX$x-RAu;%l;)Y#*ryD+*T zt$ZsMP*$Z~nvgch3QTx`J7PF@>9g|nsc|Jw0;q4J3;H`o$rn-viI<@7OrkK=OlTdPUEGc@=dC_is4L}{^gHLF3>7B4!7K+3$iG%tZOM_3)p;$u zW{;(jDDaB%8LuBGQy^Qt$Hw3ev9SW|C>imQf^3RADT*O$fuBph|DzlyV_wjKg~C$2 zX3yHVI7B}*j%;>8Pp;WAW)(GVHc$T;T_qbC^vn1rt6HySD&No7qf32y{l|y>&*p2; zsy@BJQtpF}t*)~eFPTlK;Ai`Js0otBLc}pl%kl@{*BW5th@+**)dxA)8tgiTVf6Wp zeZ}&w!bw)B zgi43*_gs2@Fw+2)0cq)9%h1cLLiXV<|4`B;cn1*#Wgw}_;&(C*kDU9>VGiKa3q=+< zE&_`kCLtMtQXlPaq|tFF^)SB*<_RV}q!74&{>RFnEonEIdI&X+p(fX6>0hNB_+tTR z21*mQqUFd{Sg7{4oE5I53WBqk03<4b#RPYuO!J+pEO;t2&5`7L@QUvWxcW~3H9+^N zSE2J#`y6(|;&l`~(G8OVL%7C8!JGs|yPf|X5}cE1HvlIhm0G3t;TJdh1~GE~{RNey zkt{{#kr#ma35=#cFMIDX(~^yF65dZ8sERv{=s0@$EX*rTPuu_Ony0<_R%su;fDwz@ z7Yt&%@btc>O<=WyPn*tb9>AC0{`DbfeBaC45SGP9=!O1u42>^g8U1|w^rCLZiM(vI z`Oovc&-YU>LYC;HMmB+t$uwX*>iS6Z7`UVWIw(eFn<}M zxE*^BcVnSnv8B3e?vCL{o#Gwv9#6L=aJ>2u0i|M*|Bte>`@;4!gUWp!?1m^&k%hty zESi~#mFh6xkARj1<6M5V_dgqoYjYwBj{L{jhqrtm2cTK3Sypp?l9o`T6ArehHCgzD zwhnq;Hr_$ZUe;Xc#{q`5GErN_L07N*J%cVXt0BNL^yeVz&jJ@4zxMBW@*vQ2PV{q@ z8UNpney|qe9tCPux%)K`UzMe*fWc7~Poe0RcT?v~jsjGeB?3Yi%=x*P`rNY;ZT1ux z{Nc72p4v(tY;^+XKsy}$qQ6dVAP-&^WpO@C!gxUYqqeJiGBYQFm}8%LGw*H69}$+CxZ8>mSj6po7Fy!G?#yHH6*Qzp@HFF(e25j@ zzukHM=f8S_e$)9QrP5J{?7%sPV)FBea&mvf`>h<*6v*MX2n+P6X6KxT+2XpD`el+g z6g5+cc&G#K1ajiHMZa?K65_$ zYBKs{cS*gib}$O@Ur7Yj5QJi;pi~hF`5|fj_Wq)1LisbqgKzS@Y^BB6atwh#z!FG06t2>)`Sdi^Mp5apH$uHV!B15s0Ezknn zRT37f^dKWgChh!si?6fSRB8yiR(cTG*ZADFK;Tw#S$ixGirTSmY)dbb?37hAVyw4> zeqOlzVg)_t^Sitwwyil924#))72^!U~cZAmiy<5007 zLo%Z&Iyk%LDiJVy9?SWdvkBQ4;^Q=N4HD7EZV6U_=s%6sci9ABCldY8z5!T`^2Or` z#kr=UtcaRMByBHTmVWy*?lQ-0Bz5H25iLb6f7IN|6Sq90mSrZ|_aWKwb>5#?@Kzi! z;4Lrsb@m#d7Y~%b`oT?2j{ppw)4?y6DAn_GqQfsiuY#?X6H{nFPXXvj{P+neo(c|Puo4YrX2q3 z_=ybYqfoIGH{2=Ww3?{pxSQ(^%=MFDeo_Yzs|wQF-QX880z)-d7qdAA$SV}Bra)2> zTI|DC>r0?CUq_8rez3ITFB9OJM522YnNI3rCT;`Xn8YKj0FddUmz%NzAVH z`M)F8j+#G5{>ux_^KFf;z}*j%jckdPYk1RsYfN9V*;+LZ!aEDP9xj~j)4#Ju0i+;O z-)>h-S(F3cx8v%+qkAD;T2^~m*pT@-ME%#66I2l+v^FNRaQulU`aO=VbI6s&(ep&C zdsZ(8T+mgcc{jY{YmA9H!v{w^POzd+e?QBEbKDJMo4P-LB@srb)$ zPke_AW}@!>7C*U66=7N7_V8pDkmLxq@4;HEj&z*jvwUwMBoKo1tWC#pvPMm-{l5B! z9F<^UIDg%!X|a&1nx^9e+-&i)scE^K_KF#SdgTih-5I~+gQ z<_SxJIGK2@{oNJMS*l>aI$11B54Z!zSdk9*dm_gQMqV55D^Kchhf00G=o(L1{ulK0 zAigc|>vlFipi2#0r ziV>gCDdEJoYHzx#K%=-xlM0aDcqKVCe)og4*Y5;sioRvHF@gCf(^S66JpRSW6V&*X z^h6LLKuvN7g|ph;VSjQ@DeN#KG#M}6?fS(|B6sWicG8t}aJ?{D0XP#b2ojY?x{x}I z7s7Ho7f0G+g}O#;=J>QUqdOYw_=#tQ2-9j}vW&F^AY0#JVi~ED8P7mQvQIxXxsDqI zmlZWqx^ex;TwG-i!X>hUR*q*2%BK8cBH&yceKHtFh5f?B;F9;!V{Prk2&`aQ3dQ?K zRA@ltWRqk7&t0&?@!RP%bL3^l!bp^ViaAzG#D;dzC7+f>^J)vzFun?iVEMsoYBQ%0 zFVKvWO)dKV&>d|W6yg3uP5=Rf-HC`ou%iXRZo&3LYXE=2?v-u zv}RezctJ&k1O~VN)|lU+t5ATnjKnTM3ru)nOrj;)u|deW_(v#z-iZ_IzoEa0irc4* zSj2we;<1-+It6@oXZ!%2PJD(7$O9h~Jec=-2C{-loFcUT^Qi32a~zVajMDK|yq6%~ z;@Vo-H3S+ND~%{o|5mcSDKhZ7d`P-rKGMQ6j{V)S>WqF)*u;n&MT>48Fg+IoE;!!2 zLX)`*zK9TWT>>t4ox;PvQhwXuhUhBl>B<4|WVKptu zUxk|euC_Fq|44Ju1&6C#f}{+>TU95T#!6#4yhfQzjIRt&5f<@rJ? zq_}rRnT--zOFSts*zIaub*Y>YxOzXE^&5E0#FRFjq_N^$DXLoTIj)5k6Fnj{` zxM3V;tg_K=)BDj+>J=ukAH?K`*s5Q35kz9qUbx=`P**(PuG7vFM|o=Jot21*F0tha zD5UPYf!Of4`iJ6-TcC~AddJj>q-A(1_C1v9`t18mBz9|E4v%e(-G|v7*bZM)@j^hh zhlG}=9iK%HbG7V{)jKV|CS^>qaWiF1hLKQuhnGrqQ!m(}Wf7sH#slmfvjkQ%AO zs``3B{{xwK9m-1yvmyu~cJPx&l#}SQpUBdC2{uZQs0tSjqH0mSr2Hyz4f&6ZhEWSw zjZ3YzWY{>%#FcFde8wbQ@*ci8CgqT z8O76(X^q>?b??4MSV+w?474c6bXVeS-$%!^xgDP}a#GAs;y2^Ga03r_gt(uw9K9te zlU^JRyA~ODW$72=m*nRYdBl$7cs|ccf{9R{sz)3p(!}#NTMXy&wHp2m=qdJYjSj+< z{WI^BlZisUO69Izfs~rmDtj%qG}o#=kZ59Xz_U1qoyS)Nm>W||Y?ko%V{R&%J_7ds ze#1>5JrYgMl5&^zW>k!9;LF_ft;)Z^Ys${UM(jcVle~fB&jLXanth7$X+J5fT=xa2 z1RU*+K;dnuD7m*1x5YogGQP? z1{43$k~9}ZV>JK1`=;&%-O9ai=5)ywk2!GUU;+~AV z9(!4MeMW+mG*BF&`kTVR`CNWL`^m?!Ox9LB8|_Rt{xZk9b^<34z2w!M1!h>9>St{_ z{O8NEVV-ml@rW^{O!7hRKD@o3W;A8!`G|umQhU~QsOF~x+#-Rpe~#W-HXQeK8|fEw zHUO?Wa$kRSCZa5MRT9<}6SS#BFEZDiepE`!>KXm4>a3I8JKx!m9QW^)xn@l5e{5Cr zrRzCMB9ktzNp@>XT!NX)_GUZq{7|L^Z6{jN(0&Zo#bE#Duc%T}GZdT1sD2FaxM{vbJ^dA6$M6&p zfFU82O|Z?@CdCwg46sC>=fVmTD_FWwl^Q{}8PV_VH`&mUw&k9|7~X7k+dCQ~INVz( zr34+eFVB!j?l-gU3;5y|)7ivlV8`(2Dy*$seXsu!<@(7smyJHVy`VxeaF$g1dwF{8 zxMmYSYiXdEbG-X;qu8!b2d_`0w<|fBjHRA60A75%TbUIPYZd>Ldg+7v%Rxg1?y_3* z`pa4LXV;Ygv-8az*DikG%rEE8qfBBmv=2E?RxW&V0lj3X-txrR(TEPxrx|65^l3vN zvwi0=5OW1~5zWaT>fRw8h_%!jVd#*eOu(mRyM-qh@P_Zn%Ea( zZeHZBb&0(wJ|uYc)z~(MrSPlhRBw|rve&)xX2mWKJNkDY^**nSUYrTHw}CM}tJiPG z=xY>(B3=4$Y_IOlK~((HJ~T?8x?aa(B!Ume?wz~{WQif?=3p5^Xo)#8_X7D5V`_Ls=Y4l)yr zby+d`j-%rsd7uNNIUSI1ND%feEdg75CNP$)x{Xfvy7Zx@ zkd-$VkrBobcHY@<$~FR-=rP+mz+nW%X|CQ>b;FTNgA=V8_1q>GjocGX)m?+^S+(&N z4(P<$(bl)1N_6V3{O?IWDgTCt7<*$34n=QOHgc;gFOK4brTsglvP@nPCDi8L683<| zn{mGKDr>xG=|?|SU*G+ycLn|`Vm0UL`GdGzw0h$jFZ?R6_z$GnDfR}OU2>ZgakUG& zHo7Vxdm4TX5a)S>d`9*vP}q;EeR`uN5g)qJpEMNuS^-7B!U30d0De<7c#bnX`2*hm z6V2lR*4}gh<-z;0c0b7*u1bdWU>&P$W}4G#+-hKxM@tIF>`N=~X=@N6uKa!e$|Z$6 z)j$z;5V83x>W$D8ZteVM?z5cf>OLKPVo2R8;5i77Vep9jj6!2zAmp zOmN+2mMAl6JWMVx1rLtT7QEr`CD*v+Z}{WiUn!ZjDQ;hF;w1H{(UWmeUlVQyY+w_E zU$qu9c5dmDSriasi!B9W&@82sjnbgNP_OY)?B{R@<8YKdQBe_gc)y; z5U?aKNqk@Ht>fyAqzKOLw_=j^Bhumljrr?YYjsZt^wz^Ph4FWbEpr@8=D^SILvKR%dg`T$qu1K5`jDx^6Er9X4+mnu#=X@j))Tp=a&ct^>Kl z4NJ{YCf%1f4?{oJY&VniLtMd#@5jIVcYzQm$eT=Zf7>V=76rSC$bH!d#=?=4qX~B| zqpbT*3Y=tA=z2NZ&S!oO=&kGAOMVQDW{zW!5R zpxeREn(cKeDx@X&M`HY3;8jW8)g_BAz7V}3WjrF)^z2JrOQ~$`Gq1D$B1gi{KFK#l z!8ogcdo4SSPzqUThDHGHkp_B+k26MAC9MAG7L7T+xw-6 z2pQZdhJM~S0imT@ULtv+CS0YwHu7;5D`C$_H;KZ@KTgmOleYkr5oNiRcQ3OdSWp(| zB4ccg3wXO*HC2p`sbzUdx0gUZr#SPlK6>ydJOQvNF<0%$*D@+fT@C*K`egK3H?A_Z zH>d}H`83-SWE+d-3&>S4vcB0HACE}JOK5tO2o3%OsFCM zIAN&H4^0!>eBfr=6{w{+>`vy$SuikO)d|(+qQ)CMls6g}5-;*n)wq8by#3dyK310( z=eukAtM#M#(>#xb)KmXi+)BQa6qyHD1qlhnAU9J!Fy6VqGheCrD+9XW`gWB>EhEv4 zzZy4&E-5*(AW#nd777LcPchfS0(?0kVK>p5HRead>1UxIH?Qf+vZTP7H{S>JqkHZsX60{O#c(~}KigcI zR5-AuL1f>KnCXH0bJJtST#2j-;@c5C*dRf|9$h!`rjLgoR(l_bL#l)b_3DLErpH{R$VAQgdGhfTiL3H@i}6=a2%K z$z&RrQQS&@rW%5T)kqF@5)zVCt9tlA4&e;8S6p?j1a7r$JS_Ril^2WV6o>(>=)QW+ z2O@Ok=ZWpk;3{Nu-C6-?7Chg$X8`y2k`%wEMWI5U=k|mEZH>Cv)uOw2nMq3T99C4U zC>*aZNw{!Pg3!{9aR&Odn)J3OL(!Y+RsS#{)5j)i0mE5Cv}a!miA0$gHE)$xo5SNI z2DPG$8qhbW364t?3G&{;_m`pOH^0Gwu5?xcOwi9bgCk$GqfVCQZrC2O)0?1G%iw%bzPCoWNF+!)Vs&Rx+l_RGQF)! zk#2S&y+?gdNTuwtpt3O5B3-I4p|2;L zI*t4qEz(ogx>Nck=v(gIj|wh?+(o2CTf-t{B0x(#PXY)vZ^PNE5<}weB)3h79jCAG zk{m)kn0Dv4;`RPJP|Q_Cz5f zg(=H!@!vNSU+Z!3(jf)zov|E2NU))6+y?Ojs%9vg%uC9oW1@TkoKh= z`L3CXwCKp*#U}Qs2xcG(&*0>?&S-5t)#VTO!MwKfO{rFc6+E!QzL=pL(_1CzpxKN< z`5FSXH_M=5q11#6*DTOV*w=RSONd?F!Hgtq;Mmp8=YT31Q!qmLVwD)DAEBRpGD8b~ z*y{bdZPC-;eYS#Q_E%W>VfS?jSC7~sRs7=L;;(?&oN2-we=ut;SOiLMJLpH4Wp1V#+u8L`E- z=fk&s^exE{A3YCr{RzBrY@YfCHKd}Lvozhq3^I$EalDU&W+0tbzB!Z-f1|-=@-(4 zxcfcBz0qvC z1cs@DR2|^p~ZH?<<@KEo@@>;pGUn#26C_o!- s_x&lVMr;auT3Ht>t7zPF)?}CC+7vUa42@%!V*j!on+co=wvN506Ck~Dqsm;Y(piHN@Zn{lIMe3-T}j{QUK zL057*XV-Fi9$6$(Q7YMgPI9nSFMkF$j#R=^lkssH1BXni`Q7ix>rB$#7`P`e#UZeB z91%I$4CR0Wrn&JF`J)6Pe*c-UC6Vo46t$yrI*jq>Cf&l~>%v=G6aSbH^swecBoc^} z8$t?inY25s&prFAtnq&K!Y-5OjRj-Dh(oDE%3WC*?rr;0LT>;AH$Im+7>u{X0N#F) zJYbm2*KlZlO&Uf~8mcC|`WnIYHC7$Q$Ug$kljdL%%K0@~kSa7^?Qw^eEdIm#dPq~D zVdraHLbnv$Sc}&}6Kqd&k@Y|FXmFL#d<#Q;?8jhm52F31T?0e;RQDp#Ye4fNYJ-WI zqp>T0{?EtAL`F4PZ45i7G8(#5d0W117h0f$!Lc#LiKrWzm!$vO(eR-i^G8opk+9II z@y_R~Kau;LjOR4poyt3TIkWL|b@CvVK$8adrVTYR^Xjx= zAaU2HjsDEm)oH_UNZfU4!$9J$OB)6^5_d=1<|eMHJ&?A^iE9)|IJ_d3Qyj`Ow8J7{QQE9Bd60hBHbZ+?!$6U6d5=IMr+HKhol6Eu1`>&`WC)cUo{li(}Fpin4Ot!a07?mg;fxg}1I=EPD9O5(BYgiksVHwsOF3iSs-Y;MajIx>`O2nwXqA$L#>;QetVP+^B-%AP zD#;9a`P97lvl^)uAf-hV=Bg#K7Nu?gXp7`mEg3akl3I)8g`gRVvagXu;xto3Nows) ziCser^tHHZd|D%DXn>05#Yvc;MH;dqbAVM+%7gWfo5%QG`DYPZmt&g8cR77 zY}CR_H#Y}pp{OZaY*cD=tVy(L5t`4M5VTlKg#0pUq?+3`G!~K{CXKgRs%UAuXK#&c znrdzjfq$j#M4Gj<(W2I(Y`+zn_0V-AiJ91F98kU!wL7%1(R_a464^D`XhEH3IN`J% zrfAPqbDtV*wVcFnWY=8QaNu%MOf=)wT#ag)4>PrpHN3MZG>Y>y`qWlMYhR~oFKB2t zXvL79vo!vP8V+2t)nu|zj)`|#*u0pgkxz9kZl?8@c(e9VYO&PPCT%~aY246clQuU) z(}zh2n@e#?7ighz6TwNeYqDz6&^X~c&6;~_#r55;9i5;vr)y4qY=oevXwS`I(uvYI zX%8Z5X~W&d zqgv;u*2mI@`97}6+Y$jZ-QZ(d>OLz|E@p5d|M(b7q_aEgIiRzS0S{yB^_Yvqppuxnr{Z@@hrPNHr<&TOGMA98cu}u zr}sY!E%Ip%n{8lmS%LulM&`Q)#Fe`CSUUn*Afx6IPEY#$__?~m?Xyw5DK^Q0NT^`= zDFp;=eXfpJ;1!oU&xsmNIQ$<7R~{!hV%0^ zAT=$TwPF)!H`Q>^j75Trp6B)23l}0VR12v4X!gfcuGTndO}D@-Oy=N(HKeT@TFjGf(E4e+m+Ns#GHCs@JrEiaS7=nzPN$6p0q`yq z*U&;!lf&M|9a0o`p{1@ip0?XIG|n&v^r9=;X&cdiiKsR0w3f!!z|-22bVRo6I4}Lr z8NLoJ69*0V?)!_m>9@+hy96FIej8})H%1|jDv|(i5tC*C=zhk>Rh=xXy^eH=HXzg{{BTGh6=Eeu=b0U6p4^h-q=F`?#yJay|Dv%|zm9v%NH1 zU};)G7Z*<3Zknx-3gmr~;__XUS$R`Ef6xVhesZv@a;KSbnA%Y3jmrm#6PH0&%q^X05t>6aj_59{$TiTRU%*cKY5acANy2xV?{sw6`MEb}ZbuCO?JQg4X$aG|Ls( z?ZbR|r&`Jr8Z5WH*_91G#CDp1FNDM3&g06mIJ46pA!j2rzP;jDSAx!t_>SG8Ur`H0 z71;QrCTp6ge2!@`4vn^5=>_W`NDC5Ifa6#h7e?B%G?|iz_1NhP$I6^7T4^K2nEafy zl_A;ViL}C_+iHP4f6}Q%wC(-;E&H0soJ+1zY zw67a9TtSmvT1yeylJ+6cHb}GMH2i5AAgSU1B+XMa{c|+Dl2+2R#pRorhTlx%mJ)|c z#;P5nl^t4>*U&z_il%9rAECW_&}>bUi)c-BP4jDLLK;n)FWJ{KXh4>>?28;04a2r* zSuepkG*4G$awKTFK`Tg#tA}Y$8jLj0(IiLX#)OWgFSMEyr+$=%HLW5!bMV#G`zUp_ zx}v$H#1+_KnyqN+Ik&86NgBi3NppHjMjRkVX^M(9EhDbL(=@*8`wluZV^%|P6_%&5 zQjN66)vbi$aGdsjP8_6_P7lSEog<7KjVAQeYkY;hjs_!*J0J~eY0(beBpg4qdkj64o?1KvO2Ky>ocN zTwY15&uLQEK?v-%;*Dt#sm(>1|F>|k=P;?BpuK;gO&lm6Iu|%zv)>CrP0Y1MT5GEt`~VMotinU+b@hS`wVyRYrR<-s^nLT#qaF^+Y$ zKmcRnifHC#qTNJbK3836vCXsj@IGstmQf59c-bXX`;}G$WlUUgqSRtqp-sw6Yogz5 zEzROC!!gYj6Rq9>iftMIjNR2`>Z)k^&Fjs)KS(HPL8GI5Dk1F=;4{tp(VX6FwVNBH zF?Ds?cQ4;xXe^tVXhSa_IM^Ax;=2_S(wHydG0n2H3GqcMV5HTFQ#D;ch8*qP?DqN% zXw^zr)M<)z`8R_*N+x*d_~v(7n<(`s4VrBwRMIqsuW35bTpuk8t7n^f$KgFcK$JGq zT#9v7WuiGBTH{m_kC*2@Q>pDPQHvL-^yRKPw|!%>y2szg*N-Z>|FPgVt2kNE-@n z*3k2rP3|;^cADO4Xp$-mIY3kR3k`6ood(eYZfS>83GdrA(oCe-L~+sTIT|cYqd1k~ zGp#S-u(N4z`CL08&|Io{U&0}zC4)QfCtcN@*1QL~UqYienP}Qvn>MM&G&vaD9E$^q zuM9X}KT(#VKr}nbb6m0gxFB zKeU41f`Fchpas57T0C+WG;?z;kInH;alCQ=WaEPop@}z5{3{ z1^^>`IZ31;q>YFp%{tBF02mi1)$g=#04(e?GcHbw7ob(*f&ds4C*o-A4-vTJkT_le zCN7|jiqn@fUJG1uP#kHj=gqc0%CD-vey`ot!A=VRuBuA~Xk$4!p1C}&LP#4BN7`7+ zws_0nX&M5TjA#@`TDoJ;;37_1zGKhvMci^U9dZ&jwF+r$Mlm#m;z+w-+K2-k1$N=I zvGX5k7fl-z3Zp>ns%fJ*hPc|5(?)Sd+GW#5acBVzoVIfuWlalO9}R@KO*D@>R*etV zvnX1kW7W7g1<(~-J8iV3?{v3ZwLTh;f(pQPU-l_4AfMru-Ih1(h-2%QvvBCccKn~y zHa-@27BBRFimTn0$ol{I)HMKhr6Flc0jzG`Z>9gA7zP3p1(5Uq@fi0W=U4har%s*S zCum6cxrSsHN4A}~(2#7H&DJuP8Iq;AZPoj-p6LH^lM_AP|5>rU3T+zlbQ)LhD-0QT zXA0V54Z4Z14SBZzGr%`GuU%wFR!&@RNLEge)!}ch8o%^S0j@G6D<{AkG}rhDCyq%H z04_2lX%!q7`UqbYaCp*?<2%cs3)gAe6J;^_Wrn0Ukut-s^AU>U$V(f?T_}yV45VG9 iF6)rv@;dDQSdJey#*KvQyPM$v0000 Date: Tue, 16 Jul 2024 22:03:16 +0600 Subject: [PATCH 187/775] web/Omnibox: ignore keyboard shortcuts when dialog is visible --- web/src/components/save/Omnibox.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 63f6c1df..63d68fa9 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -5,6 +5,8 @@ import { t } from "$lib/i18n/translations"; + import dialogs from "$lib/dialogs"; + import { updateSetting } from "$lib/state/settings"; import type { DownloadModeOption } from "$lib/types/settings"; @@ -65,7 +67,7 @@ }; const handleKeydown = (e: KeyboardEvent) => { - if (!linkInput) { + if (!linkInput || $dialogs.length > 0) { return; } From 504dfdb995094478ab83f29915e1d24861caafaa Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 16 Jul 2024 22:11:57 +0600 Subject: [PATCH 188/775] web/Omnibox: ignore keyboard shortcuts when processing --- web/src/components/save/Omnibox.svelte | 6 ++++-- web/src/components/save/buttons/DownloadButton.svelte | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 63d68fa9..3cd09beb 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -28,6 +28,8 @@ let linkInput: HTMLInputElement | undefined; let isFocused = false; + let isDisabled: boolean = false; + let downloadButton: SvelteComponent; const validLink = (link: string) => { @@ -67,7 +69,7 @@ }; const handleKeydown = (e: KeyboardEvent) => { - if (!linkInput || $dialogs.length > 0) { + if (!linkInput || $dialogs.length > 0 || isDisabled) { return; } @@ -136,7 +138,7 @@ (link = "")} /> {/if} {#if validLink(link)} - + {/if}
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 5201b3bc..c6a37969 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -10,6 +10,7 @@ import type { DialogInfo } from "$lib/types/dialog"; export let url: string; + export let isDisabled = false; $: buttonText = ">>"; $: buttonAltText = $t('a11y.save.download'); From 8ebde3919704c3e1a9793b82f6ed22f486d966cb Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 16 Jul 2024 22:17:51 +0600 Subject: [PATCH 189/775] web/Omnibox: prevent paste button spamming --- web/src/components/save/Omnibox.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 3cd09beb..327aeea3 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -53,6 +53,10 @@ } const pasteClipboard = () => { + if (isDisabled || $dialogs.length > 0) { + return; + } + navigator.clipboard.readText().then(async (text) => { let matchLink = text.match(/https:\/\/[^\s]+/g); if (matchLink) { From e1a898bd5877bed283f0682600824a36d3a32950 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 27 Jun 2024 23:18:52 +0000 Subject: [PATCH 190/775] frontend: move update banners to new frontend --- .../static/update-banners}/bettertogether.webp | Bin .../static/update-banners}/catmakeup.webp | Bin .../static/update-banners}/catphonestand.webp | Bin .../static/update-banners}/catroomba.webp | Bin .../static/update-banners}/catsleep.webp | Bin .../static/update-banners}/catspeed.webp | Bin .../static/update-banners}/catswitchboxes.webp | Bin .../static/update-banners}/cattired.webp | Bin .../static/update-banners}/developers.webp | Bin .../static/update-banners}/happymeowth.webp | Bin .../static/update-banners}/meowth7eleven.webp | Bin .../static/update-banners}/meowthball.webp | Bin .../static/update-banners}/meowthbusinessman.webp | Bin .../static/update-banners}/meowthcenter.webp | Bin .../static/update-banners}/meowthcooking.webp | Bin .../static/update-banners}/meowthhammer.webp | Bin .../static/update-banners}/meowthpolishegg.webp | Bin .../static/update-banners}/meowthproductions.webp | Bin .../static/update-banners}/meowthsnap.webp | Bin .../static/update-banners}/meowthstrong.webp | Bin .../static/update-banners}/millionusers.webp | Bin .../static/update-banners}/newdomain.webp | Bin .../static/update-banners}/onemillionr.webp | Bin .../static/update-banners}/shutup.webp | Bin .../static/update-banners}/twitchupdate.webp | Bin .../static/update-banners}/valentines.webp | Bin 26 files changed, 0 insertions(+), 0 deletions(-) rename {src/front/updateBanners => web/static/update-banners}/bettertogether.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catmakeup.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catphonestand.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catroomba.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catsleep.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catspeed.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catswitchboxes.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/cattired.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/developers.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/happymeowth.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowth7eleven.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthball.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthbusinessman.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthcenter.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthcooking.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthhammer.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthpolishegg.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthproductions.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthsnap.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthstrong.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/millionusers.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/newdomain.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/onemillionr.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/shutup.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/twitchupdate.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/valentines.webp (100%) diff --git a/src/front/updateBanners/bettertogether.webp b/web/static/update-banners/bettertogether.webp similarity index 100% rename from src/front/updateBanners/bettertogether.webp rename to web/static/update-banners/bettertogether.webp diff --git a/src/front/updateBanners/catmakeup.webp b/web/static/update-banners/catmakeup.webp similarity index 100% rename from src/front/updateBanners/catmakeup.webp rename to web/static/update-banners/catmakeup.webp diff --git a/src/front/updateBanners/catphonestand.webp b/web/static/update-banners/catphonestand.webp similarity index 100% rename from src/front/updateBanners/catphonestand.webp rename to web/static/update-banners/catphonestand.webp diff --git a/src/front/updateBanners/catroomba.webp b/web/static/update-banners/catroomba.webp similarity index 100% rename from src/front/updateBanners/catroomba.webp rename to web/static/update-banners/catroomba.webp diff --git a/src/front/updateBanners/catsleep.webp b/web/static/update-banners/catsleep.webp similarity index 100% rename from src/front/updateBanners/catsleep.webp rename to web/static/update-banners/catsleep.webp diff --git a/src/front/updateBanners/catspeed.webp b/web/static/update-banners/catspeed.webp similarity index 100% rename from src/front/updateBanners/catspeed.webp rename to web/static/update-banners/catspeed.webp diff --git a/src/front/updateBanners/catswitchboxes.webp b/web/static/update-banners/catswitchboxes.webp similarity index 100% rename from src/front/updateBanners/catswitchboxes.webp rename to web/static/update-banners/catswitchboxes.webp diff --git a/src/front/updateBanners/cattired.webp b/web/static/update-banners/cattired.webp similarity index 100% rename from src/front/updateBanners/cattired.webp rename to web/static/update-banners/cattired.webp diff --git a/src/front/updateBanners/developers.webp b/web/static/update-banners/developers.webp similarity index 100% rename from src/front/updateBanners/developers.webp rename to web/static/update-banners/developers.webp diff --git a/src/front/updateBanners/happymeowth.webp b/web/static/update-banners/happymeowth.webp similarity index 100% rename from src/front/updateBanners/happymeowth.webp rename to web/static/update-banners/happymeowth.webp diff --git a/src/front/updateBanners/meowth7eleven.webp b/web/static/update-banners/meowth7eleven.webp similarity index 100% rename from src/front/updateBanners/meowth7eleven.webp rename to web/static/update-banners/meowth7eleven.webp diff --git a/src/front/updateBanners/meowthball.webp b/web/static/update-banners/meowthball.webp similarity index 100% rename from src/front/updateBanners/meowthball.webp rename to web/static/update-banners/meowthball.webp diff --git a/src/front/updateBanners/meowthbusinessman.webp b/web/static/update-banners/meowthbusinessman.webp similarity index 100% rename from src/front/updateBanners/meowthbusinessman.webp rename to web/static/update-banners/meowthbusinessman.webp diff --git a/src/front/updateBanners/meowthcenter.webp b/web/static/update-banners/meowthcenter.webp similarity index 100% rename from src/front/updateBanners/meowthcenter.webp rename to web/static/update-banners/meowthcenter.webp diff --git a/src/front/updateBanners/meowthcooking.webp b/web/static/update-banners/meowthcooking.webp similarity index 100% rename from src/front/updateBanners/meowthcooking.webp rename to web/static/update-banners/meowthcooking.webp diff --git a/src/front/updateBanners/meowthhammer.webp b/web/static/update-banners/meowthhammer.webp similarity index 100% rename from src/front/updateBanners/meowthhammer.webp rename to web/static/update-banners/meowthhammer.webp diff --git a/src/front/updateBanners/meowthpolishegg.webp b/web/static/update-banners/meowthpolishegg.webp similarity index 100% rename from src/front/updateBanners/meowthpolishegg.webp rename to web/static/update-banners/meowthpolishegg.webp diff --git a/src/front/updateBanners/meowthproductions.webp b/web/static/update-banners/meowthproductions.webp similarity index 100% rename from src/front/updateBanners/meowthproductions.webp rename to web/static/update-banners/meowthproductions.webp diff --git a/src/front/updateBanners/meowthsnap.webp b/web/static/update-banners/meowthsnap.webp similarity index 100% rename from src/front/updateBanners/meowthsnap.webp rename to web/static/update-banners/meowthsnap.webp diff --git a/src/front/updateBanners/meowthstrong.webp b/web/static/update-banners/meowthstrong.webp similarity index 100% rename from src/front/updateBanners/meowthstrong.webp rename to web/static/update-banners/meowthstrong.webp diff --git a/src/front/updateBanners/millionusers.webp b/web/static/update-banners/millionusers.webp similarity index 100% rename from src/front/updateBanners/millionusers.webp rename to web/static/update-banners/millionusers.webp diff --git a/src/front/updateBanners/newdomain.webp b/web/static/update-banners/newdomain.webp similarity index 100% rename from src/front/updateBanners/newdomain.webp rename to web/static/update-banners/newdomain.webp diff --git a/src/front/updateBanners/onemillionr.webp b/web/static/update-banners/onemillionr.webp similarity index 100% rename from src/front/updateBanners/onemillionr.webp rename to web/static/update-banners/onemillionr.webp diff --git a/src/front/updateBanners/shutup.webp b/web/static/update-banners/shutup.webp similarity index 100% rename from src/front/updateBanners/shutup.webp rename to web/static/update-banners/shutup.webp diff --git a/src/front/updateBanners/twitchupdate.webp b/web/static/update-banners/twitchupdate.webp similarity index 100% rename from src/front/updateBanners/twitchupdate.webp rename to web/static/update-banners/twitchupdate.webp diff --git a/src/front/updateBanners/valentines.webp b/web/static/update-banners/valentines.webp similarity index 100% rename from src/front/updateBanners/valentines.webp rename to web/static/update-banners/valentines.webp From a8569838100f3d7b1b47f1ad94074c418556e475 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 29 Jun 2024 17:36:26 +0000 Subject: [PATCH 191/775] web: convert changelogs from old format https://gist.github.com/dumbmoron/3fc6c0c747d791928aba939976fd9304 --- src/modules/changelog/changelog.json | 308 --------------------------- web/changelogs/3.5.2.md | 16 ++ web/changelogs/3.5.4.md | 5 + web/changelogs/3.5.md | 19 ++ web/changelogs/3.6.3.md | 14 ++ web/changelogs/3.6.md | 10 + web/changelogs/3.7.md | 18 ++ web/changelogs/4.0.md | 22 ++ web/changelogs/4.1.md | 10 + web/changelogs/4.2.md | 15 ++ web/changelogs/4.3.2.md | 13 ++ web/changelogs/4.3.md | 27 +++ web/changelogs/4.4.md | 12 ++ web/changelogs/4.5.md | 33 +++ web/changelogs/4.6.md | 25 +++ web/changelogs/4.7.md | 38 ++++ web/changelogs/4.8.md | 30 +++ web/changelogs/5.0.md | 41 ++++ web/changelogs/5.1.md | 45 ++++ web/changelogs/5.2.md | 52 +++++ web/changelogs/5.3.md | 20 ++ web/changelogs/5.4.md | 34 +++ web/changelogs/6.0.md | 68 ++++++ web/changelogs/6.2.md | 23 ++ web/changelogs/7.0.md | 83 ++++++++ web/changelogs/7.1.md | 28 +++ web/changelogs/7.11.md | 45 ++++ web/changelogs/7.13.md | 59 +++++ web/changelogs/7.14.md | 43 ++++ web/changelogs/7.3.md | 30 +++ web/changelogs/7.4.md | 45 ++++ web/changelogs/7.5.md | 28 +++ web/changelogs/7.6.md | 33 +++ web/changelogs/7.7.md | 30 +++ web/changelogs/7.8.md | 35 +++ web/changelogs/7.9.md | 33 +++ 36 files changed, 1082 insertions(+), 308 deletions(-) delete mode 100644 src/modules/changelog/changelog.json create mode 100644 web/changelogs/3.5.2.md create mode 100644 web/changelogs/3.5.4.md create mode 100644 web/changelogs/3.5.md create mode 100644 web/changelogs/3.6.3.md create mode 100644 web/changelogs/3.6.md create mode 100644 web/changelogs/3.7.md create mode 100644 web/changelogs/4.0.md create mode 100644 web/changelogs/4.1.md create mode 100644 web/changelogs/4.2.md create mode 100644 web/changelogs/4.3.2.md create mode 100644 web/changelogs/4.3.md create mode 100644 web/changelogs/4.4.md create mode 100644 web/changelogs/4.5.md create mode 100644 web/changelogs/4.6.md create mode 100644 web/changelogs/4.7.md create mode 100644 web/changelogs/4.8.md create mode 100644 web/changelogs/5.0.md create mode 100644 web/changelogs/5.1.md create mode 100644 web/changelogs/5.2.md create mode 100644 web/changelogs/5.3.md create mode 100644 web/changelogs/5.4.md create mode 100644 web/changelogs/6.0.md create mode 100644 web/changelogs/6.2.md create mode 100644 web/changelogs/7.0.md create mode 100644 web/changelogs/7.1.md create mode 100644 web/changelogs/7.11.md create mode 100644 web/changelogs/7.13.md create mode 100644 web/changelogs/7.14.md create mode 100644 web/changelogs/7.3.md create mode 100644 web/changelogs/7.4.md create mode 100644 web/changelogs/7.5.md create mode 100644 web/changelogs/7.6.md create mode 100644 web/changelogs/7.7.md create mode 100644 web/changelogs/7.8.md create mode 100644 web/changelogs/7.9.md diff --git a/src/modules/changelog/changelog.json b/src/modules/changelog/changelog.json deleted file mode 100644 index e90a1a33..00000000 --- a/src/modules/changelog/changelog.json +++ /dev/null @@ -1,308 +0,0 @@ -{ - "current": { - "version": "7.14", - "date": "May 17, 2024", - "title": "now helping over 1 million people monthly", - "banner": { - "file": "millionusers.webp", - "alt": "collage of two photos, side by side. left photo: brown cake with 7 lit candles forming 1000000 and one ferrero rocher candy in the middle with cobalt (double greater than symbol) logo on it. right photo: chocolate cake with 7 lit candles forming 1000000 and cobalt logo formed with whipped cream on the cake. two plushes of meowth and pompompurin in party hats are seen behind the cake.", - "width": 1736, - "height": 1440 - }, - "content": "yesterday, cobalt hit 1 million users around the world! it's an absolutely insane milestone for us and we're incredibly grateful to everyone saving and creating what they love with help of cobalt. thank you for being our friends.\n\nin anticipation of 7 figure user count, we've revamped the cobalt codebase and infrastructure to be faster and more reliable than ever. a combination of many changes has resulted into incredible download speeds (up to 30 MB/s, as tested by both developers in europe).\n\nnote: there's no backend instance in asia just yet, so if you're there, you might experience average speeds *for now*. you can help us afford a dedicated server in asia by donating to cobalt in the \"donate\" menu.\n\nchanges since the last major update\n\nservice improvements:\n*; youtube music support on the main instance is back!\n*; added support for pinterest images and gifs.\n*; cobalt will now use original soundcloud mp3 file when available.\n*; fixed a youtube bug that prevented some videos from downloading.\n\nui/ux improvements:\n*; cobalt web app is now fully optimized for ipad. you can add it to home screen from share menu to make it act like a native app!\n*; majorly reduced vertical padding when viewing cobalt in mobile web browser, allowing for more content at once. most noticeable on smaller screens.\n*; status bar color is now dynamic in the web browser on ios and web app on android.\n*; web app on android feels way more native than before.\n*; filename style icons are no longer blurry in safari.\n*; changelog notification no longer overlaps with dynamic island on newer iphones when cobalt is installed as a web app.\n*; fixed safe area padding.\n\nother changes:\n*; added support for freebind, made by one of the cobalt developers.\n*; rate limit and max video length limits are now customizable through environment variables.\n*; cobalt api now returns rate limit headers at all times.\n*; majorly cleaned up the codebase: removed unnecessary functions, rewrote those that were cryptic and confusing. it's way more comprehensible and contribution-friendly than ever before.\n*; moved the cobalt repo to our organization on github. everything stayed the same and all old links link back to it.\n\nnote for instance hosters:\nalong with cobalt repo, the docker image also moved! please update the url for it in your config along with watchtower args to include restarting containers (just in case) as seen in updated docker compose example. we're mirroring packages to old url for now, but it won't last forever.\n\nthat's it for now! hope you have an amazing day and share the 1 million celebration with us :)\n\njoin our discord server to discuss everything cobalt there" - }, - "history": [{ - "version": "7.13", - "date": "May 5, 2024", - "title": "better ux, improvements for youtube, twitter, tiktok, instagram, and more!", - "banner": { - "file": "meowthbusinessman.webp", - "alt": "photo of a businessman holding hands together (merkel-raute pose) with meowth plush head.", - "width": 1440, - "height": 960 - }, - "content": "long time no see! well, actually, you've been using the latest version for some time now. we've moved to a rolling release scheme, allowing for speedy update rollouts :)\n\nsince 7.11, there has been a ton of changes. here are the most notable of them:\n*; youtube downloads are now faster and more reliable than ever.\n*; all posts from twitter are now downloadable, including sensitive ones.\n*; you now can download tiktok videos in 1080p h265! just enable h265 support in settings > video.\n*; added support for sharing links directly to the cobalt web app on android.\n*; added 240p and 144p quality options to the quality picker in settings (for some reason, many of you wanted this).\n*; pasting a link with additional text around it will now work; cobalt will extract the link for you (works only via the paste button).\n*; added anonymous traffic analytics by plausible. we're using a selfhosted instance and don't collect any identifiable information about you. you can learn more in about > privacy policy. you can also opt out of anonymous analytics in settings > other.\n\nservice support improvements:\n*; implemented internal streams functionality, allowing for more fine-grained file streaming and therefore proper youtube support.\n*; added fallback to m4a if opus isn't available for youtube.\n*; added a total of 7 ways to get instagram post info, including mobile api, embed, and graphql api. absolute torture.\n*; added support for reddit user posts.\n*; updated the way tiktok downloads are handled for better reliability and 1080p support.\n*; added tiktok author's username to filename.\n*; added support for rutube shorts and yappy videos.\n*; added support for m.soundcloud.com links.\n*; added support for new post and reel links from instagram.\n*; added support for photo twitter links, only used for gifs.\n*; added support for m.bilibili.com links.\n*; added support for new type of vimeo links.\n*; added support for ddinstagram.com links.\n*; updated youtube codec info in settings to display the fact that av1 is a better choice now.\n*; updated best audio picking for tiktok and soundcloud.\n*; changed the youtube client to web, since android client no longer works.\n*; removed the vimeo download type switcher, as it should've always been automatic instead.\n*; removed an ability to enable the tiktok watermark, as it no longer includes the author's username.\n\nui & ux improvements:\n*; youtube audio dub switcher is now a toggle with a much easier to understand description.\n*; meowbalt now sticks out on the left side of download popup on desktop.\n*; updated \"made with love\" text to include the research & dev team behind cobalt, imput.\n*; fixed grammar of russian localization.\n*; rounded corners are now correctly rendered across all browsers.\n*; various minor improvements, including smaller button padding.\n*; removed the notification (red dot) functionality as the most recent changelog is already always on screen.\n*; removed settings migration from the old domain.\n\nother changes:\n*; various docs updates in github repo, making sure they're functional across branches and forks.\n*; major codebase cleanup.\n\nthank you for using cobalt, and thank you for being one of our 900k friends! i hope you like this update as much as we liked making it.\n\nwe're committed to keeping cobalt the best way to save what you love without ads or invasion of your privacy. there's a ton of cool stuff to come soon; stay tuned and have an amazing rest of your day <3\n\nif you want to help our goal of a better internet for everyone, just share cobalt with a friend!\n\n(original photo of a man in a suit by benzoix on freepik)" - }, { - "version": "7.11", - "date": "March 6, 2024", - "title": "cache encryption, meowbalt, dailymotion, bilibili, and much more!", - "banner": { - "file": "meowth7eleven.webp", - "alt": "meowth plush in front of 7-eleven store", - "width": 850, - "height": 640 - }, - "content": "cobalt may not have as many groceries as 7-eleven, but it sure does have lots of big changes in this update!\n\n*; all cached stream info is now encrypted and can only be decrypted with a link you get from cobalt.\n*; new popup style featuring meowbalt, cobalt's speedy mascot. you will see him more often from now on!\n*; added support for dailymotion (including short links).\n*; added support for bilibili.tv, fixed support for bilibili.com, and added support for all related short links.\n*; added support for unlisted vimeo links.\n*; added support for tumblr audio and revamped the entire module.\n*; added support for embed ok.ru links.\n\nwe also updated the privacy policy to reflect the addition of data encryption, go check it out.\n\nfor people with iphones:\n*; clearer ios saving tutorial.\n*; added \"save to files\" ios shortcut.\n*; updated save to photos shortcut.\n\nmake sure to save both shortcuts and read the updated tutorial!\n\nfor people who host a cobalt instance:\n*; updated all environment variables TO_BE_LIKE_THIS. time to update your configs! for now cobalt is backwards compatible with old variable names, but it won't last forever.\n*; added a list of all environment variables and their descriptions to run-an-instance doc.\n*; updated cookie file example with more services and improved examples.\n*; updated docker compose example with better explanations and up-to-date env variable samples.\n*; updated some packages to get rid of all unnecessary messages in console.\n\nwant to host an instance? learn how to do it here.\n\nfrontend changes:\n*; removed migration popup.\n*; corners across ui are even more round now.\n*; bottom glass bkg in popups is no longer rounded on top right.\n*; small popup no longer stretches like gum, it's fixed in size on desktop.\n*; small popup animation no longer lags on mobile.\n*; better ui scaling across resolutions.\n*; updated donation text.\n\nthank you for using cobalt, all 750k of you. hope you like this update as much as we enjoyed making it :D" - }, { - "version": "7.9", - "date": "January 17, 2024", - "title": "twitter gifs, pinterest, ok.ru, and more!", - "banner": { - "file": "meowthball.webp", - "alt": "meowth rolling on a big catnip ball", - "width": 478, - "height": 350 - }, - "content": "yes, you read that right. cobalt now lets you convert any twitter gif to an actual .gif file! (finally)\njust go to settings and enable this feature :)\n\nservice improvements:\n*; added an option to convert gifs from twitter into actual .gif format. files will be bigger and lower quality, but maybe you want that.\n*; pinterest support has been completely redone, now all videos (and even pin.it links) are supported.\n*; added support for ok.ru in case you're a russian grandma.\n*; now processing all reddit links (including old.reddit.com).\n*; instagram live vods are now supported.\n*; fixed a rare vimeo bug related to 1440p videos.\n\nother improvements:\n*; ui fade in animation is no longer present if you've disabled animations.\n*; all images now have alt descriptions.\n*; cobalt html is now biblically correct and follows the html spec.\n*; lots of cleaning up.\n\npatches since 7.8:\n*; shift+key shortcuts are now ignored if url bar is focused.\n*; longer soundcloud links are now supported, also catching more tiktok-related errors.\n*; removed mastodon from support links as that account is no longer active.\n*; added ability to download a specific video from multi media tweets and support for /mediaViewer links.\n*; fixed modal blurriness in chromium.\n*; minor html changes (road to biblically correct one).\n\nlots of long-awaited updates (especially twitter gifs), hope you enjoy them and have a great day :D" - }, { - "version": "7.8", - "date": "December 25, 2023", - "title": "new years clean up! bug fixes and fresh look for the home page", - "banner": { - "file": "catroomba.webp", - "alt": "a cat riding a roomba vacuum", - "width": 300, - "height": 168 - }, - "content": "merry christmas and happy new year! this update fixes several (very annoying) bugs to help you enjoy your holidays better.\n\nyou might have already noticed, but we've refreshed the home page on desktop and mobile! less space wasted, more pleasant to look at. let us know if you like it or not :D\n\nservice improvements:\n*; #264 anything that includes a period in the url should be possible to download (including instagram stories).\n*; #73 soundcloud: falling back to mp3 instead of refusing to download the song at all.\n*; #275 youtube: query parameters are parsed and handled correctly, all links should be supported, no matter where v query is located.\n*; tlds are parsed and validated correctly (e.g. \"pinterest.co.uk\" works now).\n*; fixvx.com links are now supported.\n\ninterface improvements:\n*; cleaner and more consistent home page layout.\n*; cleaned up support section in \"about\". also includes a link to the status page.\n\ninternal improvements:\n*; urls, subdomains, and tlds are properly validated.\n*; minor clean up.\n\nchanges since 7.7:\n*; made terms and ethics more descriptive.\n*; fix only affected twitter videos.\n*; fixed quick ⌘+V pasting on mac.\n*; now catching even more youtube-related errors.\n\nthis might not seem like a lot, but even smaller changes make a difference!\n\nenjoy this update and the rest of your day :D" - }, { - "version": "7.7", - "date": "December 2, 2023", - "title": "bugfixes and better downloads!", - "banner": { - "file": "meowthpolishegg.webp", - "alt": "meowth polishing a togepi egg", - "width": 640, - "height": 480 - }, - "content": "this update fixes various issues with supported services. no new features yet, but twitter fix is surely something good to have in the meantime!\n\nservice improvements:\n*; broken twitter videos are now automatically fixed by cobalt.\n*; all vimeo videos and audios should now be possible to download.\n*; vimeo: fixed short resolution displayed in \"basic\" and \"pretty\" filename styles.\n\ninterface improvements:\n*; streamables are now easier to save on ios.\n\ninternal improvements:\n*; port env variable is now not strictly necessary for cobalt to run.\n*; minor clean up.\n\nchanges since 7.6:\n*; fix for an issue related to youtube dubs.\n*; fixed a memory leak related to live renders.\n*; handling all errors related to twitter downloads.\n*; fixed support for reddit links in various languages.\n*; added rich filenames support for twitch clips.\n*; updated support and donation lists.\n\nstay tuned for future updates and have a great day :D" - }, { - "version": "7.6", - "date": "October 15, 2023", - "title": "customizable file names, instagram stories, and first cobalt sponsor!", - "banner": { - "file": "meowthcenter.webp", - "alt": "meowth plush in a datacenter wearing a hardhat, wielding a hammer", - "width": 851, - "height": 640 - }, - "content": "as many have (very) often requested, cobalt now lets you pick between several file name format styles!\ngo to settings > other and change it to whichever you like! there's a preview of each style, so you know how exactly files are gonna look like.\n\nif you liked file names the way they were before, don't worry: classic style is still the default :)\n\non a different but not any less important note: cobalt is now sponsored by royalehosting.net!\noverall service performance and stability is gonna be better, but also more content will be possible to download thanks to geniuine server locations. and yes, still no ads or trackers.\n\nthis update also includes a bunch of other changes, check them out:\n\nservice improvements:\n*; added support for instagram stories thanks to #194.\n*; fixed reddit support thanks to #221.\n*; added support for rich file names for youtube, vimeo, soundcloud, rutube, and vk.\n*; numbers and emoji no longer disappear from file name and metadata.\n*; mute and audio dub file name tags don't appear together anymore.\n*; youtube: dub file name tag doesn't appear anymore if audio track is default.\n\ninterface improvements:\n*; added a list of sponsors to about tab. if you host an instance, it's disabled by default, but can be enabled with showSponsors env variable.\n*; about button now opens about tab when no new changelog is available.\n*; fixed download button thickness on ios.\n\nyou now can reach out to cobalt via email for support! it's located in the about tab along with other socials, such as discord.\n\ni hope you enjoy this long-awaited update and have a blissful day :D" - }, { - "version": "7.5", - "date": "September 16, 2023", - "title": "support for twitch clips and rutube!", - "banner": { - "file": "twitchupdate.webp", - "alt": "meowth plush staring into the camera, laptop with generic purple service in the background", - "width": 851, - "height": 640 - }, - "content": "hey! this update (finally) adds support for twitch clips and rutube, among other smaller changes.\n\nservice improvements:\n*; added support for twitch clips. no vods, they're unnecessary. just clip whatever you want to download!\n*; added support for rutube in case you ever wanted to download something russian.\n\ninterface improvements:\n*; added a note about cobalt not being affiliated with any supported services.\n*; added a note about meta (the company) in russian.\n*; better russian localization. will keep improving it to make it sound not so robotic over time.\n\nother improvements:\n*; all official servers are now using the docker package. and so should you!\n*; moved the load balancer to poland. requests should be slightly faster now.\n*; minor codebase clean up.\n\nif you're confused about the new domain, read the older changelog! just scroll lower and press \"expand\".\n\ni hope you find this update useful and have a wonderful day :)\n\nbtw, cobalt has a pretty active community server on discord. go to about > support & source code to join!" - }, { - "version": "7.4", - "date": "September 9, 2023", - "title": "new domain, what's coming in future, bug fixes, and more!", - "banner": { - "file": "newdomain.webp", - "alt": "text: new domain, same cobalt", - "width": 960, - "height": 540 - }, - "content": "cobalt is finally moving to its own domain! many of you have been anticipating this, and many kept forgetting the link due to how cryptic it was.\n\nwell, worry no more - cobalt.tools is here.\n\nif you haven't yet, open co.wukko.me to transfer your settings here! no additional action from you is required. just open the old link and cobalt will do everything for you :)\n\nmake sure to update your bookmarks and reinstall the web app!\n\nhere's what domain change means:\n*; still no ads, same owner, same features, same reliability. just a way more rememberable link (it's literally two words).\n*; cobalt.tools makes it clear that cobalt is a tool and that it's \"cobalt\", not \"wukko\".\n*; i can host various versions of cobalt on subdomains without links looking awkward.\n*; i can host cobalt-related websites without polluting my personal domain's dns (such as crowdin).\n*; i stand by same privacy policies (and in fact am using the same exact server as before).\n\nthe domain change is required for the future of cobalt.\n\nhere's what's coming soon:\n*; support for many top-requested sites, such as (but not limited to) twitch and niconico.\n*; education version of cobalt, as often requested by students and educators.\n*; major localization system upgrade, allowing for simpler community contributions.\n*; region-specific versions with 100% translations and tweaks.\n*; native clients for desktop and mobile (not sure about this one, i'm no superman).\n*; ...and more!\n\nnow, here's what's new in 7.4:\n*; tabs in popups now scroll to top on tab bar tap.\n*; padding across web app was tuned.\n*; (obviously) a migration agent. soon will be used for importing and exporting settings.\n*; some minor clean ups in codebase.\n\nif you want to help cobalt achieve goals listed above, consider donating! donations are the only way i can keep cobalt ad-less, powerful, (basically) limitless, and also 100% free.\n\nin fact, donations have helped me grow cobalt more than i've ever anticipated. just imagine how much better it will be in a year.\n\ngo to donations down below to find ways to donate!\n\nthank you for reading through all of this. i hope you enjoy this update and have a great day :D" - }, { - "version": "7.2 & 7.3", - "date": "September 6, 2023", - "title": "extended video length limit, metadata toggle, ui improvements, and more!", - "banner": { - "file": "meowthsnap.webp", - "alt": "cartoon meowth pointing paw dramatically and saying something", - "width": 500, - "height": 280 - }, - "content": "this update gives cobalt a sharp look in chromium browsers and makes it even more useful than before. check out the full changelog below!\n\nservice improvements:\n*; increased video length limit from 3 hours to 5 hours. feel free to download lectures you need :)\n*; you can now disable file metadata in settings.\n*; fixed a bug which previously caused some downloads to end up being 0 bytes.\n\nui improvements:\n*; fixed clickable area for urgent notice (text on top).\n*; fixed blurry header in chrome.\n*; fixed blurry tab bar in chrome.\n*; fixed blurry switches in chrome.\n*; fixed weirdly rounded corners in popups.\n*; fixed 1px gap on edges of various elements in popup in chrome.\n*; fixed overscrolling in other settings tab on ios.\n*; fixed unexpected button highlight effect on phones.\n*; removed outdated fixes for tiny screens.\n\nother improvements:\n*; cobalt web & api start faster than before, additional preparation functions aren't unexpectedly run anymore.\n*; cobalt is now available as a docker package. check it out on github.\n\nthank you for being here. i hope you have a great day :D" - }, { - "version": "7.1", - "date": "August 20, 2023", - "title": "instagram, streamable, video metadata, and more!", - "banner": { - "file": "meowthproductions.webp", - "alt": "meowth roaring in a fancy circle, à la MGM studios intro", - "width": 640, - "height": 358 - }, - "content": "service improvements:\n*; extended instagram support: high quality photos, videos, reels. everything should work without any issues, enjoy! :)\n*; added support for streamable.com (thanks to #179)\n*; added video metadata to youtube videos.\n*; fixed vk video downloads.\n*; vxtwitter links are now supported.\n*; fixed support for youtube audio dubs.\n\nui improvements:\n*; fixed picker popup: it's now scrollable in all cases and clickable areas don't overlap each other.\n\nbackend improvements:\n*; cobalt will now let you know if something goes wrong during video download instead of nuking the stream.\n*; added support for cookies (thanks to #177)\n*; replaced got with undici (thanks to #182). downloads should be slightly faster and clean of garbage in headers.\n\ninternal improvements:\n*; moved host overrides into its own module.\n*; minor clean ups.\n\neven more cool stuff is coming in future updates! thank you for using cobalt :D" - }, { - "version": "7.0", - "date": "August 15, 2023", - "title": "biggest ui refresh yet!", - "banner": { - "file": "meowthcooking.webp", - "alt": "meowth handling orders in a restaurant", - "width": 640, - "height": 360 - }, - "content": "hey! this update is huge and mostly aimed to refresh the ui, but there are also some other nice fixes/additions. read below for more info :)\n\ntl;dr:\n*; entirety of web app has been refreshed. it's more prettier and optimized than ever, both on phone and desktop.\n*; if you're on ios, try adding cobalt to home screen! it'll look and act like a native app.\n*; all soundcloud links are now supported and audio quality is higher than before.\n*; all x (previously twitter) links are now supported and work properly.\n*; newer reddit videos are downloadable now.\n*; added some sort of eula, list of keyboard shortcuts, updated privacy policy for more clarity. check it all in refreshed about tab!\n*; cobalt now lets you know if your browser doesn't support clipboard pasting and helps you fix it.\n\naccessibility notice:\nthis update includes animations and transparency, if you'd like to disable any or all of them, head to settings > other > accessibility.\n\n[full changelog]\n\nservice improvements:\n*; fixed unexpected 502 errors when downloading newer reddit videos.\n*; newer reddit videos (with audio) are downloadable now.\n*; upgraded soundcloud downloads to use higher audio quality than before.\n*; all soundcloud links are now supported.\n*; added support for x.com urls.\n*; changed twitter api once again. now everything works, again.\n\nweb improvements:\n*; all-new matte glass aesthetic, applied to revamped popup headers, tab selectors, and also small popups.\n*; rounded corners everywhere! cobalt is now safe for everyone who can't handle sharp objects.\n*; paddings everywhere are smaller, more content fits on the screen at once.\n*; optimized installed web app to look and act like a native app, especially on ios.\n*; added update release dates to changelogs.\n*; cobalt now lets you know if your browser doesn't support clipboard api and helps you fix it.\n*; refreshed all popups: less padding, more content.\n*; completely remade error and download popups, they're consistent with the rest of refreshed design.\n*; refreshed the look of entire changelog tab: separated title and version/commit, made title bigger, evened out all paddings.\n*; replaced close button with back button, moved it to left.\n*; added interaction animations.\n*; added more keyboard shorcuts.\n*; added a list of keyboard shortcuts to about tab.\n*; added eula to about tab. check it out.\n*; added more accessibility options, put them all into one category. you can disable animations and transparency if you want to.\n*; added a link to self-troubleshooting guide to about tab.\n*; renamed 2160p and 4320p to 4k and 8k respectfully for better clarity.\n*; popups now work without any weird workarounds, especially on mobile. they're clean and nice.\n*; home screen now also works without any weird workarounds. it is also clean and nice.\n*; optimized css of almost all ui elements. should be even more consistent across platforms now.\n*; added ability to translate \"cobalt\" more in-depth localization. for example, in russian \"cobalt\" is now \"кобальт\", that's the style i'll be going with from now on.\n*; updated many localization strings for more clarity.\n*; removed ability to change the app name dynamically in all locations. cobalt is a sustained app name.\n*; updated donation and privacy policy texts for more clarity in both english and russian.\n*; home screen now smoothly fades in instead of popping in.\n*; proper banner loading. no more jumping text!\n*; proper banner error handling. if banner wasn't loaded, it'll simply go grey instead of disappearing.\n*; links are no longer italic and are instead underlined.\n*; collapsible lists now have corresponding emoji.\n*; donate button is now highlighted with magenta instead of white.\n*; proper dropdown arrow.\n*; removed 6.0 api fallback.\n*; fixed celebrations emoji. again.\n*; cleaned up all related frontend modules, especially page.js.\n*; urgent notice is now a js element, not a static piece of text. can be updated easily.\n\napi improvements:\n*; now catching all json api related errors.\n*; moved on demand blocks to web server, now changelog can be updated independently from preferred api server.\n*; now sending standard rate limiting headers.\n*; better readability in source.\n\nother improvements:\n*; renamed docker-compose.yml.example to docker-compose.example.yml for linting in code editors.\n*; added a wiki with wip troubleshooting guide on github. more guides are coming soon!\n\nthat's a ton of changes! i really hope you like this update as much as i do.\n\nif you experience any issues, feel free to contact me on any platform listed in about tab! i'd love to hear back from you.\n\nthank you for sticking with me and cobalt, i hope you have THE best day :D" - }, { - "version": "6.2", - "date": "June 27 2023", - "title": "all network issues have been fixed!", - "banner": { - "file": "meowthhammer.webp", - "alt": "meowth plush holding a hammer in real life", - "width": 1280, - "height": 827 - }, - "content": "hey! there have been some hiccups in cobalt's stability lately, i was going through finals while trying to scale up the infrastructure, and that didn't really work out, lol.\nBUT i'm happy to announce that i've optimized all nodes! there should no longer be any networking issues.\n\nenjoy stable experience while i work in background to make cobalt even better :)\n\nhere's what's new in this update:\n*; better button contrast in both themes. \n*; button highlight in light theme now actually looks like a highlight.\n*; removed ip gate for streamables and updated privacy policy to reflect this change.\n*; streamable links now last for 20 seconds instead of 2 minutes.\n*; cleaned up stream verification algorithm. now the same function doesn't run 4 times in a row.\n*; removed deprecated way of hosting a cobalt instance.\n\nthank you for sticking with cobalt, and i hope you have a great day :D\n\nbanner photo is by @halftroller on twitter, thank you so much!" - }, { - "version": "6.0", - "date": "June 7, 2023", - "title": "better reliability, new infrastructure, pinterest support, and way more!", - "banner": { - "file": "catswitchboxes.webp", - "alt": "a cat climbing into two empty boxes of asahi beer", - "width": 600, - "height": 314 - }, - "content": "hey! long time no see, hopefully over 40 changes will make up for it :)\n\ncobalt now has an official community discord server. you can go there for news, support, or just to chat. go check it out!\n\ntl;dr\n*; new infra, new hosting structure, new main instance api url. developers, get it here.\n*; added support for pinterest, vine archive, tumblr audio, youtube vr videos.\n*; better web app performance and look.\n*; better stability thanks to load balancing.\n*; (hopefully) no more random video/audio download drops.\n\nservice improvements:\n*; added support for pinterest videos and stories (pr by @Snazzah).\n*; added support for tumblr audio. sorry, tumblr.\n*; added support for youtube vr videos. please note that they're in youtube's proprietary ratio.\n*; added support for vine archive.\n*; added support for ancient vk videos in 240p.\n*; fixed an issue related to muted video downloads from tumblr.\n*; moved to twitter v2 api.\n*; soundcloud share links are now processed without errors.\n\nui improvements:\n*; lazy image loading. should significantly speed up the page load.\n*; fixed checkbox width on mobile devices.\n*; addition of a temporary urgent notice.\n*; added hover border to all buttons.\n*; less annoying donation button highlight.\n*; more consistent color scheme.\n*; added link to a discord server into about popup.\n*; remember celebratory emoji changes? they've been fixed, and are now dynamically loaded!\n*; changelog history now lets you try to load it again if first attempt failed for whatever reason.\n*; padding (everywhere) has been slightly reduced to fit in more content and be consistent across ui.\n*; added more info to the \"how to save\" popup for ios devices.\n*; crypto wallet press-to-copy buttons now look like buttons.\n*; improved ui layout for smallest screens (iphone 5, 5s, se, etc).\n*; removed partial translations for sake of clarity and consistency.\n\ninternal improvements:\n*; separated web and api servers. they're now completely independent and therefore more stress-resistant.\n*; added a dedicated script for building the web app if you don't want to reload the frontend server.\n*; web app building improvements.\n*; async localization preloading.\n*; consistent server start time reporting.\n*; dynamic stream and ip hashing salt generation.\n\ninfrastructure improvements:\n*; load balancing: your api requests are now sent to the least busy server. yes, there are now several of them with more to come in the future.\n*; when possible, server in closest region is used instead of a far-away one. this should help with download speeds.\n*; currently there are multiple servers in europe. i will let you know when (and if) i manage to get an american one.\n\nupdates for developers and instance hosters:\n*; server info api endpoint: you can now check up on the api server of choice. it reports all the basic info you may need. check the api docs for more info.\n*; api names: each and every api instance should have a distinctive name. this will be useful in the future :)\n*; added docker compose sample config.\n*; updated and more granular setup script.\n*; better api scalability and faster server start up thanks to web and api separation.\n*; added ability to specify ffmpeg threads. simply add ffmpegThreads to your environment variables!\n\ni'm still in awe from how popular cobalt has become. there are now over 200k of unique users monthly, and that number only keeps growing. i even had to come up with something to accommodate for larger traffic, it's absolutely insane.\n\nlove you all, have a great day :D" - }, { - "version": "5.4", - "title": "instagram support, docker, and more!", - "banner": { - "file": "catphonestand.webp", - "alt": "a cat holding a phone under its chin while a person plays clash of clans on it", - "width": 451, - "height": 272 - }, - "content": "something many of you've been waiting for is finally here! try it out and let me know what you think :)\n\ntl;dr:\n*; added experimental instagram support! download any reels or videos you like, and make sure to report any issues you encounter. yes, you can convert either to audio.\n*; fixed support for on.soundcloud links.\n*; added share button to \"how to save?\" popup.\n*; added docker support.\n\nservice improvements:\n*; added experimental support for videos from instagram. currently only reels and post videos are downloadable, but i'm looking into ways to save high resolution photos too. if you experience any issues, please report them on either of support platforms.\n*; fixed support for on.soundcloud share links. should work just as well as other versions!\n*; fixed an issue that made some youtube videos impossible to download.\n\ninterface improvements:\n*; new css-only checkmark! yes, i can't stop tinkering with it because slight flashing on svg load annoyed me. now it loads instantly (and also looks slightly better).\n*; fixed copy animation.\n*; minor localization improvements.\n*; fixed the embed logo that i broke somewhere in between 5.3 and 5.4.\n\ninternal improvements:\n*; now using nanoid for live render stream ids.\n*; added support for docker. it's kind of clumsy because of how i get .git folder inside the container, but if you know how to do it better, feel free to make a pr.\n*; cobalt now checks only for existence of environment variables, not exactly the .env file.\n*; changed the way user ip address is retrieved for instances using cloudflare.\n*; added ability to disable cors, both to setup script and environment variables.\n\ni can't believe how diverse and widespread cobalt has become. it's used in all fields: music production, education, content creation, and even game development. thank you. this is absolutely nuts.\nif you don't mind sharing, please tell me about your use case. i'd really love to hear how you use cobalt and how i could make it even more useful for you." - }, { - "version": "5.3", - "title": "better looks, better feel", - "banner": { - "file": "cattired.webp", - "alt": "a cat laying on a sofa face down, wiggling its tail", - "width": 640, - "height": 286 - }, - "content": "this update isn't as big as previous ones, but it still greatly enhances the cobalt experience.\n\nhere's what's up:\n*; new mode switcher! elegant and 100% clear. should no longer cause any confusion. let me know if you like it better this way :D\n*; wide paste button on mobile is back, but now it's even closer to your finger.\n*; removed the weird grey chin on changelog banners.\n*; removed left-handed layout toggle since it is no longer needed.\n*; fixed input area display in chromium 112+.\n*; centered the main action box.\n*; cleaned up css of main action box to get rid of tricks and ensure correct display on all devices.\n*; fixed a bug that'd cause notifications dots to disappear when an unrelated checkbox was checked.\n\nhopefully from now on i'll focus on adding support for more services.\nthank you for using cobalt. stay cool :)" - }, { - "version": "5.2", - "title": "fastest one in the game", - "banner": { - "file": "catspeed.webp", - "alt": "a cat running very fast in an exercise wheel", - "width": 640, - "height": 356 - }, - "content": "hey, notice anything different? well, at very least the page loaded way faster! this update includes many improvements and fixes, but also some new features.\n\ntl;dr:\n*; twitter retweet links are now supported.\n*; all vimeo videos should now be possible to download.\n*; you now can download audio from vimeo.\n*; it's now possible to pick between preferred vimeo download method in settings.\n*; fixed issues related to tiktok, twitter, twitter spaces, and vimeo downloads.\n*; overall cobalt performance should be MUCH better.\n\nservice improvements:\n*; added support for twitter retweet links. now all kinds of tweet links are supported.\n*; fixed the issue related to periods in tiktok usernames (#96).\n*; fixed twitter spaces downloads.\n*; added support for audio downloads from vimeo.\n*; added ability to choose between \"progressive\" and \"dash\" vimeo downloads. go to settings > video to pick your preference.\n*; fixed the issue related to vimeo quality picking.\n*; fixed the issue when vimeo module wouldn't show appropriate errors and instead would fallback to default ones.\n*; improved audio only downloads for some edge cases.\n*; (hopefully) better youtube reliability.\n*; temporarily disabled douyin support due to api endpoint cut off.\n\ninterface improvements:\n*; merged clipboard and mode switcher rows into one for mobile view.\n*; added left-handed layout toggle for those who prefer to have the clipboard button on left.\n*; new custom-made clipboard icon. now it clearly indicates what it does.\n*; improved english and russian localization. both are way more direct and less bloaty.\n*; frontend page is now rendered once and is cached on disk instead of being rendered every time someone requests a page. this greatly improves page loading speeds and further reduces strain put on the server.\n*; frontend page is now minimized just like js and css files. this should minimize traffic wasted on loading the page, along with minor loading speed improvement.\n*; added proper checkbox icon for better clarity.\n*; checkboxes are now stretched edge-to-edge on phone to be easier to manage for right-handed people.\n*; removed button hover highlights on phones.\n*; fixed button press animations for safari on ios.\n*; fixed text selection on ios. previously you could select text or images anywhere, but now they're selectable in limited places, just like on other platforms.\n*; frontend platform is now marked in settings: p is for pc; m is for mobile; i is for ios. this is done for possible future debugging and issue-solving.\n*; better error messaging.\n\ninternal improvements:\n*; better rate limiting, there should be way less cases of accidental limits.\n*; added support for m3u8 playlists. this will be useful for future additions, and is currently used by vimeo module.\n*; added support for \"chop\" stream format for vimeo downloads.\n*; fixed vk user id extraction. i assumed the - in url was a separator, but it's actually a part of id.\n*; completely reworked the vimeo module. it's much cleaner and better performant now.\n*; minor clean ups across the board.\n\nnot really related to this update, but thank you for 50k monthly users! i really appreciate that you're still here, because that means i'm doing some things right :D" - }, { - "version": "5.1", - "title": "the evil has been defeated", - "banner": { - "file": "happymeowth.webp", - "alt": "meowth jumping up into the sky very excitedly", - "width": 500, - "height": 330 - }, - "content": "hey, ever wanted to download a youtube video without a hassle? cobalt is here to help. this update fixes all issues related to youtube downloads.\nnot only that, but it also introduces features never before seen in a downloader, such as youtube dub downloads! read below to see what's up :)\n\ntl;dr:\n*; audio in youtube videos FINALLY no longer gets cut off.\n*; you now can pick any video resolution you want (from 360p to 8k) and any possible youtube video codec (h264/av1/vp9).\n*; you now can download youtube videos with dubs in your native language. just check settings > audio.\n*; youtube processing has been vastly sped up.\n\nok, now onto the nerdy part of changelog. this update is pretty huge and includes improvements across the board.\n\nservice improvements:\n*; all youtube functionality has been reworked. cobalt now relies on innertube apis, not web scraping.\n*; random audio cut off issue has been fixed, let me know if it ever occurs again. (closes #62, #66, #75, #88).\n*; added support for youtube dubs. currently it's using your browser's default language when enabled, but i have plans on making a picker. i'll ask people on twitter and mastodon if this feature is needed, and add a picker in next updates.\n*; instead of adding more quality presets, i added granular quality options. pick whatever you like, from 360p up to 4320p (for all services, not just youtube).\n*; replaced a format picker with codec picker for youtube. you can pick h264, av1, or vp9. all of them should work as expected (closes #88).\n*; youtube audio files are now properly matched to corresponding video files.\n*; it's now always possible to download pristine h264 720p/360p videos from youtube. these videos will work ANYWHERE, so they're default for mobile.\n*; youtube requests are no longer permanently cached, ram usage should drop even further.\n*; youtube video and audio file names now include codec and dub language when applicable.\n*; max video and audio duration limits have been bumped up to 3 hours.\n*; general performance of entire youtube download process has been greatly improved.\n*; vk module has been reworked to be more compact and not make use of outdated technique of quality picking. should also be way more reliable.\n\ninternal improvements:\n*; cleaned up services config, all constants have been moved directly to modules for quicker access.\n*; matching module has been slightly cleaned up.\n\ninterface improvements:\n*; many descriptions and error messages have been slightly tuned to be less wordy.\n*; unnecessary title duplications in settings have been merged into one.\n*; added more clarity to quality and codec descriptions.\n\nif you use cobalt api, please note that you have to update your creation to support new features.\n\nthis is the second batch of 5.x improvements, there's way more to come. thank you for being here, i really appreciate your support.\n\nif you want to thank me (the developer), there's a nice tab under this changelog that has \"donations\" text on it. anything helps me continue developing and hosting the friendliest media downloader :D" - }, { - "version": "5.0", - "title": "it's all about attention to detail!", - "banner": { - "file": "valentines.webp", - "alt": "relaxed meowth with sakura petals falling in front of them", - "width": 489, - "height": 374 - }, - "content": "happy valentine's day! i have an update for you, as a gift :D\n\ntl;dr: added support for reddit gifs, fixed douyin downloads, fixed vimeo quality picking, revamped entirety of codebase, and many other fixes.\n\nhere's more info:\n\nthis update is mostly about cleaning up and polishing the codebase, but it also has some new features. here's what's up:\n\nservice-related improvements:\n*; you now can download gifs from reddit!\n*; attempting to download a video from douyin no longer throws an error (bytedance changed the api endpoint, yet again).\n*; fixed quality picking for vimeo downloads.\n*; fixed length limit check in vimeo module.\n*; fixed support for \"user view\" vk clips links.\n*; various twitter errors are now displayed correctly instead of falling back to the default error.\n*; state of all services is now tested on each commit.\n\nui improvements:\n*; cobalt social links no longer disappear if you have an aggressive ad blocking extension installed.\n*; various localization improvements for both english and russian.\n*; changed some service aliases to display full list of supported downloads.\n*; added current branch information to version text (in settings).\n*; fixed typos in older changelogs.\n\ninternal improvements:\n*; everything has been sanitized, improved, and refactored. code is now much easier to read and maintain.\n*; rewrote and/or optimized all modules that were messy or inefficient.\n*; all git interaction functions now store info in cache instead of fetching it every time the function is called.\n*; added a test script that checks functionality of all supported services.\n*; updated deepsource config. checks are more accurate now.\n*; requests from internet explorer are now dropped entirely instead of redirecting people stuck in 90s to a proper browser download page. this was done to avoid (my) personal bias towards browsers.\n\ni put a ton of effort into this version, and i hope you like it as much as i do.\n\nthank you for using cobalt. there's so much more to come :)" - }, { - "version": "4.8", - "title": "prettier than ever", - "banner": { - "file": "catmakeup.webp", - "alt": "a cat being brushed with a powder makeup brush", - "width": 394, - "height": 266 - }, - "content": "this version brings many visual improvements and a completely revamped \"about\" tab.\n\nwhat's new in \"about\" tab:\n*; all information is now split into collapsible sections, making it easier to navigate.\n*; added privacy policy to further prove that none of your data is collected.\n*; added emoji to the page title to make it look consistent with other pages.\n*; added mastodon account handle and link.\n*; there are now short notes at the end of each section.\n*; other changes that are too small to describe. just go check it out!\n\nvisual improvements:\n*; less wasted space: paddings and margins have been reduced and optimized for usability, consistency, and overall beauty.\n*; all links are now in italic. it's much easier to tell them apart from regular highlights.\n*; error popup no longer looks broken and out of place.\n*; download popup now has a proper close button, not something from 2.x era.\n*; emoji are no longer selectable or draggable.\n*; better scalability: desktop layout for home screen is shown if device viewport is wide enough to fit in three action buttons.\n*; page shouldn't look broken on phones in landscape mode (i still highly recommend using cobalt in portrait mode).\n*; removed bulletpoint padding. it was unnecessary.\n*; updated some service names.\n\nas always, you can suggest features or report bugs on any platform listed in the \"support\" section of about tab.\n\nthank you for using cobalt. i hope you have a good day :)" - }, { - "version": "4.7", - "title": "we're better together! thank you for bug reports.", - "banner": { - "file": "bettertogether.webp", - "alt": "various different pokémon jumping in happiness", - "width": 640, - "height": 358 - }, - "content": "this update includes a bunch of improvements, many of which were made thanks to the community :D\n\nservice-related improvements:\n*; private soundcloud links are now supported (#68);\n*; tiktok usernames with dots in them no longer confuse cobalt (#71);\n*; .ogg files no longer wrongfully include a video channel (#67);\n*; fixed an issue that caused cobalt to freak out when user attempted to download an audio from audio-only service with \"mute video\" option enabled.\n\nui improvements:\n*; popup padding has been evened out. popups are now able to fit in more information on scroll, especially on mobile;\n*; all buttons are now of even size and are displayed without any padding issues across all modern browsers and devices;\n*; checkbox is no longer crippled on ios;\n*; many explanation texts have been simplified to get rid of unnecessary bloat (no bullshit, remember?);\n*; moved tiktok section in video settings higher due to higher priority;\n*; fixed unexpectedly displayed scrollbars on switch rows in firefox.\n\nstability improvements:\n*; ffmpeg process now should end upon finishing the render;\n*; ffmpeg should also quit when download is abruptly cut off;\n*; fixed a memory leak that was caused by misconfigured stream information caching (#63).\n\ninternal improvements:\n*; requested streams are now stored in cache for 2 minutes instead of 1000 hours (yes, 1000 hours, i fucked up);\n*; cached data is now reused if user requests same content within 2 minutes;\n*; page render module is now even cleaner than before;\n*; proper support for bullet-points in loc strings.\n\nyou can suggest features or report bugs on github or twitter. both work just fine, use whichever you're more comfortable with.\n\nthank you for using cobalt, and thank you for reading this changelog.\n\nyou're amazing, keep it up :)" - }, { - "version": "4.6", - "title": "mute videos and proper soundcloud support", - "banner": { - "file": "shutup.webp", - "alt": "a cat yawning, with a crossed out loudspeaker icon next to it", - "width": 1024, - "height": 665 - }, - "content": "i've been longing to implement both of these things, and here they finally are.\n\nservice-related improvements:\n*; you now can download videos with no audio! simply enable the \"mute audio\" option in settings > audio.\n*; soundcloud module has been updated, and downloads should no longer break after some time.\nvisual improvements:\n*; moved some things around in settings popup, and added separators where separation is needed.\n*; updated some texts in english and russian.\n*; version and commit hash have been joined together, now they're a single unit.\ninternal improvements:\n*; updated api documentation to include isAudioMuted.\n*; simplified the startup message.\n*; created render elements for separator and explanation due to high duplication of them in the page.\n*; fully deprecated GET method for API requests.\n*; fixed some code quirks.\nhere's how soundcloud downloads got fixed:\n\npreviously, client_id was (stupidly) hardcoded. that means cobalt wasn't able to fetch song data if soundcloud web app got updated.\nnow, cobalt tries to find the up-to-date client_id, caches it in memory, and checks if web app version has changed to update the id accordingly. you can see this change for yourself on github." - }, { - "version": "4.5", - "title": "better, faster, stronger, stable", - "banner": { - "file": "meowthstrong.webp", - "alt": "meowth stretching", - "width": 500, - "height": 280 - }, - "content": "your favorite social media downloader just got even better! this update includes a ton of improvements and fixes.\n\nin fact, there are so many changes, i had to split them in sections.\n\nservice-related improvements:\n*; vimeo module has been revamped, all sorts of videos should now be supported.\n*; vimeo audio downloads! you now can download audios from more recent videos.\n*; cobalt now supports all sorts of tumblr links. (even those scary ones from the mobile app)\n*; vk clips support has been fixed. they rolled back the separation of videos and clips, so i had to do the same.\n*; youtube videos with community warnings should now be possible to download.\nuser interface improvements:\n*; list of supported services is now MUCH easier to read.\n*; banners in changelog history should no longer overlap each other.\n*; bullet points! they have a bit of extra padding, so it makes them stand out of the rest of text.\ninternal improvements:\n*; cobalt will now match the link to regex when using ?u= query for autopasting it into input area.\n*; better rate limiting: limiting now is done per minute, not per 20 minutes. this ensures less waiting and less attack area for request spammers.\n*; moved to my own fork of ytdl-core, cause main project seems to have been abandoned. go check it out on github or npm!\n*; ALL user inputs are now properly sanitized on the server. that includes variables for POST api method, too.\n*; \"got\" package has been (mostly) replaced by native fetch api. this should greatly reduce ram usage.\n*; all unnecessary duplications of module imports have been gotten rid of. no more error passing strings from inside of service modules. you don't make mistakes only if you don't do anything, right?\n*; other code optimizations. there's less clutter overall.\nhuge update, right? seems like everything's fixed now?\n\nnope, one issue still persists: sometimes youtube server drops packets for an audio file while cobalt's rendering the video for you. this results in abrupt cuts of audio. if you want to help solving this issue, please feel free to do it on github!\n\nthank you for reading this, and thank you for sticking with cobalt and me." - }, { - "version": "4.4", - "title": "over 1 million monthly requests. thank you.", - "banner": { - "file": "onemillionr.webp", - "alt": "cobalt logo and a confetti emoji", - "width": 1441, - "height": 1441 - }, - "content": "this is a huge milestone for me, i cannot express enough how grateful i am for each and every one of you.\nthank you for using cobalt, and thank you for showing that people love the web that's friendly and bullshit-free. i'm hoping to never disappoint you in the future and keep up the good work.\n\nthank you <3\n\nif you want to thank ME, check out the renovated donations tab, which now is also linked alongside bottom action buttons." - }, { - "version": "4.3.2", - "title": "twitter improvements & changelog overhaul", - "content": "- you can download explicit content from twitter.\n- direct video links from twitter are properly supported (video/1, video/2, etc.).\n- changelog history got support for banners.\n- changelog categories are not messy anymore.\n- cobalt version in changelogs is now highlighted.\n- changelog history got separators to make text easier to read.\n- changelog history can be collapsed after loading.\n- download button takes less time to change back to pressable state.\n\nif you're a developer and would like to play around with cobalt's api, then read more about it in older changelogs below!" - }, { - "version": "4.3", - "title": "developers, developers, developers, developers", - "banner": { - "file": "developers.webp", - "alt": "steve ballmer going \"developers, developers, developers\"", - "width": 640, - "height": 360 - }, - "content": "this update features a TON of improvements.\n\ndevelopers, you now can rely on cobalt for getting content from social media. the api has been revamped and documentation is now available. you can read more about API changes down below. go crazy, and have fun :D\n\nif you're not a developer, here's a list of changes that you probably care about:\n- rate limit is now approximately 8 times bigger. no more waiting, even if you want to download entirety of your tiktok \"for you\" page.\n- some updates will now have expressive banners, just like this one.\n- fixed what was causing an error when a youtube video had no description.\n- mp4 format button text should now be displayed properly, no matter if you touched the switcher or not.\n\nnext, the star of this update — improved api!\n- main endpoint now uses POST method instead of GET.\n- internal variables for preferences have been updated to be consistent and easier to understand.\n- ip address is now hashed right upon request, not somewhere deep inside the code.\n- global stream salt variable is no longer unnecessarily passed over a billion functions.\n- url and picker keys are now separate in the json response.\n- cobalt web app now correctly processes responses with \"success\" status.\n\nif you currently have a siri shortcut or some other script that uses the GET method, make sure to update it soon. this method is deprecated, limited, and will be removed entirely in coming updates.\n\nif you ever make something using cobalt's api, make sure to mention @justusecobalt on twitter, i would absolutely love to see what you made." - }, { - "version": "4.2", - "title": "optimized quality picking and 8k video support", - "content": "- this update fixes quality picking that was accidentally broken in 4.0 update.\n- you now can download videos in 8k from youtube. why would you that? no idea. but i'm more than happy to give you this option.\n- default video quality for downloads from pc is now 1440p, and 720p for phones.\n- default video format is now mp4 for everyone.\n- default audio format is now mp3 for everyone.\n\nyou can always change new defaults back to whatever you prefer in settings.\n\nother changes:\n- added more clarity to quality picker description.\n- youtube video codecs are now right in the picker.\n- setup script is now easier to understand." - }, { - "version": "4.1", - "title": "better tiktok image downloads", - "content": "here's what's up:\n- tiktok images are saved as .jpeg instead of .webp (finally, i know).\n- added support for image downloads from douyin.\n- fixed tiktok audio downloads from the image picker.\n- emoji in about button now changes on special occasions. be it halloween or christmas, cobalt will change just a tiny bit to fit in :D\n\nif you're not caught up with new stuff in cobalt 4.x yet, check out the previous changelog down below. there's a ton of stuff to like." - }, { - "version": "4.0", - "title": "better and faster than ever", - "content": "this update has a ton of improvements and new features.\n\nchanges you probably care about:\n- cobalt now has support for recorded twitter spaces! download the previous conversation no matter how long it was.\n- download speeds from youtube are at least 10 times better now. you're welcome.\n- both video and audio length limits have been extended to 2 hours.\n- audio downloads from youtube, youtube music, twitter spaces, and soundcloud now have metadata! most often it's just title and artist, but when cobalt is able to get more info, it adds that metadata too.\n- tiktok downloads have been fixed, yet again, and if they ever break in the future, cobalt will fall back to downloading a less annoyingly watermarked video.\n- soundcloud downloads have been fixed, too.\n\nless notable changes:\n- currently experimenting with using mp3 as default audio format. if you set something other than mp3 before, it'll be set to mp3. you can always change it back in settings. let me know what you think about this.\n- \"download audio\" button from image picker no longer stays on the screen after popup was closed.\n- clipboard button now shows up depending on your browser's support for it.\n- you can no longer manually hide the clipboard button, 'cause it's unnecessary.\n- small internal improvements such as separation of changelog version and title.\n- fair bit of internal clean up.\n\nif you want to help me implement covers for downloaded audios, you can do it on github." - }, { - "version": "3.7", - "title": "support for multi media tweets is here!", - "content": "cobalt now lets you save any of the videos or gifs in a tweet. even if there are many of them.\n\nsimply paste a link like you'd usually do and cobalt will ask what exactly you want to save.\n\nFIREFOX USERS: if you have strict tracking protection on, you might wanna turn it off for cobalt, or else twitter video previews won't load. firefox filters out twitter image cdn as if it was a tracker, which it's not. it's a false-positive.\n\nhowever, you can leave it on if you're fine with blank squares and video numbers. i have thought of that in prior, you're welcome.\n\nother changes:\n- repurposed ex tiktok-only image picker to be dynamic and adapt depending on content to pick. that's exactly how twitter multi media downloads work.\n- cobalt is now properly viewable on phones with tiny screens, such as first gen iphone se.\n- scrollbars now should be visible only where they're needed.\n- brought back proper twitter api, because other one doesn't have multi media stuff (at least yet).\n- cleaned up some internal files, including main frontend js file.\n- reorganized some files in project directory, now you won't get lost when contributing or just looking through cobalt's code." - }, { - "version": "3.6.2 + 3.6.3", - "title": "less disturbance", - "content": "changelog popup no longer annoys you after a major update! this action has been replaced with a notification dot. if you see a red dot, then there's something new.\n\nyour old setting that disabled the changelog popup now applies to notifications.\n\nnew users will see a notification dot instead of an about popup, too. this was mostly done to prevent complications if your browser is set up to clean local storage when you close it.\n\nother changes:\n- popups are now a bit wider, just so more content fits at once.\n- better interface scaling.\n- code is a bit cleaner now.\n- changed twitter api endpoint. there should no longer be any rate limits." - }, { - "version": "3.6", - "title": "improvements all around!", - "content": "- download mode switcher is moving places, it's now right next to link input area.\n- smart mode has been renamed to auto mode, because this name is easier to understand.\n- all spacings in ui have been evened out. no more eye strain.\n- added support for twitter /video/1 links\n- clipboard button exception has been redone to prepare for adoption of readtext clipboard api in firefox.\n- cobalt is now using different tiktok api endpoint, because previous one got killed, just like the one before.\n- \"other\" settings tab has been cleaned up." - }, { - "version": "3.5.4", - "title": "tiktok support is back :D", - "content": "you can download videos, sounds, and images from tiktok again!\nhuge thank you to @minzique for finding another api endpoint that works." - }, { - "version": "3.5.2", - "title": "vk clips support, improved changelog system, and less bugs", - "content": "new features: \n- added support for vk clips. cobalt now lets you download even more cringy videos!\n- added update history right to the changelog menu. it's not loaded by default to minimize page load time, but can be loaded upon pressing a button. probably someone will enjoy this.\n- as you've just read, cobalt now has on-demand blocks. they're rendered on server upon request and exist to prevent any unnecessary clutter by default. the first feature to use on-demand rendering is history of updates in changelog tab.\n\nchanges:\n- moved twitter entry to about tab and made it localized.\n- added clarity to what services exactly are supported in about tab.\n\nbug fixes:\n- cobalt should no longer crash to firefox users if they love to play around with user-agent switching.\n- vk videos of any resolution and aspect ratio should now be downloadable.\n- vk quality picking has been fixed after vk broke it for parsers on their side." - }, { - "version": "3.5", - "title": "ui revamp and usability improvements", - "content": "new features:\n- cobalt now lets you paste the link in your clipboard and download the file in a single press of a button.if your clipboard's latest content isn't a valid url, cobalt won't process or paste it. you can also hide the clipboard button in settings if you want to.\nunfortunately, the clipboard feature is not available to firefox users because mozilla didn't add proper support for clipboard api.\n- there's now a button to quickly clean the input area, right next to download button. it's really useful in case when you want to quickly save a bunch of videos and don't want to bother selecting text.\n- keyboard shortcuts! you love them, i love them, and now we can use them to perform quick actions in cobalt. use ctrl+v combo to paste the link without focusing the input area; press escape key to close the active popup or clean the input area; and if you didn't know, you can also press enter to download content from the link.\n\nnew looks:\n- main box has been revamped. it has lost its border, thick padding, and now feels light and fresh.\n- download button is now prettier, and has been tuned to make >> look just like the logo.\n- buttons on the bottom now actually look like buttons and are way more descriptive. no more #@+?$ bullshit. it's way easier to see and understand what each of them does.\n- bottom buttons are prettier and easier to use on a phone. they're bigger and stretch out to sides, making them easier to press.\n\nfixes:\n- it's now impossible to overlap multiple popups at once. no more mess if you decide to explore popups while waiting for request to process.\n- popup tabs have been slightly moved down to prevent popup content overlapping.\n- ui scalability has been improved." - }] -} diff --git a/web/changelogs/3.5.2.md b/web/changelogs/3.5.2.md new file mode 100644 index 00000000..7add6687 --- /dev/null +++ b/web/changelogs/3.5.2.md @@ -0,0 +1,16 @@ +--- +title: "vk clips support, improved changelog system, and less bugs" +--- +new features: +- added support for vk clips. cobalt now lets you download even more cringy videos! +- added update history right to the changelog menu. it's not loaded by default to minimize page load time, but can be loaded upon pressing a button. probably someone will enjoy this. +- as you've just read, cobalt now has on-demand blocks. they're rendered on server upon request and exist to prevent any unnecessary clutter by default. the first feature to use on-demand rendering is history of updates in changelog tab. + +changes: +- moved twitter entry to about tab and made it localized. +- added clarity to what services exactly are supported in about tab. + +bug fixes: +- cobalt should no longer crash to firefox users if they love to play around with user-agent switching. +- vk videos of any resolution and aspect ratio should now be downloadable. +- vk quality picking has been fixed after vk broke it for parsers on their side. \ No newline at end of file diff --git a/web/changelogs/3.5.4.md b/web/changelogs/3.5.4.md new file mode 100644 index 00000000..f3a4cd64 --- /dev/null +++ b/web/changelogs/3.5.4.md @@ -0,0 +1,5 @@ +--- +title: "tiktok support is back :D" +--- +you can download videos, sounds, and images from tiktok again! +huge thank you to @minzique for finding another api endpoint that works. \ No newline at end of file diff --git a/web/changelogs/3.5.md b/web/changelogs/3.5.md new file mode 100644 index 00000000..0e706cdc --- /dev/null +++ b/web/changelogs/3.5.md @@ -0,0 +1,19 @@ +--- +title: "ui revamp and usability improvements" +--- +new features: +- cobalt now lets you paste the link in your clipboard and download the file in a single press of a button.if your clipboard's latest content isn't a valid url, cobalt won't process or paste it. you can also hide the clipboard button in settings if you want to. +unfortunately, the clipboard feature is not available to firefox users because mozilla didn't add proper support for clipboard api. +- there's now a button to quickly clean the input area, right next to download button. it's really useful in case when you want to quickly save a bunch of videos and don't want to bother selecting text. +- keyboard shortcuts! you love them, i love them, and now we can use them to perform quick actions in cobalt. use ctrl+v combo to paste the link without focusing the input area; press escape key to close the active popup or clean the input area; and if you didn't know, you can also press enter to download content from the link. + +new looks: +- main box has been revamped. it has lost its border, thick padding, and now feels light and fresh. +- download button is now prettier, and has been tuned to make >> look just like the logo. +- buttons on the bottom now actually look like buttons and are way more descriptive. no more #@+?$ bullshit. it's way easier to see and understand what each of them does. +- bottom buttons are prettier and easier to use on a phone. they're bigger and stretch out to sides, making them easier to press. + +fixes: +- it's now impossible to overlap multiple popups at once. no more mess if you decide to explore popups while waiting for request to process. +- popup tabs have been slightly moved down to prevent popup content overlapping. +- ui scalability has been improved. \ No newline at end of file diff --git a/web/changelogs/3.6.3.md b/web/changelogs/3.6.3.md new file mode 100644 index 00000000..49459ecc --- /dev/null +++ b/web/changelogs/3.6.3.md @@ -0,0 +1,14 @@ +--- +title: "less disturbance" +--- +changelog popup no longer annoys you after a major update! this action has been replaced with a notification dot. if you see a red dot, then there's something new. + +your old setting that disabled the changelog popup now applies to notifications. + +new users will see a notification dot instead of an about popup, too. this was mostly done to prevent complications if your browser is set up to clean local storage when you close it. + +other changes: +- popups are now a bit wider, just so more content fits at once. +- better interface scaling. +- code is a bit cleaner now. +- changed twitter api endpoint. there should no longer be any rate limits. \ No newline at end of file diff --git a/web/changelogs/3.6.md b/web/changelogs/3.6.md new file mode 100644 index 00000000..39d34308 --- /dev/null +++ b/web/changelogs/3.6.md @@ -0,0 +1,10 @@ +--- +title: "improvements all around!" +--- +- download mode switcher is moving places, it's now right next to link input area. +- smart mode has been renamed to auto mode, because this name is easier to understand. +- all spacings in ui have been evened out. no more eye strain. +- added support for twitter /video/1 links +- clipboard button exception has been redone to prepare for adoption of readtext clipboard api in firefox. +- cobalt is now using different tiktok api endpoint, because previous one got killed, just like the one before. +- "other" settings tab has been cleaned up. \ No newline at end of file diff --git a/web/changelogs/3.7.md b/web/changelogs/3.7.md new file mode 100644 index 00000000..3fdad1e6 --- /dev/null +++ b/web/changelogs/3.7.md @@ -0,0 +1,18 @@ +--- +title: "support for multi media tweets is here!" +--- +cobalt now lets you save any of the videos or gifs in a tweet. even if there are many of them. + +simply paste a link like you'd usually do and cobalt will ask what exactly you want to save. + +FIREFOX USERS: if you have strict tracking protection on, you might wanna turn it off for cobalt, or else twitter video previews won't load. firefox filters out twitter image cdn as if it was a tracker, which it's not. it's a false-positive. + +however, you can leave it on if you're fine with blank squares and video numbers. i have thought of that in prior, you're welcome. + +other changes: +- repurposed ex tiktok-only image picker to be dynamic and adapt depending on content to pick. that's exactly how twitter multi media downloads work. +- cobalt is now properly viewable on phones with tiny screens, such as first gen iphone se. +- scrollbars now should be visible only where they're needed. +- brought back proper twitter api, because other one doesn't have multi media stuff (at least yet). +- cleaned up some internal files, including main frontend js file. +- reorganized some files in project directory, now you won't get lost when contributing or just looking through cobalt's code. \ No newline at end of file diff --git a/web/changelogs/4.0.md b/web/changelogs/4.0.md new file mode 100644 index 00000000..287c5625 --- /dev/null +++ b/web/changelogs/4.0.md @@ -0,0 +1,22 @@ +--- +title: "better and faster than ever" +--- +this update has a ton of improvements and new features. + +changes you probably care about: +- cobalt now has support for recorded twitter spaces! download the previous conversation no matter how long it was. +- download speeds from youtube are at least 10 times better now. you're welcome. +- both video and audio length limits have been extended to 2 hours. +- audio downloads from youtube, youtube music, twitter spaces, and soundcloud now have metadata! most often it's just title and artist, but when cobalt is able to get more info, it adds that metadata too. +- tiktok downloads have been fixed, yet again, and if they ever break in the future, cobalt will fall back to downloading a less annoyingly watermarked video. +- soundcloud downloads have been fixed, too. + +less notable changes: +- currently experimenting with using mp3 as default audio format. if you set something other than mp3 before, it'll be set to mp3. you can always change it back in settings. let me know what you think about this. +- "download audio" button from image picker no longer stays on the screen after popup was closed. +- clipboard button now shows up depending on your browser's support for it. +- you can no longer manually hide the clipboard button, 'cause it's unnecessary. +- small internal improvements such as separation of changelog version and title. +- fair bit of internal clean up. + +if you want to help me implement covers for downloaded audios, you can do it on github. \ No newline at end of file diff --git a/web/changelogs/4.1.md b/web/changelogs/4.1.md new file mode 100644 index 00000000..c8dacab1 --- /dev/null +++ b/web/changelogs/4.1.md @@ -0,0 +1,10 @@ +--- +title: "better tiktok image downloads" +--- +here's what's up: +- tiktok images are saved as .jpeg instead of .webp (finally, i know). +- added support for image downloads from douyin. +- fixed tiktok audio downloads from the image picker. +- emoji in about button now changes on special occasions. be it halloween or christmas, cobalt will change just a tiny bit to fit in :D + +if you're not caught up with new stuff in cobalt 4.x yet, check out the previous changelog down below. there's a ton of stuff to like. \ No newline at end of file diff --git a/web/changelogs/4.2.md b/web/changelogs/4.2.md new file mode 100644 index 00000000..9424f061 --- /dev/null +++ b/web/changelogs/4.2.md @@ -0,0 +1,15 @@ +--- +title: "optimized quality picking and 8k video support" +--- +- this update fixes quality picking that was accidentally broken in 4.0 update. +- you now can download videos in 8k from youtube. why would you that? no idea. but i'm more than happy to give you this option. +- default video quality for downloads from pc is now 1440p, and 720p for phones. +- default video format is now mp4 for everyone. +- default audio format is now mp3 for everyone. + +you can always change new defaults back to whatever you prefer in settings. + +other changes: +- added more clarity to quality picker description. +- youtube video codecs are now right in the picker. +- setup script is now easier to understand. \ No newline at end of file diff --git a/web/changelogs/4.3.2.md b/web/changelogs/4.3.2.md new file mode 100644 index 00000000..adabaff3 --- /dev/null +++ b/web/changelogs/4.3.2.md @@ -0,0 +1,13 @@ +--- +title: "twitter improvements & changelog overhaul" +--- +- you can download explicit content from twitter. +- direct video links from twitter are properly supported (video/1, video/2, etc.). +- changelog history got support for banners. +- changelog categories are not messy anymore. +- cobalt version in changelogs is now highlighted. +- changelog history got separators to make text easier to read. +- changelog history can be collapsed after loading. +- download button takes less time to change back to pressable state. + +if you're a developer and would like to play around with cobalt's api, then read more about it in older changelogs below! \ No newline at end of file diff --git a/web/changelogs/4.3.md b/web/changelogs/4.3.md new file mode 100644 index 00000000..8d07cb9a --- /dev/null +++ b/web/changelogs/4.3.md @@ -0,0 +1,27 @@ +--- +title: "developers, developers, developers, developers" +banner: + file: "developers.webp" + alt: "steve ballmer going \"developers, developers, developers\"" +--- +this update features a TON of improvements. + +developers, you now can rely on cobalt for getting content from social media. the api has been revamped and documentation is now available. you can read more about API changes down below. go crazy, and have fun :D + +if you're not a developer, here's a list of changes that you probably care about: +- rate limit is now approximately 8 times bigger. no more waiting, even if you want to download entirety of your tiktok "for you" page. +- some updates will now have expressive banners, just like this one. +- fixed what was causing an error when a youtube video had no description. +- mp4 format button text should now be displayed properly, no matter if you touched the switcher or not. + +next, the star of this update — improved api! +- main endpoint now uses POST method instead of GET. +- internal variables for preferences have been updated to be consistent and easier to understand. +- ip address is now hashed right upon request, not somewhere deep inside the code. +- global stream salt variable is no longer unnecessarily passed over a billion functions. +- url and picker keys are now separate in the json response. +- cobalt web app now correctly processes responses with "success" status. + +if you currently have a siri shortcut or some other script that uses the GET method, make sure to update it soon. this method is deprecated, limited, and will be removed entirely in coming updates. + +if you ever make something using cobalt's api, make sure to mention @justusecobalt on twitter, i would absolutely love to see what you made. \ No newline at end of file diff --git a/web/changelogs/4.4.md b/web/changelogs/4.4.md new file mode 100644 index 00000000..5d63ea5d --- /dev/null +++ b/web/changelogs/4.4.md @@ -0,0 +1,12 @@ +--- +title: "over 1 million monthly requests. thank you." +banner: + file: "onemillionr.webp" + alt: "cobalt logo and a confetti emoji" +--- +this is a huge milestone for me, i cannot express enough how grateful i am for each and every one of you. +thank you for using cobalt, and thank you for showing that people love the web that's friendly and bullshit-free. i'm hoping to never disappoint you in the future and keep up the good work. + +thank you &lt;3 + +if you want to thank ME, check out the renovated donations tab, which now is also linked alongside bottom action buttons. \ No newline at end of file diff --git a/web/changelogs/4.5.md b/web/changelogs/4.5.md new file mode 100644 index 00000000..26e68881 --- /dev/null +++ b/web/changelogs/4.5.md @@ -0,0 +1,33 @@ +--- +title: "better, faster, stronger, stable" +banner: + file: "meowthstrong.webp" + alt: "meowth stretching" +--- +your favorite social media downloader just got even better! this update includes a ton of improvements and fixes. + +in fact, there are so many changes, i had to split them in sections. + +service-related improvements: +- vimeo module has been revamped, all sorts of videos should now be supported. +- vimeo audio downloads! you now can download audios from more recent videos. +- cobalt now supports all sorts of tumblr links. (even those scary ones from the mobile app) +- vk clips support has been fixed. they rolled back the separation of videos and clips, so i had to do the same. +- youtube videos with community warnings should now be possible to download. +user interface improvements: +- list of supported services is now MUCH easier to read. +- banners in changelog history should no longer overlap each other. +- bullet points! they have a bit of extra padding, so it makes them stand out of the rest of text. +internal improvements: +- cobalt will now match the link to regex when using ?u= query for autopasting it into input area. +- better rate limiting: limiting now is done per minute, not per 20 minutes. this ensures less waiting and less attack area for request spammers. +- moved to my own fork of ytdl-core, cause main project seems to have been abandoned. go check it out on github or npm! +- ALL user inputs are now properly sanitized on the server. that includes variables for POST api method, too. +- "got" package has been (mostly) replaced by native fetch api. this should greatly reduce ram usage. +- all unnecessary duplications of module imports have been gotten rid of. no more error passing strings from inside of service modules. you don't make mistakes only if you don't do anything, right? +- other code optimizations. there's less clutter overall. +huge update, right? seems like everything's fixed now? + +nope, one issue still persists: sometimes youtube server drops packets for an audio file while cobalt's rendering the video for you. this results in abrupt cuts of audio. if you want to help solving this issue, please feel free to do it on github! + +thank you for reading this, and thank you for sticking with cobalt and me. \ No newline at end of file diff --git a/web/changelogs/4.6.md b/web/changelogs/4.6.md new file mode 100644 index 00000000..bc13fc99 --- /dev/null +++ b/web/changelogs/4.6.md @@ -0,0 +1,25 @@ +--- +title: "mute videos and proper soundcloud support" +banner: + file: "shutup.webp" + alt: "a cat yawning, with a crossed out loudspeaker icon next to it" +--- +i've been longing to implement both of these things, and here they finally are. + +service-related improvements: +- you now can download videos with no audio! simply enable the "mute audio" option in settings > audio. +- soundcloud module has been updated, and downloads should no longer break after some time. +visual improvements: +- moved some things around in settings popup, and added separators where separation is needed. +- updated some texts in english and russian. +- version and commit hash have been joined together, now they're a single unit. +internal improvements: +- updated api documentation to include isAudioMuted. +- simplified the startup message. +- created render elements for separator and explanation due to high duplication of them in the page. +- fully deprecated GET method for API requests. +- fixed some code quirks. +here's how soundcloud downloads got fixed: + +previously, client_id was (stupidly) hardcoded. that means cobalt wasn't able to fetch song data if soundcloud web app got updated. +now, cobalt tries to find the up-to-date client_id, caches it in memory, and checks if web app version has changed to update the id accordingly. you can see this change for yourself on github. \ No newline at end of file diff --git a/web/changelogs/4.7.md b/web/changelogs/4.7.md new file mode 100644 index 00000000..b81c16e0 --- /dev/null +++ b/web/changelogs/4.7.md @@ -0,0 +1,38 @@ +--- +title: "we're better together! thank you for bug reports." +banner: + file: "bettertogether.webp" + alt: "various different pokémon jumping in happiness" +--- +this update includes a bunch of improvements, many of which were made thanks to the community :D + +service-related improvements: +- private soundcloud links are now supported (#68); +- tiktok usernames with dots in them no longer confuse cobalt (#71); +- .ogg files no longer wrongfully include a video channel (#67); +- fixed an issue that caused cobalt to freak out when user attempted to download an audio from audio-only service with "mute video" option enabled. + +ui improvements: +- popup padding has been evened out. popups are now able to fit in more information on scroll, especially on mobile; +- all buttons are now of even size and are displayed without any padding issues across all modern browsers and devices; +- checkbox is no longer crippled on ios; +- many explanation texts have been simplified to get rid of unnecessary bloat (no bullshit, remember?); +- moved tiktok section in video settings higher due to higher priority; +- fixed unexpectedly displayed scrollbars on switch rows in firefox. + +stability improvements: +- ffmpeg process now should end upon finishing the render; +- ffmpeg should also quit when download is abruptly cut off; +- fixed a memory leak that was caused by misconfigured stream information caching (#63). + +internal improvements: +- requested streams are now stored in cache for 2 minutes instead of 1000 hours (yes, 1000 hours, i fucked up); +- cached data is now reused if user requests same content within 2 minutes; +- page render module is now even cleaner than before; +- proper support for bullet-points in loc strings. + +you can suggest features or report bugs on github or twitter. both work just fine, use whichever you're more comfortable with. + +thank you for using cobalt, and thank you for reading this changelog. + +you're amazing, keep it up :) \ No newline at end of file diff --git a/web/changelogs/4.8.md b/web/changelogs/4.8.md new file mode 100644 index 00000000..60db3452 --- /dev/null +++ b/web/changelogs/4.8.md @@ -0,0 +1,30 @@ +--- +title: "prettier than ever" +banner: + file: "catmakeup.webp" + alt: "a cat being brushed with a powder makeup brush" +--- +this version brings many visual improvements and a completely revamped "about" tab. + +what's new in "about" tab: +- all information is now split into collapsible sections, making it easier to navigate. +- added privacy policy to further prove that none of your data is collected. +- added emoji to the page title to make it look consistent with other pages. +- added mastodon account handle and link. +- there are now short notes at the end of each section. +- other changes that are too small to describe. just go check it out! + +visual improvements: +- less wasted space: paddings and margins have been reduced and optimized for usability, consistency, and overall beauty. +- all links are now in italic. it's much easier to tell them apart from regular highlights. +- error popup no longer looks broken and out of place. +- download popup now has a proper close button, not something from 2.x era. +- emoji are no longer selectable or draggable. +- better scalability: desktop layout for home screen is shown if device viewport is wide enough to fit in three action buttons. +- page shouldn't look broken on phones in landscape mode (i still highly recommend using cobalt in portrait mode). +- removed bulletpoint padding. it was unnecessary. +- updated some service names. + +as always, you can suggest features or report bugs on any platform listed in the "support" section of about tab. + +thank you for using cobalt. i hope you have a good day :) \ No newline at end of file diff --git a/web/changelogs/5.0.md b/web/changelogs/5.0.md new file mode 100644 index 00000000..328fdbf0 --- /dev/null +++ b/web/changelogs/5.0.md @@ -0,0 +1,41 @@ +--- +title: "it's all about attention to detail!" +banner: + file: "valentines.webp" + alt: "relaxed meowth with sakura petals falling in front of them" +--- +happy valentine's day! i have an update for you, as a gift :D + +tl;dr: added support for reddit gifs, fixed douyin downloads, fixed vimeo quality picking, revamped entirety of codebase, and many other fixes. + +here's more info: + +this update is mostly about cleaning up and polishing the codebase, but it also has some new features. here's what's up: + +service-related improvements: +- you now can download gifs from reddit! +- attempting to download a video from douyin no longer throws an error (bytedance changed the api endpoint, yet again). +- fixed quality picking for vimeo downloads. +- fixed length limit check in vimeo module. +- fixed support for "user view" vk clips links. +- various twitter errors are now displayed correctly instead of falling back to the default error. +- state of all services is now tested on each commit. + +ui improvements: +- cobalt social links no longer disappear if you have an aggressive ad blocking extension installed. +- various localization improvements for both english and russian. +- changed some service aliases to display full list of supported downloads. +- added current branch information to version text (in settings). +- fixed typos in older changelogs. + +internal improvements: +- everything has been sanitized, improved, and refactored. code is now much easier to read and maintain. +- rewrote and/or optimized all modules that were messy or inefficient. +- all git interaction functions now store info in cache instead of fetching it every time the function is called. +- added a test script that checks functionality of all supported services. +- updated deepsource config. checks are more accurate now. +- requests from internet explorer are now dropped entirely instead of redirecting people stuck in 90s to a proper browser download page. this was done to avoid (my) personal bias towards browsers. + +i put a ton of effort into this version, and i hope you like it as much as i do. + +thank you for using cobalt. there's so much more to come :) \ No newline at end of file diff --git a/web/changelogs/5.1.md b/web/changelogs/5.1.md new file mode 100644 index 00000000..905c573d --- /dev/null +++ b/web/changelogs/5.1.md @@ -0,0 +1,45 @@ +--- +title: "the evil has been defeated" +banner: + file: "happymeowth.webp" + alt: "meowth jumping up into the sky very excitedly" +--- +hey, ever wanted to download a youtube video without a hassle? cobalt is here to help. this update fixes all issues related to youtube downloads. +not only that, but it also introduces features never before seen in a downloader, such as youtube dub downloads! read below to see what's up :) + +tl;dr: +- audio in youtube videos FINALLY no longer gets cut off. +- you now can pick any video resolution you want (from 360p to 8k) and any possible youtube video codec (h264/av1/vp9). +- you now can download youtube videos with dubs in your native language. just check settings > audio. +- youtube processing has been vastly sped up. + +ok, now onto the nerdy part of changelog. this update is pretty huge and includes improvements across the board. + +service improvements: +- all youtube functionality has been reworked. cobalt now relies on innertube apis, not web scraping. +- random audio cut off issue has been fixed, let me know if it ever occurs again. (closes #62, #66, #75, #88). +- added support for youtube dubs. currently it's using your browser's default language when enabled, but i have plans on making a picker. i'll ask people on twitter and mastodon if this feature is needed, and add a picker in next updates. +- instead of adding more quality presets, i added granular quality options. pick whatever you like, from 360p up to 4320p (for all services, not just youtube). +- replaced a format picker with codec picker for youtube. you can pick h264, av1, or vp9. all of them should work as expected (closes #88). +- youtube audio files are now properly matched to corresponding video files. +- it's now always possible to download pristine h264 720p/360p videos from youtube. these videos will work ANYWHERE, so they're default for mobile. +- youtube requests are no longer permanently cached, ram usage should drop even further. +- youtube video and audio file names now include codec and dub language when applicable. +- max video and audio duration limits have been bumped up to 3 hours. +- general performance of entire youtube download process has been greatly improved. +- vk module has been reworked to be more compact and not make use of outdated technique of quality picking. should also be way more reliable. + +internal improvements: +- cleaned up services config, all constants have been moved directly to modules for quicker access. +- matching module has been slightly cleaned up. + +interface improvements: +- many descriptions and error messages have been slightly tuned to be less wordy. +- unnecessary title duplications in settings have been merged into one. +- added more clarity to quality and codec descriptions. + +if you use cobalt api, please note that you have to update your creation to support new features. + +this is the second batch of 5.x improvements, there's way more to come. thank you for being here, i really appreciate your support. + +if you want to thank me (the developer), there's a nice tab under this changelog that has "donations" text on it. anything helps me continue developing and hosting the friendliest media downloader :D \ No newline at end of file diff --git a/web/changelogs/5.2.md b/web/changelogs/5.2.md new file mode 100644 index 00000000..e6e7c72b --- /dev/null +++ b/web/changelogs/5.2.md @@ -0,0 +1,52 @@ +--- +title: "fastest one in the game" +banner: + file: "catspeed.webp" + alt: "a cat running very fast in an exercise wheel" +--- +hey, notice anything different? well, at very least the page loaded way faster! this update includes many improvements and fixes, but also some new features. + +tl;dr: +- twitter retweet links are now supported. +- all vimeo videos should now be possible to download. +- you now can download audio from vimeo. +- it's now possible to pick between preferred vimeo download method in settings. +- fixed issues related to tiktok, twitter, twitter spaces, and vimeo downloads. +- overall cobalt performance should be MUCH better. + +service improvements: +- added support for twitter retweet links. now all kinds of tweet links are supported. +- fixed the issue related to periods in tiktok usernames (#96). +- fixed twitter spaces downloads. +- added support for audio downloads from vimeo. +- added ability to choose between "progressive" and "dash" vimeo downloads. go to settings > video to pick your preference. +- fixed the issue related to vimeo quality picking. +- fixed the issue when vimeo module wouldn't show appropriate errors and instead would fallback to default ones. +- improved audio only downloads for some edge cases. +- (hopefully) better youtube reliability. +- temporarily disabled douyin support due to api endpoint cut off. + +interface improvements: +- merged clipboard and mode switcher rows into one for mobile view. +- added left-handed layout toggle for those who prefer to have the clipboard button on left. +- new custom-made clipboard icon. now it clearly indicates what it does. +- improved english and russian localization. both are way more direct and less bloaty. +- frontend page is now rendered once and is cached on disk instead of being rendered every time someone requests a page. this greatly improves page loading speeds and further reduces strain put on the server. +- frontend page is now minimized just like js and css files. this should minimize traffic wasted on loading the page, along with minor loading speed improvement. +- added proper checkbox icon for better clarity. +- checkboxes are now stretched edge-to-edge on phone to be easier to manage for right-handed people. +- removed button hover highlights on phones. +- fixed button press animations for safari on ios. +- fixed text selection on ios. previously you could select text or images anywhere, but now they're selectable in limited places, just like on other platforms. +- frontend platform is now marked in settings: p is for pc; m is for mobile; i is for ios. this is done for possible future debugging and issue-solving. +- better error messaging. + +internal improvements: +- better rate limiting, there should be way less cases of accidental limits. +- added support for m3u8 playlists. this will be useful for future additions, and is currently used by vimeo module. +- added support for "chop" stream format for vimeo downloads. +- fixed vk user id extraction. i assumed the - in url was a separator, but it's actually a part of id. +- completely reworked the vimeo module. it's much cleaner and better performant now. +- minor clean ups across the board. + +not really related to this update, but thank you for 50k monthly users! i really appreciate that you're still here, because that means i'm doing some things right :D \ No newline at end of file diff --git a/web/changelogs/5.3.md b/web/changelogs/5.3.md new file mode 100644 index 00000000..3233f365 --- /dev/null +++ b/web/changelogs/5.3.md @@ -0,0 +1,20 @@ +--- +title: "better looks, better feel" +banner: + file: "cattired.webp" + alt: "a cat laying on a sofa face down, wiggling its tail" +--- +this update isn't as big as previous ones, but it still greatly enhances the cobalt experience. + +here's what's up: +- new mode switcher! elegant and 100% clear. should no longer cause any confusion. let me know if you like it better this way :D +- wide paste button on mobile is back, but now it's even closer to your finger. +- removed the weird grey chin on changelog banners. +- removed left-handed layout toggle since it is no longer needed. +- fixed input area display in chromium 112+. +- centered the main action box. +- cleaned up css of main action box to get rid of tricks and ensure correct display on all devices. +- fixed a bug that'd cause notifications dots to disappear when an unrelated checkbox was checked. + +hopefully from now on i'll focus on adding support for more services. +thank you for using cobalt. stay cool :) \ No newline at end of file diff --git a/web/changelogs/5.4.md b/web/changelogs/5.4.md new file mode 100644 index 00000000..ef405fc5 --- /dev/null +++ b/web/changelogs/5.4.md @@ -0,0 +1,34 @@ +--- +title: "instagram support, docker, and more!" +banner: + file: "catphonestand.webp" + alt: "a cat holding a phone under its chin while a person plays clash of clans on it" +--- +something many of you've been waiting for is finally here! try it out and let me know what you think :) + +tl;dr: +- added experimental instagram support! download any reels or videos you like, and make sure to report any issues you encounter. yes, you can convert either to audio. +- fixed support for on.soundcloud links. +- added share button to "how to save?" popup. +- added docker support. + +service improvements: +- added experimental support for videos from instagram. currently only reels and post videos are downloadable, but i'm looking into ways to save high resolution photos too. if you experience any issues, please report them on either of support platforms. +- fixed support for on.soundcloud share links. should work just as well as other versions! +- fixed an issue that made some youtube videos impossible to download. + +interface improvements: +- new css-only checkmark! yes, i can't stop tinkering with it because slight flashing on svg load annoyed me. now it loads instantly (and also looks slightly better). +- fixed copy animation. +- minor localization improvements. +- fixed the embed logo that i broke somewhere in between 5.3 and 5.4. + +internal improvements: +- now using nanoid for live render stream ids. +- added support for docker. it's kind of clumsy because of how i get .git folder inside the container, but if you know how to do it better, feel free to make a pr. +- cobalt now checks only for existence of environment variables, not exactly the .env file. +- changed the way user ip address is retrieved for instances using cloudflare. +- added ability to disable cors, both to setup script and environment variables. + +i can't believe how diverse and widespread cobalt has become. it's used in all fields: music production, education, content creation, and even game development. thank you. this is absolutely nuts. +if you don't mind sharing, please tell me about your use case. i'd really love to hear how you use cobalt and how i could make it even more useful for you. \ No newline at end of file diff --git a/web/changelogs/6.0.md b/web/changelogs/6.0.md new file mode 100644 index 00000000..109f4832 --- /dev/null +++ b/web/changelogs/6.0.md @@ -0,0 +1,68 @@ +--- +title: "better reliability, new infrastructure, pinterest support, and way more!" +date: "June 7, 2023" +banner: + file: "catswitchboxes.webp" + alt: "a cat climbing into two empty boxes of asahi beer" +--- +hey! long time no see, hopefully over 40 changes will make up for it :) + +cobalt now has an official community discord server. you can go there for news, support, or just to chat. go check it out! + +tl;dr +- new infra, new hosting structure, new main instance api url. developers, get it here. +- added support for pinterest, vine archive, tumblr audio, youtube vr videos. +- better web app performance and look. +- better stability thanks to load balancing. +- (hopefully) no more random video/audio download drops. + +service improvements: +- added support for pinterest videos and stories (pr by @Snazzah). +- added support for tumblr audio. sorry, tumblr. +- added support for youtube vr videos. please note that they're in youtube's proprietary ratio. +- added support for vine archive. +- added support for ancient vk videos in 240p. +- fixed an issue related to muted video downloads from tumblr. +- moved to twitter v2 api. +- soundcloud share links are now processed without errors. + +ui improvements: +- lazy image loading. should significantly speed up the page load. +- fixed checkbox width on mobile devices. +- addition of a temporary urgent notice. +- added hover border to all buttons. +- less annoying donation button highlight. +- more consistent color scheme. +- added link to a discord server into about popup. +- remember celebratory emoji changes? they've been fixed, and are now dynamically loaded! +- changelog history now lets you try to load it again if first attempt failed for whatever reason. +- padding (everywhere) has been slightly reduced to fit in more content and be consistent across ui. +- added more info to the "how to save" popup for ios devices. +- crypto wallet press-to-copy buttons now look like buttons. +- improved ui layout for smallest screens (iphone 5, 5s, se, etc). +- removed partial translations for sake of clarity and consistency. + +internal improvements: +- separated web and api servers. they're now completely independent and therefore more stress-resistant. +- added a dedicated script for building the web app if you don't want to reload the frontend server. +- web app building improvements. +- async localization preloading. +- consistent server start time reporting. +- dynamic stream and ip hashing salt generation. + +infrastructure improvements: +- load balancing: your api requests are now sent to the least busy server. yes, there are now several of them with more to come in the future. +- when possible, server in closest region is used instead of a far-away one. this should help with download speeds. +- currently there are multiple servers in europe. i will let you know when (and if) i manage to get an american one. + +updates for developers and instance hosters: +- server info api endpoint: you can now check up on the api server of choice. it reports all the basic info you may need. check the api docs for more info. +- api names: each and every api instance should have a distinctive name. this will be useful in the future :) +- added docker compose sample config. +- updated and more granular setup script. +- better api scalability and faster server start up thanks to web and api separation. +- added ability to specify ffmpeg threads. simply add ffmpegThreads to your environment variables! + +i'm still in awe from how popular cobalt has become. there are now over 200k of unique users monthly, and that number only keeps growing. i even had to come up with something to accommodate for larger traffic, it's absolutely insane. + +love you all, have a great day :D \ No newline at end of file diff --git a/web/changelogs/6.2.md b/web/changelogs/6.2.md new file mode 100644 index 00000000..012d06c6 --- /dev/null +++ b/web/changelogs/6.2.md @@ -0,0 +1,23 @@ +--- +title: "all network issues have been fixed!" +date: "June 27 2023" +banner: + file: "meowthhammer.webp" + alt: "meowth plush holding a hammer in real life" +--- +hey! there have been some hiccups in cobalt's stability lately, i was going through finals while trying to scale up the infrastructure, and that didn't really work out, lol. +BUT i'm happy to announce that i've optimized all nodes! there should no longer be any networking issues. + +enjoy stable experience while i work in background to make cobalt even better :) + +here's what's new in this update: +- better button contrast in both themes. +- button highlight in light theme now actually looks like a highlight. +- removed ip gate for streamables and updated privacy policy to reflect this change. +- streamable links now last for 20 seconds instead of 2 minutes. +- cleaned up stream verification algorithm. now the same function doesn't run 4 times in a row. +- removed deprecated way of hosting a cobalt instance. + +thank you for sticking with cobalt, and i hope you have a great day :D + +banner photo is by @halftroller on twitter, thank you so much! \ No newline at end of file diff --git a/web/changelogs/7.0.md b/web/changelogs/7.0.md new file mode 100644 index 00000000..594d4316 --- /dev/null +++ b/web/changelogs/7.0.md @@ -0,0 +1,83 @@ +--- +title: "biggest ui refresh yet!" +date: "August 15, 2023" +banner: + file: "meowthcooking.webp" + alt: "meowth handling orders in a restaurant" +--- +hey! this update is huge and mostly aimed to refresh the ui, but there are also some other nice fixes/additions. read below for more info :) + +tl;dr: +- entirety of web app has been refreshed. it's more prettier and optimized than ever, both on phone and desktop. +- if you're on ios, try adding cobalt to home screen! it'll look and act like a native app. +- all soundcloud links are now supported and audio quality is higher than before. +- all x (previously twitter) links are now supported and work properly. +- newer reddit videos are downloadable now. +- added some sort of eula, list of keyboard shortcuts, updated privacy policy for more clarity. check it all in refreshed about tab! +- cobalt now lets you know if your browser doesn't support clipboard pasting and helps you fix it. + +accessibility notice: +this update includes animations and transparency, if you'd like to disable any or all of them, head to settings > other > accessibility. + +[full changelog] + +service improvements: +- fixed unexpected 502 errors when downloading newer reddit videos. +- newer reddit videos (with audio) are downloadable now. +- upgraded soundcloud downloads to use higher audio quality than before. +- all soundcloud links are now supported. +- added support for x.com urls. +- changed twitter api once again. now everything works, again. + +web improvements: +- all-new matte glass aesthetic, applied to revamped popup headers, tab selectors, and also small popups. +- rounded corners everywhere! cobalt is now safe for everyone who can't handle sharp objects. +- paddings everywhere are smaller, more content fits on the screen at once. +- optimized installed web app to look and act like a native app, especially on ios. +- added update release dates to changelogs. +- cobalt now lets you know if your browser doesn't support clipboard api and helps you fix it. +- refreshed all popups: less padding, more content. +- completely remade error and download popups, they're consistent with the rest of refreshed design. +- refreshed the look of entire changelog tab: separated title and version/commit, made title bigger, evened out all paddings. +- replaced close button with back button, moved it to left. +- added interaction animations. +- added more keyboard shorcuts. +- added a list of keyboard shortcuts to about tab. +- added eula to about tab. check it out. +- added more accessibility options, put them all into one category. you can disable animations and transparency if you want to. +- added a link to self-troubleshooting guide to about tab. +- renamed 2160p and 4320p to 4k and 8k respectfully for better clarity. +- popups now work without any weird workarounds, especially on mobile. they're clean and nice. +- home screen now also works without any weird workarounds. it is also clean and nice. +- optimized css of almost all ui elements. should be even more consistent across platforms now. +- added ability to translate "cobalt" more in-depth localization. for example, in russian "cobalt" is now "кобальт", that's the style i'll be going with from now on. +- updated many localization strings for more clarity. +- removed ability to change the app name dynamically in all locations. cobalt is a sustained app name. +- updated donation and privacy policy texts for more clarity in both english and russian. +- home screen now smoothly fades in instead of popping in. +- proper banner loading. no more jumping text! +- proper banner error handling. if banner wasn't loaded, it'll simply go grey instead of disappearing. +- links are no longer italic and are instead underlined. +- collapsible lists now have corresponding emoji. +- donate button is now highlighted with magenta instead of white. +- proper dropdown arrow. +- removed 6.0 api fallback. +- fixed celebrations emoji. again. +- cleaned up all related frontend modules, especially page.js. +- urgent notice is now a js element, not a static piece of text. can be updated easily. + +api improvements: +- now catching all json api related errors. +- moved on demand blocks to web server, now changelog can be updated independently from preferred api server. +- now sending standard rate limiting headers. +- better readability in source. + +other improvements: +- renamed docker-compose.yml.example to docker-compose.example.yml for linting in code editors. +- added a wiki with wip troubleshooting guide on github. more guides are coming soon! + +that's a ton of changes! i really hope you like this update as much as i do. + +if you experience any issues, feel free to contact me on any platform listed in about tab! i'd love to hear back from you. + +thank you for sticking with me and cobalt, i hope you have THE best day :D \ No newline at end of file diff --git a/web/changelogs/7.1.md b/web/changelogs/7.1.md new file mode 100644 index 00000000..cf49d0b7 --- /dev/null +++ b/web/changelogs/7.1.md @@ -0,0 +1,28 @@ +--- +title: "instagram, streamable, video metadata, and more!" +date: "August 20, 2023" +banner: + file: "meowthproductions.webp" + alt: "meowth roaring in a fancy circle, à la MGM studios intro" +--- +service improvements: +- extended instagram support: high quality photos, videos, reels. everything should work without any issues, enjoy! :) +- added support for streamable.com (thanks to #179) +- added video metadata to youtube videos. +- fixed vk video downloads. +- vxtwitter links are now supported. +- fixed support for youtube audio dubs. + +ui improvements: +- fixed picker popup: it's now scrollable in all cases and clickable areas don't overlap each other. + +backend improvements: +- cobalt will now let you know if something goes wrong during video download instead of nuking the stream. +- added support for cookies (thanks to #177) +- replaced got with undici (thanks to #182). downloads should be slightly faster and clean of garbage in headers. + +internal improvements: +- moved host overrides into its own module. +- minor clean ups. + +even more cool stuff is coming in future updates! thank you for using cobalt :D \ No newline at end of file diff --git a/web/changelogs/7.11.md b/web/changelogs/7.11.md new file mode 100644 index 00000000..9de3b125 --- /dev/null +++ b/web/changelogs/7.11.md @@ -0,0 +1,45 @@ +--- +title: "cache encryption, meowbalt, dailymotion, bilibili, and much more!" +date: "March 6, 2024" +banner: + file: "meowth7eleven.webp" + alt: "meowth plush in front of 7-eleven store" +--- +cobalt may not have as many groceries as 7-eleven, but it sure does have lots of big changes in this update! + +- all cached stream info is now encrypted and can only be decrypted with a link you get from cobalt. +- new popup style featuring meowbalt, cobalt's speedy mascot. you will see him more often from now on! +- added support for dailymotion (including short links). +- added support for bilibili.tv, fixed support for bilibili.com, and added support for all related short links. +- added support for unlisted vimeo links. +- added support for tumblr audio and revamped the entire module. +- added support for embed ok.ru links. + +we also updated the privacy policy to reflect the addition of data encryption, go check it out. + +for people with iphones: +- clearer ios saving tutorial. +- added "save to files" ios shortcut. +- updated save to photos shortcut. + +make sure to save both shortcuts and read the updated tutorial! + +for people who host a cobalt instance: +- updated all environment variables TO_BE_LIKE_THIS. time to update your configs! for now cobalt is backwards compatible with old variable names, but it won't last forever. +- added a list of all environment variables and their descriptions to run-an-instance doc. +- updated cookie file example with more services and improved examples. +- updated docker compose example with better explanations and up-to-date env variable samples. +- updated some packages to get rid of all unnecessary messages in console. + +want to host an instance? learn how to do it here. + +frontend changes: +- removed migration popup. +- corners across ui are even more round now. +- bottom glass bkg in popups is no longer rounded on top right. +- small popup no longer stretches like gum, it's fixed in size on desktop. +- small popup animation no longer lags on mobile. +- better ui scaling across resolutions. +- updated donation text. + +thank you for using cobalt, all 750k of you. hope you like this update as much as we enjoyed making it :D \ No newline at end of file diff --git a/web/changelogs/7.13.md b/web/changelogs/7.13.md new file mode 100644 index 00000000..fa78c536 --- /dev/null +++ b/web/changelogs/7.13.md @@ -0,0 +1,59 @@ +--- +title: "better ux, improvements for youtube, twitter, tiktok, instagram, and more!" +date: "May 5, 2024" +banner: + file: "meowthbusinessman.webp" + alt: "photo of a businessman holding hands together (merkel-raute pose) with meowth plush head." +--- +long time no see! well, actually, you've been using the latest version for some time now. we've moved to a rolling release scheme, allowing for speedy update rollouts :) + +since 7.11, there has been a ton of changes. here are the most notable of them: +- youtube downloads are now faster and more reliable than ever. +- all posts from twitter are now downloadable, including sensitive ones. +- you now can download tiktok videos in 1080p h265! just enable h265 support in settings > video. +- added support for sharing links directly to the cobalt web app on android. +- added 240p and 144p quality options to the quality picker in settings (for some reason, many of you wanted this). +- pasting a link with additional text around it will now work; cobalt will extract the link for you (works only via the paste button). +- added anonymous traffic analytics by plausible. we're using a selfhosted instance and don't collect any identifiable information about you. you can learn more in about > privacy policy. you can also opt out of anonymous analytics in settings > other. + +service support improvements: +- implemented internal streams functionality, allowing for more fine-grained file streaming and therefore proper youtube support. +- added fallback to m4a if opus isn't available for youtube. +- added a total of 7 ways to get instagram post info, including mobile api, embed, and graphql api. absolute torture. +- added support for reddit user posts. +- updated the way tiktok downloads are handled for better reliability and 1080p support. +- added tiktok author's username to filename. +- added support for rutube shorts and yappy videos. +- added support for m.soundcloud.com links. +- added support for new post and reel links from instagram. +- added support for photo twitter links, only used for gifs. +- added support for m.bilibili.com links. +- added support for new type of vimeo links. +- added support for ddinstagram.com links. +- updated youtube codec info in settings to display the fact that av1 is a better choice now. +- updated best audio picking for tiktok and soundcloud. +- changed the youtube client to web, since android client no longer works. +- removed the vimeo download type switcher, as it should've always been automatic instead. +- removed an ability to enable the tiktok watermark, as it no longer includes the author's username. + +ui & ux improvements: +- youtube audio dub switcher is now a toggle with a much easier to understand description. +- meowbalt now sticks out on the left side of download popup on desktop. +- updated "made with love" text to include the research & dev team behind cobalt, imput. +- fixed grammar of russian localization. +- rounded corners are now correctly rendered across all browsers. +- various minor improvements, including smaller button padding. +- removed the notification (red dot) functionality as the most recent changelog is already always on screen. +- removed settings migration from the old domain. + +other changes: +- various docs updates in github repo, making sure they're functional across branches and forks. +- major codebase cleanup. + +thank you for using cobalt, and thank you for being one of our 900k friends! i hope you like this update as much as we liked making it. + +we're committed to keeping cobalt the best way to save what you love without ads or invasion of your privacy. there's a ton of cool stuff to come soon; stay tuned and have an amazing rest of your day &lt;3 + +if you want to help our goal of a better internet for everyone, just share cobalt with a friend! + +(original photo of a man in a suit by benzoix on freepik) \ No newline at end of file diff --git a/web/changelogs/7.14.md b/web/changelogs/7.14.md new file mode 100644 index 00000000..386f1d5c --- /dev/null +++ b/web/changelogs/7.14.md @@ -0,0 +1,43 @@ +--- +title: "now helping over 1 million people monthly" +date: "May 17, 2024" +banner: + file: "millionusers.webp" + alt: "collage of two photos, side by side. left photo: brown cake with 7 lit candles forming 1000000 and one ferrero rocher candy in the middle with cobalt (double greater than symbol) logo on it. right photo: chocolate cake with 7 lit candles forming 1000000 and cobalt logo formed with whipped cream on the cake. two plushes of meowth and pompompurin in party hats are seen behind the cake." +--- +yesterday, cobalt hit 1 million users around the world! it's an absolutely insane milestone for us and we're incredibly grateful to everyone saving and creating what they love with help of cobalt. thank you for being our friends. + +in anticipation of 7 figure user count, we've revamped the cobalt codebase and infrastructure to be faster and more reliable than ever. a combination of many changes has resulted into incredible download speeds (up to 30 MB/s, as tested by both developers in europe). + +note: there's no backend instance in asia just yet, so if you're there, you might experience average speeds *for now*. you can help us afford a dedicated server in asia by donating to cobalt in the "donate" menu. + +changes since the last major update + +service improvements: +- youtube music support on the main instance is back! +- added support for pinterest images and gifs. +- cobalt will now use original soundcloud mp3 file when available. +- fixed a youtube bug that prevented some videos from downloading. + +ui/ux improvements: +- cobalt web app is now fully optimized for ipad. you can add it to home screen from share menu to make it act like a native app! +- majorly reduced vertical padding when viewing cobalt in mobile web browser, allowing for more content at once. most noticeable on smaller screens. +- status bar color is now dynamic in the web browser on ios and web app on android. +- web app on android feels way more native than before. +- filename style icons are no longer blurry in safari. +- changelog notification no longer overlaps with dynamic island on newer iphones when cobalt is installed as a web app. +- fixed safe area padding. + +other changes: +- added support for freebind, made by one of the cobalt developers. +- rate limit and max video length limits are now customizable through environment variables. +- cobalt api now returns rate limit headers at all times. +- majorly cleaned up the codebase: removed unnecessary functions, rewrote those that were cryptic and confusing. it's way more comprehensible and contribution-friendly than ever before. +- moved the cobalt repo to our organization on github. everything stayed the same and all old links link back to it. + +note for instance hosters: +along with cobalt repo, the docker image also moved! please update the url for it in your config along with watchtower args to include restarting containers (just in case) as seen in updated docker compose example. we're mirroring packages to old url for now, but it won't last forever. + +that's it for now! hope you have an amazing day and share the 1 million celebration with us :) + +join our discord server to discuss everything cobalt there \ No newline at end of file diff --git a/web/changelogs/7.3.md b/web/changelogs/7.3.md new file mode 100644 index 00000000..d16e2898 --- /dev/null +++ b/web/changelogs/7.3.md @@ -0,0 +1,30 @@ +--- +title: "extended video length limit, metadata toggle, ui improvements, and more!" +date: "September 6, 2023" +banner: + file: "meowthsnap.webp" + alt: "cartoon meowth pointing paw dramatically and saying something" +--- +this update gives cobalt a sharp look in chromium browsers and makes it even more useful than before. check out the full changelog below! + +service improvements: +- increased video length limit from 3 hours to 5 hours. feel free to download lectures you need :) +- you can now disable file metadata in settings. +- fixed a bug which previously caused some downloads to end up being 0 bytes. + +ui improvements: +- fixed clickable area for urgent notice (text on top). +- fixed blurry header in chrome. +- fixed blurry tab bar in chrome. +- fixed blurry switches in chrome. +- fixed weirdly rounded corners in popups. +- fixed 1px gap on edges of various elements in popup in chrome. +- fixed overscrolling in other settings tab on ios. +- fixed unexpected button highlight effect on phones. +- removed outdated fixes for tiny screens. + +other improvements: +- cobalt web & api start faster than before, additional preparation functions aren't unexpectedly run anymore. +- cobalt is now available as a docker package. check it out on github. + +thank you for being here. i hope you have a great day :D \ No newline at end of file diff --git a/web/changelogs/7.4.md b/web/changelogs/7.4.md new file mode 100644 index 00000000..42d6a790 --- /dev/null +++ b/web/changelogs/7.4.md @@ -0,0 +1,45 @@ +--- +title: "new domain, what's coming in future, bug fixes, and more!" +date: "September 9, 2023" +banner: + file: "newdomain.webp" + alt: "text: new domain, same cobalt" +--- +cobalt is finally moving to its own domain! many of you have been anticipating this, and many kept forgetting the link due to how cryptic it was. + +well, worry no more - cobalt.tools is here. + +if you haven't yet, open co.wukko.me to transfer your settings here! no additional action from you is required. just open the old link and cobalt will do everything for you :) + +make sure to update your bookmarks and reinstall the web app! + +here's what domain change means: +- still no ads, same owner, same features, same reliability. just a way more rememberable link (it's literally two words). +- cobalt.tools makes it clear that cobalt is a tool and that it's "cobalt", not "wukko". +- i can host various versions of cobalt on subdomains without links looking awkward. +- i can host cobalt-related websites without polluting my personal domain's dns (such as crowdin). +- i stand by same privacy policies (and in fact am using the same exact server as before). + +the domain change is required for the future of cobalt. + +here's what's coming soon: +- support for many top-requested sites, such as (but not limited to) twitch and niconico. +- education version of cobalt, as often requested by students and educators. +- major localization system upgrade, allowing for simpler community contributions. +- region-specific versions with 100% translations and tweaks. +- native clients for desktop and mobile (not sure about this one, i'm no superman). +- ...and more! + +now, here's what's new in 7.4: +- tabs in popups now scroll to top on tab bar tap. +- padding across web app was tuned. +- (obviously) a migration agent. soon will be used for importing and exporting settings. +- some minor clean ups in codebase. + +if you want to help cobalt achieve goals listed above, consider donating! donations are the only way i can keep cobalt ad-less, powerful, (basically) limitless, and also 100% free. + +in fact, donations have helped me grow cobalt more than i've ever anticipated. just imagine how much better it will be in a year. + +go to donations down below to find ways to donate! + +thank you for reading through all of this. i hope you enjoy this update and have a great day :D \ No newline at end of file diff --git a/web/changelogs/7.5.md b/web/changelogs/7.5.md new file mode 100644 index 00000000..420beeb1 --- /dev/null +++ b/web/changelogs/7.5.md @@ -0,0 +1,28 @@ +--- +title: "support for twitch clips and rutube!" +date: "September 16, 2023" +banner: + file: "twitchupdate.webp" + alt: "meowth plush staring into the camera, laptop with generic purple service in the background" +--- +hey! this update (finally) adds support for twitch clips and rutube, among other smaller changes. + +service improvements: +- added support for twitch clips. no vods, they're unnecessary. just clip whatever you want to download! +- added support for rutube in case you ever wanted to download something russian. + +interface improvements: +- added a note about cobalt not being affiliated with any supported services. +- added a note about meta (the company) in russian. +- better russian localization. will keep improving it to make it sound not so robotic over time. + +other improvements: +- all official servers are now using the docker package. and so should you! +- moved the load balancer to poland. requests should be slightly faster now. +- minor codebase clean up. + +if you're confused about the new domain, read the older changelog! just scroll lower and press "expand". + +i hope you find this update useful and have a wonderful day :) + +btw, cobalt has a pretty active community server on discord. go to about > support & source code to join! \ No newline at end of file diff --git a/web/changelogs/7.6.md b/web/changelogs/7.6.md new file mode 100644 index 00000000..dd43d5b7 --- /dev/null +++ b/web/changelogs/7.6.md @@ -0,0 +1,33 @@ +--- +title: "customizable file names, instagram stories, and first cobalt sponsor!" +date: "October 15, 2023" +banner: + file: "meowthcenter.webp" + alt: "meowth plush in a datacenter wearing a hardhat, wielding a hammer" +--- +as many have (very) often requested, cobalt now lets you pick between several file name format styles! +go to settings > other and change it to whichever you like! there's a preview of each style, so you know how exactly files are gonna look like. + +if you liked file names the way they were before, don't worry: classic style is still the default :) + +on a different but not any less important note: cobalt is now sponsored by royalehosting.net! +overall service performance and stability is gonna be better, but also more content will be possible to download thanks to geniuine server locations. and yes, still no ads or trackers. + +this update also includes a bunch of other changes, check them out: + +service improvements: +- added support for instagram stories thanks to #194. +- fixed reddit support thanks to #221. +- added support for rich file names for youtube, vimeo, soundcloud, rutube, and vk. +- numbers and emoji no longer disappear from file name and metadata. +- mute and audio dub file name tags don't appear together anymore. +- youtube: dub file name tag doesn't appear anymore if audio track is default. + +interface improvements: +- added a list of sponsors to about tab. if you host an instance, it's disabled by default, but can be enabled with showSponsors env variable. +- about button now opens about tab when no new changelog is available. +- fixed download button thickness on ios. + +you now can reach out to cobalt via email for support! it's located in the about tab along with other socials, such as discord. + +i hope you enjoy this long-awaited update and have a blissful day :D \ No newline at end of file diff --git a/web/changelogs/7.7.md b/web/changelogs/7.7.md new file mode 100644 index 00000000..220d2a79 --- /dev/null +++ b/web/changelogs/7.7.md @@ -0,0 +1,30 @@ +--- +title: "bugfixes and better downloads!" +date: "December 2, 2023" +banner: + file: "meowthpolishegg.webp" + alt: "meowth polishing a togepi egg" +--- +this update fixes various issues with supported services. no new features yet, but twitter fix is surely something good to have in the meantime! + +service improvements: +- broken twitter videos are now automatically fixed by cobalt. +- all vimeo videos and audios should now be possible to download. +- vimeo: fixed short resolution displayed in "basic" and "pretty" filename styles. + +interface improvements: +- streamables are now easier to save on ios. + +internal improvements: +- port env variable is now not strictly necessary for cobalt to run. +- minor clean up. + +changes since 7.6: +- fix for an issue related to youtube dubs. +- fixed a memory leak related to live renders. +- handling all errors related to twitter downloads. +- fixed support for reddit links in various languages. +- added rich filenames support for twitch clips. +- updated support and donation lists. + +stay tuned for future updates and have a great day :D \ No newline at end of file diff --git a/web/changelogs/7.8.md b/web/changelogs/7.8.md new file mode 100644 index 00000000..e82a9786 --- /dev/null +++ b/web/changelogs/7.8.md @@ -0,0 +1,35 @@ +--- +title: "new years clean up! bug fixes and fresh look for the home page" +date: "December 25, 2023" +banner: + file: "catroomba.webp" + alt: "a cat riding a roomba vacuum" +--- +merry christmas and happy new year! this update fixes several (very annoying) bugs to help you enjoy your holidays better. + +you might have already noticed, but we've refreshed the home page on desktop and mobile! less space wasted, more pleasant to look at. let us know if you like it or not :D + +service improvements: +- #264 anything that includes a period in the url should be possible to download (including instagram stories). +- #73 soundcloud: falling back to mp3 instead of refusing to download the song at all. +- #275 youtube: query parameters are parsed and handled correctly, all links should be supported, no matter where v query is located. +- tlds are parsed and validated correctly (e.g. "pinterest.co.uk" works now). +- fixvx.com links are now supported. + +interface improvements: +- cleaner and more consistent home page layout. +- cleaned up support section in "about". also includes a link to the status page. + +internal improvements: +- urls, subdomains, and tlds are properly validated. +- minor clean up. + +changes since 7.7: +- made terms and ethics more descriptive. +- fix only affected twitter videos. +- fixed quick ⌘+V pasting on mac. +- now catching even more youtube-related errors. + +this might not seem like a lot, but even smaller changes make a difference! + +enjoy this update and the rest of your day :D \ No newline at end of file diff --git a/web/changelogs/7.9.md b/web/changelogs/7.9.md new file mode 100644 index 00000000..12af9592 --- /dev/null +++ b/web/changelogs/7.9.md @@ -0,0 +1,33 @@ +--- +title: "twitter gifs, pinterest, ok.ru, and more!" +date: "January 17, 2024" +banner: + file: "meowthball.webp" + alt: "meowth rolling on a big catnip ball" +--- +yes, you read that right. cobalt now lets you convert any twitter gif to an actual .gif file! (finally) +just go to settings and enable this feature :) + +service improvements: +- added an option to convert gifs from twitter into actual .gif format. files will be bigger and lower quality, but maybe you want that. +- pinterest support has been completely redone, now all videos (and even pin.it links) are supported. +- added support for ok.ru in case you're a russian grandma. +- now processing all reddit links (including old.reddit.com). +- instagram live vods are now supported. +- fixed a rare vimeo bug related to 1440p videos. + +other improvements: +- ui fade in animation is no longer present if you've disabled animations. +- all images now have alt descriptions. +- cobalt html is now biblically correct and follows the html spec. +- lots of cleaning up. + +patches since 7.8: +- shift+key shortcuts are now ignored if url bar is focused. +- longer soundcloud links are now supported, also catching more tiktok-related errors. +- removed mastodon from support links as that account is no longer active. +- added ability to download a specific video from multi media tweets and support for /mediaViewer links. +- fixed modal blurriness in chromium. +- minor html changes (road to biblically correct one). + +lots of long-awaited updates (especially twitter gifs), hope you enjoy them and have a great day :D \ No newline at end of file From 3aa17733d1bb3fc9b204dd6b7fbd922b75db5422 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 29 Jun 2024 17:58:00 +0000 Subject: [PATCH 192/775] frontend: install and configure mdsvex --- web/package-lock.json | 619 +++++------------------------------------- web/package.json | 2 + web/src/app.d.ts | 11 + web/svelte.config.js | 16 +- 4 files changed, 98 insertions(+), 550 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index e5760755..93f9664f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -22,7 +22,9 @@ "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint__js": "^8.42.3", "@types/node": "^20.14.10", + "compare-versions": "^6.1.0", "eslint": "^8.57.0", + "mdsvex": "^0.11.2", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", @@ -47,262 +49,6 @@ "node": ">=6.0.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/linux-x64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", @@ -319,102 +65,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -607,149 +257,6 @@ "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "dev": true }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", @@ -776,45 +283,6 @@ "linux" ] }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@sveltejs/adapter-static": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", @@ -989,6 +457,12 @@ "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", "dev": true }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", @@ -1456,6 +930,12 @@ "dev": true, "license": "MIT" }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1957,20 +1437,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2314,6 +1780,21 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, + "node_modules/mdsvex": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.11.2.tgz", + "integrity": "sha512-Y4ab+vLvTJS88196Scb/RFNaHMHVSWw6CwfsgWIQP8f42D57iDII0/qABSu530V4pkv8s6T2nx3ds0MC1VwFLA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.3", + "prism-svelte": "^0.4.7", + "prismjs": "^1.17.1", + "vfile-message": "^2.0.4" + }, + "peerDependencies": { + "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2612,6 +2093,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prism-svelte": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz", + "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==", + "dev": true + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3183,6 +2679,19 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3193,6 +2702,20 @@ "punycode": "^2.1.0" } }, + "node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "5.2.13", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", diff --git a/web/package.json b/web/package.json index 4512cc02..a787d10c 100644 --- a/web/package.json +++ b/web/package.json @@ -30,7 +30,9 @@ "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint__js": "^8.42.3", "@types/node": "^20.14.10", + "compare-versions": "^6.1.0", "eslint": "^8.57.0", + "mdsvex": "^0.11.2", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", diff --git a/web/src/app.d.ts b/web/src/app.d.ts index c7c0ed1d..b30667de 100644 --- a/web/src/app.d.ts +++ b/web/src/app.d.ts @@ -1,3 +1,14 @@ +// needed so that changelog files are appropriately +// typed as svelte components +declare module '*.md' { + import type { SvelteComponentDev } from 'svelte/internal'; + + export default class Comp extends SvelteComponentDev { + $$prop_def: {}; + } + export const metadata: Record; +} + // See https://kit.svelte.dev/docs/types#app // for information about these interfaces declare global { diff --git a/web/svelte.config.js b/web/svelte.config.js index b4751daa..821da9bb 100644 --- a/web/svelte.config.js +++ b/web/svelte.config.js @@ -1,12 +1,24 @@ import adapter from '@sveltejs/adapter-static'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import { mdsvex } from 'mdsvex'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://kit.svelte.dev/docs/integrations#preprocessors // for more information about preprocessors - preprocess: vitePreprocess(), - + extensions: [".svelte", ".md"], + preprocess: [ + vitePreprocess(), + mdsvex({ + extensions: ['.md'], + layout: join( + dirname(fileURLToPath(import.meta.url)), + '/src/components/misc/ChangelogEntryWrapper.svelte' + ) + }) + ], kit: { adapter: adapter({ // default options are shown. On some platforms From 766482c21a42299557519068790990a6d0d47f33 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 29 Jun 2024 18:23:56 +0000 Subject: [PATCH 193/775] frontend: setup initial updates page --- web/src/components/misc/ChangelogEntry.svelte | 36 ++++++++++++ .../misc/ChangelogEntryWrapper.svelte | 11 ++++ web/src/lib/changelogs.ts | 22 +++++++ web/src/lib/types/changelogs.ts | 19 ++++++ web/src/routes/updates/+page.svelte | 58 +++++++++++++++++-- 5 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 web/src/components/misc/ChangelogEntry.svelte create mode 100644 web/src/components/misc/ChangelogEntryWrapper.svelte create mode 100644 web/src/lib/changelogs.ts create mode 100644 web/src/lib/types/changelogs.ts diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte new file mode 100644 index 00000000..1b278498 --- /dev/null +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -0,0 +1,36 @@ + + +
+

{ version }: { title }

+

{ date }

+ {#if banner} + {banner.alt} + {/if} +
+ +
+
\ No newline at end of file diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/misc/ChangelogEntryWrapper.svelte new file mode 100644 index 00000000..3821fa42 --- /dev/null +++ b/web/src/components/misc/ChangelogEntryWrapper.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/web/src/lib/changelogs.ts b/web/src/lib/changelogs.ts new file mode 100644 index 00000000..78e7df75 --- /dev/null +++ b/web/src/lib/changelogs.ts @@ -0,0 +1,22 @@ +import { compareVersions } from 'compare-versions'; + +export function getVersionFromPath(path: string) { + return path.split('/').pop()?.split('.md').shift()!; +} + +export function getAllChangelogs() { + const changelogImports = import.meta.glob("/changelogs/*.md"); + + const sortedVersions = Object.keys(changelogImports) + .map(path => [path, getVersionFromPath(path)]) + .sort(([, a], [, b]) => compareVersions(a, b)); + + const sortedChangelogs = sortedVersions.reduce( + (obj, [path, version]) => ({ + [version]: changelogImports[path], + ...obj + }), {} as typeof changelogImports + ); + + return sortedChangelogs; +} diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts new file mode 100644 index 00000000..3dd41afc --- /dev/null +++ b/web/src/lib/types/changelogs.ts @@ -0,0 +1,19 @@ +import type { SvelteComponent } from "svelte" + +export interface ChangelogMetadata { + title: string, + date?: string + banner?: { + file: string, + alt: string + } +}; + +export interface MarkdownMetadata { + metadata: ChangelogMetadata +}; + +export type ChangelogImport = { + default: SvelteComponent, + metadata: ChangelogMetadata +} | undefined; diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index dc9670fa..4809d0fa 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -1,13 +1,61 @@ - + + - {$t("general.cobalt")}: {$t("tabs.donate")} + {$t("general.cobalt")}: {$t("tabs.updates")} - +
+ {#if changelog} + + {/if} + {#if versions[currentIndex + 1]} + + {/if} +
\ No newline at end of file From a22b0e51361fa430fdd8ac181947f582834a1875 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 16 Jul 2024 17:19:17 +0000 Subject: [PATCH 194/775] web/ChangelogEntry: initial css --- web/src/components/misc/ChangelogEntry.svelte | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index 1b278498..7991e304 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -5,11 +5,15 @@ export let banner: { file: string, alt: string } | undefined; -
-

{ version }: { title }

-

{ date }

- {#if banner} - {banner.alt} - {/if} -
- +
+

+
{ version }
+
{ title }
+

+ { date } +
+ {#if banner} + {banner.alt} + {/if} +
+ +
-
\ No newline at end of file + From 3305bba28a4c218594997d5879ddbf5e3c9ff56b Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 16 Jul 2024 17:21:53 +0000 Subject: [PATCH 195/775] web/updates: update hash on navigation, navigate if present on load --- web/src/routes/updates/+page.svelte | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 4809d0fa..79e70b5d 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -1,7 +1,8 @@ @@ -63,9 +114,40 @@
{#if changelog} - - {/if} - {#if versions[currentIndex + 1]} - +
+ +
+
+ +
+ + +
+
+
+ +
{/if}
\ No newline at end of file From 5c07afe4ff869875252a1481291ab705b838537a Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 16 Jul 2024 17:27:43 +0000 Subject: [PATCH 197/775] web/updates: keyboard navigation --- web/src/routes/updates/+page.svelte | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index d2dd5496..98125a9b 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -52,6 +52,11 @@ changelogs[next]().catch(() => {}); } + const handleKeydown = (e: KeyboardEvent) => { + if (e.key === 'ArrowLeft') loadPrev(); + else if (e.key === 'ArrowRight') loadNext(); + } + $: prev = versions[currentIndex - 1]; $: next = versions[currentIndex + 1]; $: currentIndex, loadChangelog(); @@ -112,6 +117,8 @@ + +
{#if changelog}
@@ -150,4 +157,4 @@
{/if} -
\ No newline at end of file +
From e6ec8c673400697e8c5f8041b5641daa20b4ce5d Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 17 Jul 2024 13:14:56 +0600 Subject: [PATCH 198/775] web/package: fix the svelte icons version & update lock --- web/package-lock.json | 1163 +++++++++++++++++++++++++++++++++-------- web/package.json | 2 +- 2 files changed, 941 insertions(+), 224 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 93f9664f..476e94e0 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0", + "@tabler/icons-svelte": "3.6.0", "sveltekit-i18n": "^2.4.2", "ts-deepmerge": "^7.0.0" }, @@ -41,6 +41,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -49,14 +50,151 @@ "node": ">=6.0.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -65,6 +203,244 @@ "node": ">=12" } }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -82,9 +458,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "license": "MIT", "engines": { @@ -116,9 +492,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz", - "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", + "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", "dev": true, "license": "MIT", "engines": { @@ -128,12 +504,14 @@ "node_modules/@fontsource-variable/noto-sans-mono": { "version": "5.0.20", "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz", - "integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==" + "integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==", + "license": "OFL-1.1" }, "node_modules/@fontsource/ibm-plex-mono": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", - "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==" + "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==", + "license": "OFL-1.1" }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", @@ -177,6 +555,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -190,6 +569,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -198,19 +578,22 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -221,6 +604,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -234,6 +618,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -243,6 +628,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -255,34 +641,233 @@ "version": "1.0.0-next.25", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", + "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", + "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", + "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", + "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", + "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", + "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", + "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", + "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", + "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", + "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", + "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", + "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", + "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", + "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", + "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", + "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sveltejs/adapter-static": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", @@ -294,11 +879,12 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.5.10", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.10.tgz", - "integrity": "sha512-OqoyTmFG2cYmCFAdBfW+Qxbg8m23H4dv6KqwEt7ofr/ROcfcIl3Z/VT56L22H9f0uNZyr+9Bs1eh2gedOCK9kA==", + "version": "2.5.18", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.18.tgz", + "integrity": "sha512-+g06hvpVAnH7b4CDjhnTDgFWBKBiQJpuSmQeGYOuzbO3SC3tdYjRNlDCrafvDtKbGiT2uxY5Dn9qdEUGVZdWOQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", @@ -330,6 +916,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", "dev": true, + "license": "MIT", "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", "debug": "^4.3.4", @@ -352,6 +939,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -383,6 +971,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.6.0.tgz", "integrity": "sha512-Zv0Ofc64RCMpZ2F8CvsWAphrSjerx5hEErt/RMmE+W8r4E5l5Lizi+My9KbbZQ4NyAtrtrOX80OY1oROZrRzEA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/codecalm" @@ -392,6 +981,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/@tabler/icons-svelte/-/icons-svelte-3.6.0.tgz", "integrity": "sha512-phI61t81MlWhodATjvQQdqw8vTL0srSW6GsHzJmuhIMJGB4rwFzAXB2Ec4Pkz0vWFzVQgkeSE/AsiOLIUKWkxA==", + "license": "MIT", "dependencies": { "@tabler/icons": "3.6.0" }, @@ -407,7 +997,8 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/eslint": { "version": "8.56.10", @@ -433,7 +1024,8 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -443,10 +1035,11 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -455,26 +1048,28 @@ "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -498,16 +1093,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", - "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -527,14 +1122,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -545,14 +1140,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -573,9 +1168,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true, "license": "MIT", "engines": { @@ -587,14 +1182,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -626,9 +1221,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -642,16 +1237,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -665,13 +1260,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/types": "7.16.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -690,9 +1285,10 @@ "license": "ISC" }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -758,6 +1354,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -777,6 +1374,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" } @@ -792,24 +1390,27 @@ } }, "node_modules/axobject-query": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", - "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", - "dependencies": { - "dequal": "^2.0.3" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -822,6 +1423,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -832,6 +1434,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -844,6 +1447,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -853,6 +1457,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -879,6 +1484,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -898,10 +1504,24 @@ "fsevents": "~2.3.2" } }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/code-red": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", @@ -934,19 +1554,22 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -970,6 +1593,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -983,6 +1607,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -1007,6 +1632,7 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1015,6 +1641,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -1024,6 +1651,7 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1032,7 +1660,8 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/dir-glob": { "version": "3.0.1", @@ -1064,14 +1693,16 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -1079,29 +1710,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escape-string-regexp": { @@ -1213,24 +1844,12 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/esm-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/espree": { "version": "9.6.1", @@ -1251,9 +1870,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1290,6 +1909,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } @@ -1316,6 +1936,7 @@ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1327,6 +1948,19 @@ "node": ">=8.6.0" } }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1346,6 +1980,7 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -1368,6 +2003,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1407,23 +2043,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", @@ -1435,7 +2054,23 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, "node_modules/glob": { "version": "7.2.3", @@ -1443,6 +2078,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1459,15 +2095,16 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/globals": { @@ -1490,7 +2127,8 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/globby": { "version": "11.1.0", @@ -1517,13 +2155,15 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", @@ -1557,6 +2197,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1573,6 +2214,7 @@ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1594,6 +2236,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1603,13 +2246,15 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1622,6 +2267,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1631,6 +2277,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -1643,6 +2290,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -1661,6 +2309,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "license": "MIT", "dependencies": { "@types/estree": "*" } @@ -1721,6 +2370,7 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1742,7 +2392,8 @@ "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", @@ -1771,6 +2422,7 @@ "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } @@ -1778,13 +2430,15 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" }, "node_modules/mdsvex": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.11.2.tgz", "integrity": "sha512-Y4ab+vLvTJS88196Scb/RFNaHMHVSWw6CwfsgWIQP8f42D57iDII0/qABSu530V4pkv8s6T2nx3ds0MC1VwFLA==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^2.0.3", "prism-svelte": "^0.4.7", @@ -1800,6 +2454,7 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -1809,6 +2464,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -1822,6 +2478,7 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -1831,6 +2488,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1843,6 +2501,7 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1852,6 +2511,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -1864,6 +2524,7 @@ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -1873,6 +2534,7 @@ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -1881,7 +2543,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.7", @@ -1894,6 +2557,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1913,6 +2577,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1922,6 +2587,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -1981,6 +2647,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -2003,6 +2670,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2031,6 +2699,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -2041,13 +2710,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -2056,9 +2727,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -2074,9 +2745,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -2097,13 +2769,15 @@ "version": "0.4.7", "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz", "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2136,13 +2810,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -2155,6 +2831,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -2164,29 +2841,35 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", + "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -2198,22 +2881,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", + "@rollup/rollup-android-arm-eabi": "4.18.1", + "@rollup/rollup-android-arm64": "4.18.1", + "@rollup/rollup-darwin-arm64": "4.18.1", + "@rollup/rollup-darwin-x64": "4.18.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", + "@rollup/rollup-linux-arm-musleabihf": "4.18.1", + "@rollup/rollup-linux-arm64-gnu": "4.18.1", + "@rollup/rollup-linux-arm64-musl": "4.18.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", + "@rollup/rollup-linux-riscv64-gnu": "4.18.1", + "@rollup/rollup-linux-s390x-gnu": "4.18.1", + "@rollup/rollup-linux-x64-gnu": "4.18.1", + "@rollup/rollup-linux-x64-musl": "4.18.1", + "@rollup/rollup-win32-arm64-msvc": "4.18.1", + "@rollup/rollup-win32-ia32-msvc": "4.18.1", + "@rollup/rollup-win32-x64-msvc": "4.18.1", "fsevents": "~2.3.2" } }, @@ -2236,6 +2919,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -2245,6 +2929,7 @@ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", "dev": true, + "license": "MIT", "dependencies": { "mri": "^1.1.0" }, @@ -2257,6 +2942,7 @@ "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", "dev": true, + "license": "MIT", "dependencies": { "es6-promise": "^3.1.2", "graceful-fs": "^4.1.3", @@ -2264,10 +2950,24 @@ "rimraf": "^2.5.2" } }, + "node_modules/sander/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -2281,7 +2981,8 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -2311,6 +3012,7 @@ "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dev": true, + "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", @@ -2335,6 +3037,7 @@ "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.14", "buffer-crc32": "^1.0.0", @@ -2349,6 +3052,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -2371,6 +3075,7 @@ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.0" }, @@ -2408,6 +3113,7 @@ "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -2429,15 +3135,14 @@ } }, "node_modules/svelte-check": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.0.tgz", - "integrity": "sha512-7Nxn+3X97oIvMzYJ7t27w00qUf1Y52irE2RU2dQAd5PyvfGp4E7NLhFKVhb6PV2fx7dCRMpNKDIuazmGthjpSQ==", + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.4.tgz", + "integrity": "sha512-61aHMkdinWyH8BkkTX9jPLYxYzaAAz/FK/VQqdr2FiCQQ/q04WCwDlpGbHff1GdrMYTmW8chlTFvRWL9k0A8vg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "chokidar": "^3.4.1", - "fast-glob": "^3.2.7", - "import-fresh": "^3.2.1", "picocolors": "^1.0.0", "sade": "^1.7.4", "svelte-preprocess": "^5.1.3", @@ -2455,6 +3160,7 @@ "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", "dev": true, + "license": "ISC", "engines": { "node": "^12.20 || ^14.13.1 || >= 16" }, @@ -2468,6 +3174,7 @@ "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@types/pug": "^2.0.6", "detect-indent": "^6.1.0", @@ -2552,6 +3259,7 @@ "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", "dev": true, + "license": "MIT", "dependencies": { "globalyzer": "0.1.0", "globrex": "^0.1.2" @@ -2562,6 +3270,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -2574,6 +3283,7 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2592,9 +3302,9 @@ } }, "node_modules/ts-deepmerge": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.0.tgz", - "integrity": "sha512-WZ/iAJrKDhdINv1WG6KZIGHrZDar6VfhftG1QJFpVbOYZMYJLJOvZOo1amictRXVdBXZIgBHKswMTXzElngprA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.1.tgz", + "integrity": "sha512-JBFCmNenZdUCc+TRNCtXVM6N8y/nDQHAcpj5BlwXG/gnogjam1NunulB9ia68mnqYI446giMfpqeBFFkOleh+g==", "license": "ISC", "engines": { "node": ">=14.13.1" @@ -2604,7 +3314,8 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", @@ -2633,9 +3344,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2647,15 +3358,15 @@ } }, "node_modules/typescript-eslint": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", - "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz", + "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "7.13.1", - "@typescript-eslint/parser": "7.13.1", - "@typescript-eslint/utils": "7.13.1" + "@typescript-eslint/eslint-plugin": "7.16.1", + "@typescript-eslint/parser": "7.16.1", + "@typescript-eslint/utils": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2677,13 +3388,15 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^2.0.2" }, @@ -2707,6 +3420,7 @@ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" @@ -2717,13 +3431,14 @@ } }, "node_modules/vite": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", - "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", + "esbuild": "^0.21.3", + "postcss": "^8.4.39", "rollup": "^4.13.0" }, "bin": { @@ -2776,6 +3491,7 @@ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", "dev": true, + "license": "MIT", "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, @@ -2815,7 +3531,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yocto-queue": { "version": "0.1.0", diff --git a/web/package.json b/web/package.json index a787d10c..30e9f0e3 100644 --- a/web/package.json +++ b/web/package.json @@ -43,7 +43,7 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0", + "@tabler/icons-svelte": "3.6.0", "sveltekit-i18n": "^2.4.2", "ts-deepmerge": "^7.0.0" } From 8eee02489914a549b02723d3af160c1ca872a745 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Wed, 17 Jul 2024 07:30:22 +0000 Subject: [PATCH 199/775] web/updates: don't prevent default action for keyboard inputs --- web/src/routes/updates/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 98125a9b..5cbaf12f 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -117,7 +117,7 @@ - +
{#if changelog} From 1ec9d92eb2123b33e153a86962521d336e182a0d Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 17 Jul 2024 13:32:07 +0600 Subject: [PATCH 200/775] web/updates: clean up components --- web/src/components/misc/ChangelogEntry.svelte | 41 ++++---- .../misc/ChangelogEntryWrapper.svelte | 1 + web/src/routes/updates/+page.svelte | 96 +++++++++---------- 3 files changed, 70 insertions(+), 68 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index 7991e304..902aa7ef 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -4,6 +4,27 @@ export let date: string; export let banner: { file: string, alt: string } | undefined; + +
+

+
{ version }
+
{ title }
+

+ { date } +
+ {#if banner} + {banner.alt} + {/if} +
+ +
+
+
+ -
-

-
{ version }
-
{ title }
-

- { date } -
- {#if banner} - {banner.alt} - {/if} -
- -
-
-
diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/misc/ChangelogEntryWrapper.svelte index 3821fa42..6dc6e56a 100644 --- a/web/src/components/misc/ChangelogEntryWrapper.svelte +++ b/web/src/components/misc/ChangelogEntryWrapper.svelte @@ -6,6 +6,7 @@ export let date = ''; export let banner = undefined; + diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 5cbaf12f..3691e055 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -62,6 +62,54 @@ $: currentIndex, loadChangelog(); + + + {$t("general.cobalt")}: {$t("tabs.updates")} + + + + + +
+ {#if changelog} +
+ +
+
+ +
+ + +
+
+
+ +
+ {/if} +
+ - - - - {$t("general.cobalt")}: {$t("tabs.updates")} - - - - - -
- {#if changelog} -
- -
-
- -
- - -
-
-
- -
- {/if} -
From 6e374fde622988b5f7927f94cc00703786d24da1 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 17 Jul 2024 14:04:53 +0600 Subject: [PATCH 201/775] web/updates: make changelogs look nicer - fixes horizontal scrolling on mobile - removes text backdrop - improves readability --- web/src/components/misc/ChangelogEntry.svelte | 80 ++++++++++--------- .../misc/ChangelogEntryWrapper.svelte | 6 +- web/src/routes/updates/+page.svelte | 79 +++++++++--------- 3 files changed, 86 insertions(+), 79 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index 902aa7ef..e4474aef 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -2,15 +2,17 @@ export let version: string; export let title: string; export let date: string; - export let banner: { file: string, alt: string } | undefined; + export let banner: { file: string; alt: string } | undefined;
-

-
{ version }
-
{ title }
-

- { date } +
+
+
{version}
+
{date}
+
+

{title}

+
{#if banner} main { - padding: 1em; + overflow-x: hidden; } - img { - max-width: 100%; - } - - h1 { - padding-top: 1em; - } - - .contents :global(.text-backdrop) { - border-radius: 4px; - background-color: var(--button); - color: var(--background); - padding: 0.3rem; - } - - .contents :global(.text-backdrop.link) { - text-decoration: underline; - } - - h1 { + #changelog-header { display: flex; flex-direction: column; align-items: start; + gap: calc(var(--padding) / 2); + padding: 1em 0; /* match default

padding */ } - h1 .changelog-version { - padding: .15rem .5rem; - border-radius: 4px; - background-color: var(--button-hover); + .changelog-info { + display: flex; + flex-direction: row; + align-items: center; + gap: 14px; } - h1 .changelog-title { - padding: .15rem 0; - text-align: left; + .changelog-version { + padding: 3px 8px; + border-radius: 6px; + background-color: var(--secondary); + color: var(--primary); + font-size: 21px; + font-weight: 500; + } + + .changelog-date { + font-size: 13px; + font-weight: 500; + color: var(--gray); + } + + .changelog-title { + padding: 0; + line-height: 1.2; } .changelog-banner { - padding: 2em; - width: 100%; - max-height: 300pt; - min-height: 210pt; display: block; object-fit: cover; + max-height: 320pt; + min-height: 210pt; + width: 100%; + max-width: 100; aspect-ratio: 16/9; + border-radius: var(--padding); } .changelog-content { @@ -84,5 +86,7 @@ .contents { max-width: 100%; + line-height: 1.5; + font-size: 15px; } diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/misc/ChangelogEntryWrapper.svelte index 6dc6e56a..d01b93f9 100644 --- a/web/src/components/misc/ChangelogEntryWrapper.svelte +++ b/web/src/components/misc/ChangelogEntryWrapper.svelte @@ -1,9 +1,9 @@ diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 3691e055..d8532ec2 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -1,17 +1,17 @@ + From 0e60ea95821eecbfdf38e56bc1b0fac634ded520 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Wed, 17 Jul 2024 09:07:25 +0000 Subject: [PATCH 211/775] web/ChangelogEntry: consistent date formatting --- web/src/components/misc/ChangelogEntry.svelte | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index a8f581d0..804705cf 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -1,15 +1,31 @@

{version}
-
{date}
+ {#if date} +
{formatDate(date)}
+ {/if}

{title}

From c3c7a6b7baedeba236af5933383b35efacdd24d6 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 20 Jul 2024 12:43:14 +0000 Subject: [PATCH 212/775] web/version: convert to readable --- web/src/lib/version.ts | 30 ++++++++++--------- .../settings/advanced/debug/+page.svelte | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/web/src/lib/version.ts b/web/src/lib/version.ts index ff9b4a0b..22539f55 100644 --- a/web/src/lib/version.ts +++ b/web/src/lib/version.ts @@ -1,3 +1,5 @@ +import { readable } from "svelte/store"; + type VersionResponse = { commit: string; branch: string; @@ -5,19 +7,19 @@ type VersionResponse = { version: string; } -const fetchVersion = async function () { - const response: VersionResponse | undefined = await fetch('/version.json') - .then(r => r.json()) - .catch(() => {}); +const unknownVersion = { + commit: "unknown", + branch: "unknown", + remote: "unknown", + version: "unknown" +}; - if (!response) return { - commit: "unknown", - branch: "unknown", - remote: "unknown", - version: "unknown" +export const version = readable( + unknownVersion, + (set) => { + fetch('/version.json') + .then(r => r.json()) + .then(set) + .catch(() => {}) } - - return response; -} - -export const version = await fetchVersion(); +) diff --git a/web/src/routes/settings/advanced/debug/+page.svelte b/web/src/routes/settings/advanced/debug/+page.svelte index 9dd63bd9..05feefeb 100644 --- a/web/src/routes/settings/advanced/debug/+page.svelte +++ b/web/src/routes/settings/advanced/debug/+page.svelte @@ -32,7 +32,7 @@

version:

- {JSON.stringify(version, null, 2)} + {JSON.stringify($version, null, 2)}
{/if} From 2c1bd50e70b33968ce74adf48f85da282b5d08c0 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 20 Jul 2024 12:43:22 +0000 Subject: [PATCH 213/775] Revert "web/vite: change build target to esnext" This reverts commit 842f91ec54cf1ed88258e2a224c8f76709d0ceae. --- web/vite.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/web/vite.config.ts b/web/vite.config.ts index 2aed5de1..d6663e0d 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -6,7 +6,6 @@ export default defineConfig({ sveltekit() ], build: { - target: "esnext", rollupOptions: { output: { manualChunks: (id) => { From cd41fc9d493ec6c9795e17112b217b1871e51d7a Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 18 Jul 2024 17:22:29 +0600 Subject: [PATCH 214/775] web/SmallDialog: fix rendering & performance issues, new mobile animation --- web/src/components/dialog/SmallDialog.svelte | 63 +++++++++++++++----- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index bee98362..8763b122 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -1,4 +1,6 @@ - +
{#if meowbalt === "error"}
@@ -76,7 +83,7 @@ From 205494b367dc46831e66b200cf58adbb41ab456f Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 20 Jul 2024 18:49:51 +0600 Subject: [PATCH 215/775] web/SmallDialog: fix scaling on small screens --- web/src/components/dialog/SmallDialog.svelte | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 8763b122..c14cd102 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -25,7 +25,7 @@ setTimeout(() => { dialogParent.close(); killDialog(); - }, 150) + }, 150); } }; @@ -33,7 +33,7 @@ dialogParent.showModal(); tick().then(() => { open = true; - }) + }); } @@ -73,11 +73,7 @@
- +
diff --git a/web/src/components/meowbalt/MeowbaltLoaf.svelte b/web/src/components/meowbalt/MeowbaltLoaf.svelte deleted file mode 100644 index 3e8533e3..00000000 --- a/web/src/components/meowbalt/MeowbaltLoaf.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - -{$t("a11y.meowbalt.smile")} - - diff --git a/web/src/components/misc/Meowbalt.svelte b/web/src/components/misc/Meowbalt.svelte new file mode 100644 index 00000000..e367758e --- /dev/null +++ b/web/src/components/misc/Meowbalt.svelte @@ -0,0 +1,31 @@ + + +{$t(`a11y.meowbalt.${emotion}`)} + + diff --git a/web/src/components/misc/Placeholder.svelte b/web/src/components/misc/Placeholder.svelte index c38e9836..a8001ab0 100644 --- a/web/src/components/misc/Placeholder.svelte +++ b/web/src/components/misc/Placeholder.svelte @@ -1,10 +1,11 @@
- +
{pageName} page is not ready yet!
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index c6a37969..b2c5ae8d 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -20,15 +20,12 @@ id: "save-error", type: "small", meowbalt: "error", - title: "", - bodySubText: "", buttons: [{ text: $t("general.gotit"), - color: "gray", main: true, action: () => {}, }] - } + } as DialogInfo const changeDownloadButton = (state: string) => { isDisabled = true; diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 20bea678..888dc646 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -1,6 +1,8 @@ +import type { MeowbaltEmotions } from "$lib/types/meowbalt"; + export type DialogButton = { text: string, - color: string, + color: "blue" | "red" | "default", main: boolean, action: () => unknown | Promise } @@ -8,7 +10,7 @@ export type DialogButton = { export type DialogInfo = { id: string, type: "small", - meowbalt: "error", + meowbalt: MeowbaltEmotions | "", title: string, bodyText: string, bodySubText: string, diff --git a/web/src/lib/types/meowbalt.ts b/web/src/lib/types/meowbalt.ts new file mode 100644 index 00000000..6913f606 --- /dev/null +++ b/web/src/lib/types/meowbalt.ts @@ -0,0 +1 @@ +export type MeowbaltEmotions = "smile" | "error" | "question" | "think"; diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index ea612eb6..efe0a00b 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -71,6 +71,9 @@ --button-text: #282828; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --button-elevated: #e3e3e3; + --button-elevated-hover: #dadada; + --popup-bg: #f1f1f1; --popup-backdrop: var(--primary); --popup-stroke: rgba(0, 0, 0, 0.08); @@ -126,6 +129,9 @@ --button-text: #e1e1e1; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --button-elevated: #282828; + --button-elevated-hover: #2f2f2f; + --popup-bg: #191919; --popup-backdrop: var(--primary); --popup-stroke: rgba(255, 255, 255, 0.08); diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 680bef45..1c59864e 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -2,7 +2,7 @@ import { t } from "$lib/i18n/translations"; import Omnibox from "$components/save/Omnibox.svelte"; - import MeowbaltLoaf from "$components/meowbalt/MeowbaltLoaf.svelte"; + import Meowbalt from "$components/misc/Meowbalt.svelte"; @@ -11,7 +11,7 @@
- +
diff --git a/web/static/meowbalt/checking.png b/web/static/meowbalt/question.png similarity index 100% rename from web/static/meowbalt/checking.png rename to web/static/meowbalt/question.png From def6e26b9ffe37fa69364c3808c1db2a429d8c19 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 20 Jul 2024 14:01:13 +0000 Subject: [PATCH 219/775] web/settings: add "erase all settings" button --- web/i18n/en/settings.json | 3 ++- .../buttons/ResetSettingsButton.svelte | 22 +++++++++++++++++++ web/src/lib/state/settings.ts | 7 ++++++ web/src/routes/+layout.svelte | 11 +++++++++- web/src/routes/settings/advanced/+page.svelte | 5 +++++ 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 web/src/components/buttons/ResetSettingsButton.svelte diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index f5380063..4df36dc5 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -92,5 +92,6 @@ "advanced.debug": "debug", "advanced.debug.title": "enable debug features", - "advanced.debug.description": "gives you access to a page with app & device info useful for debugging." + "advanced.debug.description": "gives you access to a page with app & device info useful for debugging.", + "advanced.reset": "erase all settings" } diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte new file mode 100644 index 00000000..85a2139d --- /dev/null +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -0,0 +1,22 @@ + + + + + diff --git a/web/src/lib/state/settings.ts b/web/src/lib/state/settings.ts index 555c45a9..79dfdc31 100644 --- a/web/src/lib/state/settings.ts +++ b/web/src/lib/state/settings.ts @@ -88,6 +88,13 @@ export function updateSetting(partial: PartialSettings) { }); } +export function resetSettings() { + update(() => { + localStorage.removeItem('settings'); + return {}; + }); +} + export default derived( storedSettings, $settings => mergeWithDefaults($settings) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index efe0a00b..b6eac3e6 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -60,8 +60,10 @@ --white: #ffffff; --gray: #75757e; - --blue: #2f8af9; + --red: #f92f2f; + --dark-red: #df0707; --green: #51cf5e; + --blue: #2f8af9; --button: #f4f4f4; --button-hover: #e8e8e8; @@ -111,6 +113,13 @@ rgba(0, 0, 0, 0) 96%, rgba(0, 0, 0, 0.9) 100% ); + + --skeleton-gradient: linear-gradient( + 90deg, + var(--button), + var(--button-hover), + var(--button) + ); } :global([data-theme="dark"]) { diff --git a/web/src/routes/settings/advanced/+page.svelte b/web/src/routes/settings/advanced/+page.svelte index 55b454d1..1fe02104 100644 --- a/web/src/routes/settings/advanced/+page.svelte +++ b/web/src/routes/settings/advanced/+page.svelte @@ -3,6 +3,7 @@ import SettingsCategory from "$components/settings/SettingsCategory.svelte"; import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; + import ResetSettingsButton from "$components/buttons/ResetSettingsButton.svelte"; @@ -13,3 +14,7 @@ description={$t("settings.advanced.debug.description")} /> + + + + \ No newline at end of file From d7bf98a80b7d4785cab05ff7534e7b362a122563 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 20 Jul 2024 21:48:17 +0600 Subject: [PATCH 220/775] web: settings reset confirmation, icons for small dialog - cleaned up dialog i18n - better red color - made :active state visible for dialog buttons on mobile - better body padding in small dialog - better small dialog typing with optional values --- web/i18n/en/dialog.json | 8 +++ web/i18n/en/general.json | 3 +- web/i18n/en/settings.json | 2 + .../buttons/ResetSettingsButton.svelte | 47 +++++++++++++--- web/src/components/dialog/DialogHolder.svelte | 1 + web/src/components/dialog/SmallDialog.svelte | 55 +++++++++++++++---- .../save/buttons/DownloadButton.svelte | 6 +- web/src/lib/types/dialog.ts | 13 +++-- web/src/routes/+layout.svelte | 10 +++- web/src/routes/settings/advanced/+page.svelte | 4 +- 10 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 web/i18n/en/dialog.json diff --git a/web/i18n/en/dialog.json b/web/i18n/en/dialog.json new file mode 100644 index 00000000..96a552ec --- /dev/null +++ b/web/i18n/en/dialog.json @@ -0,0 +1,8 @@ +{ + "button.gotit": "got it", + "button.cancel": "cancel", + "button.erase": "erase", + + "erase.title": "erase all settings?", + "erase.body": "are you sure you want to reset all settings? this action is immediate and irreversible." +} diff --git a/web/i18n/en/general.json b/web/i18n/en/general.json index 5a371ff8..6ea5e8a0 100644 --- a/web/i18n/en/general.json +++ b/web/i18n/en/general.json @@ -1,4 +1,3 @@ { - "cobalt": "cobalt", - "gotit": "got it" + "cobalt": "cobalt" } diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 4df36dc5..0d20cc15 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -93,5 +93,7 @@ "advanced.debug": "debug", "advanced.debug.title": "enable debug features", "advanced.debug.description": "gives you access to a page with app & device info useful for debugging.", + + "advanced.data": "settings data", "advanced.reset": "erase all settings" } diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte index 85a2139d..0434c84d 100644 --- a/web/src/components/buttons/ResetSettingsButton.svelte +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -1,22 +1,55 @@ - diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 7d6ef1dd..1f306c6b 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -12,6 +12,7 @@ id={dialog.id} title={dialog.title} meowbalt={dialog.meowbalt} + icon={dialog.icon} bodyText={dialog.bodyText} bodySubText={dialog.bodySubText} buttons={dialog.buttons} diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 3820c88e..4aa12b72 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -2,13 +2,16 @@ import { tick } from "svelte"; import { killDialog } from "$lib/dialogs"; - import type { DialogButton } from "$lib/types/dialog"; + import type { DialogButton, SmallDialogIcons } from "$lib/types/dialog"; import Meowbalt from "$components/misc/Meowbalt.svelte"; import type { MeowbaltEmotions } from "$lib/types/meowbalt"; + import IconAlertTriangle from "@tabler/icons-svelte/IconAlertTriangle.svelte"; + export let id: string; - export let meowbalt: MeowbaltEmotions; + export let meowbalt: MeowbaltEmotions | undefined; + export let icon: SmallDialogIcons | undefined; export let title: string = ""; export let bodyText: string = ""; export let bodySubText: string = ""; @@ -45,12 +48,19 @@
{/if} - {#if title} - - {/if}
From dbbd43e002d80a043496549ae1b52b76a63186db Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 14:42:17 +0600 Subject: [PATCH 228/775] web/changelog: move components to dedicated folder --- web/src/components/{misc => changelog}/ChangelogEntry.svelte | 0 .../{misc => changelog}/ChangelogEntryWrapper.svelte | 4 ++-- web/svelte.config.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename web/src/components/{misc => changelog}/ChangelogEntry.svelte (100%) rename web/src/components/{misc => changelog}/ChangelogEntryWrapper.svelte (73%) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte similarity index 100% rename from web/src/components/misc/ChangelogEntry.svelte rename to web/src/components/changelog/ChangelogEntry.svelte diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/changelog/ChangelogEntryWrapper.svelte similarity index 73% rename from web/src/components/misc/ChangelogEntryWrapper.svelte rename to web/src/components/changelog/ChangelogEntryWrapper.svelte index 0907758d..0a2dcd58 100644 --- a/web/src/components/misc/ChangelogEntryWrapper.svelte +++ b/web/src/components/changelog/ChangelogEntryWrapper.svelte @@ -1,11 +1,11 @@
-
+
{version}
{#if date} @@ -56,6 +56,10 @@ padding-bottom: 1em; /* match default

padding */ } + #changelog-header.no-padding { + padding-bottom: 0; + } + .changelog-info { display: flex; flex-direction: row; From ec768ebfc21ef1eb01c2be418f42d31c74883a64 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 16:34:37 +0600 Subject: [PATCH 230/775] web/settings/metadata: basic filename preview component --- web/i18n/en/settings.json | 3 + .../settings/FilenamePreview.svelte | 83 +++++++++++++++++++ .../settings/save/metadata/+page.svelte | 2 + 3 files changed, 88 insertions(+) create mode 100644 web/src/components/settings/FilenamePreview.svelte diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 0d20cc15..c761ff85 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -65,6 +65,9 @@ "metadata.filename.nerdy": "nerdy", "metadata.filename.description": "filename style using which cobalt files will be downloaded. this description is temporary as there's no dynamic preview component yet.", + "metadata.filename.preview.video": "Video Title", + "metadata.filename.preview.audio": "Audio Title - Audio Author", + "metadata.file": "file metadata", "metadata.disable.title": "disable file metadata", "metadata.disable.description": "title, artist, and other info will not be added to the file.", diff --git a/web/src/components/settings/FilenamePreview.svelte b/web/src/components/settings/FilenamePreview.svelte new file mode 100644 index 00000000..64fce4f4 --- /dev/null +++ b/web/src/components/settings/FilenamePreview.svelte @@ -0,0 +1,83 @@ + + +

+
+ {videoFilePreview}.{youtubeVideoExt} +
+
+ {audioFilePreview}.{audioFormat} +
+
+ + diff --git a/web/src/routes/settings/save/metadata/+page.svelte b/web/src/routes/settings/save/metadata/+page.svelte index 91c3d621..1da7010f 100644 --- a/web/src/routes/settings/save/metadata/+page.svelte +++ b/web/src/routes/settings/save/metadata/+page.svelte @@ -7,6 +7,7 @@ import Switcher from "$components/buttons/Switcher.svelte"; import SettingsButton from "$components/buttons/SettingsButton.svelte"; import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; + import FilenamePreview from "$components/settings/FilenamePreview.svelte"; @@ -24,6 +25,7 @@ {/each} + Date: Sun, 21 Jul 2024 16:40:39 +0600 Subject: [PATCH 231/775] web/ResetSettingsButton: update dialog text erase -> reset --- web/i18n/en/dialog.json | 6 +++--- web/i18n/en/settings.json | 2 +- web/src/components/buttons/ResetSettingsButton.svelte | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/web/i18n/en/dialog.json b/web/i18n/en/dialog.json index 96a552ec..b57fae5b 100644 --- a/web/i18n/en/dialog.json +++ b/web/i18n/en/dialog.json @@ -1,8 +1,8 @@ { "button.gotit": "got it", "button.cancel": "cancel", - "button.erase": "erase", + "button.reset": "reset", - "erase.title": "erase all settings?", - "erase.body": "are you sure you want to reset all settings? this action is immediate and irreversible." + "reset.title": "reset all settings?", + "reset.body": "are you sure you want to reset all settings? this action is immediate and irreversible." } diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index c761ff85..7273ea1e 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -98,5 +98,5 @@ "advanced.debug.description": "gives you access to a page with app & device info useful for debugging.", "advanced.data": "settings data", - "advanced.reset": "erase all settings" + "advanced.reset": "reset all settings" } diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte index 0434c84d..e6b6a61a 100644 --- a/web/src/components/buttons/ResetSettingsButton.svelte +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -11,8 +11,8 @@ id: "wipe-confirm", type: "small", icon: "warn-red", - title: $t("dialog.erase.title"), - bodyText: $t("dialog.erase.body"), + title: $t("dialog.reset.title"), + bodyText: $t("dialog.reset.body"), buttons: [ { text: $t("dialog.button.cancel"), @@ -20,7 +20,7 @@ action: () => {}, }, { - text: $t("dialog.button.erase"), + text: $t("dialog.button.reset"), color: "red", main: true, action: () => resetSettings(), From 0cea58922ddebb2ed1d9eabcb26dc1ffa128c1ae Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 09:42:48 +0000 Subject: [PATCH 232/775] web/changelogs: display skeleton when changelog is loading --- .../changelog/ChangelogEntry.svelte | 17 ++- .../changelog/ChangelogSkeleton.svelte | 128 ++++++++++++++++++ web/src/components/misc/Skeleton.svelte | 64 +++++++++ web/src/lib/types/changelogs.ts | 2 +- web/src/routes/updates/+page.svelte | 32 +++-- 5 files changed, 228 insertions(+), 15 deletions(-) create mode 100644 web/src/components/changelog/ChangelogSkeleton.svelte create mode 100644 web/src/components/misc/Skeleton.svelte diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index 01116d46..3026a9d4 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -1,9 +1,13 @@ + +
+
+
+
{ version }
+
+ +
+
+

+ +

+
+
+ +
+ {#each {length: 3 + Math.random() * 5} as _} +

+ +

+ {/each} +
+
+
+ + diff --git a/web/src/components/misc/Skeleton.svelte b/web/src/components/misc/Skeleton.svelte new file mode 100644 index 00000000..91e39e48 --- /dev/null +++ b/web/src/components/misc/Skeleton.svelte @@ -0,0 +1,64 @@ + + +
+ + \ No newline at end of file diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts index 3dd41afc..e4d73c5d 100644 --- a/web/src/lib/types/changelogs.ts +++ b/web/src/lib/types/changelogs.ts @@ -16,4 +16,4 @@ export interface MarkdownMetadata { export type ChangelogImport = { default: SvelteComponent, metadata: ChangelogMetadata -} | undefined; +}; \ No newline at end of file diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 11d4d959..0ebce5cd 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -5,13 +5,15 @@ import { getAllChangelogs } from "$lib/changelogs"; import type { ChangelogImport } from "$lib/types/changelogs"; + import ChangelogSkeleton from "$components/changelog/ChangelogSkeleton.svelte"; + import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; import IconChevronRight from "@tabler/icons-svelte/IconChevronRight.svelte"; const changelogs = getAllChangelogs(); const versions = Object.keys(changelogs); - let changelog: (ChangelogImport & { version: string }) | undefined; + let changelog: { version: string; page: Promise } | undefined; let currentIndex = 0; { @@ -24,17 +26,13 @@ const loadChangelog = async () => { const version = versions[currentIndex]; - const log = (await changelogs[version]()) as ChangelogImport; - if (!log) { - return; // FIXME: now wot + changelog = { + version, + page: changelogs[version]() as Promise } - changelog = { - ...log, - version, - }; - window.location.hash = version; + await changelog.page; }; const loadNext = () => { @@ -77,10 +75,17 @@
- + {#await changelog.page} + {#key changelog.version} + + {/key} + {:then page} + + {/await}
- + \ No newline at end of file diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte index 22237322..128146ac 100644 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ b/web/src/components/changelog/ChangelogSkeleton.svelte @@ -39,90 +39,4 @@
- + \ No newline at end of file From d8acb5406a262616d945ac68735e7b3a9d561ab6 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 16:49:38 +0600 Subject: [PATCH 235/775] web/layout: fix skeleton gradient --- web/src/routes/+layout.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 7191c227..c342d62e 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -118,9 +118,9 @@ --skeleton-gradient: linear-gradient( 90deg, - var(--button), var(--button-hover), - var(--button) + var(--button), + var(--button-hover) ); } From 238cd22c8d11533c225bea4c58e92ff17b62b115 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 16:57:42 +0600 Subject: [PATCH 236/775] web/ChangelogSkeleton: fix title skeleton cutting off, reduce rounding --- web/src/components/changelog/ChangelogSkeleton.svelte | 10 ++++------ web/src/components/misc/Skeleton.svelte | 3 ++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte index 128146ac..11f1d999 100644 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ b/web/src/components/changelog/ChangelogSkeleton.svelte @@ -14,12 +14,10 @@ />
-

- -

+
.skeleton { - border-radius: var(--border-radius); + border-radius: calc(var(--border-radius) / 2); background-color: var(--button); background-image: var(--skeleton-gradient); background-size: 200px 100%; @@ -40,6 +40,7 @@ } .skeleton.big { + border-radius: var(--border-radius); background-size: 700px 100%; animation: skeleton-big 1.2s ease-in-out infinite; } From 88fa780f6da417e57e0929f169b8b40bf40bf204 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 17:06:47 +0600 Subject: [PATCH 237/775] web/layout: add dark theme skeleton gradient --- web/src/routes/+layout.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index c342d62e..2cf815c9 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -107,6 +107,7 @@ --switcher-padding: var(--sidebar-inner-padding); + /* used for fading the tab bar on scroll */ --sidebar-mobile-gradient: linear-gradient( 90deg, rgba(0, 0, 0, 0.9) 0%, @@ -165,6 +166,13 @@ rgba(16, 16, 16, 0) 96%, rgba(16, 16, 16, 0.9) 100% ); + + --skeleton-gradient: linear-gradient( + 90deg, + var(--button), + var(--button-hover), + var(--button) + ); } :global([data-theme="light"] [data-reduce-transparency="true"]) { From 213f2d2c9251a2e5d6ebff60ecd9f60d8705e5ea Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 17:22:22 +0600 Subject: [PATCH 238/775] web/updates: hide navigation buttons when nowhere to navigate - removed box shadow on desktop - centered button vertically with flex --- web/src/routes/updates/+page.svelte | 43 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 0ebce5cd..1cd59664 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -68,11 +68,13 @@
{#if changelog} -
- +
+ {#if prev} + + {/if}
{#await changelog.page} @@ -102,16 +104,17 @@
-
- +
+ {#if next} + + {/if}
{/if}
@@ -127,16 +130,21 @@ .button-wrapper-desktop { display: flex; justify-content: center; + align-items: center; + height: 100%; } .button-wrapper-desktop button { position: absolute; - top: 50%; background-color: transparent; display: flex; border: none; } + .button-wrapper-desktop button:not(:focus-visible) { + box-shadow: none; + } + .changelog-wrapper { flex: 1; max-width: 850px; @@ -146,8 +154,9 @@ } button[disabled] { - opacity: 0.5; + opacity: 0; cursor: default; + pointer-events: none; } .button-wrapper-mobile { From ebaa209c47523cdcb57a62010b21e35a415923c2 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 11:29:57 +0000 Subject: [PATCH 239/775] web/changelogs: add dates to all changelogs --- web/changelogs/3.5.2.md | 3 ++- web/changelogs/3.5.4.md | 1 + web/changelogs/3.5.md | 1 + web/changelogs/3.6.3.md | 1 + web/changelogs/3.6.md | 1 + web/changelogs/3.7.md | 1 + web/changelogs/4.0.md | 1 + web/changelogs/4.1.md | 1 + web/changelogs/4.2.md | 1 + web/changelogs/4.3.2.md | 1 + web/changelogs/4.3.md | 1 + web/changelogs/4.4.md | 1 + web/changelogs/4.5.md | 1 + web/changelogs/4.6.md | 1 + web/changelogs/4.7.md | 1 + web/changelogs/4.8.md | 1 + web/changelogs/5.0.md | 1 + web/changelogs/5.1.md | 1 + web/changelogs/5.2.md | 1 + web/changelogs/5.3.md | 1 + web/changelogs/5.4.md | 1 + 21 files changed, 22 insertions(+), 1 deletion(-) diff --git a/web/changelogs/3.5.2.md b/web/changelogs/3.5.2.md index 7add6687..22e8f916 100644 --- a/web/changelogs/3.5.2.md +++ b/web/changelogs/3.5.2.md @@ -1,7 +1,8 @@ --- title: "vk clips support, improved changelog system, and less bugs" +date: "Sep 11, 2022" --- -new features: +new features: - added support for vk clips. cobalt now lets you download even more cringy videos! - added update history right to the changelog menu. it's not loaded by default to minimize page load time, but can be loaded upon pressing a button. probably someone will enjoy this. - as you've just read, cobalt now has on-demand blocks. they're rendered on server upon request and exist to prevent any unnecessary clutter by default. the first feature to use on-demand rendering is history of updates in changelog tab. diff --git a/web/changelogs/3.5.4.md b/web/changelogs/3.5.4.md index 3ad71fa1..a0e863b0 100644 --- a/web/changelogs/3.5.4.md +++ b/web/changelogs/3.5.4.md @@ -1,5 +1,6 @@ --- title: "tiktok support is back :D" +date: "Sep 21, 2022" --- you can download videos, sounds, and images from tiktok again! huge thank you to [@minzique](https://github.com/minzique) for finding another api endpoint that works. \ No newline at end of file diff --git a/web/changelogs/3.5.md b/web/changelogs/3.5.md index 0e706cdc..834d7a04 100644 --- a/web/changelogs/3.5.md +++ b/web/changelogs/3.5.md @@ -1,5 +1,6 @@ --- title: "ui revamp and usability improvements" +date: "Sep 8, 2022" --- new features: - cobalt now lets you paste the link in your clipboard and download the file in a single press of a button.if your clipboard's latest content isn't a valid url, cobalt won't process or paste it. you can also hide the clipboard button in settings if you want to. diff --git a/web/changelogs/3.6.3.md b/web/changelogs/3.6.3.md index 49459ecc..80150494 100644 --- a/web/changelogs/3.6.3.md +++ b/web/changelogs/3.6.3.md @@ -1,5 +1,6 @@ --- title: "less disturbance" +date: "Oct 5, 2022" --- changelog popup no longer annoys you after a major update! this action has been replaced with a notification dot. if you see a red dot, then there's something new. diff --git a/web/changelogs/3.6.md b/web/changelogs/3.6.md index 39d34308..cc494e7f 100644 --- a/web/changelogs/3.6.md +++ b/web/changelogs/3.6.md @@ -1,5 +1,6 @@ --- title: "improvements all around!" +date: "Sep 28, 2022" --- - download mode switcher is moving places, it's now right next to link input area. - smart mode has been renamed to auto mode, because this name is easier to understand. diff --git a/web/changelogs/3.7.md b/web/changelogs/3.7.md index 3fdad1e6..ada689d7 100644 --- a/web/changelogs/3.7.md +++ b/web/changelogs/3.7.md @@ -1,5 +1,6 @@ --- title: "support for multi media tweets is here!" +date: "Oct 9, 2022" --- cobalt now lets you save any of the videos or gifs in a tweet. even if there are many of them. diff --git a/web/changelogs/4.0.md b/web/changelogs/4.0.md index abc40fa4..cad32081 100644 --- a/web/changelogs/4.0.md +++ b/web/changelogs/4.0.md @@ -1,5 +1,6 @@ --- title: "better and faster than ever" +date: "Oct 24, 2022" --- this update has a ton of improvements and new features. diff --git a/web/changelogs/4.1.md b/web/changelogs/4.1.md index c8dacab1..3d6e2af9 100644 --- a/web/changelogs/4.1.md +++ b/web/changelogs/4.1.md @@ -1,5 +1,6 @@ --- title: "better tiktok image downloads" +date: "Oct 27, 2022" --- here's what's up: - tiktok images are saved as .jpeg instead of .webp (finally, i know). diff --git a/web/changelogs/4.2.md b/web/changelogs/4.2.md index 9424f061..f9dd4609 100644 --- a/web/changelogs/4.2.md +++ b/web/changelogs/4.2.md @@ -1,5 +1,6 @@ --- title: "optimized quality picking and 8k video support" +date: "Nov 4, 2022" --- - this update fixes quality picking that was accidentally broken in 4.0 update. - you now can download videos in 8k from youtube. why would you that? no idea. but i'm more than happy to give you this option. diff --git a/web/changelogs/4.3.2.md b/web/changelogs/4.3.2.md index adabaff3..07e8a6a5 100644 --- a/web/changelogs/4.3.2.md +++ b/web/changelogs/4.3.2.md @@ -1,5 +1,6 @@ --- title: "twitter improvements & changelog overhaul" +date: "Nov 15, 2022" --- - you can download explicit content from twitter. - direct video links from twitter are properly supported (video/1, video/2, etc.). diff --git a/web/changelogs/4.3.md b/web/changelogs/4.3.md index bdf9c018..3ec39101 100644 --- a/web/changelogs/4.3.md +++ b/web/changelogs/4.3.md @@ -1,5 +1,6 @@ --- title: "developers, developers, developers, developers" +date: "Nov 12, 2022" banner: file: "developers.webp" alt: "steve ballmer going \"developers, developers, developers\"" diff --git a/web/changelogs/4.4.md b/web/changelogs/4.4.md index 5d63ea5d..06e00198 100644 --- a/web/changelogs/4.4.md +++ b/web/changelogs/4.4.md @@ -1,5 +1,6 @@ --- title: "over 1 million monthly requests. thank you." +date: "Nov 20, 2022" banner: file: "onemillionr.webp" alt: "cobalt logo and a confetti emoji" diff --git a/web/changelogs/4.5.md b/web/changelogs/4.5.md index a0996b70..a15c10da 100644 --- a/web/changelogs/4.5.md +++ b/web/changelogs/4.5.md @@ -1,5 +1,6 @@ --- title: "better, faster, stronger, stable" +date: "Dec 6, 2022" banner: file: "meowthstrong.webp" alt: "meowth stretching" diff --git a/web/changelogs/4.6.md b/web/changelogs/4.6.md index bc13fc99..89a16380 100644 --- a/web/changelogs/4.6.md +++ b/web/changelogs/4.6.md @@ -1,5 +1,6 @@ --- title: "mute videos and proper soundcloud support" +date: "Dec 17, 2022" banner: file: "shutup.webp" alt: "a cat yawning, with a crossed out loudspeaker icon next to it" diff --git a/web/changelogs/4.7.md b/web/changelogs/4.7.md index 9c482a19..089b1358 100644 --- a/web/changelogs/4.7.md +++ b/web/changelogs/4.7.md @@ -1,5 +1,6 @@ --- title: "we're better together! thank you for bug reports." +date: "Jan 13, 2023" banner: file: "bettertogether.webp" alt: "various different pokémon jumping in happiness" diff --git a/web/changelogs/4.8.md b/web/changelogs/4.8.md index f333cc0a..ae0118dc 100644 --- a/web/changelogs/4.8.md +++ b/web/changelogs/4.8.md @@ -1,5 +1,6 @@ --- title: "prettier than ever" +date: "Jan 29, 2023" banner: file: "catmakeup.webp" alt: "a cat being brushed with a powder makeup brush" diff --git a/web/changelogs/5.0.md b/web/changelogs/5.0.md index 328fdbf0..b2599211 100644 --- a/web/changelogs/5.0.md +++ b/web/changelogs/5.0.md @@ -1,5 +1,6 @@ --- title: "it's all about attention to detail!" +date: "Feb 13, 2023" banner: file: "valentines.webp" alt: "relaxed meowth with sakura petals falling in front of them" diff --git a/web/changelogs/5.1.md b/web/changelogs/5.1.md index 905c573d..1b37d145 100644 --- a/web/changelogs/5.1.md +++ b/web/changelogs/5.1.md @@ -1,5 +1,6 @@ --- title: "the evil has been defeated" +date: "Feb 26, 2023" banner: file: "happymeowth.webp" alt: "meowth jumping up into the sky very excitedly" diff --git a/web/changelogs/5.2.md b/web/changelogs/5.2.md index e6e7c72b..d1114825 100644 --- a/web/changelogs/5.2.md +++ b/web/changelogs/5.2.md @@ -1,5 +1,6 @@ --- title: "fastest one in the game" +date: "Mar 24, 2023" banner: file: "catspeed.webp" alt: "a cat running very fast in an exercise wheel" diff --git a/web/changelogs/5.3.md b/web/changelogs/5.3.md index 3233f365..1aa2adb9 100644 --- a/web/changelogs/5.3.md +++ b/web/changelogs/5.3.md @@ -1,5 +1,6 @@ --- title: "better looks, better feel" +date: "Apr 3, 2023" banner: file: "cattired.webp" alt: "a cat laying on a sofa face down, wiggling its tail" diff --git a/web/changelogs/5.4.md b/web/changelogs/5.4.md index ef405fc5..6dfa58b2 100644 --- a/web/changelogs/5.4.md +++ b/web/changelogs/5.4.md @@ -1,5 +1,6 @@ --- title: "instagram support, docker, and more!" +date: "Apr 24, 2023" banner: file: "catphonestand.webp" alt: "a cat holding a phone under its chin while a person plays clash of clans on it" From 534af330ce56d2ab536871d7c43a91fac823a6a9 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 11:30:06 +0000 Subject: [PATCH 240/775] web/changelogs: make `date` attribute required --- web/src/components/changelog/ChangelogEntry.svelte | 2 +- web/src/lib/types/changelogs.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index 6100af31..d23500fc 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -3,7 +3,7 @@ export let version: string; export let title: string; - export let date: string | undefined; + export let date: string; export let banner: { file: string; alt: string } | undefined; let bannerLoaded = false; diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts index e4d73c5d..ed3d85f9 100644 --- a/web/src/lib/types/changelogs.ts +++ b/web/src/lib/types/changelogs.ts @@ -2,7 +2,7 @@ import type { SvelteComponent } from "svelte" export interface ChangelogMetadata { title: string, - date?: string + date: string banner?: { file: string, alt: string From 4fab0d3fb8a657870949a54ef580e34ebbf88721 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 11:31:55 +0000 Subject: [PATCH 241/775] web/ChangelogEntry: expect date to always exist --- web/src/components/changelog/ChangelogEntry.svelte | 4 +--- web/src/lib/types/changelogs.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index d23500fc..4fdc1129 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -27,9 +27,7 @@
{version}
- {#if date} -
{formatDate(date)}
- {/if} +
{formatDate(date)}

{title}

diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts index ed3d85f9..d07740d6 100644 --- a/web/src/lib/types/changelogs.ts +++ b/web/src/lib/types/changelogs.ts @@ -2,7 +2,7 @@ import type { SvelteComponent } from "svelte" export interface ChangelogMetadata { title: string, - date: string + date: string, banner?: { file: string, alt: string From 4402484a0cd70fe0dd0c9f807512dd898e991f18 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 17:34:31 +0600 Subject: [PATCH 242/775] web/updates: reduce mobile navigation padding --- web/src/routes/updates/+page.svelte | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 1cd59664..63884bd0 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -166,9 +166,8 @@ @media only screen and (max-width: 1150px) { .button-wrapper-mobile { display: flex; - padding-bottom: 1rem; - margin-left: 1rem; - margin-right: 1rem; + padding: var(--border-radius); + padding-top: 0; justify-content: space-between; } From 9b4f593f87b2b30cc55b81f5ef6daf2153af9f31 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 15:53:33 +0000 Subject: [PATCH 243/775] web/changelogs: add more historical changelogs --- web/changelogs/2.0.md | 20 ++++++++++++++++++ web/changelogs/2.2.5.md | 17 +++++++++++++++ web/changelogs/2.2.6.md | 10 +++++++++ web/changelogs/2.2.8.md | 7 +++++++ web/changelogs/2.2.9.md | 10 +++++++++ web/changelogs/2.2.md | 16 ++++++++++++++ web/changelogs/3.0.md | 46 +++++++++++++++++++++++++++++++++++++++++ web/changelogs/3.1.md | 11 ++++++++++ web/changelogs/3.2.md | 12 +++++++++++ web/changelogs/3.3.md | 17 +++++++++++++++ web/changelogs/3.4.md | 15 ++++++++++++++ 11 files changed, 181 insertions(+) create mode 100644 web/changelogs/2.0.md create mode 100644 web/changelogs/2.2.5.md create mode 100644 web/changelogs/2.2.6.md create mode 100644 web/changelogs/2.2.8.md create mode 100644 web/changelogs/2.2.9.md create mode 100644 web/changelogs/2.2.md create mode 100644 web/changelogs/3.0.md create mode 100644 web/changelogs/3.1.md create mode 100644 web/changelogs/3.2.md create mode 100644 web/changelogs/3.3.md create mode 100644 web/changelogs/3.4.md diff --git a/web/changelogs/2.0.md b/web/changelogs/2.0.md new file mode 100644 index 00000000..0e778003 --- /dev/null +++ b/web/changelogs/2.0.md @@ -0,0 +1,20 @@ +--- +title: "everything is new!" +date: "Jun 28, 2022" +--- + +- added support for: bilibili.com, youtube, youtube music, reddit, vk; +- remade the way downloads are handled; +- added proper website branding; +- added settings, donations, and changelog menu; +- added manual theme picker; +- added format picker for youtube; +- added quality picker for youtube and vk downloads (bilibili and twitter later); +- improved usability; +- upgraded the download button to be adaptive depending on current status; +- popups are now adaptive, too; +- better scalability; +- took out trash; +- moved from commonjs to ems; +- overall revamp of backend and frontend; +- fixed various issues that were present in older version. \ No newline at end of file diff --git a/web/changelogs/2.2.5.md b/web/changelogs/2.2.5.md new file mode 100644 index 00000000..11fde1c0 --- /dev/null +++ b/web/changelogs/2.2.5.md @@ -0,0 +1,17 @@ +--- +title: "remade localization system once again" +date: "Jul 24, 2022" +--- + +- new localization system: fast, dynamic, way more organized +- localization strings are WAY more descriptive +- it's now easier to add support for other languages (just one loc file instead of five) +- localization now falls back to english if localized string isnt available +- got rid of all static language selectors (probably) +- slightly updated english and russian strings +- miscellaneous settings items have been bundled together and moved to the bottom, cause they're used the least +- bottom links should no longer touch the popup border on overflow +- rearranged popup order in the rendered page +- bumped version up to 2.2.5 + +if you see strings that are like this: !!EXAMPLE!! or withoutspace please file an issue on github diff --git a/web/changelogs/2.2.6.md b/web/changelogs/2.2.6.md new file mode 100644 index 00000000..02ce1a29 --- /dev/null +++ b/web/changelogs/2.2.6.md @@ -0,0 +1,10 @@ +--- +title: "tiktok is back!" +date: "Jul 28, 2022" +--- + +- added support for tiktok (images won't work, they're only accessible through the app) +- hopefully main input bar is now not rounded on ios, i fucking hate apple +- if service is not supported, a correlating error will appear, not generic one +- removed duplicates from config that are present in package json already +- tiny bit of clean up \ No newline at end of file diff --git a/web/changelogs/2.2.8.md b/web/changelogs/2.2.8.md new file mode 100644 index 00000000..ba054adc --- /dev/null +++ b/web/changelogs/2.2.8.md @@ -0,0 +1,7 @@ +--- +title: "faster and more accessible" +date: "Jul 30, 2022" +--- + +- spanish localization by @adrigoomy +- cobalt should load even faster cause all loaded files are now way smaller (esbuild implementation) \ No newline at end of file diff --git a/web/changelogs/2.2.9.md b/web/changelogs/2.2.9.md new file mode 100644 index 00000000..ef54654c --- /dev/null +++ b/web/changelogs/2.2.9.md @@ -0,0 +1,10 @@ +--- +title: "fixes" +date: "Aug 6, 2022" +--- + +- fixed neighbor quality picking for youtube videos +- webm is now default for youtube downloads for all platforms except for ios +- even more readme changes +- a tiny bit of clean up +- preparing stuff for next major update \ No newline at end of file diff --git a/web/changelogs/2.2.md b/web/changelogs/2.2.md new file mode 100644 index 00000000..768094e6 --- /dev/null +++ b/web/changelogs/2.2.md @@ -0,0 +1,16 @@ +--- +title: "beginning of 2.2" +date: "Jul 13, 2022" +--- + +- added download popup to solve the issue with downloads on ios +- merged big and small popups into one +- made buttons in donation menu act like buttons +- began to clean up localisation +- added ability to embed repo url into localisation strings +- moved ffmpeg args to config for more flexibility (and hopefully future changes) +- removed error response in stream that could result in a crash +- removed notice for ios users from about cause it's no longer relevant +- made error popup look and act like the rest +- a tiny bit of clean up +- changelog is now made out of latest commit (and doesn't break) \ No newline at end of file diff --git a/web/changelogs/3.0.md b/web/changelogs/3.0.md new file mode 100644 index 00000000..37c2d5e8 --- /dev/null +++ b/web/changelogs/3.0.md @@ -0,0 +1,46 @@ +--- +title: "everything what you've been waiting for. welcome to cobalt 3.0 :)" +date: "Aug 12, 2022" +--- + +follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) + +stuff that you can notice: + +- you can now download audio from any supported service, in any format that you set in settings (+). yes, that includes mp3, which you all have been waiting for :D +- it's now easier to switch between download modes (just a single toggle on the bottom). +- your youtube download format has been reset, sorry, but that was required to implement all audio downloads. +- default download format for youtube videos on all platforms is now webm. except for ios. + +- cobalt now has emoji, just to spice up the black and white ui. all of them have been tuned to look the best in both themes. isn't it cool? +- about, changelog, and donation popups have been merged into just one, for covnenience. +- changelog got a huge upgrade (as you can see), and now there are both major changes and latest commit info, just so commits can finally go back to being batshit insane. +- changelog popup appears on every major update, but you can disable it in settings, if you want to. +- changelog now opens by default when pressing "?" button. i don't think anyone reads "about" as often. +- settings (+) have been split into three tabs, also for convenience and ease of use. + +- added support for donation links. you can now donate through boosty, not only via crypto :D +- donate popup has been rearranged and tuned just a tiny bit. + +- you can now click away from any popup by pressing the void behind it. +- you can also press "escape" key on keyboard to close any popup. + +- switchers and buttons are now way easier on eye. white border is gone from where it's unneeded. +- buttons are now very satisfying to press. +- switchers are scrollable if there's not enough space to fit all contents on screen. +- scaling is now even better than before. + +internal stuff: + +- frontend won't send video related stuff if audio mode is on. +- matching has, yet again, gone through mitosis, and is now probably the cleanest it can get. +- page rendering is now modular, something like what frameworks have but way lighter. this makes adding new features WAY easier. +- removed some stuff that didn't make sense (like storing language of stream request). +- cleaned up insides of cobalt, of course. +- almost all links now open in new tab, just like they should have from the very beginning. + +known issues: +- impossible to download audio from vk. i'll try to fix it in the next update. +- headers are not sticky in tabbed popups. maybe this is a good thing, i'll think about it. + +if you ever notice any issues, make sure to report them on github. your report doesn't have to sound professional, just do your best to describe the issue. \ No newline at end of file diff --git a/web/changelogs/3.1.md b/web/changelogs/3.1.md new file mode 100644 index 00000000..8b4bff75 --- /dev/null +++ b/web/changelogs/3.1.md @@ -0,0 +1,11 @@ +--- +title: small quality of life improvements +date: "Aug 16, 2022" +--- + +- tiktok videos can now be downloaded without watermark, you just have to enable it in video settings (+)! +- you now can pass "u" query to main website to fill out the input area right away (co.wukko.me?u=your_link_here). +- added ability to select text in certain areas of website. +- some internal stuff has been cleaned up. + +follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) \ No newline at end of file diff --git a/web/changelogs/3.2.md b/web/changelogs/3.2.md new file mode 100644 index 00000000..5896eb05 --- /dev/null +++ b/web/changelogs/3.2.md @@ -0,0 +1,12 @@ +--- +title: ukrainian localization and new error popup +date: "Aug 19, 2022" +--- + +- added ukrainian localization (thanks to löffel). +- new error popup! it's now prettier, more compact, and has an easily accessible close button. +- russian localization has been patched up a bit +- cleaned up css a bit +- added github contributors to made with love message. +- emojis have been tuned to have the same shade of yellow. +- updated translation guidelines in readme a bit. \ No newline at end of file diff --git a/web/changelogs/3.3.md b/web/changelogs/3.3.md new file mode 100644 index 00000000..39f50d8c --- /dev/null +++ b/web/changelogs/3.3.md @@ -0,0 +1,17 @@ +--- +title: soundcloud and better usability +date: "Sep 3, 2022" +--- + +- added ability to save images from tiktok conveniently, and without watermarks. +- it's now way easier to contribute translations to cobalt. read more on how to do it [on github](https://github.com/imputnet/cobalt#how-to-contribute-translations). in short, you don't need to fork the repo anymore, everything is handled through crowdin :D +- updated readme in github repo to make it easier to read and understand. +- began to add more descriptive errors, more to come soon. + +internal stuff: +- remade entirety of tiktok module and merged it with douyin one. now both (basically identical) platforms have perfect parity of download features. +- cleaned up the twitter module, now it's way more compact and easy to read. +- moved changelog out of english localization. +- other small improvements and fixes. + +follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) \ No newline at end of file diff --git a/web/changelogs/3.4.md b/web/changelogs/3.4.md new file mode 100644 index 00000000..c781af17 --- /dev/null +++ b/web/changelogs/3.4.md @@ -0,0 +1,15 @@ +--- +title: tiktok images and better localization +date: "Sep 3, 2022" +--- + +- added ability to save images from tiktok conveniently, and without watermarks. +- it's now way easier to contribute translations to cobalt. read more on how to do it [on github](https://github.com/imputnet/cobalt#how-to-contribute-translations). in short, you don't need to fork the repo anymore, everything is handled through crowdin :D +- updated readme in github repo to make it easier to read and understand. +- began to add more descriptive errors, more to come soon. + +internal stuff: +- remade entirety of tiktok module and merged it with douyin one. now both (basically identical) platforms have perfect parity of download features. +- cleaned up the twitter module, now it's way more compact and easy to read. +- moved changelog out of english localization. +- other small improvements and fixes. \ No newline at end of file From f93f3cd55886537334fa35176ba22341a17316de Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 22:49:26 +0600 Subject: [PATCH 244/775] web/DownloadButton: fallback if status isn't supported --- web/src/components/save/buttons/DownloadButton.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 40b78942..55657ddf 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -118,6 +118,14 @@ }) } } + + changeDownloadButton("error"); + restoreDownloadButton(); + + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: "unknown/unsupported status" + }) }; From bb446ecf3ee477bec637b96f6167d66fd6eb2727 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 17:26:21 +0000 Subject: [PATCH 245/775] web: add Optional type and use it --- web/src/components/changelog/ChangelogEntry.svelte | 3 ++- web/src/components/dialog/SmallDialog.svelte | 7 ++++--- web/src/components/misc/Skeleton.svelte | 8 +++++--- web/src/components/save/Omnibox.svelte | 3 ++- web/src/lib/api.ts | 5 +++-- web/src/lib/types/generic.ts | 1 + web/src/routes/updates/+page.svelte | 3 ++- 7 files changed, 19 insertions(+), 11 deletions(-) diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index 4fdc1129..75748940 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -1,10 +1,11 @@ + + + + diff --git a/web/src/components/dialog/DialogButtons.svelte b/web/src/components/dialog/DialogButtons.svelte new file mode 100644 index 00000000..5f086a78 --- /dev/null +++ b/web/src/components/dialog/DialogButtons.svelte @@ -0,0 +1,61 @@ + + + + + diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 7a9550fe..61503fcd 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -1,7 +1,9 @@ @@ -18,11 +20,56 @@ buttons={dialog.buttons} /> {/if} + + {#if dialog.type === "picker"} + + {/if} {/each}
diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte new file mode 100644 index 00000000..5c5c0d61 --- /dev/null +++ b/web/src/components/dialog/PickerDialog.svelte @@ -0,0 +1,231 @@ + + + +
+ +
+ {#if items} + {#each items as item} + + {/each} + {/if} +
+ {#if buttons} + + {/if} +
+ + +
+ + diff --git a/web/src/components/dialog/PickerItem.svelte b/web/src/components/dialog/PickerItem.svelte new file mode 100644 index 00000000..b56abcc9 --- /dev/null +++ b/web/src/components/dialog/PickerItem.svelte @@ -0,0 +1,65 @@ + + + + + diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 3a4cdddf..b2951d62 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -1,12 +1,14 @@ diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts new file mode 100644 index 00000000..e08320ef --- /dev/null +++ b/web/src/lib/download.ts @@ -0,0 +1,9 @@ +import { device } from "$lib/device"; + +export const downloadFile = (url: string) => { + if (device.is.iOS) { + return navigator?.share({ url }).catch(() => {}); + } else { + return window.open(url, "_blank"); + } +}; diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 6630fd6f..f6d2439d 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -9,13 +9,20 @@ export type DialogButton = { export type SmallDialogIcons = "warn-red"; +export type DialogPickerItem = { + type?: 'photo' | 'video', + url: string, + thumb?: string, +} + export type DialogInfo = { id: string, - type: "small", + type: "small" | "picker", meowbalt?: MeowbaltEmotions, icon?: SmallDialogIcons, title?: string, bodyText?: string, bodySubText?: string, - buttons: DialogButton[], + buttons?: DialogButton[], + items?: DialogPickerItem[], } From 4e4f7af43710e53adb3b6398d129792699e4df89 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 08:38:06 +0000 Subject: [PATCH 249/775] web/settings: types for preparation for future migrations --- web/src/lib/state/settings.ts | 18 +++++++++--------- web/src/lib/types/generic.ts | 2 +- web/src/lib/types/settings.ts | 13 +++++++++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/web/src/lib/state/settings.ts b/web/src/lib/state/settings.ts index 79dfdc31..e19c50bb 100644 --- a/web/src/lib/state/settings.ts +++ b/web/src/lib/state/settings.ts @@ -1,15 +1,15 @@ import { derived, readable, type Updater } from 'svelte/store'; import { merge } from 'ts-deepmerge'; -import type { RecursivePartial } from '../types/generic'; -import type { CobaltSettings } from '../types/settings'; +import type { + CobaltSettings, + PartialSettings, + AllPartialSettingsWithSchema +} from '../types/settings'; import { migrateOldSettings } from '../settings/migrate'; import defaultSettings from '../settings/defaults'; -type PartialSettings = RecursivePartial; -type PartialSettingsWithSchema = RecursivePartial & { schemaVersion: number }; - const updatePlausiblePreference = (settings: PartialSettings) => { if (settings.privacy?.disableAnalytics) { localStorage.setItem('plausible_ignore', 'true'); @@ -27,18 +27,18 @@ const writeToStorage = (settings: PartialSettings) => { return settings; } -type Migrator = (s: PartialSettings) => PartialSettings; +type Migrator = (s: AllPartialSettingsWithSchema) => AllPartialSettingsWithSchema; const migrations: Record = { } -const migrate = (settings: PartialSettingsWithSchema) => { +const migrate = (settings: AllPartialSettingsWithSchema): PartialSettings => { return Object.keys(migrations) .map(Number) .filter(version => version > settings.schemaVersion) .reduce((settings, migrationVersion) => { return migrations[migrationVersion](settings); - }, settings as PartialSettings); + }, settings as AllPartialSettingsWithSchema); } const loadFromStorage = () => { @@ -52,7 +52,7 @@ const loadFromStorage = () => { return {}; } - const parsed = JSON.parse(settings) as PartialSettingsWithSchema; + const parsed = JSON.parse(settings) as AllPartialSettingsWithSchema; if (parsed.schemaVersion < defaultSettings.schemaVersion) { return migrate(parsed); } diff --git a/web/src/lib/types/generic.ts b/web/src/lib/types/generic.ts index a03d969f..9807cea5 100644 --- a/web/src/lib/types/generic.ts +++ b/web/src/lib/types/generic.ts @@ -8,4 +8,4 @@ export type RecursivePartial = { }; export type DefaultImport = () => Promise<{ default: T }>; -export type Optional = T | undefined; \ No newline at end of file +export type Optional = T | undefined; diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts index bfeb2d10..5965bf49 100644 --- a/web/src/lib/types/settings.ts +++ b/web/src/lib/types/settings.ts @@ -1,4 +1,5 @@ import languages from '$i18n/languages.json'; +import type { RecursivePartial } from './generic'; export const themeOptions = ["auto", "light", "dark"] as const; export const audioFormatOptions = ["best", "mp3", "ogg", "wav", "opus"] as const; @@ -37,12 +38,20 @@ type CobaltSettingsSave = { youtubeDubBrowserLang: boolean, }; -export type CobaltSettings = { - schemaVersion: number, +export type CurrentCobaltSettings = { + schemaVersion: 2, advanced: CobaltSettingsAdvanced, appearance: CobaltSettingsAppearance, save: CobaltSettingsSave, privacy: CobaltSettingsPrivacy }; +export type CobaltSettings = CurrentCobaltSettings; + +export type PartialSettings = RecursivePartial; +export type PartialSettingsWithSchema = RecursivePartial & { schemaVersion: number }; + +export type AllSchemaVersions = CurrentCobaltSettings; +export type AllPartialSettingsWithSchema = RecursivePartial & { schemaVersion: number }; + export type DownloadModeOption = CobaltSettings['save']['downloadMode']; From 7c5b703e373b6c8a5480304f080f54678d109d00 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 09:06:11 +0000 Subject: [PATCH 250/775] web/dialog: refactor types and logic --- web/src/components/dialog/DialogHolder.svelte | 4 +--- .../save/buttons/DownloadButton.svelte | 8 ++++---- web/src/lib/types/dialog.ts | 17 +++++++++++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 61503fcd..a77607c3 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -19,9 +19,7 @@ bodySubText={dialog.bodySubText} buttons={dialog.buttons} /> - {/if} - - {#if dialog.type === "picker"} + {:else if dialog.type === "picker"} Date: Mon, 22 Jul 2024 15:13:51 +0600 Subject: [PATCH 251/775] web/picker: add item type icons and improve accessibility --- web/i18n/en/a11y/dialog.json | 3 +- web/src/components/dialog/PickerDialog.svelte | 10 +++- web/src/components/dialog/PickerItem.svelte | 52 +++++++++++++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/web/i18n/en/a11y/dialog.json b/web/i18n/en/a11y/dialog.json index 451d74cf..cdade377 100644 --- a/web/i18n/en/a11y/dialog.json +++ b/web/i18n/en/a11y/dialog.json @@ -1,3 +1,4 @@ { - "picker.item.generic": "media thumbnail" + "picker.item.photo": "photo thumbnail", + "picker.item.video": "video thumbnail" } diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index 5c5c0d61..c1bb82a5 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -50,6 +50,14 @@ open = true; }); } + + // item id for alt text + let counter = 0; + + const itemNumber = () => { + counter++ + return counter + } {#if items} {#each items as item} - + {/each} {/if}
diff --git a/web/src/components/dialog/PickerItem.svelte b/web/src/components/dialog/PickerItem.svelte index b56abcc9..e53dcfe2 100644 --- a/web/src/components/dialog/PickerItem.svelte +++ b/web/src/components/dialog/PickerItem.svelte @@ -6,9 +6,18 @@ import Skeleton from "$components/misc/Skeleton.svelte"; + import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; + import IconPhoto from "@tabler/icons-svelte/IconPhoto.svelte"; + export let item: DialogPickerItem; + export let number: number; let imageLoaded = false; + + let itemType = item.type; + if (!itemType) { + itemType = "photo" + } From 705fac16a69cd97b3713b032954d785c184f2cde Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 09:24:17 +0000 Subject: [PATCH 252/775] web/dialog: internal refactor --- web/src/components/dialog/DialogHolder.svelte | 19 ++++--------------- web/src/components/dialog/PickerDialog.svelte | 16 ++++------------ web/src/components/dialog/SmallDialog.svelte | 12 ++++++------ 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index a77607c3..72941b1a 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -9,22 +9,11 @@
{#each $dialogs as dialog} - {#if dialog.type === "small"} - + {@const { type, ...data } = dialog} + {#if type === "small"} + {:else if dialog.type === "picker"} - + {/if} {/each}
diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index c1bb82a5..fe269cee 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -15,8 +15,8 @@ import IconBoxMultiple from "@tabler/icons-svelte/IconBoxMultiple.svelte"; export let id: string; - export let items: Optional; - export let buttons: Optional; + export let items: Optional = undefined; + export let buttons: Optional = undefined; let dialogDescription = "dialog.picker.description."; @@ -50,14 +50,6 @@ open = true; }); } - - // item id for alt text - let counter = 0; - - const itemNumber = () => { - counter++ - return counter - }
{#if items} - {#each items as item} - + {#each items as item, i} + {/each} {/if}
diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index b2951d62..d54f2b13 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -13,12 +13,12 @@ import IconAlertTriangle from "@tabler/icons-svelte/IconAlertTriangle.svelte"; export let id: string; - export let meowbalt: Optional; - export let icon: Optional; - export let title: string = ""; - export let bodyText: string = ""; - export let bodySubText: string = ""; - export let buttons: Optional; + export let meowbalt: Optional = undefined; + export let icon: Optional = undefined; + export let title = ""; + export let bodyText = ""; + export let bodySubText = ""; + export let buttons: Optional = undefined; let dialogParent: HTMLDialogElement; From c03337fed99e42c4461aece91642effce909252d Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 10:11:23 +0000 Subject: [PATCH 253/775] web/skeleton: don't render if hidden --- web/src/components/misc/Skeleton.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/misc/Skeleton.svelte b/web/src/components/misc/Skeleton.svelte index bb0b295f..7f625e4b 100644 --- a/web/src/components/misc/Skeleton.svelte +++ b/web/src/components/misc/Skeleton.svelte @@ -10,16 +10,17 @@ $: style = [ width && `width: ${width}`, - height && `height: ${height}`, - hidden && `display: none` + height && `height: ${height}` ].filter(a => a).join(';'); +{#if hidden !== true}
+{/if} From d170f619d2d1f33627cd8539e9643cf8ba857ab1 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 10:17:06 +0000 Subject: [PATCH 255/775] web: use conditionals instead of special classes where it makes sense --- web/src/components/misc/NotchSticker.svelte | 12 +++++------- web/src/routes/settings/+layout.svelte | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/web/src/components/misc/NotchSticker.svelte b/web/src/components/misc/NotchSticker.svelte index 84c3cc76..7dd45af2 100644 --- a/web/src/components/misc/NotchSticker.svelte +++ b/web/src/components/misc/NotchSticker.svelte @@ -39,9 +39,11 @@ } - +{#if state !== "hidden"} + +{/if} \ No newline at end of file diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 2cf815c9..d5fe935d 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -76,6 +76,7 @@ --button-elevated: #e3e3e3; --button-elevated-hover: #dadada; + --button-elevated-shimmer: #ededed; --popup-bg: #f1f1f1; --popup-stroke: rgba(0, 0, 0, 0.08); @@ -123,6 +124,13 @@ var(--button), var(--button-hover) ); + + --skeleton-gradient-elevated: linear-gradient( + 90deg, + var(--button-elevated), + var(--button-elevated-shimmer), + var(--button-elevated) + ); } :global([data-theme="dark"]) { @@ -143,7 +151,7 @@ --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; --button-elevated: #282828; - --button-elevated-hover: #2f2f2f; + --button-elevated-hover: #323232; --popup-bg: #191919; --popup-stroke: rgba(255, 255, 255, 0.08); @@ -173,6 +181,13 @@ var(--button-hover), var(--button) ); + + --skeleton-gradient-elevated: linear-gradient( + 90deg, + var(--button-elevated), + var(--button-elevated-hover), + var(--button-elevated) + ); } :global([data-theme="light"] [data-reduce-transparency="true"]) { From bdd572ea5185ba63b64d2b4850cbbe4eb5ce4684 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 09:59:08 +0600 Subject: [PATCH 261/775] web/dialogs: reduce margin on mobile --- web/src/components/dialog/PickerDialog.svelte | 2 +- web/src/components/dialog/SmallDialog.svelte | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index db01c9cd..ef2089a4 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -169,7 +169,7 @@ @media screen and (max-width: 535px) { .picker-dialog { margin-bottom: calc( - var(--dialog-padding) + env(safe-area-inset-bottom) + var(--padding) / 2 + env(safe-area-inset-bottom) ); box-shadow: 0 0 0 2px var(--popup-stroke) inset; } diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index d54f2b13..9f729c48 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -98,14 +98,14 @@ text-align: center; max-width: 340px; width: calc( - 100% - var(--padding) * 2 - var(--dialog-padding) * 2 + 100% - var(--padding) - var(--dialog-padding) * 2 ); background: var(--popup-bg); box-shadow: 0 0 0 2px var(--popup-stroke) inset, 0 0 60px 10px var(--popup-bg); padding: var(--dialog-padding); - margin: var(--padding); + margin: calc(var(--padding) / 2); border-radius: 29px; position: relative; will-change: transform; @@ -148,7 +148,7 @@ @media screen and (max-width: 535px) { .small-dialog { - margin-bottom: calc(var(--padding) + env(safe-area-inset-bottom)); + margin-bottom: calc(var(--padding) / 2 + env(safe-area-inset-bottom)); box-shadow: 0 0 0 2px var(--popup-stroke) inset; } } From 8c96ccbc7bd4d2cbf1f944393b74011d964750ac Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 10:01:55 +0600 Subject: [PATCH 262/775] web/SmallDialog: make body scrollable on overflow & limit height --- web/src/components/dialog/SmallDialog.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 9f729c48..20482dd1 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -88,6 +88,7 @@ } .popup-body { + overflow-y: scroll; gap: 8px; } @@ -100,6 +101,7 @@ width: calc( 100% - var(--padding) - var(--dialog-padding) * 2 ); + max-height: 50%; background: var(--popup-bg); box-shadow: 0 0 0 2px var(--popup-stroke) inset, From 0225a7c46c4fad8c5e952079c1157c47ff6efb61 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 11:00:27 +0600 Subject: [PATCH 263/775] web/settings: simplify sidebar, add version info, flatten page navigation --- web/i18n/en/settings.json | 2 +- web/src/lib/settings/defaults.ts | 2 +- web/src/routes/settings/+layout.svelte | 46 ++++++++++++++----- .../{general => }/appearance/+page.svelte | 0 .../settings/{save => }/audio/+page.svelte | 0 .../{advanced => }/debug/+page.svelte | 0 .../{save/metadata => download}/+page.svelte | 0 .../{general => }/privacy/+page.svelte | 0 .../settings/{save => }/video/+page.svelte | 0 9 files changed, 36 insertions(+), 14 deletions(-) rename web/src/routes/settings/{general => }/appearance/+page.svelte (100%) rename web/src/routes/settings/{save => }/audio/+page.svelte (100%) rename web/src/routes/settings/{advanced => }/debug/+page.svelte (100%) rename web/src/routes/settings/{save/metadata => download}/+page.svelte (100%) rename web/src/routes/settings/{general => }/privacy/+page.svelte (100%) rename web/src/routes/settings/{save => }/video/+page.svelte (100%) diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 7273ea1e..82bfb282 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -3,7 +3,7 @@ "page.privacy": "privacy", "page.video": "video", "page.audio": "audio", - "page.metadata": "metadata", + "page.download": "downloading", "page.advanced": "advanced", "page.debug": "debug information", diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts index c8bdb8a6..38725766 100644 --- a/web/src/lib/settings/defaults.ts +++ b/web/src/lib/settings/defaults.ts @@ -39,7 +39,7 @@ const defaultSettingsPage = () => { } } - return "/settings/general/appearance"; + return "/settings/appearance"; } export default defaultSettings; diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index b76b3f8d..747ff401 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -2,6 +2,7 @@ import { page } from "$app/stores"; import settings from "$lib/state/settings"; + import { version } from "$lib/version"; import { t } from "$lib/i18n/translations"; @@ -12,7 +13,7 @@ import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; import IconMusic from "@tabler/icons-svelte/IconMusic.svelte"; - import IconFileSettings from "@tabler/icons-svelte/IconFileSettings.svelte"; + import IconFileDownload from "@tabler/icons-svelte/IconFileDownload.svelte"; import IconSettingsBolt from "@tabler/icons-svelte/IconSettingsBolt.svelte"; import IconBug from "@tabler/icons-svelte/IconBug.svelte"; import IconLock from "@tabler/icons-svelte/IconLock.svelte"; @@ -24,6 +25,8 @@ let screenWidth: number; + $: versionText = `v.${$version.version}-${$version.commit.slice(0, 7)}`; + $: currentPageTitle = $page.url.pathname.split("/").at(-1); $: stringPageTitle = currentPageTitle !== "settings" ? ` / ${$t(`settings.page.${currentPageTitle}`)}` : ""; @@ -68,51 +71,56 @@ {/if} {:else} +
+ {versionText} +

{$t("tabs.settings")}

{/if}
@@ -180,7 +194,7 @@ } #settings-sidebar { - gap: 24px; + gap: var(--padding); } #settings-navigation { @@ -192,6 +206,14 @@ --back-padding: calc(var(--padding) / 2); } + .settings-version { + padding: 0; + } + + .settings-version.center { + text-align: center; + } + .back-button { display: flex; align-items: center; diff --git a/web/src/routes/settings/general/appearance/+page.svelte b/web/src/routes/settings/appearance/+page.svelte similarity index 100% rename from web/src/routes/settings/general/appearance/+page.svelte rename to web/src/routes/settings/appearance/+page.svelte diff --git a/web/src/routes/settings/save/audio/+page.svelte b/web/src/routes/settings/audio/+page.svelte similarity index 100% rename from web/src/routes/settings/save/audio/+page.svelte rename to web/src/routes/settings/audio/+page.svelte diff --git a/web/src/routes/settings/advanced/debug/+page.svelte b/web/src/routes/settings/debug/+page.svelte similarity index 100% rename from web/src/routes/settings/advanced/debug/+page.svelte rename to web/src/routes/settings/debug/+page.svelte diff --git a/web/src/routes/settings/save/metadata/+page.svelte b/web/src/routes/settings/download/+page.svelte similarity index 100% rename from web/src/routes/settings/save/metadata/+page.svelte rename to web/src/routes/settings/download/+page.svelte diff --git a/web/src/routes/settings/general/privacy/+page.svelte b/web/src/routes/settings/privacy/+page.svelte similarity index 100% rename from web/src/routes/settings/general/privacy/+page.svelte rename to web/src/routes/settings/privacy/+page.svelte diff --git a/web/src/routes/settings/save/video/+page.svelte b/web/src/routes/settings/video/+page.svelte similarity index 100% rename from web/src/routes/settings/save/video/+page.svelte rename to web/src/routes/settings/video/+page.svelte From ee162aa23635cf4ffef091f53ff7ee5f9923e0fa Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:13:40 +0600 Subject: [PATCH 264/775] web/ClearButton: fix rendering bug in safari & clean up --- .../components/save/buttons/ClearButton.svelte | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/web/src/components/save/buttons/ClearButton.svelte b/web/src/components/save/buttons/ClearButton.svelte index 9962aa1b..4847a95a 100644 --- a/web/src/components/save/buttons/ClearButton.svelte +++ b/web/src/components/save/buttons/ClearButton.svelte @@ -1,12 +1,16 @@ - From 48078e7e756f2050cf11f5faf029bde9d235405a Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:19:12 +0600 Subject: [PATCH 265/775] web/updates: replace chevron with arrow --- web/src/routes/updates/+page.svelte | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 140eb046..2a8aa8f7 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -8,8 +8,8 @@ import ChangelogSkeleton from "$components/changelog/ChangelogSkeleton.svelte"; - import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; - import IconChevronRight from "@tabler/icons-svelte/IconChevronRight.svelte"; + import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte"; + import IconArrowRight from "@tabler/icons-svelte/IconArrowRight.svelte"; const changelogs = getAllChangelogs(); const versions = Object.keys(changelogs); @@ -72,7 +72,7 @@
{#if prev} {/if} @@ -91,7 +91,7 @@ {/await}
@@ -113,7 +113,7 @@ on:mousemove={preloadNext} > {next || ""} - + {/if}
@@ -142,6 +142,10 @@ border: none; } + button :global(svg) { + stroke-width: 1.6px; + } + .button-wrapper-desktop button:not(:focus-visible) { box-shadow: none; } From 5c6ef1913282dcae295e217df30e41b413641562 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:19:38 +0600 Subject: [PATCH 266/775] web/settings: update the back button icon --- web/src/routes/settings/+layout.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index 747ff401..a6e9d391 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -18,7 +18,7 @@ import IconBug from "@tabler/icons-svelte/IconBug.svelte"; import IconLock from "@tabler/icons-svelte/IconLock.svelte"; - import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; + import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte"; import { goto } from "$app/navigation"; import { defaultSettingsPage } from "$lib/settings/defaults"; @@ -60,7 +60,7 @@ role="button" aria-label={$t("a11y.general.back")} > - + {/if}

@@ -234,6 +234,7 @@ stroke-width: 2px; height: 22px; width: 22px; + will-change: transform; } @media screen and (max-width: 750px) { From 518f634385c1c68011c16fa5e72078916e06f11c Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:20:30 +0600 Subject: [PATCH 267/775] web/settings: reduce thickness of back button icon --- web/src/routes/settings/+layout.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index a6e9d391..b09d24b1 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -231,7 +231,7 @@ } .back-button :global(svg) { - stroke-width: 2px; + stroke-width: 1.8px; height: 22px; width: 22px; will-change: transform; From 94853f0b7b5852375fa46711ec67e373d488a583 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:34:14 +0600 Subject: [PATCH 268/775] web/FilenamePreview: finish the component --- web/i18n/en/settings.json | 2 +- .../settings/FilenamePreview.svelte | 83 +++++++++++++++++-- web/src/routes/settings/download/+page.svelte | 10 ++- 3 files changed, 84 insertions(+), 11 deletions(-) diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 82bfb282..0127627b 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -63,7 +63,7 @@ "metadata.filename.basic": "basic", "metadata.filename.pretty": "pretty", "metadata.filename.nerdy": "nerdy", - "metadata.filename.description": "filename style using which cobalt files will be downloaded. this description is temporary as there's no dynamic preview component yet.", + "metadata.filename.description": "filename style will only be used for files processed or proxied by cobalt. some services don't support filename styles.", "metadata.filename.preview.video": "Video Title", "metadata.filename.preview.audio": "Audio Title - Audio Author", diff --git a/web/src/components/settings/FilenamePreview.svelte b/web/src/components/settings/FilenamePreview.svelte index 64fce4f4..829e1745 100644 --- a/web/src/components/settings/FilenamePreview.svelte +++ b/web/src/components/settings/FilenamePreview.svelte @@ -2,6 +2,9 @@ import settings from "$lib/state/settings"; import { t } from "$lib/i18n/translations"; + import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; + import IconMusic from "@tabler/icons-svelte/IconMusic.svelte"; + let videoFilePreview: string; let audioFilePreview: string; @@ -66,18 +69,86 @@
-
- {videoFilePreview}.{youtubeVideoExt} +
+
+ +
+
+
{`${videoFilePreview}.${youtubeVideoExt}`}
+
video file preview
+
-
- {audioFilePreview}.{audioFormat} +
+
+ +
+
+
{`${audioFilePreview}.${audioFormat}`}
+
audio file preview
+
diff --git a/web/src/routes/settings/download/+page.svelte b/web/src/routes/settings/download/+page.svelte index 1da7010f..6e6ea6f0 100644 --- a/web/src/routes/settings/download/+page.svelte +++ b/web/src/routes/settings/download/+page.svelte @@ -11,10 +11,7 @@ - + {#each filenameStyleOptions as value} {/each} + + +
+ {$t("settings.metadata.filename.description")} +
Date: Tue, 23 Jul 2024 12:44:13 +0600 Subject: [PATCH 269/775] web/changelogs: remove 3.3 changelog as it's a duplicate of 3.4 --- web/changelogs/3.3.md | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 web/changelogs/3.3.md diff --git a/web/changelogs/3.3.md b/web/changelogs/3.3.md deleted file mode 100644 index 39f50d8c..00000000 --- a/web/changelogs/3.3.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: soundcloud and better usability -date: "Sep 3, 2022" ---- - -- added ability to save images from tiktok conveniently, and without watermarks. -- it's now way easier to contribute translations to cobalt. read more on how to do it [on github](https://github.com/imputnet/cobalt#how-to-contribute-translations). in short, you don't need to fork the repo anymore, everything is handled through crowdin :D -- updated readme in github repo to make it easier to read and understand. -- began to add more descriptive errors, more to come soon. - -internal stuff: -- remade entirety of tiktok module and merged it with douyin one. now both (basically identical) platforms have perfect parity of download features. -- cleaned up the twitter module, now it's way more compact and easy to read. -- moved changelog out of english localization. -- other small improvements and fixes. - -follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) \ No newline at end of file From c12088e29717bec7ad7b5a1d715775eb889d7275 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 13:18:08 +0600 Subject: [PATCH 270/775] web/SmallDialog: flex container for header & icon fixes stranded padding --- web/src/components/dialog/SmallDialog.svelte | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 20482dd1..1e55259b 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -127,7 +127,15 @@ font-size: 19px; } - .popup-header .popup-icon.warn-red :global(svg) { + .popup-header, + .popup-icon { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + .popup-icon.warn-red :global(svg) { stroke-width: 1.5px; height: 50px; width: 50px; From 314d3590ec231943924e63402223181e4fb951d3 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 13:22:05 +0600 Subject: [PATCH 271/775] web/DialogButtons: don't apply hover effect if button is colored --- web/src/components/dialog/DialogButtons.svelte | 1 + web/src/routes/+layout.svelte | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/dialog/DialogButtons.svelte b/web/src/components/dialog/DialogButtons.svelte index 5f086a78..3b9943e1 100644 --- a/web/src/components/dialog/DialogButtons.svelte +++ b/web/src/components/dialog/DialogButtons.svelte @@ -9,6 +9,7 @@ {#each buttons as button} + + +
+ + +
+

make a recurring donation via liberapay

+
+ + + +
+
+ +
+

donate with cryptocurrencies

+
+ {#each Object.entries(donate.crypto) as [ name, address ]} +
+
{ name } (press to copy)
+ +
+ {/each} +
+
+ + + From e0bc0553ca4dd54b60938e84142176e7808279a1 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Fri, 26 Jul 2024 09:05:14 +0000 Subject: [PATCH 294/775] web/donate: fix price padding --- web/src/routes/donate/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index f305ce3a..2469c4ea 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -216,7 +216,7 @@ vertical-align: middle; } - section h3 { + section > h3 { padding: var(--padding) 0; } From 7427788efd791da9ddbdd99e3ab2e7e73b2529d4 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 26 Jul 2024 21:34:18 +0600 Subject: [PATCH 295/775] web/PickerItem: add support for gifs in picker --- web/i18n/en/a11y/dialog.json | 3 ++- web/src/components/dialog/PickerItem.svelte | 5 ++++- web/src/lib/types/dialog.ts | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/web/i18n/en/a11y/dialog.json b/web/i18n/en/a11y/dialog.json index cdade377..84df736b 100644 --- a/web/i18n/en/a11y/dialog.json +++ b/web/i18n/en/a11y/dialog.json @@ -1,4 +1,5 @@ { "picker.item.photo": "photo thumbnail", - "picker.item.video": "video thumbnail" + "picker.item.video": "video thumbnail", + "picker.item.gif": "gif thumbnail" } diff --git a/web/src/components/dialog/PickerItem.svelte b/web/src/components/dialog/PickerItem.svelte index fa159981..f5071885 100644 --- a/web/src/components/dialog/PickerItem.svelte +++ b/web/src/components/dialog/PickerItem.svelte @@ -8,6 +8,7 @@ import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; import IconPhoto from "@tabler/icons-svelte/IconPhoto.svelte"; + import IconGif from "@tabler/icons-svelte/IconGif.svelte"; export let item: DialogPickerItem; export let number: number; @@ -21,6 +22,8 @@
{#if itemType === "video"} + {:else if itemType === "gif"} + {:else} {/if} @@ -31,7 +34,7 @@ src={item.thumb ?? item.url} class:loading={!imageLoaded} - class:video-thumbnail={itemType === "video"} + class:video-thumbnail={["video", "gif"].includes(itemType)} on:load={() => imageLoaded = true} alt="{$t(`a11y.dialog.picker.item.${itemType}`)} {number}" diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 2e61946d..f01af5e4 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -10,7 +10,7 @@ export type DialogButton = { export type SmallDialogIcons = "warn-red"; export type DialogPickerItem = { - type?: 'photo' | 'video', + type?: 'photo' | 'video' | 'gif', url: string, thumb?: string, } From b3d8a9bf1c065ffdd265acd03d7cb06649eccae3 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Fri, 26 Jul 2024 17:00:01 +0000 Subject: [PATCH 296/775] web/donate: minor css fixes --- web/src/routes/donate/+page.svelte | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index 2469c4ea..65b3c130 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -193,7 +193,9 @@ + > + { address } +
{/each}
@@ -204,6 +206,7 @@ #donate-page { max-width: 850px; margin: 0 auto; + overflow-x: hidden; padding: var(--padding); } @@ -271,7 +274,9 @@ width: 100%; display: block; text-align: left; - font-size: 12px; + font-size: .75em; + overflow: hidden; + text-overflow: ellipsis; } .crypto-wallets { From 82ecf16d79108610a96146edcf1e01512f946508 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Fri, 26 Jul 2024 17:06:03 +0000 Subject: [PATCH 297/775] web/donate: disable padding-left for wallets on mobile --- web/src/routes/donate/+page.svelte | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index 65b3c130..efd65747 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -228,13 +228,6 @@ justify-content: space-evenly; } - @media screen and (max-width: 750px) { - .donation-options { - flex-direction: column; - gap: 1em; - align-items: center; - } - } .donation-option { display: flex; flex-direction: column; @@ -292,10 +285,22 @@ gap: .25em; } - input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } + + @media screen and (max-width: 750px) { + .donation-options { + flex-direction: column; + gap: 1em; + align-items: center; + } + + .crypto-wallets { + padding-left: 0; + } + } + From 0a7747c497b227a1b0b432012167c2fbe1803ce8 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 12:53:57 +0600 Subject: [PATCH 298/775] web/dialogs: move duplicated dialog css to parent --- web/src/components/dialog/DialogHolder.svelte | 23 ++++++++++++++++++ web/src/components/dialog/PickerDialog.svelte | 22 ----------------- web/src/components/dialog/SmallDialog.svelte | 24 +++---------------- 3 files changed, 26 insertions(+), 43 deletions(-) diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 72941b1a..141491d0 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -95,6 +95,25 @@ -webkit-backdrop-filter: none !important; } + :global(.dialog-body) { + --dialog-padding: 18px; + + display: flex; + flex-direction: column; + align-items: center; + + background: var(--popup-bg); + box-shadow: + 0 0 0 2px var(--popup-stroke) inset, + 0 0 60px 10px var(--popup-bg); + border-radius: 29px; + + padding: var(--dialog-padding); + + position: relative; + will-change: transform; + } + :global(.open .dialog-body) { animation: modal-in 0.35s; } @@ -107,6 +126,10 @@ @media screen and (max-width: 535px) { :global(.open .dialog-body) { animation: modal-in-mobile 0.4s; + margin-bottom: calc( + var(--padding) / 2 + env(safe-area-inset-bottom) + ); + box-shadow: 0 0 0 2px var(--popup-stroke) inset; } } diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index ef2089a4..34d8d0b7 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -88,27 +88,12 @@ From 778190b2b3b541456122c21443612022a9fc6dc0 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 14:24:24 +0600 Subject: [PATCH 299/775] web/dialogs: create a container for reused code --- .../components/dialog/DialogContainer.svelte | 33 +++++++++++++++ web/src/components/dialog/PickerDialog.svelte | 42 ++++--------------- web/src/components/dialog/SmallDialog.svelte | 36 +++------------- 3 files changed, 48 insertions(+), 63 deletions(-) create mode 100644 web/src/components/dialog/DialogContainer.svelte diff --git a/web/src/components/dialog/DialogContainer.svelte b/web/src/components/dialog/DialogContainer.svelte new file mode 100644 index 00000000..0827bc19 --- /dev/null +++ b/web/src/components/dialog/DialogContainer.svelte @@ -0,0 +1,33 @@ + + + + + diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index 34d8d0b7..ce7b55f5 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -1,13 +1,13 @@ - -
+ +
+ diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 4e21beac..adf439d4 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -333,6 +333,18 @@ background-color: var(--button-hover); } + :global(.button.elevated) { + background-color: var(--button-elevated); + } + + :global(.button.elevated:active) { + background-color: var(--button-elevated-hover); + } + + :global(.button.elevated:not(:focus-visible)) { + box-shadow: none; + } + :global(.button.active) { color: var(--primary); background-color: var(--secondary); @@ -353,6 +365,10 @@ :global(button:hover) { background-color: var(--button-hover); } + + :global(.button.elevated:hover) { + background-color: var(--button-elevated-hover); + } :global(.button.active:not(.color):hover) { background-color: var(--button-active-hover); From a9f9a3e34225ec82e9a03aec6a91ab97dc7052d4 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 15:07:26 +0600 Subject: [PATCH 301/775] web/dialogs: add saving method dialog --- web/i18n/en/dialog.json | 7 +- .../buttons/VerticalActionButton.svelte | 31 ++++ web/src/components/dialog/DialogHolder.svelte | 6 +- web/src/components/dialog/SavingDialog.svelte | 139 ++++++++++++++++++ web/src/components/misc/Meowbalt.svelte | 5 +- web/src/lib/download.ts | 42 +++++- web/src/lib/types/dialog.ts | 10 +- 7 files changed, 230 insertions(+), 10 deletions(-) create mode 100644 web/src/components/buttons/VerticalActionButton.svelte create mode 100644 web/src/components/dialog/SavingDialog.svelte diff --git a/web/i18n/en/dialog.json b/web/i18n/en/dialog.json index bfe30bec..75f673f8 100644 --- a/web/i18n/en/dialog.json +++ b/web/i18n/en/dialog.json @@ -4,6 +4,9 @@ "button.reset": "reset", "button.done": "done", "button.downloadAudio": "download audio", + "button.download": "download", + "button.share": "share", + "button.copy": "copy", "reset.title": "reset all settings?", "reset.body": "are you sure you want to reset all settings? this action is immediate and irreversible.", @@ -11,5 +14,7 @@ "picker.title": "select what to save", "picker.description.desktop": "click an item to save it. images can also be saved via the right click menu.", "picker.description.phone": "press an item to save it. images can also be saved with a long press.", - "picker.description.ios": "press an item to save it with a shortcut. images can also be saved with a long press." + "picker.description.ios": "press an item to save it with a shortcut. images can also be saved with a long press.", + + "saving.title": "choose how to save" } diff --git a/web/src/components/buttons/VerticalActionButton.svelte b/web/src/components/buttons/VerticalActionButton.svelte new file mode 100644 index 00000000..a9d37689 --- /dev/null +++ b/web/src/components/buttons/VerticalActionButton.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 141491d0..7a481d42 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -3,6 +3,7 @@ import SmallDialog from "$components/dialog/SmallDialog.svelte"; import PickerDialog from "$components/dialog/PickerDialog.svelte"; + import SavingDialog from "$components/dialog/SavingDialog.svelte"; $: backdropVisible = $dialogs.length > 0; @@ -10,10 +11,13 @@
{#each $dialogs as dialog} {@const { type, ...data } = dialog} + {#if type === "small"} - {:else if dialog.type === "picker"} + {:else if type === "picker"} + {:else if type === "saving"} + {/if} {/each}
diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte new file mode 100644 index 00000000..6e039df8 --- /dev/null +++ b/web/src/components/dialog/SavingDialog.svelte @@ -0,0 +1,139 @@ + + + + + + + + + diff --git a/web/src/components/misc/Meowbalt.svelte b/web/src/components/misc/Meowbalt.svelte index 13c52556..26ad14b3 100644 --- a/web/src/components/misc/Meowbalt.svelte +++ b/web/src/components/misc/Meowbalt.svelte @@ -21,11 +21,14 @@ object-fit: cover; } - .think, .error { height: 160px; } + .question { + height: 140px; + } + .error { margin-left: 25px; } diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts index e08320ef..74f65606 100644 --- a/web/src/lib/download.ts +++ b/web/src/lib/download.ts @@ -1,9 +1,41 @@ -import { device } from "$lib/device"; +import { get } from "svelte/store"; + +import { app, device } from "$lib/device"; +import settings from "$lib/state/settings"; + +import { createDialog } from "$lib/dialogs"; + +export const openURL = (url: string) => { + return window.open(url, "_blank"); +} + +export const shareURL = async (url: string) => { + try { + return await navigator?.share({ url }); + } catch { + return false; + } +} + +export const copyURL = async (url: string) => { + try { + return await navigator?.clipboard.writeText(url); + } catch { + return false; + } +} export const downloadFile = (url: string) => { - if (device.is.iOS) { - return navigator?.share({ url }).catch(() => {}); + const savingPreference = get(settings).save.downloadPopup; + if (savingPreference) { + createDialog({ + type: "saving", + id: "saving", + url + }) + } else if (device.is.iOS && app.is.installed) { + return shareURL(url); } else { - return window.open(url, "_blank"); + return openURL(url); } -}; +} diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index f01af5e4..f7951309 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -17,7 +17,6 @@ export type DialogPickerItem = { type Dialog = { id: string, - buttons?: DialogButton[], }; type SmallDialog = Dialog & { @@ -27,11 +26,18 @@ type SmallDialog = Dialog & { title?: string, bodyText?: string, bodySubText?: string, + buttons?: DialogButton[], }; type PickerDialog = Dialog & { type: "picker", items?: DialogPickerItem[], + buttons?: DialogButton[], }; -export type DialogInfo = SmallDialog | PickerDialog; \ No newline at end of file +type SavingDialog = Dialog & { + type: "saving", + url: string, +}; + +export type DialogInfo = SmallDialog | PickerDialog | SavingDialog; From 26eaac5742ce00971a232b230edf4684cbfc97e9 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 15:07:38 +0600 Subject: [PATCH 302/775] web/ActionButton: clean up --- web/src/components/buttons/ActionButton.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/src/components/buttons/ActionButton.svelte b/web/src/components/buttons/ActionButton.svelte index 3c2a4433..8eaa5b47 100644 --- a/web/src/components/buttons/ActionButton.svelte +++ b/web/src/components/buttons/ActionButton.svelte @@ -1,6 +1,8 @@ + + diff --git a/web/src/components/dialog/DialogButtons.svelte b/web/src/components/dialog/DialogButtons.svelte index 082d20e0..f239865f 100644 --- a/web/src/components/dialog/DialogButtons.svelte +++ b/web/src/components/dialog/DialogButtons.svelte @@ -1,23 +1,14 @@ @@ -31,14 +22,4 @@ border-radius: var(--border-radius); min-height: 40px; } - - .popup-button { - width: 100%; - height: 40px; - } - - .popup-button.red { - background-color: var(--red); - color: var(--white); - } diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index f7951309..0a5004db 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -4,6 +4,7 @@ export type DialogButton = { text: string, color?: "red", main: boolean, + timeout?: number, // milliseconds action: () => unknown | Promise } From f34340a06d2c42dc74c3dad954ed5228992c4b52 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 14:50:59 +0600 Subject: [PATCH 318/775] web/TransferSettings: add a timeout to import button in dialog --- web/src/components/settings/TransferSettings.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/settings/TransferSettings.svelte b/web/src/components/settings/TransferSettings.svelte index a24ad568..a238aac9 100644 --- a/web/src/components/settings/TransferSettings.svelte +++ b/web/src/components/settings/TransferSettings.svelte @@ -54,6 +54,7 @@ text: $t("dialog.button.import"), color: "red", main: true, + timeout: 5000, action: () => updateSettings(reader), }, ], From 87adffaf0276b30a4370ab5cb0155fae03e676ac Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 14:51:02 +0600 Subject: [PATCH 319/775] web/ResetSettingsButton: add a timeout to reset button in dialog --- web/src/components/buttons/ResetSettingsButton.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte index e6b6a61a..ee60938e 100644 --- a/web/src/components/buttons/ResetSettingsButton.svelte +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -23,6 +23,7 @@ text: $t("dialog.button.reset"), color: "red", main: true, + timeout: 5000, action: () => resetSettings(), }, ], From 5c780a2d2e37757e2e74329399c4df85578234a0 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 18:59:58 +0600 Subject: [PATCH 320/775] web: added saving method preference, made downloading resilient --- web/i18n/en/settings.json | 9 +++-- web/src/components/dialog/SavingDialog.svelte | 4 +- web/src/lib/device.ts | 15 ++++--- web/src/lib/download.ts | 39 ++++++++++--------- web/src/lib/settings/defaults.ts | 2 +- web/src/lib/settings/migrate.ts | 2 - web/src/lib/types/settings.ts | 3 +- web/src/routes/settings/download/+page.svelte | 25 +++++++----- 8 files changed, 56 insertions(+), 43 deletions(-) diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 0127627b..69555ab3 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -72,9 +72,12 @@ "metadata.disable.title": "disable file metadata", "metadata.disable.description": "title, artist, and other info will not be added to the file.", - "saving.method": "saving method", - "saving.ask.title": "ask how to save", - "saving.ask.description": "offer several ways to save the file instead of opening it in a new tab.", + "saving.title": "saving method", + "saving.ask": "ask", + "saving.download": "download", + "saving.share": "share", + "saving.copy": "copy", + "saving.description": "preferred way of saving the file or link from cobalt. if preferred method is unavailable or something goes wrong, cobalt will ask you what to do next.", "accessibility": "accessibility", "accessibility.transparency.title": "reduce visual transparency", diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index 34c84b84..5e1832ab 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -34,7 +34,7 @@

- {#if !(app.is.installed && device.is.iOS)} + {#if device.supports.directDownload} {/if} - {#if navigator.share !== undefined} + {#if device.supports.share} { /* if new tab got blocked by user agent, show a saving dialog */ if (!open) { - openSavingDialog(url); + return openSavingDialog(url); } } export const shareURL = async (url: string) => { - try { - return await navigator?.share({ url }); - } catch { - return false; - } + return await navigator?.share({ url }); } export const copyURL = async (url: string) => { - try { - return await navigator?.clipboard.writeText(url); - } catch { - return false; - } + return await navigator?.clipboard?.writeText(url); } export const downloadFile = (url: string) => { - const savingPreference = get(settings).save.downloadPopup; + const pref = get(settings).save.savingMethod; /* user actions (such as invoke share, open new tab) have expiration. @@ -49,11 +41,20 @@ export const downloadFile = (url: string) => { invoke an action without the user agent interrupting it. if not, we show a saving dialog for user to re-invoke that action. */ - if (savingPreference || !navigator.userActivation.isActive) { - openSavingDialog(url); - } else if (device.is.iOS && app.is.installed) { - return shareURL(url); - } else { - return openURL(url); + + if (pref === "ask" || !navigator.userActivation.isActive) { + return openSavingDialog(url); } + + try { + if (pref === "share" && device.supports.share) { + return shareURL(url); + } else if (pref === "download" && device.supports.directDownload) { + return openURL(url); + } else if (pref === "copy") { + return copyURL(url); + } + } catch {} + + return openSavingDialog(url); } diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts index 528d2cad..58f46fec 100644 --- a/web/src/lib/settings/defaults.ts +++ b/web/src/lib/settings/defaults.ts @@ -18,8 +18,8 @@ const defaultSettings: CobaltSettings = { audioFormat: "mp3", disableMetadata: false, downloadMode: "auto", - downloadPopup: false, filenameStyle: "classic", + savingMethod: "download", tiktokH265: false, tiktokFullAudio: false, twitterGif: false, diff --git a/web/src/lib/settings/migrate.ts b/web/src/lib/settings/migrate.ts index 81feb99f..769ab360 100644 --- a/web/src/lib/settings/migrate.ts +++ b/web/src/lib/settings/migrate.ts @@ -10,7 +10,6 @@ const oldSwitcherValues = { const oldCheckboxes = [ 'audioMode', - 'downloadPopup', 'fullTikTokAudio', 'muteAudio', 'reduceTransparency', @@ -101,7 +100,6 @@ export const migrateOldSettings = () => { filenameStyle: getLiteral('filenamePattern'), tiktokFullAudio: getBool('fullTikTokAudio'), tiktokH265: getBool('tiktokH265'), - downloadPopup: getBool('downloadPopup'), disableMetadata: getBool('disableMetadata'), twitterGif: getBool('twitterGif'), youtubeDubBrowserLang: getBool('ytDub'), diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts index 5965bf49..ff4c66b7 100644 --- a/web/src/lib/types/settings.ts +++ b/web/src/lib/types/settings.ts @@ -7,6 +7,7 @@ export const downloadModeOptions = ["auto", "audio", "mute"] as const; export const filenameStyleOptions = ["classic", "basic", "pretty", "nerdy"] as const; export const videoQualityOptions = ["max", "2160", "1440", "1080", "720", "480", "360", "240", "144"] as const; export const youtubeVideoCodecOptions = ["h264", "av1", "vp9"] as const; +export const savingMethodOptions = ["ask", "download", "share", "copy"] as const; type CobaltSettingsAppearance = { theme: typeof themeOptions[number], @@ -28,8 +29,8 @@ type CobaltSettingsSave = { audioFormat: typeof audioFormatOptions[number], disableMetadata: boolean, downloadMode: typeof downloadModeOptions[number], - downloadPopup: boolean, filenameStyle: typeof filenameStyleOptions[number], + savingMethod: typeof savingMethodOptions[number], tiktokH265: boolean, tiktokFullAudio: boolean, twitterGif: boolean, diff --git a/web/src/routes/settings/download/+page.svelte b/web/src/routes/settings/download/+page.svelte index 6e6ea6f0..5c5985b2 100644 --- a/web/src/routes/settings/download/+page.svelte +++ b/web/src/routes/settings/download/+page.svelte @@ -1,7 +1,7 @@ @@ -69,6 +70,9 @@
+
+ {bodyText} +
diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts index fbd3a124..60227f21 100644 --- a/web/src/lib/download.ts +++ b/web/src/lib/download.ts @@ -1,23 +1,30 @@ import { get } from "svelte/store"; -import { device } from "$lib/device"; import settings from "$lib/state/settings"; -import { createDialog } from "$lib/dialogs"; +import { device } from "$lib/device"; +import { t } from "$lib/i18n/translations"; -export const openSavingDialog = (url: string) => - createDialog({ +import { createDialog } from "$lib/dialogs"; +import type { DialogInfo } from "$lib/types/dialog"; + +export const openSavingDialog = (url: string, body: string | void) => { + let dialogData: DialogInfo = { type: "saving", id: "saving", url - }) + } + if (body) dialogData.bodyText = body; + + createDialog(dialogData) +} export const openURL = (url: string) => { const open = window.open(url, "_blank"); /* if new tab got blocked by user agent, show a saving dialog */ if (!open) { - return openSavingDialog(url); + return openSavingDialog(url, get(t)("dialog.saving.blocked")); } } diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 0a5004db..d3d086e1 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -39,6 +39,7 @@ type PickerDialog = Dialog & { type SavingDialog = Dialog & { type: "saving", url: string, + bodyText?: string, }; export type DialogInfo = SmallDialog | PickerDialog | SavingDialog; From 3aeebcc911ca00834a60f9e43297bdeddcef4846 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 19:20:32 +0600 Subject: [PATCH 322/775] web/SavingDialog: don't render body text parent if there's no text --- web/src/components/dialog/SavingDialog.svelte | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index 4940af3c..bba591f1 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -70,9 +70,11 @@
-
- {bodyText} -
+ {#if bodyText} +
+ {bodyText} +
+ {/if} Date: Sun, 28 Jul 2024 23:29:32 +0600 Subject: [PATCH 323/775] web/SavingDialog: show that link was copied, better accessibility --- web/i18n/en/a11y/dialog.json | 4 +- .../buttons/VerticalActionButton.svelte | 15 +++++- web/src/components/dialog/SavingDialog.svelte | 21 ++++++-- web/src/components/misc/CopyIcon.svelte | 54 +++++++++++++++++++ 4 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 web/src/components/misc/CopyIcon.svelte diff --git a/web/i18n/en/a11y/dialog.json b/web/i18n/en/a11y/dialog.json index 84df736b..478a1587 100644 --- a/web/i18n/en/a11y/dialog.json +++ b/web/i18n/en/a11y/dialog.json @@ -1,5 +1,7 @@ { "picker.item.photo": "photo thumbnail", "picker.item.video": "video thumbnail", - "picker.item.gif": "gif thumbnail" + "picker.item.gif": "gif thumbnail", + + "saving.copied": "link copied" } diff --git a/web/src/components/buttons/VerticalActionButton.svelte b/web/src/components/buttons/VerticalActionButton.svelte index a9d37689..14602500 100644 --- a/web/src/components/buttons/VerticalActionButton.svelte +++ b/web/src/components/buttons/VerticalActionButton.svelte @@ -5,9 +5,17 @@ }; export let fill = false; export let elevated = false; + export let ariaLabel = ""; - @@ -19,6 +27,11 @@ gap: calc(var(--padding) / 2); } + .button.vertical :global(svg) { + width: 24px; + height: 24px; + } + .button.vertical.fill { width: 100%; padding: var(--padding) 0; diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index bba591f1..ee0a5ee4 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -10,16 +10,25 @@ import DialogButtons from "$components/dialog/DialogButtons.svelte"; import VerticalActionButton from "$components/buttons/VerticalActionButton.svelte"; - import IconCopy from "@tabler/icons-svelte/IconCopy.svelte"; import IconShare2 from "@tabler/icons-svelte/IconShare2.svelte"; import IconDownload from "@tabler/icons-svelte/IconDownload.svelte"; import IconFileDownload from "@tabler/icons-svelte/IconFileDownload.svelte"; + import CopyIcon from "$components/misc/CopyIcon.svelte"; + export let id: string; export let url: string; export let bodyText: string = ""; let close: () => void; + + let copied = false; + + $: if (copied) { + setTimeout(() => { + copied = false; + }, 1500); + } @@ -63,18 +72,24 @@ id="save-copy" fill elevated - click={async () => copyURL(url)} + click={async () => { + copyURL(url); + copied = true; + }} + ariaLabel={copied ? $t("a11y.dialog.saving.copied") : ""} > - + {$t("dialog.button.copy")} + {#if bodyText}
{bodyText}
{/if} + + import IconCopy from "@tabler/icons-svelte/IconCopy.svelte"; + import IconCheck from "@tabler/icons-svelte/IconCheck.svelte"; + + export let check = false; + + +
+
+ +
+
+ +
+
+ + From a4e0e21a976e85347e688d7c14068239a7f0fc05 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 23:36:38 +0600 Subject: [PATCH 324/775] web/Omnibox: accept keyboard shortcuts only when focused --- web/src/components/save/Omnibox.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 01772358..80d89aba 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -83,11 +83,11 @@ linkInput.focus(); } - if (e.key === "Enter" && validLink($link)) { + if (e.key === "Enter" && validLink($link) && isFocused) { downloadButton.download($link); } - if (["Escape", "Clear"].includes(e.key)) { + if (["Escape", "Clear"].includes(e.key) && isFocused) { $link = ""; } From 8b866ddf6feb092c66b7fc89e09b67d48e9c3e3a Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 29 Jul 2024 13:11:29 +0600 Subject: [PATCH 325/775] web/SettingsNavTab: reduce padding on desktop --- web/src/components/settings/SettingsNavTab.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/settings/SettingsNavTab.svelte b/web/src/components/settings/SettingsNavTab.svelte index 70838c8b..63274b99 100644 --- a/web/src/components/settings/SettingsNavTab.svelte +++ b/web/src/components/settings/SettingsNavTab.svelte @@ -32,7 +32,7 @@ \ No newline at end of file + diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte index 11f1d999..07cc02f8 100644 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ b/web/src/components/changelog/ChangelogSkeleton.svelte @@ -3,7 +3,7 @@ export let version: string; -
+
{ version }
@@ -24,7 +24,7 @@ class="big changelog-banner" width="100%" /> -
+
{#each {length: 3 + Math.random() * 5} as _}

- - \ No newline at end of file From a6a0e916749446e403060e57b4a6a5b2f9d5eb99 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 30 Jul 2024 14:08:49 +0000 Subject: [PATCH 328/775] web/TransferSettings: don't offer export if there is nothing to export --- web/src/components/settings/TransferSettings.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/src/components/settings/TransferSettings.svelte b/web/src/components/settings/TransferSettings.svelte index a238aac9..3db4ee8b 100644 --- a/web/src/components/settings/TransferSettings.svelte +++ b/web/src/components/settings/TransferSettings.svelte @@ -85,9 +85,11 @@ import + {#if $storedSettings.schemaVersion} export + {/if} diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte deleted file mode 100644 index 07cc02f8..00000000 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - -
-
-
-
{ version }
-
- -
-
- -
-
- -
- {#each {length: 3 + Math.random() * 5} as _} -

- -

- {/each} -
-
-
diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index d8e13601..99aba833 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -6,7 +6,7 @@ import type { ChangelogImport } from "$lib/types/changelogs"; import type { Optional } from "$lib/types/generic"; - import ChangelogSkeleton from "$components/changelog/ChangelogSkeleton.svelte"; + import ChangelogEntry from "$components/changelog/ChangelogEntry.svelte"; import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte"; import IconArrowRight from "@tabler/icons-svelte/IconArrowRight.svelte"; @@ -98,7 +98,10 @@
{#await changelog.page} {#key changelog.version} - + {/key} {:then page} Date: Fri, 2 Aug 2024 20:41:52 +0600 Subject: [PATCH 335/775] repo: move api src from root to own subdir --- package.json => api/package.json | 0 {src => api/src}/cobalt.js | 0 {src => api/src}/config.json | 0 {src => api/src}/core/api.js | 0 {src => api/src}/core/web.js | 0 {src => api/src}/front/assets/meowbalt/error.png | Bin {src => api/src}/front/assets/meowbalt/question.png | Bin {src => api/src}/front/cobalt.css | 0 {src => api/src}/front/cobalt.js | 0 {src => api/src}/front/emoji/3d/film_frames.png | Bin {src => api/src}/front/emoji/3d/headphone.png | Bin {src => api/src}/front/emoji/abacus.svg | 0 {src => api/src}/front/emoji/alien_monster.svg | 0 {src => api/src}/front/emoji/biceps.svg | 0 {src => api/src}/front/emoji/bird.svg | 0 {src => api/src}/front/emoji/boring_document.svg | 0 {src => api/src}/front/emoji/bubbles.svg | 0 {src => api/src}/front/emoji/cake.svg | 0 {src => api/src}/front/emoji/candle.svg | 0 {src => api/src}/front/emoji/cat.svg | 0 {src => api/src}/front/emoji/cat_crying.svg | 0 {src => api/src}/front/emoji/cat_flabbergasted.svg | 0 {src => api/src}/front/emoji/cat_grin.svg | 0 {src => api/src}/front/emoji/cat_smile.svg | 0 {src => api/src}/front/emoji/christmas_tree.svg | 0 {src => api/src}/front/emoji/clapper_board.svg | 0 {src => api/src}/front/emoji/clipboard.svg | 0 {src => api/src}/front/emoji/crystal_ball.svg | 0 {src => api/src}/front/emoji/dog.svg | 0 {src => api/src}/front/emoji/dragon_face.svg | 0 {src => api/src}/front/emoji/dragon_face_wukko.svg | 0 {src => api/src}/front/emoji/elephant.svg | 0 {src => api/src}/front/emoji/email.svg | 0 {src => api/src}/front/emoji/film_frames.svg | 0 {src => api/src}/front/emoji/gear.svg | 0 {src => api/src}/front/emoji/headphone.svg | 0 {src => api/src}/front/emoji/keyboard.svg | 0 {src => api/src}/front/emoji/link.svg | 0 {src => api/src}/front/emoji/locked.svg | 0 {src => api/src}/front/emoji/loudspeaker.svg | 0 {src => api/src}/front/emoji/magic_wand.svg | 0 {src => api/src}/front/emoji/magnifying_glass.svg | 0 {src => api/src}/front/emoji/mailbox.svg | 0 {src => api/src}/front/emoji/mending_heart.svg | 0 {src => api/src}/front/emoji/money_with_wings.svg | 0 {src => api/src}/front/emoji/musical_notes.svg | 0 {src => api/src}/front/emoji/newspaper.svg | 0 {src => api/src}/front/emoji/octopus.svg | 0 {src => api/src}/front/emoji/party_popper.svg | 0 {src => api/src}/front/emoji/pinata.svg | 0 {src => api/src}/front/emoji/pumpkin.svg | 0 {src => api/src}/front/emoji/question_mark.svg | 0 {src => api/src}/front/emoji/sparkles.svg | 0 {src => api/src}/front/emoji/sparkling_heart.svg | 0 {src => api/src}/front/emoji/wrench.svg | 0 .../src}/front/fonts/files/notosansmono_3dVQ.woff2 | Bin .../front/fonts/files/notosansmono_7dVXQQ.woff2 | Bin .../front/fonts/files/notosansmono_DdVXQQ.woff2 | Bin .../front/fonts/files/notosansmono_HdVXQQ.woff2 | Bin .../front/fonts/files/notosansmono_LdVXQQ.woff2 | Bin .../front/fonts/files/notosansmono_PdVXQQ.woff2 | Bin .../front/fonts/files/notosansmono_ndVXQQ.woff2 | Bin {src => api/src}/front/fonts/notosansmono.css | 0 .../src}/front/icons/android-chrome-192x192.png | Bin .../src}/front/icons/android-chrome-512x512.png | Bin {src => api/src}/front/icons/apple-touch-icon.png | Bin {src => api/src}/front/icons/favicon-16x16.png | Bin {src => api/src}/front/icons/favicon-32x32.png | Bin {src => api/src}/front/icons/favicon.ico | Bin {src => api/src}/front/icons/generic.png | Bin {src => api/src}/front/icons/maskable/128.png | Bin {src => api/src}/front/icons/maskable/192.png | Bin {src => api/src}/front/icons/maskable/384.png | Bin {src => api/src}/front/icons/maskable/48.png | Bin {src => api/src}/front/icons/maskable/512.png | Bin {src => api/src}/front/icons/maskable/72.png | Bin {src => api/src}/front/icons/maskable/96.png | Bin {src => api/src}/front/icons/pattern.png | Bin {src => api/src}/front/manifest.webmanifest | 0 {src => api/src}/front/robots.txt | 0 {src => api/src}/front/sponsors/royale.svg | 0 .../src}/front/updateBanners/bettertogether.webp | Bin {src => api/src}/front/updateBanners/catmakeup.webp | Bin .../src}/front/updateBanners/catphonestand.webp | Bin {src => api/src}/front/updateBanners/catroomba.webp | Bin {src => api/src}/front/updateBanners/catsleep.webp | Bin {src => api/src}/front/updateBanners/catspeed.webp | Bin .../src}/front/updateBanners/catswitchboxes.webp | Bin {src => api/src}/front/updateBanners/cattired.webp | Bin .../src}/front/updateBanners/developers.webp | Bin .../src}/front/updateBanners/happymeowth.webp | Bin .../src}/front/updateBanners/meowth7eleven.webp | Bin .../src}/front/updateBanners/meowthball.webp | Bin .../src}/front/updateBanners/meowthbusinessman.webp | Bin .../src}/front/updateBanners/meowthcenter.webp | Bin .../src}/front/updateBanners/meowthcooking.webp | Bin .../src}/front/updateBanners/meowthhammer.webp | Bin .../src}/front/updateBanners/meowthpolishegg.webp | Bin .../src}/front/updateBanners/meowthproductions.webp | Bin .../src}/front/updateBanners/meowthsnap.webp | Bin .../src}/front/updateBanners/meowthstrong.webp | Bin .../src}/front/updateBanners/millionusers.webp | Bin {src => api/src}/front/updateBanners/newdomain.webp | Bin .../src}/front/updateBanners/onemillionr.webp | Bin {src => api/src}/front/updateBanners/shutup.webp | Bin .../src}/front/updateBanners/twitchupdate.webp | Bin .../src}/front/updateBanners/valentines.webp | Bin {src => api/src}/localization/languages/en.json | 0 {src => api/src}/localization/languages/ru.json | 0 {src => api/src}/localization/manager.js | 0 {src => api/src}/modules/build.js | 0 {src => api/src}/modules/buildStatic.js | 0 {src => api/src}/modules/changelog/changelog.json | 0 .../src}/modules/changelog/changelogManager.js | 0 {src => api/src}/modules/config.js | 0 {src => api/src}/modules/emoji.js | 0 {src => api/src}/modules/pageRender/elements.js | 0 {src => api/src}/modules/pageRender/findRendered.js | 0 {src => api/src}/modules/pageRender/onDemand.js | 0 {src => api/src}/modules/pageRender/page.js | 0 .../src}/modules/processing/cookie/cookie.js | 0 .../src}/modules/processing/cookie/manager.js | 0 .../src}/modules/processing/createFilename.js | 0 {src => api/src}/modules/processing/match.js | 0 .../src}/modules/processing/matchActionDecider.js | 0 {src => api/src}/modules/processing/request.js | 0 .../src}/modules/processing/services/bilibili.js | 0 .../src}/modules/processing/services/dailymotion.js | 0 .../src}/modules/processing/services/facebook.js | 0 .../src}/modules/processing/services/instagram.js | 0 .../src}/modules/processing/services/loom.js | 0 {src => api/src}/modules/processing/services/ok.js | 0 .../src}/modules/processing/services/pinterest.js | 0 .../src}/modules/processing/services/reddit.js | 0 .../src}/modules/processing/services/rutube.js | 0 .../src}/modules/processing/services/snapchat.js | 0 .../src}/modules/processing/services/soundcloud.js | 0 .../src}/modules/processing/services/streamable.js | 0 .../src}/modules/processing/services/tiktok.js | 0 .../src}/modules/processing/services/tumblr.js | 0 .../src}/modules/processing/services/twitch.js | 0 .../src}/modules/processing/services/twitter.js | 0 .../src}/modules/processing/services/vimeo.js | 0 .../src}/modules/processing/services/vine.js | 0 {src => api/src}/modules/processing/services/vk.js | 0 .../src}/modules/processing/services/youtube.js | 0 .../src}/modules/processing/servicesConfig.json | 0 .../modules/processing/servicesPatternTesters.js | 0 {src => api/src}/modules/processing/url.js | 0 {src => api/src}/modules/setup.js | 0 {src => api/src}/modules/stream/internal-hls.js | 0 {src => api/src}/modules/stream/internal.js | 0 {src => api/src}/modules/stream/manage.js | 0 {src => api/src}/modules/stream/shared.js | 0 {src => api/src}/modules/stream/stream.js | 0 {src => api/src}/modules/stream/types.js | 0 {src => api/src}/modules/sub/alias-envs.js | 0 {src => api/src}/modules/sub/consoleText.js | 0 {src => api/src}/modules/sub/crypto.js | 0 {src => api/src}/modules/sub/currentCommit.js | 0 {src => api/src}/modules/sub/loadFromFs.js | 0 {src => api/src}/modules/sub/randomize-ciphers.js | 0 {src => api/src}/modules/sub/utils.js | 0 {src => api/src}/modules/test.js | 0 {src => api/src}/util/generate-youtube-tokens.js | 0 {src => api/src}/util/test-ci.js | 0 {src => api/src}/util/test.js | 0 {src => api/src}/util/testFilenamePresets.js | 0 {src => api/src}/util/tests.json | 0 169 files changed, 0 insertions(+), 0 deletions(-) rename package.json => api/package.json (100%) rename {src => api/src}/cobalt.js (100%) rename {src => api/src}/config.json (100%) rename {src => api/src}/core/api.js (100%) rename {src => api/src}/core/web.js (100%) rename {src => api/src}/front/assets/meowbalt/error.png (100%) rename {src => api/src}/front/assets/meowbalt/question.png (100%) rename {src => api/src}/front/cobalt.css (100%) rename {src => api/src}/front/cobalt.js (100%) rename {src => api/src}/front/emoji/3d/film_frames.png (100%) rename {src => api/src}/front/emoji/3d/headphone.png (100%) rename {src => api/src}/front/emoji/abacus.svg (100%) rename {src => api/src}/front/emoji/alien_monster.svg (100%) rename {src => api/src}/front/emoji/biceps.svg (100%) rename {src => api/src}/front/emoji/bird.svg (100%) rename {src => api/src}/front/emoji/boring_document.svg (100%) rename {src => api/src}/front/emoji/bubbles.svg (100%) rename {src => api/src}/front/emoji/cake.svg (100%) rename {src => api/src}/front/emoji/candle.svg (100%) rename {src => api/src}/front/emoji/cat.svg (100%) rename {src => api/src}/front/emoji/cat_crying.svg (100%) rename {src => api/src}/front/emoji/cat_flabbergasted.svg (100%) rename {src => api/src}/front/emoji/cat_grin.svg (100%) rename {src => api/src}/front/emoji/cat_smile.svg (100%) rename {src => api/src}/front/emoji/christmas_tree.svg (100%) rename {src => api/src}/front/emoji/clapper_board.svg (100%) rename {src => api/src}/front/emoji/clipboard.svg (100%) rename {src => api/src}/front/emoji/crystal_ball.svg (100%) rename {src => api/src}/front/emoji/dog.svg (100%) rename {src => api/src}/front/emoji/dragon_face.svg (100%) rename {src => api/src}/front/emoji/dragon_face_wukko.svg (100%) rename {src => api/src}/front/emoji/elephant.svg (100%) rename {src => api/src}/front/emoji/email.svg (100%) rename {src => api/src}/front/emoji/film_frames.svg (100%) rename {src => api/src}/front/emoji/gear.svg (100%) rename {src => api/src}/front/emoji/headphone.svg (100%) rename {src => api/src}/front/emoji/keyboard.svg (100%) rename {src => api/src}/front/emoji/link.svg (100%) rename {src => api/src}/front/emoji/locked.svg (100%) rename {src => api/src}/front/emoji/loudspeaker.svg (100%) rename {src => api/src}/front/emoji/magic_wand.svg (100%) rename {src => api/src}/front/emoji/magnifying_glass.svg (100%) rename {src => api/src}/front/emoji/mailbox.svg (100%) rename {src => api/src}/front/emoji/mending_heart.svg (100%) rename {src => api/src}/front/emoji/money_with_wings.svg (100%) rename {src => api/src}/front/emoji/musical_notes.svg (100%) rename {src => api/src}/front/emoji/newspaper.svg (100%) rename {src => api/src}/front/emoji/octopus.svg (100%) rename {src => api/src}/front/emoji/party_popper.svg (100%) rename {src => api/src}/front/emoji/pinata.svg (100%) rename {src => api/src}/front/emoji/pumpkin.svg (100%) rename {src => api/src}/front/emoji/question_mark.svg (100%) rename {src => api/src}/front/emoji/sparkles.svg (100%) rename {src => api/src}/front/emoji/sparkling_heart.svg (100%) rename {src => api/src}/front/emoji/wrench.svg (100%) rename {src => api/src}/front/fonts/files/notosansmono_3dVQ.woff2 (100%) rename {src => api/src}/front/fonts/files/notosansmono_7dVXQQ.woff2 (100%) rename {src => api/src}/front/fonts/files/notosansmono_DdVXQQ.woff2 (100%) rename {src => api/src}/front/fonts/files/notosansmono_HdVXQQ.woff2 (100%) rename {src => api/src}/front/fonts/files/notosansmono_LdVXQQ.woff2 (100%) rename {src => api/src}/front/fonts/files/notosansmono_PdVXQQ.woff2 (100%) rename {src => api/src}/front/fonts/files/notosansmono_ndVXQQ.woff2 (100%) rename {src => api/src}/front/fonts/notosansmono.css (100%) rename {src => api/src}/front/icons/android-chrome-192x192.png (100%) rename {src => api/src}/front/icons/android-chrome-512x512.png (100%) rename {src => api/src}/front/icons/apple-touch-icon.png (100%) rename {src => api/src}/front/icons/favicon-16x16.png (100%) rename {src => api/src}/front/icons/favicon-32x32.png (100%) rename {src => api/src}/front/icons/favicon.ico (100%) rename {src => api/src}/front/icons/generic.png (100%) rename {src => api/src}/front/icons/maskable/128.png (100%) rename {src => api/src}/front/icons/maskable/192.png (100%) rename {src => api/src}/front/icons/maskable/384.png (100%) rename {src => api/src}/front/icons/maskable/48.png (100%) rename {src => api/src}/front/icons/maskable/512.png (100%) rename {src => api/src}/front/icons/maskable/72.png (100%) rename {src => api/src}/front/icons/maskable/96.png (100%) rename {src => api/src}/front/icons/pattern.png (100%) rename {src => api/src}/front/manifest.webmanifest (100%) rename {src => api/src}/front/robots.txt (100%) rename {src => api/src}/front/sponsors/royale.svg (100%) rename {src => api/src}/front/updateBanners/bettertogether.webp (100%) rename {src => api/src}/front/updateBanners/catmakeup.webp (100%) rename {src => api/src}/front/updateBanners/catphonestand.webp (100%) rename {src => api/src}/front/updateBanners/catroomba.webp (100%) rename {src => api/src}/front/updateBanners/catsleep.webp (100%) rename {src => api/src}/front/updateBanners/catspeed.webp (100%) rename {src => api/src}/front/updateBanners/catswitchboxes.webp (100%) rename {src => api/src}/front/updateBanners/cattired.webp (100%) rename {src => api/src}/front/updateBanners/developers.webp (100%) rename {src => api/src}/front/updateBanners/happymeowth.webp (100%) rename {src => api/src}/front/updateBanners/meowth7eleven.webp (100%) rename {src => api/src}/front/updateBanners/meowthball.webp (100%) rename {src => api/src}/front/updateBanners/meowthbusinessman.webp (100%) rename {src => api/src}/front/updateBanners/meowthcenter.webp (100%) rename {src => api/src}/front/updateBanners/meowthcooking.webp (100%) rename {src => api/src}/front/updateBanners/meowthhammer.webp (100%) rename {src => api/src}/front/updateBanners/meowthpolishegg.webp (100%) rename {src => api/src}/front/updateBanners/meowthproductions.webp (100%) rename {src => api/src}/front/updateBanners/meowthsnap.webp (100%) rename {src => api/src}/front/updateBanners/meowthstrong.webp (100%) rename {src => api/src}/front/updateBanners/millionusers.webp (100%) rename {src => api/src}/front/updateBanners/newdomain.webp (100%) rename {src => api/src}/front/updateBanners/onemillionr.webp (100%) rename {src => api/src}/front/updateBanners/shutup.webp (100%) rename {src => api/src}/front/updateBanners/twitchupdate.webp (100%) rename {src => api/src}/front/updateBanners/valentines.webp (100%) rename {src => api/src}/localization/languages/en.json (100%) rename {src => api/src}/localization/languages/ru.json (100%) rename {src => api/src}/localization/manager.js (100%) rename {src => api/src}/modules/build.js (100%) rename {src => api/src}/modules/buildStatic.js (100%) rename {src => api/src}/modules/changelog/changelog.json (100%) rename {src => api/src}/modules/changelog/changelogManager.js (100%) rename {src => api/src}/modules/config.js (100%) rename {src => api/src}/modules/emoji.js (100%) rename {src => api/src}/modules/pageRender/elements.js (100%) rename {src => api/src}/modules/pageRender/findRendered.js (100%) rename {src => api/src}/modules/pageRender/onDemand.js (100%) rename {src => api/src}/modules/pageRender/page.js (100%) rename {src => api/src}/modules/processing/cookie/cookie.js (100%) rename {src => api/src}/modules/processing/cookie/manager.js (100%) rename {src => api/src}/modules/processing/createFilename.js (100%) rename {src => api/src}/modules/processing/match.js (100%) rename {src => api/src}/modules/processing/matchActionDecider.js (100%) rename {src => api/src}/modules/processing/request.js (100%) rename {src => api/src}/modules/processing/services/bilibili.js (100%) rename {src => api/src}/modules/processing/services/dailymotion.js (100%) rename {src => api/src}/modules/processing/services/facebook.js (100%) rename {src => api/src}/modules/processing/services/instagram.js (100%) rename {src => api/src}/modules/processing/services/loom.js (100%) rename {src => api/src}/modules/processing/services/ok.js (100%) rename {src => api/src}/modules/processing/services/pinterest.js (100%) rename {src => api/src}/modules/processing/services/reddit.js (100%) rename {src => api/src}/modules/processing/services/rutube.js (100%) rename {src => api/src}/modules/processing/services/snapchat.js (100%) rename {src => api/src}/modules/processing/services/soundcloud.js (100%) rename {src => api/src}/modules/processing/services/streamable.js (100%) rename {src => api/src}/modules/processing/services/tiktok.js (100%) rename {src => api/src}/modules/processing/services/tumblr.js (100%) rename {src => api/src}/modules/processing/services/twitch.js (100%) rename {src => api/src}/modules/processing/services/twitter.js (100%) rename {src => api/src}/modules/processing/services/vimeo.js (100%) rename {src => api/src}/modules/processing/services/vine.js (100%) rename {src => api/src}/modules/processing/services/vk.js (100%) rename {src => api/src}/modules/processing/services/youtube.js (100%) rename {src => api/src}/modules/processing/servicesConfig.json (100%) rename {src => api/src}/modules/processing/servicesPatternTesters.js (100%) rename {src => api/src}/modules/processing/url.js (100%) rename {src => api/src}/modules/setup.js (100%) rename {src => api/src}/modules/stream/internal-hls.js (100%) rename {src => api/src}/modules/stream/internal.js (100%) rename {src => api/src}/modules/stream/manage.js (100%) rename {src => api/src}/modules/stream/shared.js (100%) rename {src => api/src}/modules/stream/stream.js (100%) rename {src => api/src}/modules/stream/types.js (100%) rename {src => api/src}/modules/sub/alias-envs.js (100%) rename {src => api/src}/modules/sub/consoleText.js (100%) rename {src => api/src}/modules/sub/crypto.js (100%) rename {src => api/src}/modules/sub/currentCommit.js (100%) rename {src => api/src}/modules/sub/loadFromFs.js (100%) rename {src => api/src}/modules/sub/randomize-ciphers.js (100%) rename {src => api/src}/modules/sub/utils.js (100%) rename {src => api/src}/modules/test.js (100%) rename {src => api/src}/util/generate-youtube-tokens.js (100%) rename {src => api/src}/util/test-ci.js (100%) rename {src => api/src}/util/test.js (100%) rename {src => api/src}/util/testFilenamePresets.js (100%) rename {src => api/src}/util/tests.json (100%) diff --git a/package.json b/api/package.json similarity index 100% rename from package.json rename to api/package.json diff --git a/src/cobalt.js b/api/src/cobalt.js similarity index 100% rename from src/cobalt.js rename to api/src/cobalt.js diff --git a/src/config.json b/api/src/config.json similarity index 100% rename from src/config.json rename to api/src/config.json diff --git a/src/core/api.js b/api/src/core/api.js similarity index 100% rename from src/core/api.js rename to api/src/core/api.js diff --git a/src/core/web.js b/api/src/core/web.js similarity index 100% rename from src/core/web.js rename to api/src/core/web.js diff --git a/src/front/assets/meowbalt/error.png b/api/src/front/assets/meowbalt/error.png similarity index 100% rename from src/front/assets/meowbalt/error.png rename to api/src/front/assets/meowbalt/error.png diff --git a/src/front/assets/meowbalt/question.png b/api/src/front/assets/meowbalt/question.png similarity index 100% rename from src/front/assets/meowbalt/question.png rename to api/src/front/assets/meowbalt/question.png diff --git a/src/front/cobalt.css b/api/src/front/cobalt.css similarity index 100% rename from src/front/cobalt.css rename to api/src/front/cobalt.css diff --git a/src/front/cobalt.js b/api/src/front/cobalt.js similarity index 100% rename from src/front/cobalt.js rename to api/src/front/cobalt.js diff --git a/src/front/emoji/3d/film_frames.png b/api/src/front/emoji/3d/film_frames.png similarity index 100% rename from src/front/emoji/3d/film_frames.png rename to api/src/front/emoji/3d/film_frames.png diff --git a/src/front/emoji/3d/headphone.png b/api/src/front/emoji/3d/headphone.png similarity index 100% rename from src/front/emoji/3d/headphone.png rename to api/src/front/emoji/3d/headphone.png diff --git a/src/front/emoji/abacus.svg b/api/src/front/emoji/abacus.svg similarity index 100% rename from src/front/emoji/abacus.svg rename to api/src/front/emoji/abacus.svg diff --git a/src/front/emoji/alien_monster.svg b/api/src/front/emoji/alien_monster.svg similarity index 100% rename from src/front/emoji/alien_monster.svg rename to api/src/front/emoji/alien_monster.svg diff --git a/src/front/emoji/biceps.svg b/api/src/front/emoji/biceps.svg similarity index 100% rename from src/front/emoji/biceps.svg rename to api/src/front/emoji/biceps.svg diff --git a/src/front/emoji/bird.svg b/api/src/front/emoji/bird.svg similarity index 100% rename from src/front/emoji/bird.svg rename to api/src/front/emoji/bird.svg diff --git a/src/front/emoji/boring_document.svg b/api/src/front/emoji/boring_document.svg similarity index 100% rename from src/front/emoji/boring_document.svg rename to api/src/front/emoji/boring_document.svg diff --git a/src/front/emoji/bubbles.svg b/api/src/front/emoji/bubbles.svg similarity index 100% rename from src/front/emoji/bubbles.svg rename to api/src/front/emoji/bubbles.svg diff --git a/src/front/emoji/cake.svg b/api/src/front/emoji/cake.svg similarity index 100% rename from src/front/emoji/cake.svg rename to api/src/front/emoji/cake.svg diff --git a/src/front/emoji/candle.svg b/api/src/front/emoji/candle.svg similarity index 100% rename from src/front/emoji/candle.svg rename to api/src/front/emoji/candle.svg diff --git a/src/front/emoji/cat.svg b/api/src/front/emoji/cat.svg similarity index 100% rename from src/front/emoji/cat.svg rename to api/src/front/emoji/cat.svg diff --git a/src/front/emoji/cat_crying.svg b/api/src/front/emoji/cat_crying.svg similarity index 100% rename from src/front/emoji/cat_crying.svg rename to api/src/front/emoji/cat_crying.svg diff --git a/src/front/emoji/cat_flabbergasted.svg b/api/src/front/emoji/cat_flabbergasted.svg similarity index 100% rename from src/front/emoji/cat_flabbergasted.svg rename to api/src/front/emoji/cat_flabbergasted.svg diff --git a/src/front/emoji/cat_grin.svg b/api/src/front/emoji/cat_grin.svg similarity index 100% rename from src/front/emoji/cat_grin.svg rename to api/src/front/emoji/cat_grin.svg diff --git a/src/front/emoji/cat_smile.svg b/api/src/front/emoji/cat_smile.svg similarity index 100% rename from src/front/emoji/cat_smile.svg rename to api/src/front/emoji/cat_smile.svg diff --git a/src/front/emoji/christmas_tree.svg b/api/src/front/emoji/christmas_tree.svg similarity index 100% rename from src/front/emoji/christmas_tree.svg rename to api/src/front/emoji/christmas_tree.svg diff --git a/src/front/emoji/clapper_board.svg b/api/src/front/emoji/clapper_board.svg similarity index 100% rename from src/front/emoji/clapper_board.svg rename to api/src/front/emoji/clapper_board.svg diff --git a/src/front/emoji/clipboard.svg b/api/src/front/emoji/clipboard.svg similarity index 100% rename from src/front/emoji/clipboard.svg rename to api/src/front/emoji/clipboard.svg diff --git a/src/front/emoji/crystal_ball.svg b/api/src/front/emoji/crystal_ball.svg similarity index 100% rename from src/front/emoji/crystal_ball.svg rename to api/src/front/emoji/crystal_ball.svg diff --git a/src/front/emoji/dog.svg b/api/src/front/emoji/dog.svg similarity index 100% rename from src/front/emoji/dog.svg rename to api/src/front/emoji/dog.svg diff --git a/src/front/emoji/dragon_face.svg b/api/src/front/emoji/dragon_face.svg similarity index 100% rename from src/front/emoji/dragon_face.svg rename to api/src/front/emoji/dragon_face.svg diff --git a/src/front/emoji/dragon_face_wukko.svg b/api/src/front/emoji/dragon_face_wukko.svg similarity index 100% rename from src/front/emoji/dragon_face_wukko.svg rename to api/src/front/emoji/dragon_face_wukko.svg diff --git a/src/front/emoji/elephant.svg b/api/src/front/emoji/elephant.svg similarity index 100% rename from src/front/emoji/elephant.svg rename to api/src/front/emoji/elephant.svg diff --git a/src/front/emoji/email.svg b/api/src/front/emoji/email.svg similarity index 100% rename from src/front/emoji/email.svg rename to api/src/front/emoji/email.svg diff --git a/src/front/emoji/film_frames.svg b/api/src/front/emoji/film_frames.svg similarity index 100% rename from src/front/emoji/film_frames.svg rename to api/src/front/emoji/film_frames.svg diff --git a/src/front/emoji/gear.svg b/api/src/front/emoji/gear.svg similarity index 100% rename from src/front/emoji/gear.svg rename to api/src/front/emoji/gear.svg diff --git a/src/front/emoji/headphone.svg b/api/src/front/emoji/headphone.svg similarity index 100% rename from src/front/emoji/headphone.svg rename to api/src/front/emoji/headphone.svg diff --git a/src/front/emoji/keyboard.svg b/api/src/front/emoji/keyboard.svg similarity index 100% rename from src/front/emoji/keyboard.svg rename to api/src/front/emoji/keyboard.svg diff --git a/src/front/emoji/link.svg b/api/src/front/emoji/link.svg similarity index 100% rename from src/front/emoji/link.svg rename to api/src/front/emoji/link.svg diff --git a/src/front/emoji/locked.svg b/api/src/front/emoji/locked.svg similarity index 100% rename from src/front/emoji/locked.svg rename to api/src/front/emoji/locked.svg diff --git a/src/front/emoji/loudspeaker.svg b/api/src/front/emoji/loudspeaker.svg similarity index 100% rename from src/front/emoji/loudspeaker.svg rename to api/src/front/emoji/loudspeaker.svg diff --git a/src/front/emoji/magic_wand.svg b/api/src/front/emoji/magic_wand.svg similarity index 100% rename from src/front/emoji/magic_wand.svg rename to api/src/front/emoji/magic_wand.svg diff --git a/src/front/emoji/magnifying_glass.svg b/api/src/front/emoji/magnifying_glass.svg similarity index 100% rename from src/front/emoji/magnifying_glass.svg rename to api/src/front/emoji/magnifying_glass.svg diff --git a/src/front/emoji/mailbox.svg b/api/src/front/emoji/mailbox.svg similarity index 100% rename from src/front/emoji/mailbox.svg rename to api/src/front/emoji/mailbox.svg diff --git a/src/front/emoji/mending_heart.svg b/api/src/front/emoji/mending_heart.svg similarity index 100% rename from src/front/emoji/mending_heart.svg rename to api/src/front/emoji/mending_heart.svg diff --git a/src/front/emoji/money_with_wings.svg b/api/src/front/emoji/money_with_wings.svg similarity index 100% rename from src/front/emoji/money_with_wings.svg rename to api/src/front/emoji/money_with_wings.svg diff --git a/src/front/emoji/musical_notes.svg b/api/src/front/emoji/musical_notes.svg similarity index 100% rename from src/front/emoji/musical_notes.svg rename to api/src/front/emoji/musical_notes.svg diff --git a/src/front/emoji/newspaper.svg b/api/src/front/emoji/newspaper.svg similarity index 100% rename from src/front/emoji/newspaper.svg rename to api/src/front/emoji/newspaper.svg diff --git a/src/front/emoji/octopus.svg b/api/src/front/emoji/octopus.svg similarity index 100% rename from src/front/emoji/octopus.svg rename to api/src/front/emoji/octopus.svg diff --git a/src/front/emoji/party_popper.svg b/api/src/front/emoji/party_popper.svg similarity index 100% rename from src/front/emoji/party_popper.svg rename to api/src/front/emoji/party_popper.svg diff --git a/src/front/emoji/pinata.svg b/api/src/front/emoji/pinata.svg similarity index 100% rename from src/front/emoji/pinata.svg rename to api/src/front/emoji/pinata.svg diff --git a/src/front/emoji/pumpkin.svg b/api/src/front/emoji/pumpkin.svg similarity index 100% rename from src/front/emoji/pumpkin.svg rename to api/src/front/emoji/pumpkin.svg diff --git a/src/front/emoji/question_mark.svg b/api/src/front/emoji/question_mark.svg similarity index 100% rename from src/front/emoji/question_mark.svg rename to api/src/front/emoji/question_mark.svg diff --git a/src/front/emoji/sparkles.svg b/api/src/front/emoji/sparkles.svg similarity index 100% rename from src/front/emoji/sparkles.svg rename to api/src/front/emoji/sparkles.svg diff --git a/src/front/emoji/sparkling_heart.svg b/api/src/front/emoji/sparkling_heart.svg similarity index 100% rename from src/front/emoji/sparkling_heart.svg rename to api/src/front/emoji/sparkling_heart.svg diff --git a/src/front/emoji/wrench.svg b/api/src/front/emoji/wrench.svg similarity index 100% rename from src/front/emoji/wrench.svg rename to api/src/front/emoji/wrench.svg diff --git a/src/front/fonts/files/notosansmono_3dVQ.woff2 b/api/src/front/fonts/files/notosansmono_3dVQ.woff2 similarity index 100% rename from src/front/fonts/files/notosansmono_3dVQ.woff2 rename to api/src/front/fonts/files/notosansmono_3dVQ.woff2 diff --git a/src/front/fonts/files/notosansmono_7dVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_7dVXQQ.woff2 similarity index 100% rename from src/front/fonts/files/notosansmono_7dVXQQ.woff2 rename to api/src/front/fonts/files/notosansmono_7dVXQQ.woff2 diff --git a/src/front/fonts/files/notosansmono_DdVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_DdVXQQ.woff2 similarity index 100% rename from src/front/fonts/files/notosansmono_DdVXQQ.woff2 rename to api/src/front/fonts/files/notosansmono_DdVXQQ.woff2 diff --git a/src/front/fonts/files/notosansmono_HdVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_HdVXQQ.woff2 similarity index 100% rename from src/front/fonts/files/notosansmono_HdVXQQ.woff2 rename to api/src/front/fonts/files/notosansmono_HdVXQQ.woff2 diff --git a/src/front/fonts/files/notosansmono_LdVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_LdVXQQ.woff2 similarity index 100% rename from src/front/fonts/files/notosansmono_LdVXQQ.woff2 rename to api/src/front/fonts/files/notosansmono_LdVXQQ.woff2 diff --git a/src/front/fonts/files/notosansmono_PdVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_PdVXQQ.woff2 similarity index 100% rename from src/front/fonts/files/notosansmono_PdVXQQ.woff2 rename to api/src/front/fonts/files/notosansmono_PdVXQQ.woff2 diff --git a/src/front/fonts/files/notosansmono_ndVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_ndVXQQ.woff2 similarity index 100% rename from src/front/fonts/files/notosansmono_ndVXQQ.woff2 rename to api/src/front/fonts/files/notosansmono_ndVXQQ.woff2 diff --git a/src/front/fonts/notosansmono.css b/api/src/front/fonts/notosansmono.css similarity index 100% rename from src/front/fonts/notosansmono.css rename to api/src/front/fonts/notosansmono.css diff --git a/src/front/icons/android-chrome-192x192.png b/api/src/front/icons/android-chrome-192x192.png similarity index 100% rename from src/front/icons/android-chrome-192x192.png rename to api/src/front/icons/android-chrome-192x192.png diff --git a/src/front/icons/android-chrome-512x512.png b/api/src/front/icons/android-chrome-512x512.png similarity index 100% rename from src/front/icons/android-chrome-512x512.png rename to api/src/front/icons/android-chrome-512x512.png diff --git a/src/front/icons/apple-touch-icon.png b/api/src/front/icons/apple-touch-icon.png similarity index 100% rename from src/front/icons/apple-touch-icon.png rename to api/src/front/icons/apple-touch-icon.png diff --git a/src/front/icons/favicon-16x16.png b/api/src/front/icons/favicon-16x16.png similarity index 100% rename from src/front/icons/favicon-16x16.png rename to api/src/front/icons/favicon-16x16.png diff --git a/src/front/icons/favicon-32x32.png b/api/src/front/icons/favicon-32x32.png similarity index 100% rename from src/front/icons/favicon-32x32.png rename to api/src/front/icons/favicon-32x32.png diff --git a/src/front/icons/favicon.ico b/api/src/front/icons/favicon.ico similarity index 100% rename from src/front/icons/favicon.ico rename to api/src/front/icons/favicon.ico diff --git a/src/front/icons/generic.png b/api/src/front/icons/generic.png similarity index 100% rename from src/front/icons/generic.png rename to api/src/front/icons/generic.png diff --git a/src/front/icons/maskable/128.png b/api/src/front/icons/maskable/128.png similarity index 100% rename from src/front/icons/maskable/128.png rename to api/src/front/icons/maskable/128.png diff --git a/src/front/icons/maskable/192.png b/api/src/front/icons/maskable/192.png similarity index 100% rename from src/front/icons/maskable/192.png rename to api/src/front/icons/maskable/192.png diff --git a/src/front/icons/maskable/384.png b/api/src/front/icons/maskable/384.png similarity index 100% rename from src/front/icons/maskable/384.png rename to api/src/front/icons/maskable/384.png diff --git a/src/front/icons/maskable/48.png b/api/src/front/icons/maskable/48.png similarity index 100% rename from src/front/icons/maskable/48.png rename to api/src/front/icons/maskable/48.png diff --git a/src/front/icons/maskable/512.png b/api/src/front/icons/maskable/512.png similarity index 100% rename from src/front/icons/maskable/512.png rename to api/src/front/icons/maskable/512.png diff --git a/src/front/icons/maskable/72.png b/api/src/front/icons/maskable/72.png similarity index 100% rename from src/front/icons/maskable/72.png rename to api/src/front/icons/maskable/72.png diff --git a/src/front/icons/maskable/96.png b/api/src/front/icons/maskable/96.png similarity index 100% rename from src/front/icons/maskable/96.png rename to api/src/front/icons/maskable/96.png diff --git a/src/front/icons/pattern.png b/api/src/front/icons/pattern.png similarity index 100% rename from src/front/icons/pattern.png rename to api/src/front/icons/pattern.png diff --git a/src/front/manifest.webmanifest b/api/src/front/manifest.webmanifest similarity index 100% rename from src/front/manifest.webmanifest rename to api/src/front/manifest.webmanifest diff --git a/src/front/robots.txt b/api/src/front/robots.txt similarity index 100% rename from src/front/robots.txt rename to api/src/front/robots.txt diff --git a/src/front/sponsors/royale.svg b/api/src/front/sponsors/royale.svg similarity index 100% rename from src/front/sponsors/royale.svg rename to api/src/front/sponsors/royale.svg diff --git a/src/front/updateBanners/bettertogether.webp b/api/src/front/updateBanners/bettertogether.webp similarity index 100% rename from src/front/updateBanners/bettertogether.webp rename to api/src/front/updateBanners/bettertogether.webp diff --git a/src/front/updateBanners/catmakeup.webp b/api/src/front/updateBanners/catmakeup.webp similarity index 100% rename from src/front/updateBanners/catmakeup.webp rename to api/src/front/updateBanners/catmakeup.webp diff --git a/src/front/updateBanners/catphonestand.webp b/api/src/front/updateBanners/catphonestand.webp similarity index 100% rename from src/front/updateBanners/catphonestand.webp rename to api/src/front/updateBanners/catphonestand.webp diff --git a/src/front/updateBanners/catroomba.webp b/api/src/front/updateBanners/catroomba.webp similarity index 100% rename from src/front/updateBanners/catroomba.webp rename to api/src/front/updateBanners/catroomba.webp diff --git a/src/front/updateBanners/catsleep.webp b/api/src/front/updateBanners/catsleep.webp similarity index 100% rename from src/front/updateBanners/catsleep.webp rename to api/src/front/updateBanners/catsleep.webp diff --git a/src/front/updateBanners/catspeed.webp b/api/src/front/updateBanners/catspeed.webp similarity index 100% rename from src/front/updateBanners/catspeed.webp rename to api/src/front/updateBanners/catspeed.webp diff --git a/src/front/updateBanners/catswitchboxes.webp b/api/src/front/updateBanners/catswitchboxes.webp similarity index 100% rename from src/front/updateBanners/catswitchboxes.webp rename to api/src/front/updateBanners/catswitchboxes.webp diff --git a/src/front/updateBanners/cattired.webp b/api/src/front/updateBanners/cattired.webp similarity index 100% rename from src/front/updateBanners/cattired.webp rename to api/src/front/updateBanners/cattired.webp diff --git a/src/front/updateBanners/developers.webp b/api/src/front/updateBanners/developers.webp similarity index 100% rename from src/front/updateBanners/developers.webp rename to api/src/front/updateBanners/developers.webp diff --git a/src/front/updateBanners/happymeowth.webp b/api/src/front/updateBanners/happymeowth.webp similarity index 100% rename from src/front/updateBanners/happymeowth.webp rename to api/src/front/updateBanners/happymeowth.webp diff --git a/src/front/updateBanners/meowth7eleven.webp b/api/src/front/updateBanners/meowth7eleven.webp similarity index 100% rename from src/front/updateBanners/meowth7eleven.webp rename to api/src/front/updateBanners/meowth7eleven.webp diff --git a/src/front/updateBanners/meowthball.webp b/api/src/front/updateBanners/meowthball.webp similarity index 100% rename from src/front/updateBanners/meowthball.webp rename to api/src/front/updateBanners/meowthball.webp diff --git a/src/front/updateBanners/meowthbusinessman.webp b/api/src/front/updateBanners/meowthbusinessman.webp similarity index 100% rename from src/front/updateBanners/meowthbusinessman.webp rename to api/src/front/updateBanners/meowthbusinessman.webp diff --git a/src/front/updateBanners/meowthcenter.webp b/api/src/front/updateBanners/meowthcenter.webp similarity index 100% rename from src/front/updateBanners/meowthcenter.webp rename to api/src/front/updateBanners/meowthcenter.webp diff --git a/src/front/updateBanners/meowthcooking.webp b/api/src/front/updateBanners/meowthcooking.webp similarity index 100% rename from src/front/updateBanners/meowthcooking.webp rename to api/src/front/updateBanners/meowthcooking.webp diff --git a/src/front/updateBanners/meowthhammer.webp b/api/src/front/updateBanners/meowthhammer.webp similarity index 100% rename from src/front/updateBanners/meowthhammer.webp rename to api/src/front/updateBanners/meowthhammer.webp diff --git a/src/front/updateBanners/meowthpolishegg.webp b/api/src/front/updateBanners/meowthpolishegg.webp similarity index 100% rename from src/front/updateBanners/meowthpolishegg.webp rename to api/src/front/updateBanners/meowthpolishegg.webp diff --git a/src/front/updateBanners/meowthproductions.webp b/api/src/front/updateBanners/meowthproductions.webp similarity index 100% rename from src/front/updateBanners/meowthproductions.webp rename to api/src/front/updateBanners/meowthproductions.webp diff --git a/src/front/updateBanners/meowthsnap.webp b/api/src/front/updateBanners/meowthsnap.webp similarity index 100% rename from src/front/updateBanners/meowthsnap.webp rename to api/src/front/updateBanners/meowthsnap.webp diff --git a/src/front/updateBanners/meowthstrong.webp b/api/src/front/updateBanners/meowthstrong.webp similarity index 100% rename from src/front/updateBanners/meowthstrong.webp rename to api/src/front/updateBanners/meowthstrong.webp diff --git a/src/front/updateBanners/millionusers.webp b/api/src/front/updateBanners/millionusers.webp similarity index 100% rename from src/front/updateBanners/millionusers.webp rename to api/src/front/updateBanners/millionusers.webp diff --git a/src/front/updateBanners/newdomain.webp b/api/src/front/updateBanners/newdomain.webp similarity index 100% rename from src/front/updateBanners/newdomain.webp rename to api/src/front/updateBanners/newdomain.webp diff --git a/src/front/updateBanners/onemillionr.webp b/api/src/front/updateBanners/onemillionr.webp similarity index 100% rename from src/front/updateBanners/onemillionr.webp rename to api/src/front/updateBanners/onemillionr.webp diff --git a/src/front/updateBanners/shutup.webp b/api/src/front/updateBanners/shutup.webp similarity index 100% rename from src/front/updateBanners/shutup.webp rename to api/src/front/updateBanners/shutup.webp diff --git a/src/front/updateBanners/twitchupdate.webp b/api/src/front/updateBanners/twitchupdate.webp similarity index 100% rename from src/front/updateBanners/twitchupdate.webp rename to api/src/front/updateBanners/twitchupdate.webp diff --git a/src/front/updateBanners/valentines.webp b/api/src/front/updateBanners/valentines.webp similarity index 100% rename from src/front/updateBanners/valentines.webp rename to api/src/front/updateBanners/valentines.webp diff --git a/src/localization/languages/en.json b/api/src/localization/languages/en.json similarity index 100% rename from src/localization/languages/en.json rename to api/src/localization/languages/en.json diff --git a/src/localization/languages/ru.json b/api/src/localization/languages/ru.json similarity index 100% rename from src/localization/languages/ru.json rename to api/src/localization/languages/ru.json diff --git a/src/localization/manager.js b/api/src/localization/manager.js similarity index 100% rename from src/localization/manager.js rename to api/src/localization/manager.js diff --git a/src/modules/build.js b/api/src/modules/build.js similarity index 100% rename from src/modules/build.js rename to api/src/modules/build.js diff --git a/src/modules/buildStatic.js b/api/src/modules/buildStatic.js similarity index 100% rename from src/modules/buildStatic.js rename to api/src/modules/buildStatic.js diff --git a/src/modules/changelog/changelog.json b/api/src/modules/changelog/changelog.json similarity index 100% rename from src/modules/changelog/changelog.json rename to api/src/modules/changelog/changelog.json diff --git a/src/modules/changelog/changelogManager.js b/api/src/modules/changelog/changelogManager.js similarity index 100% rename from src/modules/changelog/changelogManager.js rename to api/src/modules/changelog/changelogManager.js diff --git a/src/modules/config.js b/api/src/modules/config.js similarity index 100% rename from src/modules/config.js rename to api/src/modules/config.js diff --git a/src/modules/emoji.js b/api/src/modules/emoji.js similarity index 100% rename from src/modules/emoji.js rename to api/src/modules/emoji.js diff --git a/src/modules/pageRender/elements.js b/api/src/modules/pageRender/elements.js similarity index 100% rename from src/modules/pageRender/elements.js rename to api/src/modules/pageRender/elements.js diff --git a/src/modules/pageRender/findRendered.js b/api/src/modules/pageRender/findRendered.js similarity index 100% rename from src/modules/pageRender/findRendered.js rename to api/src/modules/pageRender/findRendered.js diff --git a/src/modules/pageRender/onDemand.js b/api/src/modules/pageRender/onDemand.js similarity index 100% rename from src/modules/pageRender/onDemand.js rename to api/src/modules/pageRender/onDemand.js diff --git a/src/modules/pageRender/page.js b/api/src/modules/pageRender/page.js similarity index 100% rename from src/modules/pageRender/page.js rename to api/src/modules/pageRender/page.js diff --git a/src/modules/processing/cookie/cookie.js b/api/src/modules/processing/cookie/cookie.js similarity index 100% rename from src/modules/processing/cookie/cookie.js rename to api/src/modules/processing/cookie/cookie.js diff --git a/src/modules/processing/cookie/manager.js b/api/src/modules/processing/cookie/manager.js similarity index 100% rename from src/modules/processing/cookie/manager.js rename to api/src/modules/processing/cookie/manager.js diff --git a/src/modules/processing/createFilename.js b/api/src/modules/processing/createFilename.js similarity index 100% rename from src/modules/processing/createFilename.js rename to api/src/modules/processing/createFilename.js diff --git a/src/modules/processing/match.js b/api/src/modules/processing/match.js similarity index 100% rename from src/modules/processing/match.js rename to api/src/modules/processing/match.js diff --git a/src/modules/processing/matchActionDecider.js b/api/src/modules/processing/matchActionDecider.js similarity index 100% rename from src/modules/processing/matchActionDecider.js rename to api/src/modules/processing/matchActionDecider.js diff --git a/src/modules/processing/request.js b/api/src/modules/processing/request.js similarity index 100% rename from src/modules/processing/request.js rename to api/src/modules/processing/request.js diff --git a/src/modules/processing/services/bilibili.js b/api/src/modules/processing/services/bilibili.js similarity index 100% rename from src/modules/processing/services/bilibili.js rename to api/src/modules/processing/services/bilibili.js diff --git a/src/modules/processing/services/dailymotion.js b/api/src/modules/processing/services/dailymotion.js similarity index 100% rename from src/modules/processing/services/dailymotion.js rename to api/src/modules/processing/services/dailymotion.js diff --git a/src/modules/processing/services/facebook.js b/api/src/modules/processing/services/facebook.js similarity index 100% rename from src/modules/processing/services/facebook.js rename to api/src/modules/processing/services/facebook.js diff --git a/src/modules/processing/services/instagram.js b/api/src/modules/processing/services/instagram.js similarity index 100% rename from src/modules/processing/services/instagram.js rename to api/src/modules/processing/services/instagram.js diff --git a/src/modules/processing/services/loom.js b/api/src/modules/processing/services/loom.js similarity index 100% rename from src/modules/processing/services/loom.js rename to api/src/modules/processing/services/loom.js diff --git a/src/modules/processing/services/ok.js b/api/src/modules/processing/services/ok.js similarity index 100% rename from src/modules/processing/services/ok.js rename to api/src/modules/processing/services/ok.js diff --git a/src/modules/processing/services/pinterest.js b/api/src/modules/processing/services/pinterest.js similarity index 100% rename from src/modules/processing/services/pinterest.js rename to api/src/modules/processing/services/pinterest.js diff --git a/src/modules/processing/services/reddit.js b/api/src/modules/processing/services/reddit.js similarity index 100% rename from src/modules/processing/services/reddit.js rename to api/src/modules/processing/services/reddit.js diff --git a/src/modules/processing/services/rutube.js b/api/src/modules/processing/services/rutube.js similarity index 100% rename from src/modules/processing/services/rutube.js rename to api/src/modules/processing/services/rutube.js diff --git a/src/modules/processing/services/snapchat.js b/api/src/modules/processing/services/snapchat.js similarity index 100% rename from src/modules/processing/services/snapchat.js rename to api/src/modules/processing/services/snapchat.js diff --git a/src/modules/processing/services/soundcloud.js b/api/src/modules/processing/services/soundcloud.js similarity index 100% rename from src/modules/processing/services/soundcloud.js rename to api/src/modules/processing/services/soundcloud.js diff --git a/src/modules/processing/services/streamable.js b/api/src/modules/processing/services/streamable.js similarity index 100% rename from src/modules/processing/services/streamable.js rename to api/src/modules/processing/services/streamable.js diff --git a/src/modules/processing/services/tiktok.js b/api/src/modules/processing/services/tiktok.js similarity index 100% rename from src/modules/processing/services/tiktok.js rename to api/src/modules/processing/services/tiktok.js diff --git a/src/modules/processing/services/tumblr.js b/api/src/modules/processing/services/tumblr.js similarity index 100% rename from src/modules/processing/services/tumblr.js rename to api/src/modules/processing/services/tumblr.js diff --git a/src/modules/processing/services/twitch.js b/api/src/modules/processing/services/twitch.js similarity index 100% rename from src/modules/processing/services/twitch.js rename to api/src/modules/processing/services/twitch.js diff --git a/src/modules/processing/services/twitter.js b/api/src/modules/processing/services/twitter.js similarity index 100% rename from src/modules/processing/services/twitter.js rename to api/src/modules/processing/services/twitter.js diff --git a/src/modules/processing/services/vimeo.js b/api/src/modules/processing/services/vimeo.js similarity index 100% rename from src/modules/processing/services/vimeo.js rename to api/src/modules/processing/services/vimeo.js diff --git a/src/modules/processing/services/vine.js b/api/src/modules/processing/services/vine.js similarity index 100% rename from src/modules/processing/services/vine.js rename to api/src/modules/processing/services/vine.js diff --git a/src/modules/processing/services/vk.js b/api/src/modules/processing/services/vk.js similarity index 100% rename from src/modules/processing/services/vk.js rename to api/src/modules/processing/services/vk.js diff --git a/src/modules/processing/services/youtube.js b/api/src/modules/processing/services/youtube.js similarity index 100% rename from src/modules/processing/services/youtube.js rename to api/src/modules/processing/services/youtube.js diff --git a/src/modules/processing/servicesConfig.json b/api/src/modules/processing/servicesConfig.json similarity index 100% rename from src/modules/processing/servicesConfig.json rename to api/src/modules/processing/servicesConfig.json diff --git a/src/modules/processing/servicesPatternTesters.js b/api/src/modules/processing/servicesPatternTesters.js similarity index 100% rename from src/modules/processing/servicesPatternTesters.js rename to api/src/modules/processing/servicesPatternTesters.js diff --git a/src/modules/processing/url.js b/api/src/modules/processing/url.js similarity index 100% rename from src/modules/processing/url.js rename to api/src/modules/processing/url.js diff --git a/src/modules/setup.js b/api/src/modules/setup.js similarity index 100% rename from src/modules/setup.js rename to api/src/modules/setup.js diff --git a/src/modules/stream/internal-hls.js b/api/src/modules/stream/internal-hls.js similarity index 100% rename from src/modules/stream/internal-hls.js rename to api/src/modules/stream/internal-hls.js diff --git a/src/modules/stream/internal.js b/api/src/modules/stream/internal.js similarity index 100% rename from src/modules/stream/internal.js rename to api/src/modules/stream/internal.js diff --git a/src/modules/stream/manage.js b/api/src/modules/stream/manage.js similarity index 100% rename from src/modules/stream/manage.js rename to api/src/modules/stream/manage.js diff --git a/src/modules/stream/shared.js b/api/src/modules/stream/shared.js similarity index 100% rename from src/modules/stream/shared.js rename to api/src/modules/stream/shared.js diff --git a/src/modules/stream/stream.js b/api/src/modules/stream/stream.js similarity index 100% rename from src/modules/stream/stream.js rename to api/src/modules/stream/stream.js diff --git a/src/modules/stream/types.js b/api/src/modules/stream/types.js similarity index 100% rename from src/modules/stream/types.js rename to api/src/modules/stream/types.js diff --git a/src/modules/sub/alias-envs.js b/api/src/modules/sub/alias-envs.js similarity index 100% rename from src/modules/sub/alias-envs.js rename to api/src/modules/sub/alias-envs.js diff --git a/src/modules/sub/consoleText.js b/api/src/modules/sub/consoleText.js similarity index 100% rename from src/modules/sub/consoleText.js rename to api/src/modules/sub/consoleText.js diff --git a/src/modules/sub/crypto.js b/api/src/modules/sub/crypto.js similarity index 100% rename from src/modules/sub/crypto.js rename to api/src/modules/sub/crypto.js diff --git a/src/modules/sub/currentCommit.js b/api/src/modules/sub/currentCommit.js similarity index 100% rename from src/modules/sub/currentCommit.js rename to api/src/modules/sub/currentCommit.js diff --git a/src/modules/sub/loadFromFs.js b/api/src/modules/sub/loadFromFs.js similarity index 100% rename from src/modules/sub/loadFromFs.js rename to api/src/modules/sub/loadFromFs.js diff --git a/src/modules/sub/randomize-ciphers.js b/api/src/modules/sub/randomize-ciphers.js similarity index 100% rename from src/modules/sub/randomize-ciphers.js rename to api/src/modules/sub/randomize-ciphers.js diff --git a/src/modules/sub/utils.js b/api/src/modules/sub/utils.js similarity index 100% rename from src/modules/sub/utils.js rename to api/src/modules/sub/utils.js diff --git a/src/modules/test.js b/api/src/modules/test.js similarity index 100% rename from src/modules/test.js rename to api/src/modules/test.js diff --git a/src/util/generate-youtube-tokens.js b/api/src/util/generate-youtube-tokens.js similarity index 100% rename from src/util/generate-youtube-tokens.js rename to api/src/util/generate-youtube-tokens.js diff --git a/src/util/test-ci.js b/api/src/util/test-ci.js similarity index 100% rename from src/util/test-ci.js rename to api/src/util/test-ci.js diff --git a/src/util/test.js b/api/src/util/test.js similarity index 100% rename from src/util/test.js rename to api/src/util/test.js diff --git a/src/util/testFilenamePresets.js b/api/src/util/testFilenamePresets.js similarity index 100% rename from src/util/testFilenamePresets.js rename to api/src/util/testFilenamePresets.js diff --git a/src/util/tests.json b/api/src/util/tests.json similarity index 100% rename from src/util/tests.json rename to api/src/util/tests.json From 213d259b09f7c320328326067c36def5a21161a4 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 20:43:37 +0600 Subject: [PATCH 336/775] repo: remove package-lock --- package-lock.json | 1142 --------------------------------------------- 1 file changed, 1142 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 5f09ef3e..00000000 --- a/package-lock.json +++ /dev/null @@ -1,1142 +0,0 @@ -{ - "name": "cobalt", - "version": "7.15", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "cobalt", - "version": "7.15", - "license": "AGPL-3.0", - "dependencies": { - "content-disposition-header": "0.6.0", - "cors": "^2.8.5", - "dotenv": "^16.0.1", - "esbuild": "^0.14.51", - "express": "^4.18.1", - "express-rate-limit": "^6.3.0", - "ffmpeg-static": "^5.1.0", - "hls-parser": "^0.10.7", - "ipaddr.js": "2.1.0", - "nanoid": "^4.0.2", - "node-cache": "^5.1.2", - "psl": "1.9.0", - "set-cookie-parser": "2.6.0", - "undici": "^5.19.1", - "url-pattern": "1.0.3", - "youtubei.js": "^10.3.0" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "freebind": "^0.2.2" - } - }, - "node_modules/@derhuerst/http-basic": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.4.tgz", - "integrity": "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==", - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^2.0.0", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-disposition-header": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/content-disposition-header/-/content-disposition-header-0.6.0.tgz", - "integrity": "sha512-+PKF6Y7JHgwD2Dld48L5jozC6pGDdnioJHfM7VyfF92pAU6wDF/N8K/cfecoq7b19KnelOnjntkVyN5hMm2F+w==" - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", - "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/linux-loong64": "0.14.54", - "esbuild-android-64": "0.14.54", - "esbuild-android-arm64": "0.14.54", - "esbuild-darwin-64": "0.14.54", - "esbuild-darwin-arm64": "0.14.54", - "esbuild-freebsd-64": "0.14.54", - "esbuild-freebsd-arm64": "0.14.54", - "esbuild-linux-32": "0.14.54", - "esbuild-linux-64": "0.14.54", - "esbuild-linux-arm": "0.14.54", - "esbuild-linux-arm64": "0.14.54", - "esbuild-linux-mips64le": "0.14.54", - "esbuild-linux-ppc64le": "0.14.54", - "esbuild-linux-riscv64": "0.14.54", - "esbuild-linux-s390x": "0.14.54", - "esbuild-netbsd-64": "0.14.54", - "esbuild-openbsd-64": "0.14.54", - "esbuild-sunos-64": "0.14.54", - "esbuild-windows-32": "0.14.54", - "esbuild-windows-64": "0.14.54", - "esbuild-windows-arm64": "0.14.54" - } - }, - "node_modules/esbuild-linux-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", - "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-rate-limit": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.11.2.tgz", - "integrity": "sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw==", - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "express": "^4 || ^5" - } - }, - "node_modules/ffmpeg-static": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.2.0.tgz", - "integrity": "sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA==", - "hasInstallScript": true, - "dependencies": { - "@derhuerst/http-basic": "^8.2.0", - "env-paths": "^2.2.0", - "https-proxy-agent": "^5.0.0", - "progress": "^2.0.3" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/freebind": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/freebind/-/freebind-0.2.2.tgz", - "integrity": "sha512-H3PdpY9gMa46ra2CkDLZxAqvJiiazb5ZpQcvmOriB0cPVRzFSi+pXY/m3mN31tkZhE/0D4O+pCGTMezh/jwLnw==", - "optional": true, - "dependencies": { - "ipaddr.js": "2.1.0", - "syscall-napi": "0.0.6", - "undici": "^5.27.0" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hls-parser": { - "version": "0.10.9", - "resolved": "https://registry.npmjs.org/hls-parser/-/hls-parser-0.10.9.tgz", - "integrity": "sha512-BGtoMd3sbhndHYKVQEoEmpuRe6++iWQc38x84x5uqitYmP6V5opKHWaYJT4GAwhnVRaNhMTuZbS0AruzPw4qgw==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/jintr": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/jintr/-/jintr-2.1.1.tgz", - "integrity": "sha512-89cwX4ouogeDGOBsEVsVYsnWWvWjchmwXBB4kiBhmjOKw19FiOKhNhMhpxhTlK2ctl7DS+d/ethfmuBpzoNNgA==", - "funding": [ - "https://github.com/sponsors/LuanRT" - ], - "license": "MIT", - "dependencies": { - "acorn": "^8.8.0" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/nanoid": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", - "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^14 || ^16 || >=18" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-cache": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", - "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", - "dependencies": { - "clone": "2.x" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", - "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/syscall-napi": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/syscall-napi/-/syscall-napi-0.0.6.tgz", - "integrity": "sha512-qHbwjyFXAAekKUXxl70lhDiBYJ3e7XM7kQwu7LV3F0pHMenKox+VcZPZkRkhdmL/wNJD3NmrMGnL7161kdecUQ==", - "hasInstallScript": true, - "optional": true - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/url-pattern": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/url-pattern/-/url-pattern-1.0.3.tgz", - "integrity": "sha512-uQcEj/2puA4aq1R3A2+VNVBgaWYR24FdWjl7VNW83rnWftlhyzOZ/tBjezRiC2UkIzuxC8Top3IekN3vUf1WxA==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/youtubei.js": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/youtubei.js/-/youtubei.js-10.3.0.tgz", - "integrity": "sha512-tLmeJCECK2xF2hZZtF2nEqirdKVNLFSDpa0LhTaXY3tngtL7doQXyy7M2CLueramDTlmCnFaW+rctHirTPFaRQ==", - "funding": [ - "https://github.com/sponsors/LuanRT" - ], - "license": "MIT", - "dependencies": { - "jintr": "^2.1.1", - "tslib": "^2.5.0", - "undici": "^5.19.1" - } - } - } -} From 65e095b178dcd267eaf1cb89ae8ae20c72058613 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 20:45:32 +0600 Subject: [PATCH 337/775] repo: add pnpm workspace config & lock --- pnpm-lock.yaml | 1090 +++++++++++++++++++++++++++++++++++++++++++ pnpm-workspace.yaml | 2 + 2 files changed, 1092 insertions(+) create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..5cf6edac --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1090 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + api: + dependencies: + content-disposition-header: + specifier: 0.6.0 + version: 0.6.0 + cors: + specifier: ^2.8.5 + version: 2.8.5 + dotenv: + specifier: ^16.0.1 + version: 16.4.5 + esbuild: + specifier: ^0.14.51 + version: 0.14.54 + express: + specifier: ^4.18.1 + version: 4.19.2 + express-rate-limit: + specifier: ^6.3.0 + version: 6.11.2(express@4.19.2) + ffmpeg-static: + specifier: ^5.1.0 + version: 5.2.0 + hls-parser: + specifier: ^0.10.7 + version: 0.10.9 + ipaddr.js: + specifier: 2.1.0 + version: 2.1.0 + nanoid: + specifier: ^4.0.2 + version: 4.0.2 + node-cache: + specifier: ^5.1.2 + version: 5.1.2 + psl: + specifier: 1.9.0 + version: 1.9.0 + set-cookie-parser: + specifier: 2.6.0 + version: 2.6.0 + undici: + specifier: ^5.19.1 + version: 5.28.4 + url-pattern: + specifier: 1.0.3 + version: 1.0.3 + youtubei.js: + specifier: ^10.3.0 + version: 10.3.0 + optionalDependencies: + freebind: + specifier: ^0.2.2 + version: 0.2.2 + +packages: + + '@derhuerst/http-basic@8.2.4': + resolution: {integrity: sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==} + engines: {node: '>=6.0.0'} + + '@esbuild/linux-loong64@0.14.54': + resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + + content-disposition-header@0.6.0: + resolution: {integrity: sha512-+PKF6Y7JHgwD2Dld48L5jozC6pGDdnioJHfM7VyfF92pAU6wDF/N8K/cfecoq7b19KnelOnjntkVyN5hMm2F+w==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + esbuild-android-64@0.14.54: + resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + esbuild-android-arm64@0.14.54: + resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + esbuild-darwin-64@0.14.54: + resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + esbuild-darwin-arm64@0.14.54: + resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + esbuild-freebsd-64@0.14.54: + resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + esbuild-freebsd-arm64@0.14.54: + resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + esbuild-linux-32@0.14.54: + resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + esbuild-linux-64@0.14.54: + resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + esbuild-linux-arm64@0.14.54: + resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + esbuild-linux-arm@0.14.54: + resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + esbuild-linux-mips64le@0.14.54: + resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + esbuild-linux-ppc64le@0.14.54: + resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + esbuild-linux-riscv64@0.14.54: + resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + esbuild-linux-s390x@0.14.54: + resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + esbuild-netbsd-64@0.14.54: + resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + esbuild-openbsd-64@0.14.54: + resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + esbuild-sunos-64@0.14.54: + resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + esbuild-windows-32@0.14.54: + resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + esbuild-windows-64@0.14.54: + resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + esbuild-windows-arm64@0.14.54: + resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + esbuild@0.14.54: + resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} + engines: {node: '>=12'} + hasBin: true + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + express-rate-limit@6.11.2: + resolution: {integrity: sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw==} + engines: {node: '>= 14'} + peerDependencies: + express: ^4 || ^5 + + express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} + + ffmpeg-static@5.2.0: + resolution: {integrity: sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA==} + engines: {node: '>=16'} + + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + freebind@0.2.2: + resolution: {integrity: sha512-H3PdpY9gMa46ra2CkDLZxAqvJiiazb5ZpQcvmOriB0cPVRzFSi+pXY/m3mN31tkZhE/0D4O+pCGTMezh/jwLnw==} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hls-parser@0.10.9: + resolution: {integrity: sha512-BGtoMd3sbhndHYKVQEoEmpuRe6++iWQc38x84x5uqitYmP6V5opKHWaYJT4GAwhnVRaNhMTuZbS0AruzPw4qgw==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.1.0: + resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==} + engines: {node: '>= 10'} + + jintr@2.1.1: + resolution: {integrity: sha512-89cwX4ouogeDGOBsEVsVYsnWWvWjchmwXBB4kiBhmjOKw19FiOKhNhMhpxhTlK2ctl7DS+d/ethfmuBpzoNNgA==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@4.0.2: + resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} + engines: {node: ^14 || ^16 || >=18} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-cache@5.1.2: + resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==} + engines: {node: '>= 8.0.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + set-cookie-parser@2.6.0: + resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + syscall-napi@0.0.6: + resolution: {integrity: sha512-qHbwjyFXAAekKUXxl70lhDiBYJ3e7XM7kQwu7LV3F0pHMenKox+VcZPZkRkhdmL/wNJD3NmrMGnL7161kdecUQ==} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + url-pattern@1.0.3: + resolution: {integrity: sha512-uQcEj/2puA4aq1R3A2+VNVBgaWYR24FdWjl7VNW83rnWftlhyzOZ/tBjezRiC2UkIzuxC8Top3IekN3vUf1WxA==} + engines: {node: '>=0.12.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + youtubei.js@10.3.0: + resolution: {integrity: sha512-tLmeJCECK2xF2hZZtF2nEqirdKVNLFSDpa0LhTaXY3tngtL7doQXyy7M2CLueramDTlmCnFaW+rctHirTPFaRQ==} + +snapshots: + + '@derhuerst/http-basic@8.2.4': + dependencies: + caseless: 0.12.0 + concat-stream: 2.0.0 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 + + '@esbuild/linux-loong64@0.14.54': + optional: true + + '@fastify/busboy@2.1.1': {} + + '@types/node@10.17.60': {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn@8.12.1: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + + array-flatten@1.1.1: {} + + body-parser@1.20.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + buffer-from@1.1.2: {} + + bytes@3.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + caseless@0.12.0: {} + + clone@2.1.2: {} + + concat-stream@2.0.0: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + + content-disposition-header@0.6.0: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie@0.6.0: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + depd@2.0.0: {} + + destroy@1.2.0: {} + + dotenv@16.4.5: {} + + ee-first@1.1.1: {} + + encodeurl@1.0.2: {} + + env-paths@2.2.1: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + esbuild-android-64@0.14.54: + optional: true + + esbuild-android-arm64@0.14.54: + optional: true + + esbuild-darwin-64@0.14.54: + optional: true + + esbuild-darwin-arm64@0.14.54: + optional: true + + esbuild-freebsd-64@0.14.54: + optional: true + + esbuild-freebsd-arm64@0.14.54: + optional: true + + esbuild-linux-32@0.14.54: + optional: true + + esbuild-linux-64@0.14.54: + optional: true + + esbuild-linux-arm64@0.14.54: + optional: true + + esbuild-linux-arm@0.14.54: + optional: true + + esbuild-linux-mips64le@0.14.54: + optional: true + + esbuild-linux-ppc64le@0.14.54: + optional: true + + esbuild-linux-riscv64@0.14.54: + optional: true + + esbuild-linux-s390x@0.14.54: + optional: true + + esbuild-netbsd-64@0.14.54: + optional: true + + esbuild-openbsd-64@0.14.54: + optional: true + + esbuild-sunos-64@0.14.54: + optional: true + + esbuild-windows-32@0.14.54: + optional: true + + esbuild-windows-64@0.14.54: + optional: true + + esbuild-windows-arm64@0.14.54: + optional: true + + esbuild@0.14.54: + optionalDependencies: + '@esbuild/linux-loong64': 0.14.54 + esbuild-android-64: 0.14.54 + esbuild-android-arm64: 0.14.54 + esbuild-darwin-64: 0.14.54 + esbuild-darwin-arm64: 0.14.54 + esbuild-freebsd-64: 0.14.54 + esbuild-freebsd-arm64: 0.14.54 + esbuild-linux-32: 0.14.54 + esbuild-linux-64: 0.14.54 + esbuild-linux-arm: 0.14.54 + esbuild-linux-arm64: 0.14.54 + esbuild-linux-mips64le: 0.14.54 + esbuild-linux-ppc64le: 0.14.54 + esbuild-linux-riscv64: 0.14.54 + esbuild-linux-s390x: 0.14.54 + esbuild-netbsd-64: 0.14.54 + esbuild-openbsd-64: 0.14.54 + esbuild-sunos-64: 0.14.54 + esbuild-windows-32: 0.14.54 + esbuild-windows-64: 0.14.54 + esbuild-windows-arm64: 0.14.54 + + escape-html@1.0.3: {} + + etag@1.8.1: {} + + express-rate-limit@6.11.2(express@4.19.2): + dependencies: + express: 4.19.2 + + express@4.19.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.2 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.6.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + ffmpeg-static@5.2.0: + dependencies: + '@derhuerst/http-basic': 8.2.4 + env-paths: 2.2.1 + https-proxy-agent: 5.0.1 + progress: 2.0.3 + transitivePeerDependencies: + - supports-color + + finalhandler@1.2.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + forwarded@0.2.0: {} + + freebind@0.2.2: + dependencies: + ipaddr.js: 2.1.0 + syscall-napi: 0.0.6 + undici: 5.28.4 + optional: true + + fresh@0.5.2: {} + + function-bind@1.1.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hls-parser@0.10.9: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-response-object@3.0.2: + dependencies: + '@types/node': 10.17.60 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.1.0: {} + + jintr@2.1.1: + dependencies: + acorn: 8.12.1 + + media-typer@0.3.0: {} + + merge-descriptors@1.0.1: {} + + methods@1.1.2: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + nanoid@4.0.2: {} + + negotiator@0.6.3: {} + + node-cache@5.1.2: + dependencies: + clone: 2.1.2 + + object-assign@4.1.1: {} + + object-inspect@1.13.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + parse-cache-control@1.0.1: {} + + parseurl@1.3.3: {} + + path-to-regexp@0.1.7: {} + + progress@2.0.3: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + psl@1.9.0: {} + + qs@6.11.0: + dependencies: + side-channel: 1.0.6 + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + send@0.18.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.15.0: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + set-cookie-parser@2.6.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + statuses@2.0.1: {} + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + syscall-napi@0.0.6: + optional: true + + toidentifier@1.0.1: {} + + tslib@2.6.3: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typedarray@0.0.6: {} + + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + + unpipe@1.0.0: {} + + url-pattern@1.0.3: {} + + util-deprecate@1.0.2: {} + + utils-merge@1.0.1: {} + + vary@1.1.2: {} + + youtubei.js@10.3.0: + dependencies: + jintr: 2.1.1 + tslib: 2.6.3 + undici: 5.28.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..d24178b3 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "api" From 4f877f199b8dd19c2b3b1da325c8d66ca2430538 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 21:03:25 +0600 Subject: [PATCH 338/775] web: add to pnpm workspace and move lock to pnpm --- pnpm-lock.yaml | 2299 ++++++++++++++++++++++++++ pnpm-workspace.yaml | 1 + web/package-lock.json | 3594 ----------------------------------------- 3 files changed, 2300 insertions(+), 3594 deletions(-) delete mode 100644 web/package-lock.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5cf6edac..cda1121c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,29 +61,527 @@ importers: specifier: ^0.2.2 version: 0.2.2 + web: + dependencies: + '@fontsource-variable/noto-sans-mono': + specifier: ^5.0.20 + version: 5.0.20 + '@fontsource/ibm-plex-mono': + specifier: ^5.0.13 + version: 5.0.13 + '@tabler/icons-svelte': + specifier: 3.6.0 + version: 3.6.0(svelte@4.2.18) + sveltekit-i18n: + specifier: ^2.4.2 + version: 2.4.2(svelte@4.2.18) + ts-deepmerge: + specifier: ^7.0.0 + version: 7.0.1 + devDependencies: + '@eslint/js': + specifier: ^9.5.0 + version: 9.8.0 + '@sveltejs/adapter-static': + specifier: ^3.0.2 + version: 3.0.2(@sveltejs/kit@2.5.19(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14))) + '@sveltejs/kit': + specifier: ^2.0.0 + version: 2.5.19(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)) + '@sveltejs/vite-plugin-svelte': + specifier: ^3.0.0 + version: 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)) + '@types/eslint__js': + specifier: ^8.42.3 + version: 8.42.3 + '@types/node': + specifier: ^20.14.10 + version: 20.14.14 + compare-versions: + specifier: ^6.1.0 + version: 6.1.1 + eslint: + specifier: ^8.57.0 + version: 8.57.0 + mdsvex: + specifier: ^0.11.2 + version: 0.11.2(svelte@4.2.18) + svelte: + specifier: ^4.2.7 + version: 4.2.18 + svelte-check: + specifier: ^3.6.0 + version: 3.8.5(postcss@8.4.40)(svelte@4.2.18) + svelte-preprocess: + specifier: ^6.0.2 + version: 6.0.2(postcss@8.4.40)(svelte@4.2.18)(typescript@5.5.4) + tslib: + specifier: ^2.4.1 + version: 2.6.3 + typescript: + specifier: ^5.4.5 + version: 5.5.4 + typescript-eslint: + specifier: ^7.13.1 + version: 7.18.0(eslint@8.57.0)(typescript@5.5.4) + vite: + specifier: ^5.0.3 + version: 5.3.5(@types/node@20.14.14) + packages: + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + '@derhuerst/http-basic@8.2.4': resolution: {integrity: sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==} engines: {node: '>=6.0.0'} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.14.54': resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@9.8.0': + resolution: {integrity: sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@fastify/busboy@2.1.1': resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} + '@fontsource-variable/noto-sans-mono@5.0.20': + resolution: {integrity: sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==} + + '@fontsource/ibm-plex-mono@5.0.13': + resolution: {integrity: sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@polka/url@1.0.0-next.25': + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + + '@rollup/rollup-android-arm-eabi@4.19.2': + resolution: {integrity: sha512-OHflWINKtoCFSpm/WmuQaWW4jeX+3Qt3XQDepkkiFTsoxFc5BpF3Z5aDxFZgBqRjO6ATP5+b1iilp4kGIZVWlA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.19.2': + resolution: {integrity: sha512-k0OC/b14rNzMLDOE6QMBCjDRm3fQOHAL8Ldc9bxEWvMo4Ty9RY6rWmGetNTWhPo+/+FNd1lsQYRd0/1OSix36A==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.19.2': + resolution: {integrity: sha512-IIARRgWCNWMTeQH+kr/gFTHJccKzwEaI0YSvtqkEBPj7AshElFq89TyreKNFAGh5frLfDCbodnq+Ye3dqGKPBw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.19.2': + resolution: {integrity: sha512-52udDMFDv54BTAdnw+KXNF45QCvcJOcYGl3vQkp4vARyrcdI/cXH8VXTEv/8QWfd6Fru8QQuw1b2uNersXOL0g==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.19.2': + resolution: {integrity: sha512-r+SI2t8srMPYZeoa1w0o/AfoVt9akI1ihgazGYPQGRilVAkuzMGiTtexNZkrPkQsyFrvqq/ni8f3zOnHw4hUbA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.19.2': + resolution: {integrity: sha512-+tYiL4QVjtI3KliKBGtUU7yhw0GMcJJuB9mLTCEauHEsqfk49gtUBXGtGP3h1LW8MbaTY6rSFIQV1XOBps1gBA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.19.2': + resolution: {integrity: sha512-OR5DcvZiYN75mXDNQQxlQPTv4D+uNCUsmSCSY2FolLf9W5I4DSoJyg7z9Ea3TjKfhPSGgMJiey1aWvlWuBzMtg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.19.2': + resolution: {integrity: sha512-Hw3jSfWdUSauEYFBSFIte6I8m6jOj+3vifLg8EU3lreWulAUpch4JBjDMtlKosrBzkr0kwKgL9iCfjA8L3geoA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.19.2': + resolution: {integrity: sha512-rhjvoPBhBwVnJRq/+hi2Q3EMiVF538/o9dBuj9TVLclo9DuONqt5xfWSaE6MYiFKpo/lFPJ/iSI72rYWw5Hc7w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.19.2': + resolution: {integrity: sha512-EAz6vjPwHHs2qOCnpQkw4xs14XJq84I81sDRGPEjKPFVPBw7fwvtwhVjcZR6SLydCv8zNK8YGFblKWd/vRmP8g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.19.2': + resolution: {integrity: sha512-IJSUX1xb8k/zN9j2I7B5Re6B0NNJDJ1+soezjNojhT8DEVeDNptq2jgycCOpRhyGj0+xBn7Cq+PK7Q+nd2hxLA==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.19.2': + resolution: {integrity: sha512-OgaToJ8jSxTpgGkZSkwKE+JQGihdcaqnyHEFOSAU45utQ+yLruE1dkonB2SDI8t375wOKgNn8pQvaWY9kPzxDQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.19.2': + resolution: {integrity: sha512-5V3mPpWkB066XZZBgSd1lwozBk7tmOkKtquyCJ6T4LN3mzKENXyBwWNQn8d0Ci81hvlBw5RoFgleVpL6aScLYg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.19.2': + resolution: {integrity: sha512-ayVstadfLeeXI9zUPiKRVT8qF55hm7hKa+0N1V6Vj+OTNFfKSoUxyZvzVvgtBxqSb5URQ8sK6fhwxr9/MLmxdA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.19.2': + resolution: {integrity: sha512-Mda7iG4fOLHNsPqjWSjANvNZYoW034yxgrndof0DwCy0D3FvTjeNo+HGE6oGWgvcLZNLlcp0hLEFcRs+UGsMLg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.19.2': + resolution: {integrity: sha512-DPi0ubYhSow/00YqmG1jWm3qt1F8aXziHc/UNy8bo9cpCacqhuWu+iSq/fp2SyEQK7iYTZ60fBU9cat3MXTjIQ==} + cpu: [x64] + os: [win32] + + '@sveltejs/adapter-static@3.0.2': + resolution: {integrity: sha512-/EBFydZDwfwFfFEuF1vzUseBoRziwKP7AoHAwv+Ot3M084sE/HTVBHf9mCmXfdM9ijprY5YEugZjleflncX5fQ==} + peerDependencies: + '@sveltejs/kit': ^2.0.0 + + '@sveltejs/kit@2.5.19': + resolution: {integrity: sha512-r/lah3nnYEZX1btlvpSy+Exkt1aWhmOP5pnCt+BBro+tZrh2Zci+26Xnm1fCBLLMeM5q7gHvWiS8c/UtrWjdvQ==} + engines: {node: '>=18.13'} + hasBin: true + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^3.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.3 + + '@sveltejs/vite-plugin-svelte-inspector@2.1.0': + resolution: {integrity: sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==} + engines: {node: ^18.0.0 || >=20} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^3.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 + + '@sveltejs/vite-plugin-svelte@3.1.1': + resolution: {integrity: sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==} + engines: {node: ^18.0.0 || >=20} + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 + + '@sveltekit-i18n/base@1.3.7': + resolution: {integrity: sha512-kg1kql1/ro/lIudwFiWrv949Q07gmweln87tflUZR51MNdXXzK4fiJQv5Mw50K/CdQ5BOk/dJ0WOH2vOtBI6yw==} + peerDependencies: + svelte: '>=3.49.0' + + '@sveltekit-i18n/parser-default@1.1.1': + resolution: {integrity: sha512-/gtzLlqm/sox7EoPKD56BxGZktK/syGc79EbJAPWY5KVitQD9SM0TP8yJCqDxTVPk7Lk0WJhrBGUE2Nn0f5M1w==} + + '@tabler/icons-svelte@3.6.0': + resolution: {integrity: sha512-phI61t81MlWhodATjvQQdqw8vTL0srSW6GsHzJmuhIMJGB4rwFzAXB2Ec4Pkz0vWFzVQgkeSE/AsiOLIUKWkxA==} + peerDependencies: + svelte: '>=3 <5' + + '@tabler/icons@3.6.0': + resolution: {integrity: sha512-Zv0Ofc64RCMpZ2F8CvsWAphrSjerx5hEErt/RMmE+W8r4E5l5Lizi+My9KbbZQ4NyAtrtrOX80OY1oROZrRzEA==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/eslint@9.6.0': + resolution: {integrity: sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==} + + '@types/eslint__js@8.42.3': + resolution: {integrity: sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/node@10.17.60': resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + '@types/node@20.14.14': + resolution: {integrity: sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==} + + '@types/pug@2.0.10': + resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==} + + '@types/unist@2.0.10': + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn@8.12.1: resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} engines: {node: '>=0.4.0'} @@ -93,13 +591,63 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -111,13 +659,41 @@ packages: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + clone@2.1.2: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} + code-red@1.0.4: + resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + concat-stream@2.0.0: resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} engines: {'0': node >= 6.0} @@ -144,6 +720,14 @@ packages: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -161,6 +745,13 @@ packages: supports-color: optional: true + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -169,10 +760,29 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + devalue@5.0.0: + resolution: {integrity: sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} @@ -196,6 +806,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es6-promise@3.3.1: + resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + esbuild-android-64@0.14.54: resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} engines: {node: '>=12'} @@ -321,9 +934,57 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + + esm-env@1.0.0: + resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} @@ -338,14 +999,49 @@ packages: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + ffmpeg-static@5.2.0: resolution: {integrity: sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA==} engines: {node: '>=16'} + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + finalhandler@1.2.0: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -357,6 +1053,14 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -364,9 +1068,45 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globalyzer@0.1.0: + resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -400,6 +1140,25 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -411,9 +1170,80 @@ packages: resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==} engines: {node: '>= 10'} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-reference@3.0.2: + resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jintr@2.1.1: resolution: {integrity: sha512-89cwX4ouogeDGOBsEVsVYsnWWvWjchmwXBB4kiBhmjOKw19FiOKhNhMhpxhTlK2ctl7DS+d/ethfmuBpzoNNgA==} + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + mdsvex@0.11.2: + resolution: {integrity: sha512-Y4ab+vLvTJS88196Scb/RFNaHMHVSWw6CwfsgWIQP8f42D57iDII0/qABSu530V4pkv8s6T2nx3ds0MC1VwFLA==} + peerDependencies: + svelte: ^3.56.0 || ^4.0.0 || ^5.0.0-next.120 + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -421,10 +1251,18 @@ packages: merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -438,6 +1276,32 @@ packages: engines: {node: '>=4'} hasBin: true + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -447,11 +1311,19 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + nanoid@4.0.2: resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} engines: {node: ^14 || ^16 || >=18} hasBin: true + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -460,6 +1332,10 @@ packages: resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==} engines: {node: '>= 8.0.0'} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -472,6 +1348,25 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + parse-cache-control@1.0.1: resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} @@ -479,9 +1374,50 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + periscopic@3.1.0: + resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + postcss@8.4.40: + resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prism-svelte@0.4.7: + resolution: {integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==} + + prismjs@1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -493,10 +1429,17 @@ packages: psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -509,12 +1452,54 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup@4.19.2: + resolution: {integrity: sha512-6/jgnN1svF9PjNYJ4ya3l+cqutg49vOZ4rVgsDKxdl+5gpGPnByFXWGyfH9YGx9i3nfBwSu1Iyu6vGwFFA0BdQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sander@0.5.1: + resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} @@ -533,10 +1518,34 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + sorcery@0.11.1: + resolution: {integrity: sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==} + hasBin: true + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -544,16 +1553,159 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + svelte-check@3.8.5: + resolution: {integrity: sha512-3OGGgr9+bJ/+1nbPgsvulkLC48xBsqsgtc8Wam281H4G9F5v3mYGa2bHRsPuwHC5brKl4AxJH95QF73kmfihGQ==} + hasBin: true + peerDependencies: + svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0 + + svelte-hmr@0.16.0: + resolution: {integrity: sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: ^3.19.0 || ^4.0.0 + + svelte-preprocess@5.1.4: + resolution: {integrity: sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==} + engines: {node: '>= 16.0.0'} + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 + svelte: ^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0 + typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0' + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + + svelte-preprocess@6.0.2: + resolution: {integrity: sha512-OvDTLfaOkkhjprbDKO0SOCkjNYuHy16dbD4SpqbIi6QiabOMHxRT4km5/dzbFFkmW1L0E2INF3MFltG2pgOyKQ==} + engines: {node: '>= 18.0.0'} + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + postcss: ^7 || ^8 + postcss-load-config: '>=3' + pug: ^3.0.0 + sass: ^1.26.8 + stylus: '>=0.55' + sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.100 || ^5.0.0 + typescript: ^5.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + + svelte@4.2.18: + resolution: {integrity: sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==} + engines: {node: '>=16'} + + sveltekit-i18n@2.4.2: + resolution: {integrity: sha512-hjRWn4V4DBL8JQKJoJa3MRvn6d32Zo+rWkoSP5bsQ/XIAguPdQUZJ8LMe6Nc1rST8WEVdu9+vZI3aFdKYGR3+Q==} + peerDependencies: + svelte: '>=3.49.0' + syscall-napi@0.0.6: resolution: {integrity: sha512-qHbwjyFXAAekKUXxl70lhDiBYJ3e7XM7kQwu7LV3F0pHMenKox+VcZPZkRkhdmL/wNJD3NmrMGnL7161kdecUQ==} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + tiny-glob@0.2.9: + resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-deepmerge@7.0.1: + resolution: {integrity: sha512-JBFCmNenZdUCc+TRNCtXVM6N8y/nDQHAcpj5BlwXG/gnogjam1NunulB9ia68mnqYI446giMfpqeBFFkOleh+g==} + engines: {node: '>=14.13.1'} + tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -561,14 +1713,38 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + typescript-eslint@7.18.0: + resolution: {integrity: sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-pattern@1.0.3: resolution: {integrity: sha512-uQcEj/2puA4aq1R3A2+VNVBgaWYR24FdWjl7VNW83rnWftlhyzOZ/tBjezRiC2UkIzuxC8Top3IekN3vUf1WxA==} engines: {node: '>=0.12.0'} @@ -584,11 +1760,71 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vfile-message@2.0.4: + resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + + vite@5.3.5: + resolution: {integrity: sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitefu@0.2.5: + resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + vite: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + youtubei.js@10.3.0: resolution: {integrity: sha512-tLmeJCECK2xF2hZZtF2nEqirdKVNLFSDpa0LhTaXY3tngtL7doQXyy7M2CLueramDTlmCnFaW+rctHirTPFaRQ==} snapshots: + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + '@derhuerst/http-basic@8.2.4': dependencies: caseless: 0.12.0 @@ -596,18 +1832,375 @@ snapshots: http-response-object: 3.0.2 parse-cache-control: 1.0.1 + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-loong64@0.14.54': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.0': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.6 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@eslint/js@9.8.0': {} + '@fastify/busboy@2.1.1': {} + '@fontsource-variable/noto-sans-mono@5.0.20': {} + + '@fontsource/ibm-plex-mono@5.0.13': {} + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.6 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@polka/url@1.0.0-next.25': {} + + '@rollup/rollup-android-arm-eabi@4.19.2': + optional: true + + '@rollup/rollup-android-arm64@4.19.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.19.2': + optional: true + + '@rollup/rollup-darwin-x64@4.19.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.19.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.19.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.19.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.19.2': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.19.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.19.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.19.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.19.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.19.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.19.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.19.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.19.2': + optional: true + + '@sveltejs/adapter-static@3.0.2(@sveltejs/kit@2.5.19(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))': + dependencies: + '@sveltejs/kit': 2.5.19(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)) + + '@sveltejs/kit@2.5.19(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14))': + dependencies: + '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)) + '@types/cookie': 0.6.0 + cookie: 0.6.0 + devalue: 5.0.0 + esm-env: 1.0.0 + import-meta-resolve: 4.1.0 + kleur: 4.1.5 + magic-string: 0.30.11 + mrmime: 2.0.0 + sade: 1.8.1 + set-cookie-parser: 2.6.0 + sirv: 2.0.4 + svelte: 4.2.18 + tiny-glob: 0.2.9 + vite: 5.3.5(@types/node@20.14.14) + + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14))': + dependencies: + '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)) + debug: 4.3.6 + svelte: 4.2.18 + vite: 5.3.5(@types/node@20.14.14) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)))(svelte@4.2.18)(vite@5.3.5(@types/node@20.14.14)) + debug: 4.3.6 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.11 + svelte: 4.2.18 + svelte-hmr: 0.16.0(svelte@4.2.18) + vite: 5.3.5(@types/node@20.14.14) + vitefu: 0.2.5(vite@5.3.5(@types/node@20.14.14)) + transitivePeerDependencies: + - supports-color + + '@sveltekit-i18n/base@1.3.7(svelte@4.2.18)': + dependencies: + svelte: 4.2.18 + + '@sveltekit-i18n/parser-default@1.1.1': {} + + '@tabler/icons-svelte@3.6.0(svelte@4.2.18)': + dependencies: + '@tabler/icons': 3.6.0 + svelte: 4.2.18 + + '@tabler/icons@3.6.0': {} + + '@types/cookie@0.6.0': {} + + '@types/eslint@9.6.0': + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + + '@types/eslint__js@8.42.3': + dependencies: + '@types/eslint': 9.6.0 + + '@types/estree@1.0.5': {} + + '@types/json-schema@7.0.15': {} + '@types/node@10.17.60': {} + '@types/node@20.14.14': + dependencies: + undici-types: 5.26.5 + + '@types/pug@2.0.10': {} + + '@types/unist@2.0.10': {} + + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.6 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + debug: 4.3.6 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.18.0': {} + + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.6 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + accepts@1.3.8: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 + acorn-jsx@5.3.2(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + acorn@8.12.1: {} agent-base@6.0.2: @@ -616,8 +2209,40 @@ snapshots: transitivePeerDependencies: - supports-color + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + array-flatten@1.1.1: {} + array-union@2.1.0: {} + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + body-parser@1.20.2: dependencies: bytes: 3.1.2 @@ -635,6 +2260,21 @@ snapshots: transitivePeerDependencies: - supports-color + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + buffer-crc32@1.0.0: {} + buffer-from@1.1.2: {} bytes@3.1.2: {} @@ -647,10 +2287,47 @@ snapshots: get-intrinsic: 1.2.4 set-function-length: 1.2.2 + callsites@3.1.0: {} + caseless@0.12.0: {} + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + clone@2.1.2: {} + code-red@1.0.4: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + '@types/estree': 1.0.5 + acorn: 8.12.1 + estree-walker: 3.0.3 + periscopic: 3.1.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + compare-versions@6.1.1: {} + + concat-map@0.0.1: {} + concat-stream@2.0.0: dependencies: buffer-from: 1.1.2 @@ -675,6 +2352,17 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.0 + debug@2.6.9: dependencies: ms: 2.0.0 @@ -683,6 +2371,10 @@ snapshots: dependencies: ms: 2.1.2 + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 @@ -691,8 +2383,22 @@ snapshots: depd@2.0.0: {} + dequal@2.0.3: {} + destroy@1.2.0: {} + detect-indent@6.1.0: {} + + devalue@5.0.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + dotenv@16.4.5: {} ee-first@1.1.1: {} @@ -707,6 +2413,8 @@ snapshots: es-errors@1.3.0: {} + es6-promise@3.3.1: {} + esbuild-android-64@0.14.54: optional: true @@ -791,8 +2499,110 @@ snapshots: esbuild-windows-64: 0.14.54 esbuild-windows-arm64: 0.14.54 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + escape-html@1.0.3: {} + escape-string-regexp@4.0.0: {} + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.6 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + esm-env@1.0.0: {} + + espree@9.6.1: + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 3.4.3 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + esutils@2.0.3: {} + etag@1.8.1: {} express-rate-limit@6.11.2(express@4.19.2): @@ -835,6 +2645,24 @@ snapshots: transitivePeerDependencies: - supports-color + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + ffmpeg-static@5.2.0: dependencies: '@derhuerst/http-basic': 8.2.4 @@ -844,6 +2672,14 @@ snapshots: transitivePeerDependencies: - supports-color + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + finalhandler@1.2.0: dependencies: debug: 2.6.9 @@ -856,6 +2692,19 @@ snapshots: transitivePeerDependencies: - supports-color + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.3.1: {} + forwarded@0.2.0: {} freebind@0.2.2: @@ -867,6 +2716,11 @@ snapshots: fresh@0.5.2: {} + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + function-bind@1.1.2: {} get-intrinsic@1.2.4: @@ -877,10 +2731,50 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globalyzer@0.1.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + globrex@0.1.2: {} + gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 @@ -918,22 +2812,108 @@ snapshots: dependencies: safer-buffer: 2.1.2 + ignore@5.3.1: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-meta-resolve@4.1.0: {} + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} ipaddr.js@1.9.1: {} ipaddr.js@2.1.0: {} + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-reference@3.0.2: + dependencies: + '@types/estree': 1.0.5 + + isexe@2.0.0: {} + jintr@2.1.1: dependencies: acorn: 8.12.1 + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-character@3.0.0: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + mdn-data@2.0.30: {} + + mdsvex@0.11.2(svelte@4.2.18): + dependencies: + '@types/unist': 2.0.10 + prism-svelte: 0.4.7 + prismjs: 1.29.0 + svelte: 4.2.18 + vfile-message: 2.0.4 + media-typer@0.3.0: {} merge-descriptors@1.0.1: {} + merge2@1.4.1: {} + methods@1.1.2: {} + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mime-db@1.52.0: {} mime-types@2.1.35: @@ -942,20 +2922,46 @@ snapshots: mime@1.6.0: {} + min-indent@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mri@1.2.0: {} + + mrmime@2.0.0: {} + ms@2.0.0: {} ms@2.1.2: {} ms@2.1.3: {} + nanoid@3.3.7: {} + nanoid@4.0.2: {} + natural-compare@1.4.0: {} + negotiator@0.6.3: {} node-cache@5.1.2: dependencies: clone: 2.1.2 + normalize-path@3.0.0: {} + object-assign@4.1.1: {} object-inspect@1.13.2: {} @@ -964,12 +2970,67 @@ snapshots: dependencies: ee-first: 1.1.1 + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + parse-cache-control@1.0.1: {} parseurl@1.3.3: {} + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + path-to-regexp@0.1.7: {} + path-type@4.0.0: {} + + periscopic@3.1.0: + dependencies: + '@types/estree': 1.0.5 + estree-walker: 3.0.3 + is-reference: 3.0.2 + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + postcss@8.4.40: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + prelude-ls@1.2.1: {} + + prism-svelte@0.4.7: {} + + prismjs@1.29.0: {} + progress@2.0.3: {} proxy-addr@2.0.7: @@ -979,10 +3040,14 @@ snapshots: psl@1.9.0: {} + punycode@2.3.1: {} + qs@6.11.0: dependencies: side-channel: 1.0.6 + queue-microtask@1.2.3: {} + range-parser@1.2.1: {} raw-body@2.5.2: @@ -998,10 +3063,65 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + resolve-from@4.0.0: {} + + reusify@1.0.4: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup@4.19.2: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.19.2 + '@rollup/rollup-android-arm64': 4.19.2 + '@rollup/rollup-darwin-arm64': 4.19.2 + '@rollup/rollup-darwin-x64': 4.19.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.19.2 + '@rollup/rollup-linux-arm-musleabihf': 4.19.2 + '@rollup/rollup-linux-arm64-gnu': 4.19.2 + '@rollup/rollup-linux-arm64-musl': 4.19.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.19.2 + '@rollup/rollup-linux-riscv64-gnu': 4.19.2 + '@rollup/rollup-linux-s390x-gnu': 4.19.2 + '@rollup/rollup-linux-x64-gnu': 4.19.2 + '@rollup/rollup-linux-x64-musl': 4.19.2 + '@rollup/rollup-win32-arm64-msvc': 4.19.2 + '@rollup/rollup-win32-ia32-msvc': 4.19.2 + '@rollup/rollup-win32-x64-msvc': 4.19.2 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} + sander@0.5.1: + dependencies: + es6-promise: 3.3.1 + graceful-fs: 4.2.11 + mkdirp: 0.5.6 + rimraf: 2.7.1 + + semver@7.6.3: {} + send@0.18.0: dependencies: debug: 2.6.9 @@ -1042,6 +3162,12 @@ snapshots: setprototypeof@1.2.0: {} + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + side-channel@1.0.6: dependencies: call-bind: 1.0.7 @@ -1049,19 +3175,141 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.2 + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + + slash@3.0.0: {} + + sorcery@0.11.1: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + buffer-crc32: 1.0.0 + minimist: 1.2.8 + sander: 0.5.1 + + source-map-js@1.2.0: {} + statuses@2.0.1: {} string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + svelte-check@3.8.5(postcss@8.4.40)(svelte@4.2.18): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + chokidar: 3.6.0 + picocolors: 1.0.1 + sade: 1.8.1 + svelte: 4.2.18 + svelte-preprocess: 5.1.4(postcss@8.4.40)(svelte@4.2.18)(typescript@5.5.4) + typescript: 5.5.4 + transitivePeerDependencies: + - '@babel/core' + - coffeescript + - less + - postcss + - postcss-load-config + - pug + - sass + - stylus + - sugarss + + svelte-hmr@0.16.0(svelte@4.2.18): + dependencies: + svelte: 4.2.18 + + svelte-preprocess@5.1.4(postcss@8.4.40)(svelte@4.2.18)(typescript@5.5.4): + dependencies: + '@types/pug': 2.0.10 + detect-indent: 6.1.0 + magic-string: 0.30.11 + sorcery: 0.11.1 + strip-indent: 3.0.0 + svelte: 4.2.18 + optionalDependencies: + postcss: 8.4.40 + typescript: 5.5.4 + + svelte-preprocess@6.0.2(postcss@8.4.40)(svelte@4.2.18)(typescript@5.5.4): + dependencies: + svelte: 4.2.18 + optionalDependencies: + postcss: 8.4.40 + typescript: 5.5.4 + + svelte@4.2.18: + dependencies: + '@ampproject/remapping': 2.3.0 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + '@types/estree': 1.0.5 + acorn: 8.12.1 + aria-query: 5.3.0 + axobject-query: 4.1.0 + code-red: 1.0.4 + css-tree: 2.3.1 + estree-walker: 3.0.3 + is-reference: 3.0.2 + locate-character: 3.0.0 + magic-string: 0.30.11 + periscopic: 3.1.0 + + sveltekit-i18n@2.4.2(svelte@4.2.18): + dependencies: + '@sveltekit-i18n/base': 1.3.7(svelte@4.2.18) + '@sveltekit-i18n/parser-default': 1.1.1 + svelte: 4.2.18 + syscall-napi@0.0.6: optional: true + text-table@0.2.0: {} + + tiny-glob@0.2.9: + dependencies: + globalyzer: 0.1.0 + globrex: 0.1.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + toidentifier@1.0.1: {} + totalist@3.0.1: {} + + ts-api-utils@1.3.0(typescript@5.5.4): + dependencies: + typescript: 5.5.4 + + ts-deepmerge@7.0.1: {} + tslib@2.6.3: {} + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -1069,12 +3317,35 @@ snapshots: typedarray@0.0.6: {} + typescript-eslint@7.18.0(eslint@8.57.0)(typescript@5.5.4): + dependencies: + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + eslint: 8.57.0 + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + typescript@5.5.4: {} + + undici-types@5.26.5: {} + undici@5.28.4: dependencies: '@fastify/busboy': 2.1.1 + unist-util-stringify-position@2.0.3: + dependencies: + '@types/unist': 2.0.10 + unpipe@1.0.0: {} + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + url-pattern@1.0.3: {} util-deprecate@1.0.2: {} @@ -1083,6 +3354,34 @@ snapshots: vary@1.1.2: {} + vfile-message@2.0.4: + dependencies: + '@types/unist': 2.0.10 + unist-util-stringify-position: 2.0.3 + + vite@5.3.5(@types/node@20.14.14): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.40 + rollup: 4.19.2 + optionalDependencies: + '@types/node': 20.14.14 + fsevents: 2.3.3 + + vitefu@0.2.5(vite@5.3.5(@types/node@20.14.14)): + optionalDependencies: + vite: 5.3.5(@types/node@20.14.14) + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + yocto-queue@0.1.0: {} + youtubei.js@10.3.0: dependencies: jintr: 2.1.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d24178b3..8c71ee3e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - "api" + - "web" diff --git a/web/package-lock.json b/web/package-lock.json deleted file mode 100644 index 774a7bf7..00000000 --- a/web/package-lock.json +++ /dev/null @@ -1,3594 +0,0 @@ -{ - "name": "cobalt-web", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "cobalt-web", - "version": "0.0.1", - "license": "CC-BY-NC-SA-4.0", - "dependencies": { - "@fontsource-variable/noto-sans-mono": "^5.0.20", - "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "3.6.0", - "sveltekit-i18n": "^2.4.2", - "ts-deepmerge": "^7.0.0" - }, - "devDependencies": { - "@eslint/js": "^9.5.0", - "@sveltejs/adapter-static": "^3.0.2", - "@sveltejs/kit": "^2.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "@types/eslint__js": "^8.42.3", - "@types/node": "^20.14.10", - "compare-versions": "^6.1.0", - "eslint": "^8.57.0", - "mdsvex": "^0.11.2", - "svelte": "^4.2.7", - "svelte-check": "^3.6.0", - "svelte-preprocess": "^6.0.2", - "tslib": "^2.4.1", - "typescript": "^5.4.5", - "typescript-eslint": "^7.13.1", - "vite": "^5.0.3" - }, - "engines": { - "node": ">=20.9", - "npm": ">=9" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.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" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", - "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@fontsource-variable/noto-sans-mono": { - "version": "5.0.20", - "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz", - "integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==", - "license": "OFL-1.1" - }, - "node_modules/@fontsource/ibm-plex-mono": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", - "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==", - "license": "OFL-1.1" - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.25", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", - "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", - "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", - "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", - "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", - "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", - "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", - "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", - "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", - "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", - "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", - "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", - "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", - "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", - "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", - "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", - "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", - "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sveltejs/adapter-static": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", - "integrity": "sha512-/EBFydZDwfwFfFEuF1vzUseBoRziwKP7AoHAwv+Ot3M084sE/HTVBHf9mCmXfdM9ijprY5YEugZjleflncX5fQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, - "node_modules/@sveltejs/kit": { - "version": "2.5.18", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.18.tgz", - "integrity": "sha512-+g06hvpVAnH7b4CDjhnTDgFWBKBiQJpuSmQeGYOuzbO3SC3tdYjRNlDCrafvDtKbGiT2uxY5Dn9qdEUGVZdWOQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@types/cookie": "^0.6.0", - "cookie": "^0.6.0", - "devalue": "^5.0.0", - "esm-env": "^1.0.0", - "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": "^2.0.4", - "tiny-glob": "^0.2.9" - }, - "bin": { - "svelte-kit": "svelte-kit.js" - }, - "engines": { - "node": ">=18.13" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", - "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", - "debug": "^4.3.4", - "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.10", - "svelte-hmr": "^0.16.0", - "vitefu": "^0.2.5" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", - "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@sveltekit-i18n/base": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@sveltekit-i18n/base/-/base-1.3.7.tgz", - "integrity": "sha512-kg1kql1/ro/lIudwFiWrv949Q07gmweln87tflUZR51MNdXXzK4fiJQv5Mw50K/CdQ5BOk/dJ0WOH2vOtBI6yw==", - "license": "MIT", - "peerDependencies": { - "svelte": ">=3.49.0" - } - }, - "node_modules/@sveltekit-i18n/parser-default": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@sveltekit-i18n/parser-default/-/parser-default-1.1.1.tgz", - "integrity": "sha512-/gtzLlqm/sox7EoPKD56BxGZktK/syGc79EbJAPWY5KVitQD9SM0TP8yJCqDxTVPk7Lk0WJhrBGUE2Nn0f5M1w==", - "license": "MIT" - }, - "node_modules/@tabler/icons": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.6.0.tgz", - "integrity": "sha512-Zv0Ofc64RCMpZ2F8CvsWAphrSjerx5hEErt/RMmE+W8r4E5l5Lizi+My9KbbZQ4NyAtrtrOX80OY1oROZrRzEA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/codecalm" - } - }, - "node_modules/@tabler/icons-svelte": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@tabler/icons-svelte/-/icons-svelte-3.6.0.tgz", - "integrity": "sha512-phI61t81MlWhodATjvQQdqw8vTL0srSW6GsHzJmuhIMJGB4rwFzAXB2Ec4Pkz0vWFzVQgkeSE/AsiOLIUKWkxA==", - "license": "MIT", - "dependencies": { - "@tabler/icons": "3.6.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/codecalm" - }, - "peerDependencies": { - "svelte": ">=3 <5" - } - }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint__js": { - "version": "8.42.3", - "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", - "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/pug": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", - "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", - "dev": true - }, - "node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", - "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/type-utils": "7.16.1", - "@typescript-eslint/utils": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", - "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", - "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/utils": "7.16.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-crc32": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", - "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/compare-versions": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", - "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/devalue": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", - "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/esm-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", - "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true, - "license": "MIT" - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-character": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "license": "CC0-1.0" - }, - "node_modules/mdsvex": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.11.2.tgz", - "integrity": "sha512-Y4ab+vLvTJS88196Scb/RFNaHMHVSWw6CwfsgWIQP8f42D57iDII0/qABSu530V4pkv8s6T2nx3ds0MC1VwFLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.3", - "prism-svelte": "^0.4.7", - "prismjs": "^1.17.1", - "vfile-message": "^2.0.4" - }, - "peerDependencies": { - "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prism-svelte": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz", - "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", - "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.1", - "@rollup/rollup-android-arm64": "4.18.1", - "@rollup/rollup-darwin-arm64": "4.18.1", - "@rollup/rollup-darwin-x64": "4.18.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", - "@rollup/rollup-linux-arm-musleabihf": "4.18.1", - "@rollup/rollup-linux-arm64-gnu": "4.18.1", - "@rollup/rollup-linux-arm64-musl": "4.18.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", - "@rollup/rollup-linux-riscv64-gnu": "4.18.1", - "@rollup/rollup-linux-s390x-gnu": "4.18.1", - "@rollup/rollup-linux-x64-gnu": "4.18.1", - "@rollup/rollup-linux-x64-musl": "4.18.1", - "@rollup/rollup-win32-arm64-msvc": "4.18.1", - "@rollup/rollup-win32-ia32-msvc": "4.18.1", - "@rollup/rollup-win32-x64-msvc": "4.18.1", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sander": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", - "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", - "dev": true, - "dependencies": { - "es6-promise": "^3.1.2", - "graceful-fs": "^4.1.3", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2" - } - }, - "node_modules/sander/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", - "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/sorcery": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", - "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.14", - "buffer-crc32": "^1.0.0", - "minimist": "^1.2.0", - "sander": "^0.5.0" - }, - "bin": { - "sorcery": "bin/sorcery" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/svelte": { - "version": "4.2.18", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", - "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", - "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/svelte-check": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.4.tgz", - "integrity": "sha512-61aHMkdinWyH8BkkTX9jPLYxYzaAAz/FK/VQqdr2FiCQQ/q04WCwDlpGbHff1GdrMYTmW8chlTFvRWL9k0A8vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "chokidar": "^3.4.1", - "picocolors": "^1.0.0", - "sade": "^1.7.4", - "svelte-preprocess": "^5.1.3", - "typescript": "^5.0.3" - }, - "bin": { - "svelte-check": "bin/svelte-check" - }, - "peerDependencies": { - "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" - } - }, - "node_modules/svelte-check/node_modules/svelte-preprocess": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", - "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/pug": "^2.0.6", - "detect-indent": "^6.1.0", - "magic-string": "^0.30.5", - "sorcery": "^0.11.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">= 16.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.10.2", - "coffeescript": "^2.5.1", - "less": "^3.11.3 || ^4.0.0", - "postcss": "^7 || ^8", - "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", - "pug": "^3.0.0", - "sass": "^1.26.8", - "stylus": "^0.55.0", - "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", - "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "coffeescript": { - "optional": true - }, - "less": { - "optional": true - }, - "postcss": { - "optional": true - }, - "postcss-load-config": { - "optional": true - }, - "pug": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/svelte-hmr": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", - "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^12.20 || ^14.13.1 || >= 16" - }, - "peerDependencies": { - "svelte": "^3.19.0 || ^4.0.0" - } - }, - "node_modules/svelte-preprocess": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-6.0.2.tgz", - "integrity": "sha512-OvDTLfaOkkhjprbDKO0SOCkjNYuHy16dbD4SpqbIi6QiabOMHxRT4km5/dzbFFkmW1L0E2INF3MFltG2pgOyKQ==", - "dev": true, - "hasInstallScript": true, - "engines": { - "node": ">= 18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.10.2", - "coffeescript": "^2.5.1", - "less": "^3.11.3 || ^4.0.0", - "postcss": "^7 || ^8", - "postcss-load-config": ">=3", - "pug": "^3.0.0", - "sass": "^1.26.8", - "stylus": ">=0.55", - "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.100 || ^5.0.0", - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "coffeescript": { - "optional": true - }, - "less": { - "optional": true - }, - "postcss": { - "optional": true - }, - "postcss-load-config": { - "optional": true - }, - "pug": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/sveltekit-i18n": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/sveltekit-i18n/-/sveltekit-i18n-2.4.2.tgz", - "integrity": "sha512-hjRWn4V4DBL8JQKJoJa3MRvn6d32Zo+rWkoSP5bsQ/XIAguPdQUZJ8LMe6Nc1rST8WEVdu9+vZI3aFdKYGR3+Q==", - "license": "MIT", - "workspaces": [ - "./examples/*/" - ], - "dependencies": { - "@sveltekit-i18n/base": "~1.3.0", - "@sveltekit-i18n/parser-default": "~1.1.0" - }, - "peerDependencies": { - "svelte": ">=3.49.0" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/tiny-glob": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", - "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-deepmerge": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.1.tgz", - "integrity": "sha512-JBFCmNenZdUCc+TRNCtXVM6N8y/nDQHAcpj5BlwXG/gnogjam1NunulB9ia68mnqYI446giMfpqeBFFkOleh+g==", - "license": "ISC", - "engines": { - "node": ">=14.13.1" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true, - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz", - "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "7.16.1", - "@typescript-eslint/parser": "7.16.1", - "@typescript-eslint/utils": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true, - "license": "MIT" - }, - "node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", - "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vitefu": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", - "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} From ec98605336ede837276b80cbce3897f974c0da5d Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 21:16:04 +0600 Subject: [PATCH 339/775] git: update general gitignore & web gitignore --- .gitignore | 15 ++++++--------- web/.gitignore | 8 +++----- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index a7c47612..05a7c403 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,18 @@ -# os stuff +# OS directory info files .DS_Store desktop.ini -# npm +# node node_modules # secrets .env +.env.* +!.env.example +cookies.json # docker docker-compose.yml -# vscode +# ide .vscode - -# cookie file -cookies.json - -# page build -build diff --git a/web/.gitignore b/web/.gitignore index 6635cf55..52516b88 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -1,10 +1,8 @@ -.DS_Store -node_modules +# builds /build /.svelte-kit /package -.env -.env.* -!.env.example + +# vite vite.config.js.timestamp-* vite.config.ts.timestamp-* From eede972ace0583cfb47c1cf0cf71c23228fb7783 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 21:23:56 +0600 Subject: [PATCH 340/775] api: remove old frontend files --- api/src/core/web.js | 97 -- api/src/front/assets/meowbalt/error.png | Bin 15420 -> 0 bytes api/src/front/assets/meowbalt/question.png | Bin 21198 -> 0 bytes api/src/front/cobalt.css | 1265 ----------------- api/src/front/cobalt.js | 708 --------- api/src/front/emoji/3d/film_frames.png | Bin 8720 -> 0 bytes api/src/front/emoji/3d/headphone.png | Bin 11316 -> 0 bytes api/src/front/emoji/abacus.svg | 8 - api/src/front/emoji/alien_monster.svg | 9 - api/src/front/emoji/biceps.svg | 7 - api/src/front/emoji/bird.svg | 6 - api/src/front/emoji/boring_document.svg | 8 - api/src/front/emoji/bubbles.svg | 30 - api/src/front/emoji/cake.svg | 11 - api/src/front/emoji/candle.svg | 7 - api/src/front/emoji/cat.svg | 13 - api/src/front/emoji/cat_crying.svg | 14 - api/src/front/emoji/cat_flabbergasted.svg | 21 - api/src/front/emoji/cat_grin.svg | 13 - api/src/front/emoji/cat_smile.svg | 13 - api/src/front/emoji/christmas_tree.svg | 11 - api/src/front/emoji/clapper_board.svg | 13 - api/src/front/emoji/clipboard.svg | 11 - api/src/front/emoji/crystal_ball.svg | 7 - api/src/front/emoji/dog.svg | 11 - api/src/front/emoji/dragon_face.svg | 11 - api/src/front/emoji/dragon_face_wukko.svg | 11 - api/src/front/emoji/elephant.svg | 8 - api/src/front/emoji/email.svg | 9 - api/src/front/emoji/film_frames.svg | 4 - api/src/front/emoji/gear.svg | 5 - api/src/front/emoji/headphone.svg | 7 - api/src/front/emoji/keyboard.svg | 4 - api/src/front/emoji/link.svg | 4 - api/src/front/emoji/locked.svg | 5 - api/src/front/emoji/loudspeaker.svg | 6 - api/src/front/emoji/magic_wand.svg | 5 - api/src/front/emoji/magnifying_glass.svg | 5 - api/src/front/emoji/mailbox.svg | 12 - api/src/front/emoji/mending_heart.svg | 5 - api/src/front/emoji/money_with_wings.svg | 12 - api/src/front/emoji/musical_notes.svg | 5 - api/src/front/emoji/newspaper.svg | 5 - api/src/front/emoji/octopus.svg | 12 - api/src/front/emoji/party_popper.svg | 15 - api/src/front/emoji/pinata.svg | 16 - api/src/front/emoji/pumpkin.svg | 7 - api/src/front/emoji/question_mark.svg | 4 - api/src/front/emoji/sparkles.svg | 5 - api/src/front/emoji/sparkling_heart.svg | 5 - api/src/front/emoji/wrench.svg | 3 - .../front/fonts/files/notosansmono_3dVQ.woff2 | Bin 9292 -> 0 bytes .../fonts/files/notosansmono_7dVXQQ.woff2 | Bin 5912 -> 0 bytes .../fonts/files/notosansmono_DdVXQQ.woff2 | Bin 17708 -> 0 bytes .../fonts/files/notosansmono_HdVXQQ.woff2 | Bin 4460 -> 0 bytes .../fonts/files/notosansmono_LdVXQQ.woff2 | Bin 2592 -> 0 bytes .../fonts/files/notosansmono_PdVXQQ.woff2 | Bin 26380 -> 0 bytes .../fonts/files/notosansmono_ndVXQQ.woff2 | Bin 5272 -> 0 bytes api/src/front/fonts/notosansmono.css | 1 - .../front/icons/android-chrome-192x192.png | Bin 3580 -> 0 bytes .../front/icons/android-chrome-512x512.png | Bin 9818 -> 0 bytes api/src/front/icons/apple-touch-icon.png | Bin 3278 -> 0 bytes api/src/front/icons/favicon-16x16.png | Bin 215 -> 0 bytes api/src/front/icons/favicon-32x32.png | Bin 365 -> 0 bytes api/src/front/icons/favicon.ico | Bin 9662 -> 0 bytes api/src/front/icons/generic.png | Bin 9818 -> 0 bytes api/src/front/icons/maskable/128.png | Bin 815 -> 0 bytes api/src/front/icons/maskable/192.png | Bin 1014 -> 0 bytes api/src/front/icons/maskable/384.png | Bin 1856 -> 0 bytes api/src/front/icons/maskable/48.png | Bin 390 -> 0 bytes api/src/front/icons/maskable/512.png | Bin 2828 -> 0 bytes api/src/front/icons/maskable/72.png | Bin 569 -> 0 bytes api/src/front/icons/maskable/96.png | Bin 617 -> 0 bytes api/src/front/icons/pattern.png | Bin 91509 -> 0 bytes api/src/front/manifest.webmanifest | 75 - api/src/front/robots.txt | 8 - api/src/front/sponsors/royale.svg | 1 - api/src/modules/build.js | 41 - api/src/modules/buildStatic.js | 7 - api/src/modules/changelog/changelogManager.js | 46 - api/src/modules/emoji.js | 66 - api/src/modules/pageRender/elements.js | 270 ---- api/src/modules/pageRender/findRendered.js | 6 - api/src/modules/pageRender/onDemand.js | 33 - api/src/modules/pageRender/page.js | 666 --------- 85 files changed, 3693 deletions(-) delete mode 100644 api/src/core/web.js delete mode 100644 api/src/front/assets/meowbalt/error.png delete mode 100644 api/src/front/assets/meowbalt/question.png delete mode 100644 api/src/front/cobalt.css delete mode 100644 api/src/front/cobalt.js delete mode 100644 api/src/front/emoji/3d/film_frames.png delete mode 100644 api/src/front/emoji/3d/headphone.png delete mode 100644 api/src/front/emoji/abacus.svg delete mode 100644 api/src/front/emoji/alien_monster.svg delete mode 100644 api/src/front/emoji/biceps.svg delete mode 100644 api/src/front/emoji/bird.svg delete mode 100644 api/src/front/emoji/boring_document.svg delete mode 100644 api/src/front/emoji/bubbles.svg delete mode 100644 api/src/front/emoji/cake.svg delete mode 100644 api/src/front/emoji/candle.svg delete mode 100644 api/src/front/emoji/cat.svg delete mode 100644 api/src/front/emoji/cat_crying.svg delete mode 100644 api/src/front/emoji/cat_flabbergasted.svg delete mode 100644 api/src/front/emoji/cat_grin.svg delete mode 100644 api/src/front/emoji/cat_smile.svg delete mode 100644 api/src/front/emoji/christmas_tree.svg delete mode 100644 api/src/front/emoji/clapper_board.svg delete mode 100644 api/src/front/emoji/clipboard.svg delete mode 100644 api/src/front/emoji/crystal_ball.svg delete mode 100644 api/src/front/emoji/dog.svg delete mode 100644 api/src/front/emoji/dragon_face.svg delete mode 100644 api/src/front/emoji/dragon_face_wukko.svg delete mode 100644 api/src/front/emoji/elephant.svg delete mode 100644 api/src/front/emoji/email.svg delete mode 100644 api/src/front/emoji/film_frames.svg delete mode 100644 api/src/front/emoji/gear.svg delete mode 100644 api/src/front/emoji/headphone.svg delete mode 100644 api/src/front/emoji/keyboard.svg delete mode 100644 api/src/front/emoji/link.svg delete mode 100644 api/src/front/emoji/locked.svg delete mode 100644 api/src/front/emoji/loudspeaker.svg delete mode 100644 api/src/front/emoji/magic_wand.svg delete mode 100644 api/src/front/emoji/magnifying_glass.svg delete mode 100644 api/src/front/emoji/mailbox.svg delete mode 100644 api/src/front/emoji/mending_heart.svg delete mode 100644 api/src/front/emoji/money_with_wings.svg delete mode 100644 api/src/front/emoji/musical_notes.svg delete mode 100644 api/src/front/emoji/newspaper.svg delete mode 100644 api/src/front/emoji/octopus.svg delete mode 100644 api/src/front/emoji/party_popper.svg delete mode 100644 api/src/front/emoji/pinata.svg delete mode 100644 api/src/front/emoji/pumpkin.svg delete mode 100644 api/src/front/emoji/question_mark.svg delete mode 100644 api/src/front/emoji/sparkles.svg delete mode 100644 api/src/front/emoji/sparkling_heart.svg delete mode 100644 api/src/front/emoji/wrench.svg delete mode 100644 api/src/front/fonts/files/notosansmono_3dVQ.woff2 delete mode 100644 api/src/front/fonts/files/notosansmono_7dVXQQ.woff2 delete mode 100644 api/src/front/fonts/files/notosansmono_DdVXQQ.woff2 delete mode 100644 api/src/front/fonts/files/notosansmono_HdVXQQ.woff2 delete mode 100644 api/src/front/fonts/files/notosansmono_LdVXQQ.woff2 delete mode 100644 api/src/front/fonts/files/notosansmono_PdVXQQ.woff2 delete mode 100644 api/src/front/fonts/files/notosansmono_ndVXQQ.woff2 delete mode 100644 api/src/front/fonts/notosansmono.css delete mode 100644 api/src/front/icons/android-chrome-192x192.png delete mode 100644 api/src/front/icons/android-chrome-512x512.png delete mode 100644 api/src/front/icons/apple-touch-icon.png delete mode 100644 api/src/front/icons/favicon-16x16.png delete mode 100644 api/src/front/icons/favicon-32x32.png delete mode 100644 api/src/front/icons/favicon.ico delete mode 100644 api/src/front/icons/generic.png delete mode 100644 api/src/front/icons/maskable/128.png delete mode 100644 api/src/front/icons/maskable/192.png delete mode 100644 api/src/front/icons/maskable/384.png delete mode 100644 api/src/front/icons/maskable/48.png delete mode 100644 api/src/front/icons/maskable/512.png delete mode 100644 api/src/front/icons/maskable/72.png delete mode 100644 api/src/front/icons/maskable/96.png delete mode 100644 api/src/front/icons/pattern.png delete mode 100644 api/src/front/manifest.webmanifest delete mode 100644 api/src/front/robots.txt delete mode 100644 api/src/front/sponsors/royale.svg delete mode 100644 api/src/modules/build.js delete mode 100644 api/src/modules/buildStatic.js delete mode 100644 api/src/modules/changelog/changelogManager.js delete mode 100644 api/src/modules/emoji.js delete mode 100644 api/src/modules/pageRender/elements.js delete mode 100644 api/src/modules/pageRender/findRendered.js delete mode 100644 api/src/modules/pageRender/onDemand.js delete mode 100644 api/src/modules/pageRender/page.js diff --git a/api/src/core/web.js b/api/src/core/web.js deleted file mode 100644 index d892c56c..00000000 --- a/api/src/core/web.js +++ /dev/null @@ -1,97 +0,0 @@ - -import { Bright, Cyan } from "../modules/sub/consoleText.js"; -import { languageCode } from "../modules/sub/utils.js"; -import { version, env } from "../modules/config.js"; - -import { buildFront } from "../modules/build.js"; -import findRendered from "../modules/pageRender/findRendered.js"; - -import { celebrationsEmoji } from "../modules/pageRender/elements.js"; -import { changelogHistory } from "../modules/pageRender/onDemand.js"; -import { createResponse } from "../modules/processing/request.js"; - -export async function runWeb(express, app, gitCommit, gitBranch, __dirname) { - const startTime = new Date(); - const startTimestamp = Math.floor(startTime.getTime()); - - await buildFront(gitCommit, gitBranch); - - app.use('/', express.static('./build/min')); - app.use('/', express.static('./src/front')); - - app.use((req, res, next) => { - try { decodeURIComponent(req.path) } catch (e) { return res.redirect('/') } - next(); - }) - - app.get('/onDemand', (req, res) => { - try { - if (typeof req.query.blockId !== 'string') { - return res.status(400).json({ - status: "error", - text: "couldn't render this block, please try again!" - }); - } - - let blockId = req.query.blockId.slice(0, 3); - let blockData; - switch(blockId) { - // changelog history - case "0": - let history = changelogHistory(); - if (history) { - blockData = createResponse("success", { t: history }) - } else { - blockData = createResponse("error", { - t: "couldn't render this block, please try again!" - }) - } - break; - // celebrations emoji - case "1": - let celebration = celebrationsEmoji(); - if (celebration) { - blockData = createResponse("success", { t: celebration }) - } - break; - default: - blockData = createResponse("error", { - t: "couldn't find a block with this id" - }) - break; - } - - if (blockData?.body) { - return res.status(blockData.status).json(blockData.body); - } else { - return res.status(204).end(); - } - } catch { - return res.status(400).json({ - status: "error", - text: "couldn't render this block, please try again!" - }) - } - }) - - app.get("/", (req, res) => { - return res.sendFile(`${__dirname}/${findRendered(languageCode(req))}`) - }) - - app.get("/favicon.ico", (req, res) => { - return res.sendFile(`${__dirname}/src/front/icons/favicon.ico`) - }) - - app.get("/*", (req, res) => { - return res.redirect('/') - }) - - app.listen(env.webPort, () => { - console.log(`\n` + - `${Cyan("cobalt")} WEB ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` + - `Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` + - `URL: ${Cyan(`${env.webURL}`)}\n` + - `Port: ${env.webPort}\n` - ) - }) -} diff --git a/api/src/front/assets/meowbalt/error.png b/api/src/front/assets/meowbalt/error.png deleted file mode 100644 index 533858a70ebc3a95ef3f226c7c4abd73237c0723..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15420 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 diff --git a/api/src/front/assets/meowbalt/question.png b/api/src/front/assets/meowbalt/question.png deleted file mode 100644 index 330cd69b7de23dd0a316558af38b23eab3addfe5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21198 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 diff --git a/api/src/front/cobalt.css b/api/src/front/cobalt.css deleted file mode 100644 index ab8c5e3b..00000000 --- a/api/src/front/cobalt.css +++ /dev/null @@ -1,1265 +0,0 @@ -:root { - --transparent: rgba(0, 0, 0, 0); - --without-padding: calc(100% - 4rem); - --border-15: 0.15rem solid var(--accent); - --border-10: 0.1rem solid var(--accent); - --inset-focus: 0 0 0 0.1rem var(--accent) inset; - --inset-focus-inv: 0 0 0 0.15rem var(--background) inset; - --font-mono: 'Noto Sans Mono', 'Consolas', 'SF Mono', monospace; - --padding: 0.7rem; - --padding-small: 0.2rem; - --padding-dialog: 18px; - --line-height: 1.65rem; - --red: rgb(249, 47, 96); - --blue: rgb(47, 138, 249); - --gap: 0.5rem; - --gap-no-icon: 0.6rem; -} -[data-theme="dark"] { - --accent: rgb(225, 225, 225); - --accent-highlight: rgb(225, 225, 225, 4%); - --accent-subtext: rgb(110, 110, 110); - --accent-hover: rgb(30, 30, 30); - --accent-hover-elevated: rgb(48, 48, 48); - --accent-hover-transparent: rgba(48, 48, 48, 0.5); - --accent-button: rgb(25, 25, 25); - --accent-button-elevated: rgb(42, 42, 42); - --glass: rgba(25, 25, 25, 0.85); - --glass-lite: rgba(25, 25, 25, 0.98); - --subbackground: rgb(10, 10, 10); - --background: rgb(0, 0, 0); - --background-backdrop: rgba(0, 0, 0, 0.5); -} -[data-theme="light"] { - --accent: rgb(25, 25, 25); - --accent-highlight: rgb(25, 25, 25, 4%); - --accent-subtext: rgb(110, 110, 110); - --accent-hover: rgb(225, 225, 225); - --accent-hover-elevated: rgb(210, 210, 210); - --accent-hover-transparent: rgba(215, 215, 215, 0.5); - --accent-button: rgb(232, 232, 232); - --accent-button-elevated: rgb(215, 215, 215); - --glass: rgba(232, 232, 232, 0.85); - --glass-lite: rgba(232, 232, 232, 0.98); - --subbackground: rgb(240, 240, 240); - --background: rgb(255, 255, 255); - --background-backdrop: rgba(255, 255, 255, 0.5); -} -html, -body { - height: calc(100% + env(safe-area-inset-top) / 2); - margin: 0; - background: var(--background); - color: var(--accent); - -webkit-tap-highlight-color: var(--transparent); - font-family: var(--font-mono); - user-select: none; - -webkit-user-select: none; - overflow: hidden; - -ms-overflow-style: none; - scrollbar-width: none; -} -#home { - position: fixed; - width: 100%; - height: 100%; -} -a { - color: var(--accent); - text-decoration: none; - user-select: none; - -webkit-user-select: none; -} -::placeholder, -::moz-placeholder { - color: var(--accent-subtext); -} -.switches::-webkit-scrollbar, -.popup-content::-webkit-scrollbar { - display: none; -} -:focus-visible { - outline: var(--border-15); -} -.checkbox { - display: inline-flex; - align-items: center; - flex-direction: row; - flex-wrap: nowrap; - padding: calc(var(--gap) - 0.1rem) calc(var(--gap)*2 - var(--padding-small)) calc(var(--gap) - 0.1rem) var(--gap); - width: auto; - margin-right: var(--padding); - margin-bottom: var(--padding); - background: var(--accent-button); -} -.checkbox-label { - line-height: 1.3rem; -} -[type="checkbox"] { - -webkit-appearance: none; - appearance: none; - width: 20px; - height: 20px; - z-index: 0; - margin-right: var(--padding); - border: 0.15rem solid var(--accent); -} -[type="checkbox"]::before { - content: ""; - display: none; - position: relative; - width: 6px; - height: 12px; - z-index: 5; - transform: scaleX(0.9)rotate(45deg); - left: 6px; - top: 1px; - border-bottom: 0.18rem solid var(--background); - border-right: 0.18rem solid var(--background); -} -[type="checkbox"]:checked::before { - display: block; -} -[type="checkbox"]:checked { - background-color: var(--accent); - border: 0; -} -input[type="checkbox"] { - cursor: pointer; -} -button { - background: none; - border: none; - font-family: var(--font-mono); - color: var(--accent); - font-size: 0.9rem; -} -input, -input[type="text"], -[type="text"] { - border-radius: 0; -} -.glass-bkg { - background: var(--glass); - backdrop-filter: blur(7px); - -webkit-backdrop-filter: blur(7px); -} -.glass-bkg.alone { - z-index: -1; - top: 0; - left: 0; - bottom: 0; - right: 0; - position: absolute; -} -.glass-bkg.small { - top: 0; - left: 0; - bottom: 0; - right: 0; - z-index: -1; - position: absolute; - border: var(--accent-highlight) solid 0.15rem; - border-radius: 22px; -} -.desktop button:hover, -.desktop .switch:hover, -.desktop .checkbox:hover, -.desktop .text-to-copy:hover, -.desktop .collapse-header:hover { - background: var(--accent-hover); - box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset; - cursor: pointer; -} -button:active, -.switch:active, -.checkbox:active, -.text-to-copy:active { - box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset; - cursor: pointer; - transform: scale(0.95); -} -.collapse-header:active { - box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset; -} -.popup.small .switch { - background: var(--accent-button-elevated); -} -.desktop .popup.small .switch:hover { - background: var(--accent-hover-elevated); -} -.switch.text-backdrop, -.switch.text-backdrop:hover, -.switch.text-backdrop:active, -.text-to-copy.text-backdrop, -.text-to-copy.text-backdrop:hover, -.text-to-copy.text-backdrop:active, -.popup.small .switch.text-backdrop, -.popup.small .switch.text-backdrop:hover, -.popup.small .switch.text-backdrop:active { - background: var(--accent); - color: var(--background); - box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset; -} -.picker-image:active { - cursor: pointer; - transform: scale(0.95); -} -.button { - background: none; - border: var(--border-15); - color: var(--accent); - padding: 0.3rem var(--padding) 0.5rem; - font-size: 1rem; -} -.mono { - font-family: var(--font-mono); -} -.center { - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} -#cobalt-main-box { - position: fixed; - width: 40rem; - height: auto; - display: flex; - flex-direction: column; - align-content: center; - align-items: center; -} -#logo { - text-align: center; - font-size: 1rem; - height: 2.5rem; - align-items: center; - display: flex; - gap: 0.3rem; -} -.logo-sub { - color: var(--blue); - font-size: 0.8rem; -} -#download-area { - display: flex; - flex-direction: column; - width: 100%; -} -#cobalt-main-box #top { - display: inline-flex; - height: 2.5rem; - flex-direction: row; -} -#cobalt-main-box #bottom { - padding-top: calc(1rem - var(--padding-small)); - display: flex; - flex-direction: row; - justify-content: space-between; -} -.box { - background: var(--background); - color: var(--accent); -} -#url-input-area { - background: none; - padding-left: calc(20px + 1.4rem); - width: 100%; - color: var(--accent); - border: 0; - float: right; - border-bottom: 0.1rem solid var(--accent-subtext); - outline: none; - font-size: 0.8rem; -} -#url-clear { - height: 100%; - background: none; - padding: 0 1rem var(--padding-small); - transform: none; - font-size: 1rem; - box-shadow: none!important; -} -#url-input-area:focus { - outline: none; - border-bottom: var(--border-10); -} -#link-icon { - display: flex; - position: absolute; - width: 20px; - padding-top: var(--padding-small); - left: var(--padding); - flex-wrap: nowrap; - color: var(--accent-subtext); -} -#download-button { - height: 2.5rem; - color: var(--accent); - background: none; - border: none; - font-size: 1.8rem; - cursor: pointer; - padding: 0; - letter-spacing: -0.35rem; - font-weight: normal!important; -} -#download-button:disabled { - color: var(--accent-subtext); - cursor: not-allowed; -} -#cobalt-main-box .switch, -#footer .switch { - box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset; -} -#footer { - bottom: 0; - width: 100%; - position: absolute; - display: flex; - justify-content: center; - padding-bottom: 2rem; - font-size: 0.9rem; - text-align: center; -} -#cobalt-main-box #bottom, -#footer-buttons, -#footer-buttons, .footer-pair { - gap: var(--gap); -} -#footer-buttons, .footer-pair { - display: flex; - flex-direction: row; - align-items: center; -} -.footer-button { - width: auto!important; - color: var(--accent-subtext); - padding: var(--gap) 1rem!important; - align-content: center; -} -.notification-dot { - width: 8px; - height: 8px; - background: var(--red); - margin-right: 0.4rem; - border-radius: 99rem; -} -.text-backdrop { - background: var(--accent); - color: var(--background); - padding: 0 0.3rem; -} -.text-backdrop.link { - text-decoration: underline; -} -.cobalt-support-link { - display: flex; - flex-direction: row; - justify-content: flex-start; - gap: 0.3rem; - margin-top: 0.5rem; - user-select: none; - -webkit-user-select: none; -} -::-moz-selection { - background-color: var(--accent); - color: var(--background); -} -::selection { - background-color: var(--accent); - color: var(--background); -} -.popup { - visibility: hidden; - position: fixed; - height: auto; - width: 36%; - z-index: 999; - font-size: 0.9rem; - max-height: 95%; - opacity: 0; - transform: translate(-50%,-48%)scale(.95); - box-shadow: 0 0 0 var(--padding-small) var(--glass) inset, - 0 0 20px 0 var(--accent-hover-transparent); -} -.popup.visible { - visibility: visible; - opacity: 1; - transform: translate(-50%, -50%); - transition: transform 100ms ease-out, opacity 100ms ease-in-out; -} -#popup-backdrop { - visibility: hidden; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 998; - opacity: 0; - background: var(--background-backdrop); -} -#popup-backdrop.visible { - visibility: visible; - opacity: 1; - transition: opacity .13s ease-in-out; - backdrop-filter: blur(7px); - -webkit-backdrop-filter: blur(7px); -} -.popup.small { - width: 21rem; - box-shadow: 0px 0px 60px 0px var(--accent-hover); - padding: var(--padding-dialog); - transform: translate(-50%, -50%)scale(.95); - pointer-events: all; - border-radius: 22px; -} -.popup.small .popup-content-inner { - display: flex; - flex-direction: column; - gap: var(--padding-dialog); - width: 100%; -} -.popup.small.visible { - transform: translate(-50%, -50%); -} -.popup.small .popup-header-contents, -.popup.small .popup-content-inner, -.popup.small .popup-header { - padding: 0; -} -.popup.small .popup-header { - position: relative; - border: none; -} -.popup.small .popup-title { - margin-bottom: 0.6rem; -} -.popup.small .close-error.switch { - background: var(--accent)!important; - color: var(--background); - height: 2.5rem; -} -#popup-error, -#popup-download { - display: flex; - flex-direction: column; - padding-top: 4rem; -} -#popup-error { - justify-content: center; - align-items: center; -} -.popout-meowbalt { - position: absolute; - top: -7rem; - user-select: none; - -webkit-user-select: none; - pointer-events: none; - height: 180px; - width: 180px; -} -#popup-download .popout-meowbalt { - left: -2rem; -} -.popup.scrollable { - height: 95%; -} -.changelog-subtitle { - font-size: 1.3rem; - padding-bottom: var(--gap-no-icon); -} -.changelog-banner { - position: relative; - width: 100%; - max-height: 300px; - min-height: 210px; - margin-bottom: var(--padding); - float: left; - background: var(--accent-hover); - display: flex; -} -.changelog-img { - object-fit: cover; - width: inherit; - height: inherit; - max-height: inherit; -} -.changelog-tags { - display: inline-flex; - align-items: center; - gap: var(--padding); - padding-bottom: var(--padding); - flex-wrap: wrap; -} -.changelog-tag-version { - font-size: 1rem; - padding: 0.15rem 0.5rem; -} -.changelog-tag-date { - color: var(--accent-subtext); - font-size: 0.8rem; -} -.nowrap { - white-space: nowrap; -} -.no-top-padding { - padding-top: 0!important; -} -.desc-padding { - padding-bottom: var(--padding); -} -#popup-subtitle { - font-size: 1.1rem; - padding-bottom: var(--padding); -} -.popup-desc, -.desc-error, -#popup-info-desc { - width: 100%; - text-align: left; - float: left; - line-height: var(--line-height); - user-select: text; - -webkit-user-select: text; -} -.desc-error { - padding-bottom: 0rem; - text-align: center; -} -.popup-title { - font-size: 1.5rem; - display: flex; - align-items: center; - line-height: 1em; - margin-bottom: 0.4rem; - margin-top: 0.4rem; -} -.popup-above-title { - color: var(--accent-subtext); - font-size: 0.8rem; -} -.popup-content { - overflow-x: scroll; - overflow-y: auto; - height: 100%; - scrollbar-width: none; -} -.popup-content-inner, -.tab-content-settings, -#picker-holder { - padding-top: calc(var(--padding) + 4rem); - padding-bottom: 4.8rem; -} -.tab-content-settings, -#tab-about-about .popup-content-inner { - padding-top: 6rem; -} -.bullpadding { - padding-left: 0.58rem; -} -.popup-header { - position: absolute; - z-index: 999; - padding-top: calc(var(--padding) + 1rem); - width: 100%; -} -.settings-category { - padding-bottom: var(--padding); -} -.separator { - float: left; -} -.separator, -.category-title { - width: 100%; - color: var(--accent-subtext); - border-bottom: 0.05rem solid var(--accent-subtext); - padding-bottom: 0.25rem; - margin-bottom: calc(var(--gap-no-icon)*1.5); -} -.category-title { - text-align: left; - line-height: var(--line-height); -} -.bottom-margin { - margin-bottom: var(--padding)!important; -} -.top-margin { - margin-top: var(--padding)!important; -} -.top-margin-only { - margin-top: var(--padding)!important; - margin-bottom: 0!important; -} -.no-margin { - margin: 0!important; -} -.switch-container { - width: 100%; -} -.subtitle { - width: 100%; - text-align: left; - line-height: var(--line-height); - padding-bottom: 0.4rem; - color: var(--accent); -} -.small-padding .subtitle { - margin-top: 0.5rem; -} -.explanation { - margin-top: var(--padding); - width: 100%; - font-size: 0.8rem; - text-align: left; - line-height: 1.3rem!important; - color: var(--accent-subtext); -} -.explanation.embedded { - margin-top: 0.825rem; - margin-bottom: 0.825rem; -} -.subtext { - color: var(--accent-subtext); -} -.switch { - padding: var(--gap-no-icon); - width: 100%; - text-align: left; - color: var(--accent); - background: var(--accent-button); - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; -} -.switch.space-right { - margin-right: var(--padding); -} -.switch:focus { - box-shadow: var(--inset-focus) inset; -} -.popup-tabs .switch { - background: none; -} -.desktop .popup-tabs .switch:hover, -.popup-tabs .switch:active { - background: var(--accent-hover-transparent); - box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset; -} -.switch[data-enabled="true"], -.popup-tabs .switch[data-enabled="true"] { - color: var(--background); - background: var(--accent)!important; - cursor: default; -} -.switch[data-enabled="true"]:hover { - background: var(--accent); -} -.switch[data-enabled="true"]:focus { - box-shadow: var(--inset-focus-inv) inset; -} -.switches { - display: flex; - width: auto; - flex-direction: row; - flex-wrap: nowrap; - scrollbar-width: none; -} -.switches .switch { - padding-left: calc(var(--gap-no-icon) + 0.1rem); - padding-right: calc(var(--gap-no-icon) + 0.1rem); -} -#popup-settings .switches .switch { - text-align: center; -} -.autowidth { - width: auto; -} -.bottom-space { - margin-bottom: 2rem; -} -.text-to-copy { - user-select: text; - -webkit-user-select: text; - background: var(--accent-button); - padding: var(--gap-no-icon); - overflow: clip; -} -.back-button { - padding: 0; - background: none; - max-width: 4rem; - font-size: 1rem; -} -.back-button svg path, -.collapse-indicator svg path { - fill: var(--accent); -} -.popup-tab-content[data-enabled="false"] { - display: none; -} -.popup-tabs { - z-index: 999; - bottom: 0; - position: absolute; - width: 100%; - padding-top: var(--padding-small); - padding-bottom: calc(var(--padding) + 1rem); -} -.popup-tabs-child { - width: 100%; - padding: 0 var(--padding-small); -} -.emoji, svg { - user-select: none; - -webkit-user-select: none; - pointer-events: none; -} -.emoji { - margin-right: 0.4rem; -} -.picker-image { - object-fit: cover; - width: 100%; - height: 100%; - cursor: pointer; - user-select: all; - -webkit-user-select: all; -} -.picker-image-container { - width: calc(100% / 3); - height: 12rem; - background-color: var(--accent-button); - cursor: pointer; - position: relative; -} -#picker-holder { - display: flex; - justify-content: start; - flex-wrap: wrap; - align-content: space-around; - padding-top: 7.6rem; - padding-bottom: 4.8rem; - padding-left: var(--padding-small); - padding-right: var(--padding-small); -} -.imageBlock { - width: 100%; - height: 100%; - position: absolute; - z-index: 99; -} -.picker-element-name { - position: absolute; - background: var(--background); - color: var(--accent); - padding: 0.3rem var(--gap); - font-size: 0.8rem; - opacity: 0.7; - margin: 0.4rem; -} -#popup-picker .explanation { - margin-top: 0!important; - margin-bottom: var(--padding); -} -#cobalt-main-box #bottom button { - width: auto; - padding: var(--gap) 0.9rem; -} -.collapse-list { - background: var(--subbackground); - user-select: none; - -webkit-user-select: none; -} -.collapse-header { - padding: 0.5rem var(--padding); - font-size: 0.95rem; - display: flex; - flex-direction: row; - align-items: center; - cursor: pointer; - background: var(--accent-button); -} -.collapse-header .emoji { - margin-right: var(--padding); -} -.collapse-indicator { - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - transform: none; -} -.collapse-list.expanded .collapse-indicator { - transform: rotate(180deg); -} -.collapse-title { - width: 100%; - display: flex; - flex-direction: row; - align-items: center; -} -.collapse-body { - display: none; - padding: var(--padding); - padding-bottom: 1rem; - user-select: text; - -webkit-user-select: text; -} -.expanded .collapse-body { - display: block; -} -#download-switcher .switches { - gap: var(--gap); -} -#pd-share { - display: none; -} -.popup-content-inner, -.tab-content-settings, -.popup-header-contents { - padding-left: 1rem; - padding-right: 1rem; -} -.urgent-notice { - width: 100%; - text-align: center; - position: absolute; - display: flex; - justify-content: center; - align-items: center; - padding-top: 1rem; -} -.urgent-text { - display: flex; - align-items: center; - cursor: pointer; -} -.no-transparency .glass-bkg, -.no-transparency #popup-backdrop { - backdrop-filter: none; - -webkit-backdrop-filter: none; -} -.no-transparency .glass-bkg { - background: var(--glass-lite); -} -.no-animation .popup, -.no-animation #popup-backdrop { - transition: none; -} -.popup-from-bottom { - position: fixed; - width: 100%; - height: 100%; - bottom: 0; - z-index: 999; - visibility: hidden; - pointer-events: none; -} -.popup-from-bottom.visible { - visibility: visible; -} -#keyboard-collapse { - display: none; -} -.desktop #keyboard-collapse { - display: block; -} -.text-backdrop.key { - color: var(--accent-hover-elevated); -} -#keyboard-shortcuts { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - align-items: flex-start; - gap: 1.5rem; - user-select: none; - color: var(--accent); -} -.loader { - text-align: center; -} -#picker-download { - visibility: hidden; -} -#picker-download.visible { - visibility: visible; -} -#home { - opacity: 0; -} -#home.visible { - opacity: 1; - transition: opacity 0.2s ease-out; -} -.no-animation #home { - transition: none; -} -.sponsored-by-text { - text-align: center!important; - font-size: .85rem; - color: var(--accent-subtext); - user-select: none; -} -#sponsored-logos { - width: 100%; - display: flex; - justify-content: center; - flex-wrap: wrap; - gap: var(--padding-small) 1rem; - margin-bottom: 1rem; -} -.sponsored-logo svg { - height: inherit; - width: inherit; -} -.sponsored-logo svg path { - fill: var(--accent-subtext); -} -#filename-preview { - background: var(--accent-button); - margin-top: 0.8rem; -} -.filename-item { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - gap: 1rem; - padding: 0.5rem var(--padding); -} -.filename-item.line { - border-bottom: 0.1rem solid var(--accent-button-elevated); -} -.filename-label { - color: var(--accent-subtext); - font-size: 0.8rem; -} -.filename-container { - overflow-wrap: anywhere; -} -/* rounded corners */ -#bottom #paste, -#footer .switch, -#audioMode, -.popup-content .switches, -.checkbox, -.changelog-img, -.changelog-banner, -.close-error, -#download-switcher .switch, -#popup-about .switch, -.popup-tabs .switch, -.text-to-copy, -.text-to-copy.text-backdrop, -#filename-preview { - border-radius: 9px; -} -[type=checkbox] { - border-radius: 4px; -} -.popup, -.scrollable .popup-content { - border-radius: 12px; -} -.popup-header .glass-bkg { - border-top-left-radius: 12px; - border-top-right-radius: 12px; - border-bottom: var(--accent-highlight) solid 0.1rem; - top: -1px; -} -.popup-tabs .glass-bkg { - border-bottom-left-radius: 12px; - border-bottom-right-radius: 12px; - border-top: var(--accent-highlight) solid 0.1rem; - bottom: -1px; -} -.switches .switch:first-child { - border-top-left-radius: 9px; - border-bottom-left-radius: 9px; -} -.switches .switch:last-child { - border-top-right-radius: 9px; - border-bottom-right-radius: 9px; -} -.text-backdrop { - border-radius: 4px; -} -.collapse-list:first-child, -.collapse-list:first-child .collapse-header { - border-top-left-radius: 8px; - border-top-right-radius: 8px; -} -.collapse-list:last-child, -.collapse-list:last-child .collapse-header { - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; -} -.collapse-list:last-child.expanded .collapse-header { - border-radius: 0; -} -/* prevent resizing fliecker on ios if web app is installed as standalone */ -@media all and (display-mode: standalone) { - #home.visible { - transition-delay: 0.1s; - } -} -/* adapt the page according to screen size */ -@media screen and (max-width: 1550px) { - .popup { - width: 40%; - } -} -@media screen and (max-width: 1440px) { - .popup { - width: 45%; - } -} -@media screen and (max-width: 1300px) { - .popup { - width: 50%; - } -} -@media screen and (max-width: 1200px) { - .popup { - width: 55%; - } -} -@media screen and (max-width: 1025px) { - .popup { - width: 60%; - } -} -@media screen and (max-width: 850px) { - .popup { - width: 75%; - } -} -@media screen and (max-width: 680px) { - .popup { - width: 90%; - } -} -@media screen and (max-width: 660px) { - #cobalt-main-box { - width: calc(100% - (var(--padding) * 2)); - } -} -/* mobile page */ -@media screen and (max-width: 499px) { - .tab { - font-size: 0!important; - } - .tab .emoji { - margin-right: 0; - } - .checkbox { - width: calc(100% - 1.3rem); - } -} -@media screen and (max-width: 535px) { - #cobalt-main-box #bottom { - flex-direction: row-reverse; - } - #cobalt-main-box #bottom #audioMode button, #audioMode { - width: 100%; - } - #footer-buttons { - flex-direction: column; - align-items: stretch; - width: 100%; - padding: 0 var(--padding); - } - .footer-pair .footer-button { - width: 100%!important; - } - #logo { - width: 100%; - height: auto; - justify-content: center; - } - #cobalt-main-box { - display: flex; - border: none; - padding: 0; - flex-direction: column; - gap: var(--gap); - } - .popup, - .popup-header .glass-bkg, - .popup-tabs .glass-bkg, - .glass-bkg.small { - border-radius: 0; - } - .popup-tabs .glass-bkg { - bottom: 0; - } - .switches { - overflow-x: scroll; - } - .checkbox { - margin-right: 0; - } - .popup.center { - top: unset; - left: unset; - transform: unset; - } - .popup.small { - width: calc(100% - var(--padding-dialog) * 2); - height: auto; - top: unset; - bottom: 0; - left: 0; - transform: none; - position: absolute; - transform: translateY(30rem); - } - #popup-download .popout-meowbalt { - left: unset; - } - .glass-bkg.small { - border: none; - border-top: var(--accent-highlight) solid 0.15rem; - } - .popup.small.visible { - transform: translateY(0rem); - transition: transform 250ms cubic-bezier(0.075, 0.82, 0.165, 1), opacity 130ms ease-in-out; - } - .popup.small .popup-header { - background: none; - } - .no-animation .popup.small { - transition: none; - } - .close-error { - bottom: 3rem; - } - #picker-holder { - padding-left: 0; - padding-right: 0; - } - #picker-holder::-webkit-scrollbar { - display: none; - } - #picker-holder.various { - flex-wrap: wrap; - gap: 0; - overflow-x: hidden; - overflow-y: scroll; - } - .popup, .popup.scrollable { - border: none; - width: 100%; - height: 100%; - max-height: 100%; - box-shadow: none; - } - .popup-content-inner, - .tab-content-settings, - .popup-tabs-child, - .popup-header-contents { - padding-left: var(--padding); - padding-right: var(--padding); - } - .popup-content-inner, - .tab-content-settings, - #picker-holder { - padding-bottom: calc(var(--padding) + 3.5rem); - padding-top: calc(var(--padding) + 3rem - var(--padding-small)); - } - #footer, - .popup-tabs { - padding-bottom: var(--padding); - } - .popup.small { - padding-bottom: var(--padding-dialog) - } - .urgent-notice { - padding-top: 1rem; - } - .popup-title { - margin-top: var(--padding-small); - } - .popup-header { - padding-top: var(--padding); - } - .tab-content-settings, - #tab-about-about .popup-content-inner { - padding-top: calc(5rem - var(--padding-small)); - } -} -@media screen and (max-width: 535px) and (display-mode: standalone) { - .popup-header { - padding-top: max( - calc(env(safe-area-inset-top)), - var(--padding) + 1rem - ); - } - .urgent-notice { - padding-top: max( - calc(env(safe-area-inset-top) - var(--padding-small)), - var(--padding) - ); - } - #footer, - .popup-tabs { - padding-bottom: max( - calc(env(safe-area-inset-bottom) + var(--padding-small)), - var(--padding) - ); - } - .popup.small { - padding-bottom: max( - calc(env(safe-area-inset-bottom) + var(--padding-small)), - var(--padding-dialog) - ); - } - .popup-content-inner, - .tab-content-settings { - padding-top: max( - calc(env(safe-area-inset-top) + var(--padding) + var(--padding-small) + 2rem), - calc(var(--padding) + 4rem - var(--padding-small)) - ); - padding-bottom: max( - calc(env(safe-area-inset-bottom) + var(--padding) + 3rem), - calc(var(--padding) + var(--padding-small) * 2 + 3rem) - ); - } - .tab-content-settings, - #tab-about-about .popup-content-inner { - padding-top: max( - calc(env(safe-area-inset-top) + var(--padding) + var(--padding-small) * 2 + 3rem), - calc(var(--padding) + 5rem) - ); - } - #picker-holder { - padding-top: max( - calc(env(safe-area-inset-top) + var(--padding) + 5rem), - calc(var(--padding) * 2 + 6rem) - ); - padding-bottom: max( - calc(env(safe-area-inset-bottom) + var(--padding) + 2rem), - calc(4rem - var(--padding) + var(--padding-small)) - ); - } - - .android .popup-header { - padding-top: var(--padding); - } - .android .popup-content-inner, - .android .tab-content-settings, - .android #picker-holder { - padding-bottom: calc(var(--padding) + 3.5rem); - padding-top: calc(var(--padding) + 3rem - var(--padding-small)); - } - .android .tab-content-settings, - .android #tab-about-about .popup-content-inner { - padding-top: calc(5rem - var(--padding-small)); - } -} diff --git a/api/src/front/cobalt.js b/api/src/front/cobalt.js deleted file mode 100644 index 0c89dec2..00000000 --- a/api/src/front/cobalt.js +++ /dev/null @@ -1,708 +0,0 @@ -const ua = navigator.userAgent.toLowerCase(); -const isIOS = ua.includes("iphone os") || (ua.includes("mac os") && navigator.maxTouchPoints > 0); -const isAndroid = ua.includes("android"); -const isMobile = ua.includes("android") || isIOS; -const isSafari = ua.includes("safari/"); -const isFirefox = ua.includes("firefox/"); -const isOldFirefox = ua.includes("firefox/") && ua.split("firefox/")[1].split('.')[0] < 103; - -const switchers = { - "theme": ["auto", "light", "dark"], - "vCodec": ["h264", "av1", "vp9"], - "vQuality": ["720", "max", "2160", "1440", "1080", "480", "360", "240", "144"], - "aFormat": ["mp3", "best", "ogg", "wav", "opus"], - "audioMode": ["false", "true"], - "filenamePattern": ["classic", "pretty", "basic", "nerdy"] -} -const checkboxes = [ - "alwaysVisibleButton", - "downloadPopup", - "fullTikTokAudio", - "muteAudio", - "reduceTransparency", - "disableAnimations", - "disableMetadata", - "twitterGif", - "plausible_ignore", - "ytDub", - "tiktokH265" -] -const bottomPopups = ["error", "download"] - -let store = {}; - -const validLink = (link) => { - try { - return /^https:/i.test(new URL(link).protocol); - } catch { - return false - } -} - -const fixApiUrl = (url) => { - return url.endsWith('/') ? url.slice(0, -1) : url -} - -let apiURL = fixApiUrl(defaultApiUrl); - -const changeApi = (url) => { - apiURL = fixApiUrl(url); - return true -} - -const eid = (id) => { - return document.getElementById(id) -} - -const sGet = (id) =>{ - return localStorage.getItem(id) -} -const sSet = (id, value) => { - localStorage.setItem(id, value) -} -const lazyGet = (key) => { - const value = sGet(key); - if (key in switchers) { - if (switchers[key][0] !== value) - return value; - } else if (checkboxes.includes(key)) { - if (value === 'true') - return true; - } -} - -const changeDownloadButton = (action, text) => { - switch (action) { - case "hidden": // hidden, but only visible when alwaysVisibleButton is true - eid("download-button").disabled = true - if (sGet("alwaysVisibleButton") === "true") { - eid("download-button").value = '>>' - eid("download-button").style.padding = '0 1rem' - } else { - eid("download-button").value = '' - eid("download-button").style.padding = '0' - } - break; - case "disabled": - eid("download-button").disabled = true - eid("download-button").value = text - eid("download-button").style.padding = '0 1rem' - break; - default: - eid("download-button").disabled = false - eid("download-button").value = '>>' - eid("download-button").style.padding = '0 1rem' - break; - } -} - -const button = () => { - let regexTest = validLink(eid("url-input-area").value); - - eid("url-clear").style.display = "none"; - - if ((eid("url-input-area").value).length > 0) { - eid("url-clear").style.display = "block"; - } - - if (regexTest) { - changeDownloadButton() - } else { - changeDownloadButton("hidden") - } -} - -const clearInput = () => { - eid("url-input-area").value = ''; - button(); -} - -const copy = (id, data) => { - let target = document.getElementById(id); - target.classList.add("text-backdrop"); - - setTimeout(() => { - target.classList.remove("text-backdrop") - }, 600); - - if (data) { - navigator.clipboard.writeText(data) - } else { - navigator.clipboard.writeText(target.textContent) - } -} - -const share = url => navigator?.share({ url }).catch(() => {}); - -const preferredColorScheme = () => { - let theme = "auto"; - let localTheme = sGet("theme"); - let isLightPreferred = false; - - if (localTheme) { - theme = localTheme; - } - if (window.matchMedia) { - isLightPreferred = window.matchMedia('(prefers-color-scheme: light)').matches; - } - if (theme === "auto") { - theme = isLightPreferred ? "light" : "dark" - } - - return theme -} - -const changeStatusBarColor = () => { - const theme = preferredColorScheme(); - const colors = { - "dark": "#000000", - "light": "#ffffff", - "dark-popup": "#151515", - "light-popup": "#ebebeb" - } - - let state = store.isPopupOpen ? "dark-popup" : "dark"; - - if (theme === "light") { - state = store.isPopupOpen ? "light-popup" : "light"; - } - - document.querySelector('meta[name="theme-color"]').setAttribute('content', colors[state]); -} -const detectColorScheme = () => { - document.documentElement.setAttribute("data-theme", preferredColorScheme()); - changeStatusBarColor(); -} - -if (window.matchMedia) { - window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', () => { - changeStatusBarColor() - detectColorScheme() - }) -} - -const updateFilenamePreview = () => { - let videoFilePreview = ``; - let audioFilePreview = ``; - let resMatch = { - "max": "3840x2160", - "2160": "3840x2160", - "1440": "2560x1440", - "1080": "1920x1080", - "720": "1280x720", - "480": "854x480", - "360": "640x360", - } - - switch(sGet("filenamePattern")) { - case "classic": - videoFilePreview = `youtube_dQw4w9WgXcQ_${resMatch[sGet('vQuality')]}_${sGet('vCodec')}` - + `${sGet("muteAudio") === "true" ? "_mute" : ""}` - + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`; - audioFilePreview = `youtube_dQw4w9WgXcQ_audio` - + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`; - break; - case "basic": - videoFilePreview = `${loc.FilenamePreviewVideoTitle} ` - + `(${sGet('vQuality') === "max" ? "2160p" : `${sGet('vQuality')}p`}, ` - + `${sGet('vCodec')}${sGet("muteAudio") === "true" ? ", mute" : ""})` - + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`; - audioFilePreview = `${loc.FilenamePreviewAudioTitle} - ${loc.FilenamePreviewAudioAuthor}` - + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`; - break; - case "pretty": - videoFilePreview = `${loc.FilenamePreviewVideoTitle} ` - + `(${sGet('vQuality') === "max" ? "2160p" : `${sGet('vQuality')}p`}, ${sGet('vCodec')}, ` - + `${sGet("muteAudio") === "true" ? "mute, " : ""}youtube)` - + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`; - audioFilePreview = `${loc.FilenamePreviewAudioTitle} - ${loc.FilenamePreviewAudioAuthor} (soundcloud)` - + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`; - break; - case "nerdy": - videoFilePreview = `${loc.FilenamePreviewVideoTitle} ` - + `(${sGet('vQuality') === "max" ? "2160p" : `${sGet('vQuality')}p`}, ${sGet('vCodec')}, ` - + `${sGet("muteAudio") === "true" ? "mute, " : ""}youtube, dQw4w9WgXcQ)` - + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`; - audioFilePreview = `${loc.FilenamePreviewAudioTitle} - ${loc.FilenamePreviewAudioAuthor} ` - + `(soundcloud, 1242868615)` - + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`; - break; - } - eid("video-filename-text").innerHTML = videoFilePreview - eid("audio-filename-text").innerHTML = audioFilePreview -} - -const changeTab = (evnt, tabId, tabClass) => { - if (tabId === "tab-settings-other") updateFilenamePreview(); - - let tabcontent = document.getElementsByClassName(`tab-content-${tabClass}`); - let tablinks = document.getElementsByClassName(`tab-${tabClass}`); - - for (let i = 0; i < tabcontent.length; i++) { - tabcontent[i].dataset.enabled = "false"; - } - for (let i = 0; i < tablinks.length; i++) { - tablinks[i].dataset.enabled = "false"; - } - - evnt.currentTarget.dataset.enabled = "true"; - eid(tabId).dataset.enabled = "true"; - eid(tabId).parentElement.scrollTop = 0; -} - -const expandCollapsible = (evnt) => { - let classlist = evnt.currentTarget.parentNode.classList; - let c = "expanded"; - !classlist.contains(c) ? classlist.add(c) : classlist.remove(c); -} - -const hideAllPopups = () => { - let filter = document.getElementsByClassName('popup'); - for (let i = 0; i < filter.length; i++) { - filter[i].classList.remove("visible"); - } - eid("popup-backdrop").classList.remove("visible"); - store.isPopupOpen = false; - - // clear the picker - eid("picker-holder").innerHTML = ''; - eid("picker-download").href = '/'; - eid("picker-download").classList.remove("visible"); -} - -const popup = (type, action, text) => { - if (action === 1) { - hideAllPopups(); // hide the previous popup before showing a new one - store.isPopupOpen = true; - - // if not a small popup, update status bar color to match the popup header - if (!bottomPopups.includes(type)) changeStatusBarColor(); - switch (type) { - case "about": - let tabId = "about"; - if (text) tabId = text; - eid(`tab-button-${type}-${tabId}`).click(); - break; - case "settings": - eid(`tab-button-${type}-video`).click(); - break; - case "error": - eid("desc-error").innerHTML = text; - break; - case "download": - eid("pd-download").href = text; - eid("pd-copy").setAttribute("onClick", `copy('pd-copy', '${text}')`); - eid("pd-share").setAttribute("onClick", `share('${text}')`); - if (navigator.canShare) eid("pd-share").style.display = "flex"; - break; - case "picker": - eid("picker-title").innerHTML = loc.MediaPickerTitle; - eid("picker-subtitle").innerHTML = isMobile ? loc.MediaPickerExplanationPhone : loc.MediaPickerExplanationPC; - - switch (text.type) { - case "images": - eid("picker-holder").classList.remove("various"); - - eid("picker-download").href = text.audio; - eid("picker-download").classList.add("visible"); - - for (let i in text.arr) { - eid("picker-holder").innerHTML += - `` + - `` + - `` - } - break; - default: - eid("picker-holder").classList.add("various"); - - for (let i in text.arr) { - eid("picker-holder").innerHTML += - `` + - `
${text.arr[i].type}
` + - (text.arr[i].type === 'photo' ? '' : '
') + - `` + - `
` - } - eid("picker-download").classList.remove("visible"); - break; - } - break; - default: - break; - } - } else { - store.isPopupOpen = false; - - // reset status bar to base color - changeStatusBarColor(); - - if (type === "picker") { - eid("picker-download").href = '/'; - eid("picker-download").classList.remove("visible"); - eid("picker-holder").innerHTML = '' - } - } - if (bottomPopups.includes(type)) { - eid(`popup-${type}-container`).classList.toggle("visible"); - } - eid("popup-backdrop").classList.toggle("visible"); - eid(`popup-${type}`).classList.toggle("visible"); - eid(`popup-${type}`).focus(); -} - -const changeSwitcher = (switcher, state) => { - if (state) { - if (!switchers[switcher].includes(state)) { - state = switchers[switcher][0]; - } - sSet(switcher, state); - - for (let i in switchers[switcher]) { - if (switchers[switcher][i] === state) { - eid(`${switcher}-${state}`).dataset.enabled = "true"; - } else { - eid(`${switcher}-${switchers[switcher][i]}`).dataset.enabled = "false"; - } - } - if (switcher === "theme") detectColorScheme(); - if (switcher === "filenamePattern") updateFilenamePreview(); - } else { - let defaultValue = switchers[switcher][0]; - sSet(switcher, defaultValue); - for (let i in switchers[switcher]) { - if (switchers[switcher][i] === defaultValue) { - eid(`${switcher}-${defaultValue}`).dataset.enabled = "true"; - } else { - eid(`${switcher}-${switchers[switcher][i]}`).dataset.enabled = "false"; - } - } - } -} - -const checkbox = (action) => { - sSet(action, !!eid(action).checked); - switch(action) { - case "alwaysVisibleButton": button(); break; - case "reduceTransparency": eid("cobalt-body").classList.toggle('no-transparency'); break; - case "disableAnimations": eid("cobalt-body").classList.toggle('no-animation'); break; - } -} - -const changeButton = (type, text) => { - switch (type) { - case "error": //error - eid("url-input-area").disabled = false - eid("url-clear").style.display = "block"; - changeDownloadButton("disabled", '!!'); - popup("error", 1, text); - setTimeout(() => { changeButton("default") }, 2500); - break; - case "default": //enable back - changeDownloadButton(); - eid("url-clear").style.display = "block"; - eid("url-input-area").disabled = false - break; - case "error-default": //enable back + information popup - popup("error", 1, text); - changeDownloadButton(); - eid("url-clear").style.display = "block"; - eid("url-input-area").disabled = false - break; - } -} - -const internetError = () => { - eid("url-input-area").disabled = false - changeDownloadButton("disabled", '!!'); - setTimeout(() => { changeButton("default") }, 2500); - popup("error", 1, loc.ErrorNoInternet); -} - -const resetSettings = () => { - localStorage.clear(); - window.location.reload(); -} - -const download = async(url) => { - changeDownloadButton("disabled", '...'); - - eid("url-clear").style.display = "none"; - eid("url-input-area").disabled = true; - - let req = { - url, - vCodec: lazyGet("vCodec"), - vQuality: lazyGet("vQuality"), - aFormat: lazyGet("aFormat"), - filenamePattern: lazyGet("filenamePattern"), - isAudioOnly: lazyGet("audioMode"), - isTTFullAudio: lazyGet("fullTikTokAudio"), - isAudioMuted: lazyGet("muteAudio"), - disableMetadata: lazyGet("disableMetadata"), - dubLang: lazyGet("ytDub"), - twitterGif: lazyGet("twitterGif"), - tiktokH265: lazyGet("tiktokH265"), - } - - let j = await fetch(`${apiURL}/api/json`, { - method: "POST", - body: JSON.stringify(req), - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - }).then(r => r.json()).catch(() => {}); - - if (!j) { - internetError(); - return; - } - - if ((j.status === "error" || j.status === "rate-limit") && j && j.text) { - changeButton("error", j.text); - return; - } - - if (j.text && (!j.url || !j.picker)) { - if (j.status === "success") { - changeButton("error-default", j.text) - } else { - changeButton("error", loc.ErrorNoUrlReturned); - } - } - switch (j.status) { - case "redirect": - changeDownloadButton("disabled", '>>>'); - setTimeout(() => { changeButton("default") }, 1500); - - if (sGet("downloadPopup") === "true") { - popup('download', 1, j.url) - } else { - window.open(j.url, '_blank') - } - break; - case "stream": - changeDownloadButton("disabled", '?..'); - - let probeStream = await fetch(`${j.url}&p=1`).then(r => r.json()).catch(() => {}); - if (!probeStream) return internetError(); - - if (probeStream.status !== "continue") { - changeButton("error", probeStream.text); - return; - } - - changeDownloadButton("disabled", '>>>'); - if (sGet("downloadPopup") === "true") { - popup('download', 1, j.url) - } else { - if (isMobile || isSafari) { - window.location.href = j.url; - } else { - window.open(j.url, '_blank'); - } - } - setTimeout(() => { changeButton("default") }, 2500); - break; - case "picker": - if (j.audio && j.picker) { - changeDownloadButton("disabled", '>>>'); - popup('picker', 1, { - audio: j.audio, - arr: j.picker, - type: j.pickerType - }); - setTimeout(() => { changeButton("default") }, 2500); - } else if (j.picker) { - changeDownloadButton("disabled", '>>>'); - popup('picker', 1, { - arr: j.picker, - type: j.pickerType - }); - setTimeout(() => { changeButton("default") }, 2500); - } else { - changeButton("error", loc.ErrorNoUrlReturned); - } - break; - case "success": - changeButton("error-default", j.text); - break; - default: - changeButton("error", loc.ErrorUnknownStatus); - break; - } -} - -const pasteClipboard = async() => { - try { - let clipboard = await navigator.clipboard.readText(); - let onlyURL = clipboard.match(/https:\/\/[^\s]+/g) - if (onlyURL) { - eid("url-input-area").value = onlyURL; - download(eid("url-input-area").value); - } - } catch (e) { - let errorMessage = loc.FeatureErrorGeneric; - let doError = true; - let error = String(e).toLowerCase(); - - if (error.includes("denied")) errorMessage = loc.ClipboardErrorNoPermission; - if (error.includes("dismissed") || isIOS) doError = false; - if (error.includes("function") && isFirefox) errorMessage = loc.ClipboardErrorFirefox; - - if (doError) popup("error", 1, errorMessage); - } -} - -const loadCelebrationsEmoji = async() => { - let aboutButtonBackup = eid("about-footer").innerHTML; - try { - let j = await fetch(`/onDemand?blockId=1`).then(r => r.json()).catch(() => {}); - if (j && j.status === "success" && j.text) { - eid("about-footer").innerHTML = eid("about-footer").innerHTML.replace( - `${aboutButtonBackup.split('> ')[0]}>`, - j.text - ) - } - } catch { - eid("about-footer").innerHTML = aboutButtonBackup; - } -} - -const loadOnDemand = async(elementId, blockId) => { - store.historyButton = eid(elementId).innerHTML; - eid(elementId).innerHTML = `
...
`; - - try { - if (!store.historyContent) { - let j = await fetch(`/onDemand?blockId=${blockId}`).then(r => r.json()).catch(() => {}); - if (!j) throw new Error(); - - if (j.status === "success") { - store.historyContent = j.text - } - } - eid(elementId).innerHTML = - ` - ${store.historyContent}`; - } catch { - eid(elementId).innerHTML = store.historyButton; - internetError() - } -} - -const restoreUpdateHistory = () => { - eid("changelog-history").innerHTML = store.historyButton; -} - -const loadSettings = () => { - if (sGet("alwaysVisibleButton") === "true") { - eid("alwaysVisibleButton").checked = true; - eid("download-button").value = '>>' - eid("download-button").style.padding = '0 1rem'; - } - if (sGet("downloadPopup") === "true" && !isIOS) { - eid("downloadPopup").checked = true; - } - if (sGet("reduceTransparency") === "true" || isOldFirefox) { - eid("cobalt-body").classList.add('no-transparency'); - } - if (sGet("disableAnimations") === "true") { - eid("cobalt-body").classList.add('no-animation'); - } - if (!isMobile) { - eid("cobalt-body").classList.add('desktop'); - } - if (isAndroid) { - eid("cobalt-body").classList.add('android'); - } - if (isIOS) { - eid("download-switcher") - .querySelector(".explanation") - .innerHTML = loc.DownloadPopupDescriptionIOS; - } - for (let i = 0; i < checkboxes.length; i++) { - try { - if (sGet(checkboxes[i]) === "true") eid(checkboxes[i]).checked = true; - } - catch { - console.error(`checkbox ${checkboxes[i]} failed to initialize`) - } - } - for (let i in switchers) { - changeSwitcher(i, sGet(i)) - } - updateFilenamePreview() -} - -window.onload = () => { - loadCelebrationsEmoji(); - - loadSettings(); - detectColorScheme(); - - changeDownloadButton("hidden"); - eid("url-input-area").value = ""; - - if (isIOS) { - sSet("downloadPopup", "true"); - eid("downloadPopup-chkbx").style.display = "none"; - } - - eid("home").style.visibility = 'visible'; - eid("home").classList.toggle("visible"); - - const pageQuery = new URLSearchParams(window.location.search); - if (pageQuery.has("u") && validLink(pageQuery.get("u"))) { - eid("url-input-area").value = pageQuery.get("u"); - button() - } - window.history.replaceState(null, '', window.location.pathname); - - // fix for animations not working in Safari - if (isIOS) { - document.addEventListener('touchstart', () => {}, true); - } -} - -eid("url-input-area").addEventListener("keydown", () => { - button(); -}) -eid("url-input-area").addEventListener("keyup", (e) => { - if (e.key === 'Enter') eid("download-button").click(); -}) - -document.addEventListener("keydown", (event) => { - if (event.key === "Tab") { - eid("download-button").value = '>>' - eid("download-button").style.padding = '0 1rem' - } -}) -document.onkeydown = (e) => { - if (!store.isPopupOpen) { - if (e.metaKey || e.ctrlKey || e.key === "/") eid("url-input-area").focus(); - if (e.key === "Escape" || e.key === "Clear") clearInput(); - - if (e.target === eid("url-input-area")) return; - - // top buttons - if (e.key === "D") pasteClipboard(); - if (e.key === "K") changeSwitcher('audioMode', 'false'); - if (e.key === "L") changeSwitcher('audioMode', 'true'); - - // popups - if (e.key === "B") popup('about', 1, 'about'); // open about - if (e.key === "N") popup('about', 1, 'changelog'); // open changelog - if (e.key === "M") popup('settings', 1); - - } else { - if (e.key === "Escape") hideAllPopups(); - } -} diff --git a/api/src/front/emoji/3d/film_frames.png b/api/src/front/emoji/3d/film_frames.png deleted file mode 100644 index 6522c5f737612757ac117488aeffaf48fff464c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8720 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 A!2kdN diff --git a/api/src/front/emoji/3d/headphone.png b/api/src/front/emoji/3d/headphone.png deleted file mode 100644 index b46173a2915807ea81fa6023e735596e29293e18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11316 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 - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/alien_monster.svg b/api/src/front/emoji/alien_monster.svg deleted file mode 100644 index 66be00bd..00000000 --- a/api/src/front/emoji/alien_monster.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/biceps.svg b/api/src/front/emoji/biceps.svg deleted file mode 100644 index 4de9e74e..00000000 --- a/api/src/front/emoji/biceps.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/api/src/front/emoji/bird.svg b/api/src/front/emoji/bird.svg deleted file mode 100644 index 55cf0208..00000000 --- a/api/src/front/emoji/bird.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/api/src/front/emoji/boring_document.svg b/api/src/front/emoji/boring_document.svg deleted file mode 100644 index ec3e642f..00000000 --- a/api/src/front/emoji/boring_document.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/bubbles.svg b/api/src/front/emoji/bubbles.svg deleted file mode 100644 index e5bccc36..00000000 --- a/api/src/front/emoji/bubbles.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/front/emoji/cake.svg b/api/src/front/emoji/cake.svg deleted file mode 100644 index c6de34d4..00000000 --- a/api/src/front/emoji/cake.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/api/src/front/emoji/candle.svg b/api/src/front/emoji/candle.svg deleted file mode 100644 index f62a93d3..00000000 --- a/api/src/front/emoji/candle.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/api/src/front/emoji/cat.svg b/api/src/front/emoji/cat.svg deleted file mode 100644 index a29d581e..00000000 --- a/api/src/front/emoji/cat.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/api/src/front/emoji/cat_crying.svg b/api/src/front/emoji/cat_crying.svg deleted file mode 100644 index 896ae898..00000000 --- a/api/src/front/emoji/cat_crying.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/cat_flabbergasted.svg b/api/src/front/emoji/cat_flabbergasted.svg deleted file mode 100644 index 92f72427..00000000 --- a/api/src/front/emoji/cat_flabbergasted.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/cat_grin.svg b/api/src/front/emoji/cat_grin.svg deleted file mode 100644 index 4b7cbb06..00000000 --- a/api/src/front/emoji/cat_grin.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/cat_smile.svg b/api/src/front/emoji/cat_smile.svg deleted file mode 100644 index 06ff249c..00000000 --- a/api/src/front/emoji/cat_smile.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/christmas_tree.svg b/api/src/front/emoji/christmas_tree.svg deleted file mode 100644 index dead8216..00000000 --- a/api/src/front/emoji/christmas_tree.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/api/src/front/emoji/clapper_board.svg b/api/src/front/emoji/clapper_board.svg deleted file mode 100644 index 8bcf482b..00000000 --- a/api/src/front/emoji/clapper_board.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/api/src/front/emoji/clipboard.svg b/api/src/front/emoji/clipboard.svg deleted file mode 100644 index b4d28229..00000000 --- a/api/src/front/emoji/clipboard.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/api/src/front/emoji/crystal_ball.svg b/api/src/front/emoji/crystal_ball.svg deleted file mode 100644 index d2a7f670..00000000 --- a/api/src/front/emoji/crystal_ball.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/api/src/front/emoji/dog.svg b/api/src/front/emoji/dog.svg deleted file mode 100644 index 03056a1f..00000000 --- a/api/src/front/emoji/dog.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/api/src/front/emoji/dragon_face.svg b/api/src/front/emoji/dragon_face.svg deleted file mode 100644 index 861ae074..00000000 --- a/api/src/front/emoji/dragon_face.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/api/src/front/emoji/dragon_face_wukko.svg b/api/src/front/emoji/dragon_face_wukko.svg deleted file mode 100644 index c389f4c8..00000000 --- a/api/src/front/emoji/dragon_face_wukko.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/api/src/front/emoji/elephant.svg b/api/src/front/emoji/elephant.svg deleted file mode 100644 index 3f96a89a..00000000 --- a/api/src/front/emoji/elephant.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/api/src/front/emoji/email.svg b/api/src/front/emoji/email.svg deleted file mode 100644 index 144c9534..00000000 --- a/api/src/front/emoji/email.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/film_frames.svg b/api/src/front/emoji/film_frames.svg deleted file mode 100644 index 7471d431..00000000 --- a/api/src/front/emoji/film_frames.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/api/src/front/emoji/gear.svg b/api/src/front/emoji/gear.svg deleted file mode 100644 index 8351a33a..00000000 --- a/api/src/front/emoji/gear.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/api/src/front/emoji/headphone.svg b/api/src/front/emoji/headphone.svg deleted file mode 100644 index 1c9b6702..00000000 --- a/api/src/front/emoji/headphone.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/keyboard.svg b/api/src/front/emoji/keyboard.svg deleted file mode 100644 index f6cb218b..00000000 --- a/api/src/front/emoji/keyboard.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/api/src/front/emoji/link.svg b/api/src/front/emoji/link.svg deleted file mode 100644 index c3d86605..00000000 --- a/api/src/front/emoji/link.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/api/src/front/emoji/locked.svg b/api/src/front/emoji/locked.svg deleted file mode 100644 index 98e9e0e7..00000000 --- a/api/src/front/emoji/locked.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/loudspeaker.svg b/api/src/front/emoji/loudspeaker.svg deleted file mode 100644 index 6acd5873..00000000 --- a/api/src/front/emoji/loudspeaker.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/api/src/front/emoji/magic_wand.svg b/api/src/front/emoji/magic_wand.svg deleted file mode 100644 index b10883b6..00000000 --- a/api/src/front/emoji/magic_wand.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/api/src/front/emoji/magnifying_glass.svg b/api/src/front/emoji/magnifying_glass.svg deleted file mode 100644 index 905da556..00000000 --- a/api/src/front/emoji/magnifying_glass.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/mailbox.svg b/api/src/front/emoji/mailbox.svg deleted file mode 100644 index 5dfd70b5..00000000 --- a/api/src/front/emoji/mailbox.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/api/src/front/emoji/mending_heart.svg b/api/src/front/emoji/mending_heart.svg deleted file mode 100644 index 3b647fa7..00000000 --- a/api/src/front/emoji/mending_heart.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/money_with_wings.svg b/api/src/front/emoji/money_with_wings.svg deleted file mode 100644 index 56d0cb0c..00000000 --- a/api/src/front/emoji/money_with_wings.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/api/src/front/emoji/musical_notes.svg b/api/src/front/emoji/musical_notes.svg deleted file mode 100644 index f66414f0..00000000 --- a/api/src/front/emoji/musical_notes.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/api/src/front/emoji/newspaper.svg b/api/src/front/emoji/newspaper.svg deleted file mode 100644 index ebe0b5fd..00000000 --- a/api/src/front/emoji/newspaper.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/octopus.svg b/api/src/front/emoji/octopus.svg deleted file mode 100644 index b8c6e906..00000000 --- a/api/src/front/emoji/octopus.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/api/src/front/emoji/party_popper.svg b/api/src/front/emoji/party_popper.svg deleted file mode 100644 index 93113d0f..00000000 --- a/api/src/front/emoji/party_popper.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/api/src/front/emoji/pinata.svg b/api/src/front/emoji/pinata.svg deleted file mode 100644 index cf260701..00000000 --- a/api/src/front/emoji/pinata.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/api/src/front/emoji/pumpkin.svg b/api/src/front/emoji/pumpkin.svg deleted file mode 100644 index 3dcf031a..00000000 --- a/api/src/front/emoji/pumpkin.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/api/src/front/emoji/question_mark.svg b/api/src/front/emoji/question_mark.svg deleted file mode 100644 index 3c7e887a..00000000 --- a/api/src/front/emoji/question_mark.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/api/src/front/emoji/sparkles.svg b/api/src/front/emoji/sparkles.svg deleted file mode 100644 index e9702d09..00000000 --- a/api/src/front/emoji/sparkles.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/api/src/front/emoji/sparkling_heart.svg b/api/src/front/emoji/sparkling_heart.svg deleted file mode 100644 index b5dd6eb2..00000000 --- a/api/src/front/emoji/sparkling_heart.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/api/src/front/emoji/wrench.svg b/api/src/front/emoji/wrench.svg deleted file mode 100644 index b186d3b3..00000000 --- a/api/src/front/emoji/wrench.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/api/src/front/fonts/files/notosansmono_3dVQ.woff2 b/api/src/front/fonts/files/notosansmono_3dVQ.woff2 deleted file mode 100644 index 1174c3628ccfb454e1934e3c3570f289cad42b9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9292 zcmV-SB(vLhPew8T0RR9103=KR4gdfE07_f{03-1L0RR9100000000000000000000 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 diff --git a/api/src/front/fonts/files/notosansmono_7dVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_7dVXQQ.woff2 deleted file mode 100644 index e9fcb07d7865eb71abf45f9d3232f00cdb766753..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5912 zcmV+z7w71APew8T0RR9102del4gdfE04^*502aLf0RR9100000000000000000000 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 diff --git a/api/src/front/fonts/files/notosansmono_HdVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_HdVXQQ.woff2 deleted file mode 100644 index 95050fe689e872094a48523cba6723519f3ab3ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4460 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 diff --git a/api/src/front/fonts/files/notosansmono_LdVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_LdVXQQ.woff2 deleted file mode 100644 index 137ea72c0d381bec968d3b2c4ecb74fe75557b48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2592 zcmV+*3g7j2Pew8T0RR91016-g4gdfE02)XD013tb0RR9100000000000000000000 z0000QHX9%uHU?lnQ&d4zBmjI0qyV603xW&)0X7081B3_!AO(aP2Ot})7NeqmaZ+Lg z|2&M1S%-(IUB#+h8jGOPVbt=R z6CDt2{~E}C0l)v>+N<50nHSyw+fCTG%$X87xx0U9&i@l+Sq8Pg_(7{k?Go$n+ZzOo3hK*CQ7~G82qrTS5CQ0ysIpaXo$*>vcvn|gT-T!Xn^ee=q-STP$xi+1%Z%&D{|%5 zbjrozAONO34htcmbTC_dF(6yb;`-wKd14R|hIo;|#7eu#N$JnhU!{M`kGfnyDDfnN zh=q2M6VhGMU!=d4zn3manf-oG?9y-lL;~A^>*@mjgx`AWRuFWZ zxkCm+)DnK{93a|lA|8h%<6^IQ$LVJoUs}r( z1EVKmszYt(bu#Y;zx*2f)uH>#g6B@uMe$RexAd1Ob_n+UjpzNz#{KIzb>)OiRm+dw z`bHSPZRgGqGhcnOx3_NFojV~sw!C;Th+~KtMnO9U=PplwljGPv9Qo*4$8YNDB19&( zTzyD8tJJIB>{3U>sMF}tzjkNmDucltcs1nEizv?4`DR3+@9??Bf{$hVu3p>tHr8$1 zd*aHi{&SZeDmfamk?TBv`TW(chXQLaTp{zE&HH@G<_nX0=G?1sq1+@DAH4C-b_5&z zwr+<%`69vVgD2BIeA2w;*Ytfyv*V6#Ok4MB#IrEd2Yx1)oyTgjovIqu*V#3&6s!`5 z>bZiY1#7Ia=9y!NFuPurULU%+s(sXcyUCQ@piFBBTcp*7ElI0yRAp4FGc=*o4GXeX zSE@5LVVlU%wB^}hu&~mSrkGUzyyGO<25 z#oA$RuvCfj+2*XDIqi@fY4>o2nas-#;AKO{K`R_RTaz`zWJsIYkyV;MK2_abrkok7 zD5#K+8lv|?!L?ea? z)#k{|+{g(z)oIh)(hCaO)6!?uWJgZWirCLvo5#_d{%c?s!wO%+Qbjgf-^+ zx^YeAsR~VM{IvjGibqpOl_b|K#OGry{>?}GsqWOT9h4~5eU@f)nU6X^ zYaf}FTi;ldVUh|9jfI$F_3k}z)^=`xZ-gj!PD5AM$ko{xT$5K>D$A&TYV(!Znle3f zWf(F+e+Ng+@So092Kmj&m3jHu%!#Fmxg-4M#4Eh~&9*~9%y-mye}74kpn00E0L>Qn`+N0@iW~_@*z^&(%0(`66D^Jqu_Dkbs{$vq+>J4! ziYkgI8(0DzXg|beKT|HEAct7OZbflscr6qW6H!GKMU)LKF@l8|KS z$ffS_@0rCKK%Ek+WHh=MN|-()lTq^x<@AekcFmeFpYTT}8?2`w^{`u$>CyeKh4neG z{o-nhsWZWi|Bs!u6!cB1@n{+?MkP$2Q8}YF*)>b@34dg=!Fr0|p<#&W=_Y*b)N@P= z-e)?s-mt(IfLiUdvBe6aPTA8E8uHokzF|iFSy4|u{lfdg7;V5;09{f8$fgsi^E1{V zpEd6rX4Jwr+!Or*T-9Ubzg+gIMbY%To?9G36?#x_?VRsh5M7A9lwPVvZXY86C|TCj zwJ)VklJdJd!+Zt6d$-b!xR5h?)&Kv!4RB|l{@&oN00I7EvCB49{Qu1Zg4#4^jHung z3uag_80nA!=z#`_D1-{xh{2D5_F^?SZHZ7i=3*7Tz$7ip!QfsM@8>O63-j_ygr%@B ztYeV^>B~ABGFglTz;zCVf5_hFt!jM>db*bo0E-fZf@H!Efl}_PTLU6|F(6h5pccF~ z!d`6~qrzv_;S@VHVB13UUbRJ-eb-ju81J@5XmVRyBGTATAk_N&2r@DqS=zLl#?ER2 z3kNx+SR;)hm#0lzxw_dnRoocQG6E{2fac!HaB`xn#@S8d*iBxmv4O6o+BmdrsnVd8 z9xu`6ur?Q4tR`v6P!nX=W)19=P_d1!@si~!Q+eX22J3Jw4u@XZDP}!YF2|qaR^@EE zwo9U*z!+uq-CC0)@>R3_yxZ7Kpim}PalP?148hEe8(7O<*ujDU0KnBv2_OIz0001O CKLx%3 diff --git a/api/src/front/fonts/files/notosansmono_PdVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_PdVXQQ.woff2 deleted file mode 100644 index e3267a5ef390d835dfeaa411c652a523045aad90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26380 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 diff --git a/api/src/front/fonts/files/notosansmono_ndVXQQ.woff2 b/api/src/front/fonts/files/notosansmono_ndVXQQ.woff2 deleted file mode 100644 index bb374b0a546c5711cfa8f97be947d5768065be78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5272 zcmV;J6ld#qPew8T0RR9102G)24gdfE04QVt02Dj`0RR9100000000000000000000 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 diff --git a/api/src/front/fonts/notosansmono.css b/api/src/front/fonts/notosansmono.css deleted file mode 100644 index 827b4f61..00000000 --- a/api/src/front/fonts/notosansmono.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('files/notosansmono_DdVXQQ.woff2') format('woff2');unicode-range:U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('files/notosansmono_ndVXQQ.woff2') format('woff2');unicode-range:U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('files/notosansmono_HdVXQQ.woff2') format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('files/notosansmono_7dVXQQ.woff2') format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('files/notosansmono_LdVXQQ.woff2') format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('files/notosansmono_PdVXQQ.woff2') format('woff2');unicode-range:U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('files/notosansmono_3dVQ.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD} \ No newline at end of file diff --git a/api/src/front/icons/android-chrome-192x192.png b/api/src/front/icons/android-chrome-192x192.png deleted file mode 100644 index 0d3ac83a24696f6d2e99ffe51177a583e01a6533..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3580 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 diff --git a/api/src/front/icons/apple-touch-icon.png b/api/src/front/icons/apple-touch-icon.png deleted file mode 100644 index b2abfa63d553dc474982d8b3d36dee71f9ceb0ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3278 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 N(3fm4)*(HT{tc`e{yYEx diff --git a/api/src/front/icons/favicon-16x16.png b/api/src/front/icons/favicon-16x16.png deleted file mode 100644 index 94f9c1a907c7a34881b87009d4903b834f305556..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx*Bp9q_EZ7UA=6Sj}hDcoQ?c2-8m?+|Me(!y8 z)?Sy88@=p~?n;X$bu=BR;$ZDnf6QwpHFZAQ#Q*`VY|+_wHC%iQPtNpFW3Km5*`~6w zVFpJ}z@~Cxt7i+Pn6g&Lv^o8~QP1ke*z&IK`m*9E^Un4&37ZQfbDyV%FmnDWzIt%~ z6|TVLTlbs|>b+Vz%k99WYQIet2Q8Yp6huC2Fp5;AC5e4;xGM-W}gvosB>hpHfYLLS0VLDM<83$;d| zeamHOGYLWGj>peT`3wQN4_tn1Bq65f$YUYhYOSEXr(`jm0ICKq$oJJ4r0h;bif&;o z4hbVe?=97A*??k?sTPQ;L5|CfJ{u4WxBV8!;sLv&kEq~b{&;)=hwo_B9UbI+00000 LNkvXXu0mjfO!k}l diff --git a/api/src/front/icons/favicon.ico b/api/src/front/icons/favicon.ico deleted file mode 100644 index 1b08e4bb950906a1ac5b144997ccb290d21b1e8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9662 zcmeHKODJ|*7~bwlxr8I+eh!DC4`Cu@ppcMT2Fh`n8JWqLnNlWZGU8;wKvI-M2IMZ6 zC<7w~QX+Tn`JVNkXSIC)r_S%&=RbAY>uc||+iN}Rectzd-nG|fS$^)H%VoLmsn(yr zS=KL>W&Q5H+^?)Z+!x-f_N!&BhJU-hy-;^?-<`{efujLO1C9n94LBNbG~j69Zw>hS z`%6GTz?b6T3)YS^8F&W<1}g49$^|(3{i9f4xx*gTNJ~qTm6a8#t*zDZ#~6L`W{22< zf&y7xU6u0k@()=0&U0Yj|s;VmS^Yc@_VD7(> z53U~>87aHFyUI5Bzr4I?E_-`>(%jsvwFEBkgZz_{lH~mS+$(l{eO+p5YCia3#=tHe zVV$6$AZcxFm7Sd(#Rai6{Wv%{P~(_~`Sb(Np`oGD+1V+_$H!i=o12?bUth0tKrG|u zs~=d0Yhi7~3>siFb#-)fByDYN5*!??{D3Z~4fxj5(jr@1TiOp`sVl^$si{fNx6=>s zH+6xSU{6_CSkU%OKTb|gq`kdeLPA26A0`&Os;jG2J)1G0AN%|JDwouf89!fh0X*Uf z4qU6axL9UpW(54vP$T4WdU`5dU0q)N0KTlOOy=k3^?Vb1czF0Bm$YYBPd})w+}vE5 zn3&LYVb%w96&o9?YlB#FDJ(3M>FH_ZJA5#8g}p8!B0^zli#R)aaDld&6MXLwJ2dQ@ zPft%OzFApWnm_G&VsmnG^nL{#@z}$Gp$+1F?Xey>a2?hJ>>`HL)Ya9MBqSt!;NXd^ ztgMvfEG{l8 zEO5j=JUqzo@UYe$Z826~>9K~nm!zhq%J}%WiWvx)nnz7%XJ>!P8+w|Wn$moMMFaoI z$w|q`$k5oYa5XWWyklZwWN2te?(grFP1r`=q2b$5T3V`Y!(Y?~oy2>)hn@PoJ?4a*p|7VPVqO*C*H4*V;BUjy=Dzu~E&#T-Y}4M@2=+z`%gq z-rjzP#W@7u1adNQeCJD#_;q)83u*}soSE;-%S-9$>G|%P%Xs7b(A(Q9s9`kVh{bvx z9Uc1oM4x@(N-XV%hllHLzRCOU?oI{=2Li|2vU4$GzF(7|sRQk4j2P zG;h0W)0=(s9pdEeJZ#SS>=|{B3*$eVx5)|d{Azvqf;Blf&-U$YPAr{RIvQ{^;Ap_n SfTMx`g$CSdblQIvfxiHiNSp`& diff --git a/api/src/front/icons/generic.png b/api/src/front/icons/generic.png deleted file mode 100644 index d1777d489d3824d04f6d6db9f1d7e167b5f4dbc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9818 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 diff --git a/api/src/front/icons/maskable/128.png b/api/src/front/icons/maskable/128.png deleted file mode 100644 index e8213cfe5828cc4435d15e4da25d5e57b3f2c472..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 815 zcmV+~1JL}5P)C0002YP)t-s00030 z|Ns5{{T3D$`T6gwv<-QBdbw3CyQgoK2BeSJ7MIN;#m$jHdIx3{aStB{b8 ziHV7HbaZ89Wll~`OG`^dMMVh-3GD3b=H}+)SUnwoKOaadSbR8&+y zKR-J=J2EmdBqSvB^YiWP?Y+IdsHmuwm6d^kfm&KxK|w*<+S%6WNt=~O%#0006W zNkl~PJx+&|Ey*O!vMtM z0l3frw1Tc_06Oak7&-Xg;QW2S#V`+SP;tw7(*UgV-4J)bEL6tXHm_6jcfe)WL#2`C z^pvCxYQZOPnYnmjEe_e1R;e}afJxF`qSEYw&U<>KR%V+}`GZQW7=tcuQS(b4F!4$* zDxC`GqGF9MM9MbdR7Pdl&bDKpT4M}c!j*R4%@WWZmegL32{75OQCUy3Z4yxH&w)uY z_33g45$FmNq*kl|mydf?-m|GNtW)~{E|o1R*Dc>xsS14TfCgL(FF%k2Y<5N8IAGFq zmQjR!I-$qjFb%Erf4HCZ}!tI^jGABIgZQgf~3>jWYa&{Am z)r<5N26}69JOE|`)Ren=`+P;>w>VzNx{WH5lAQyxuj}pI0}e=@2iX(aNa~vycsO{` ziUCXmI(Z;01Kd&!U>NZ7^Zo diff --git a/api/src/front/icons/maskable/192.png b/api/src/front/icons/maskable/192.png deleted file mode 100644 index 8268d89a58c3c6334d887d403c4a9a615343c5f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1014 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 nv_N+M?+@W;^HqDlV&cz;Xd diff --git a/api/src/front/icons/maskable/48.png b/api/src/front/icons/maskable/48.png deleted file mode 100644 index 02a5bca0fb8b6cf17cd1327fab8f337e61c79489..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 390 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 diff --git a/api/src/front/icons/maskable/72.png b/api/src/front/icons/maskable/72.png deleted file mode 100644 index 903f6bd500691990bc32f79d2192de30a594dbac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 569 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 diff --git a/api/src/front/manifest.webmanifest b/api/src/front/manifest.webmanifest deleted file mode 100644 index 3777ca6d..00000000 --- a/api/src/front/manifest.webmanifest +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "cobalt", - "short_name": "cobalt", - "start_url": "/", - "icons": [ - { - "src": "/icons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/icons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "/icons/generic.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/icons/maskable/48.png", - "sizes": "48x48", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/maskable/72.png", - "sizes": "72x72", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/maskable/96.png", - "sizes": "96x96", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/maskable/128.png", - "sizes": "128x128", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/maskable/192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/maskable/384.png", - "sizes": "384x384", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/maskable/512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ], - "share_target": { - "action": "/", - "params": { - "text": "u", - "url": "u" - } - }, - "theme_color": "#000000", - "background_color": "#000000", - "display": "standalone" -} diff --git a/api/src/front/robots.txt b/api/src/front/robots.txt deleted file mode 100644 index a5218222..00000000 --- a/api/src/front/robots.txt +++ /dev/null @@ -1,8 +0,0 @@ -User-Agent: * -Disallow: /emoji/ -Disallow: /fonts/ -Disallow: /icons/ -Disallow: /sponsors/ -Disallow: /updateBanners/ -Disallow: /*.js -Disallow: /*.css diff --git a/api/src/front/sponsors/royale.svg b/api/src/front/sponsors/royale.svg deleted file mode 100644 index c0338038..00000000 --- a/api/src/front/sponsors/royale.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/api/src/modules/build.js b/api/src/modules/build.js deleted file mode 100644 index a4c4aa6b..00000000 --- a/api/src/modules/build.js +++ /dev/null @@ -1,41 +0,0 @@ -import * as esbuild from "esbuild"; -import * as fs from "fs"; -import { loadLoc, languageList } from "../localization/manager.js"; -import { cleanHTML } from "./sub/utils.js"; - -import page from "./pageRender/page.js"; - -export async function buildFront(commitHash, branch) { - try { - // preload localization files - await loadLoc(); - - // build html - if (!fs.existsSync('./build/')){ - fs.mkdirSync('./build/'); - } - // get rid of old build path - if (fs.existsSync('./min')) { - fs.rmSync('./min', { recursive: true, force: true }); - } - for (let i in languageList) { - i = languageList[i]; - let params = { - "hash": commitHash, - "lang": i, - "branch": branch - } - fs.writeFileSync(`./build/${i}.html`, cleanHTML(page(params))); - } - // build js & css - await esbuild.build({ - entryPoints: ['src/front/cobalt.js', 'src/front/cobalt.css'], - outdir: 'build/min/', - minify: true, - loader: { '.js': 'js', '.css': 'css', }, - charset: 'utf8' - }) - } catch { - return; - } -} diff --git a/api/src/modules/buildStatic.js b/api/src/modules/buildStatic.js deleted file mode 100644 index d3ed909f..00000000 --- a/api/src/modules/buildStatic.js +++ /dev/null @@ -1,7 +0,0 @@ -import { buildFront } from "./build.js"; -import { getCurrentBranch, shortCommit } from "./sub/currentCommit.js"; - -const commitHash = shortCommit(); -const branch = getCurrentBranch(); - -await buildFront(commitHash, branch); diff --git a/api/src/modules/changelog/changelogManager.js b/api/src/modules/changelog/changelogManager.js deleted file mode 100644 index b8763fb5..00000000 --- a/api/src/modules/changelog/changelogManager.js +++ /dev/null @@ -1,46 +0,0 @@ -import { replaceBase } from "../../localization/manager.js"; -import { loadJSON } from "../sub/loadFromFs.js"; - -let changelog = loadJSON('./src/modules/changelog/changelog.json') - -export default function(string) { - try { - const currentChangelog = changelog.current; - - switch (string) { - case "version": - return `v.${currentChangelog.version}${ - currentChangelog.date ? `· ${currentChangelog.date}` : '' - }` - case "title": - return replaceBase(currentChangelog.title); - case "banner": - const currentBanner = changelog.current.banner; - return currentBanner ? { - ...currentBanner, - url: `updateBanners/${currentBanner.file}` - } : false; - case "content": - return replaceBase(currentChangelog.content); - case "history": - return changelog.history.map((log) => { - const banner = log.banner; - return { - title: replaceBase(log.title), - version: `v.${log.version}${ - log.date ? `· ${log.date}` : '' - }`, - content: replaceBase(log.content), - banner: banner ? { - ...banner, - url: `updateBanners/${banner.file}` - } : false, - } - }); - default: - return replaceBase(changelog[string]) - } - } catch (e) { - return `!!CHANGELOG_${string}!!` - } -} diff --git a/api/src/modules/emoji.js b/api/src/modules/emoji.js deleted file mode 100644 index 82273ac4..00000000 --- a/api/src/modules/emoji.js +++ /dev/null @@ -1,66 +0,0 @@ -const names = { - "🎶": "musical_notes", - "🎬": "clapper_board", - "🎉": "party_popper", - "❓": "question_mark", - "✨": "sparkles", - "🪅": "pinata", - "🪄": "magic_wand", - "🐲": "dragon_face", - "🀄": "dragon_face_wukko", - "💸": "money_with_wings", - "⚙️": "gear", - "📋": "clipboard", - "🎃": "pumpkin", - "🎄": "christmas_tree", - "🕯️": "candle", - "😺": "cat", - "🐶": "dog", - "🎂": "cake", - "🐘": "elephant", - "🐦": "bird", - "🐙": "octopus", - "🔮": "crystal_ball", - "💪": "biceps", - "💖": "sparkling_heart", - "👾": "alien_monster", - "😿": "cat_crying", - "🙀": "cat_flabbergasted", - "🐱": "cat_smile", - "❤️‍🩹": "mending_heart", - "🔒": "locked", - "🔍": "magnifying_glass", - "🔗": "link", - "⌨": "keyboard", - "📑": "boring_document", - "🧮": "abacus", - "😸": "cat_grin", - "📰": "newspaper", - "🎞️": "film_frames", - "🎧": "headphone", - "📧": "email", - "📬": "mailbox", - "📢": "loudspeaker", - "🔧": "wrench", - "🫧": "bubbles" -} -let sizing = { - 18: 0.8, - 22: 0.4, - 30: 0.7, - 32: 0.8, - 48: 0.9, - 64: 0.9, - 78: 0.9 -} -export default function(emoji, size, disablePadding, fluent) { - if (!size) size = 22; - let padding = size !== 22 ? `margin-right:${sizing[size] ? sizing[size] : "0.4"}rem;` : false; - if (disablePadding) padding = 'margin-right:0!important;'; - - if (!names[emoji]) emoji = "❓"; - - let filePath = `emoji/${names[emoji]}.svg`; - if (fluent) filePath = `emoji/3d/${names[emoji]}.png`; - return `` -} diff --git a/api/src/modules/pageRender/elements.js b/api/src/modules/pageRender/elements.js deleted file mode 100644 index ae14cd88..00000000 --- a/api/src/modules/pageRender/elements.js +++ /dev/null @@ -1,270 +0,0 @@ -import { authorInfo, celebrations, sponsors, env } from "../config.js"; -import emoji from "../emoji.js"; -import { loadFile } from "../sub/loadFromFs.js"; - -export const backButtonSVG = ` - -` - -export const dropdownSVG = ` - -` - -export const linkSVG = '' - -export function switcher(obj) { - let items = ``; - if (obj.name === "download") { - items = obj.items; - } else { - for (let i = 0; i < obj.items.length; i++) { - let classes = obj.items[i]["classes"] ? obj.items[i]["classes"] : []; - items += `` - } - } - - if (obj.noParent) return `
${items}
`; - return `
- ${obj.subtitle ? `
${obj.subtitle}
` : ``} -
${items}
- ${obj.explanation ? `
${obj.explanation}
` : ``} -
` -} -export function checkbox(obj) { - let paddings = ["bottom-margin", "top-margin", "no-margin", "top-margin-only"]; - let checkboxes = ``; - for (let i = 0; i < obj.length; i++) { - let paddingClass = obj[i].padding && paddings.includes(obj[i].padding) ? ` ${obj[i].padding}` : ''; - - checkboxes += `` - } - return checkboxes -} -export function sep(paddingType) { - let paddingClass = `` - switch(paddingType) { - case 0: - paddingClass += ` top-margin`; - break; - } - return `
` -} -export function popup(obj) { - let classes = obj.classes ? obj.classes : []; - let body = obj.body; - if (Array.isArray(obj.body)) { - body = `` - for (let i = 0; i < obj.body.length; i++) { - if (obj.body[i]["text"].length > 0) { - classes = obj.body[i]["classes"] ?? [] - if (i !== obj.body.length - 1 && !obj.body[i]["nopadding"]) { - classes.push("desc-padding") - } - body += obj.body[i]["raw"] ? obj.body[i]["text"] : `
${obj.body[i]["text"]}
` - } - } - } - return ` - ${obj.standalone ? `
` : ''}` -} - -export function multiPagePopup(obj) { - let tabs = ` - `; - - let tabContent = ``; - for (let i = 0; i < obj.tabs.length; i++) { - tabs += `` - tabContent += `` - } - - return ` - ` -} -export function collapsibleList(arr) { - let items = ``; - - for (let i = 0; i < arr.length; i++) { - let classes = arr[i]["classes"] ? arr[i]["classes"] : []; - items += `
-
-
${arr[i]["title"]}
-
${dropdownSVG}
-
-
${arr[i]["body"]}
-
` - } - return items; -} -export function popupWithBottomButtons(obj) { - let tabs = ` - ` - - for (let i = 0; i < obj.buttons.length; i++) { - tabs += obj.buttons[i] - } - return ` - ` -} -export function socialLink(emji, name, url) { - return `` -} -export function socialLinks(lang) { - let links = authorInfo.support[lang] ? authorInfo.support[lang] : authorInfo.support.default; - let r = ``; - for (let i in links) { - r += socialLink( - emoji(links[i].emoji), links[i].name, links[i].url - ) - } - return r -} -export function settingsCategory(obj) { - return `
-
${obj.title ?? obj.name}
-
${obj.body}
-
` -} - -export function footerButtons(obj) { - let items = `` - for (let i = 0; i < obj.length; i++) { - let buttonName = obj[i]["context"] ? `${obj[i]["name"]}-${obj[i]["context"]}` : obj[i]["name"], - context = obj[i]["context"] ? `, '${obj[i]["context"]}'` : '', - buttonName2, - context2; - - if (obj[i + 1]) { - buttonName2 = obj[i + 1]["context"] ? `${obj[i + 1]["name"]}-${obj[i + 1]["context"]}` : obj[i + 1]["name"]; - context2 = obj[i + 1]["context"] ? `, '${obj[i + 1]["context"]}'` : ''; - } - - items += - ``; - i++; - } - return ` - ` -} -export function explanation(text) { - return `
${text}
` -} -export function celebrationsEmoji() { - try { - let n = new Date().toISOString().split('T')[0].split('-'); - let dm = `${n[1]}-${n[2]}`; - let f = Object.keys(celebrations).includes(dm) ? celebrations[dm] : "🐲"; - return f != "🐲" ? emoji(f, 22) : false; - } catch (e) { - return false - } -} -export function urgentNotice(obj) { - if (obj.visible) { - return `
` + - `${emoji(obj.emoji, 18)} ${obj.text}` + - `
` - } - return `` -} -export function keyboardShortcuts(arr) { - let base = `
`; - - for (let i = 0; i < arr.length; i++) { - base += `
`; - for (let c = 0; c < arr[i].items.length; c++) { - let combo = arr[i].items[c].combo.split('+').map( - key => `${key}` - ).join("+") - base += `
${combo}: ${arr[i].items[c].name}
` - } - base += `
` - } - base += `
`; - - return base; -} -export function webLoc(t, arr) { - let base = ``; - for (let i = 0; i < arr.length; i++) { - base += `${arr[i]}:` + "`" + t(arr[i]) + "`" + `,` - } - return `{${base}};` -} - -export function sponsoredList() { - let base = ``; - let altText = `` - for (let i = 0; i < sponsors.length; i++) { - let s = sponsors[i]; - let loadedLogo = loadFile(`./src/front/sponsors/${s.name}.svg`); - - altText += `${s.fullName ? s.fullName : s.name}, `; - base += - `` - } - return `` -} - -export function betaTag() { - return env.isBeta ? 'β' : '' -} diff --git a/api/src/modules/pageRender/findRendered.js b/api/src/modules/pageRender/findRendered.js deleted file mode 100644 index 1cbb01aa..00000000 --- a/api/src/modules/pageRender/findRendered.js +++ /dev/null @@ -1,6 +0,0 @@ -import { languageList } from "../../localization/manager.js"; - -export default function(lang) { - let language = languageList.includes(lang) ? lang : "en"; - return `/build/${language}.html`; -} diff --git a/api/src/modules/pageRender/onDemand.js b/api/src/modules/pageRender/onDemand.js deleted file mode 100644 index 7667708f..00000000 --- a/api/src/modules/pageRender/onDemand.js +++ /dev/null @@ -1,33 +0,0 @@ -import changelogManager from "../changelog/changelogManager.js" -import { cleanHTML } from "../sub/utils.js"; - -let cache = {} - -export function changelogHistory() { // blockId 0 - if (cache['0']) return cache['0']; - let history = changelogManager("history"); - let render = ``; - - let historyLen = history.length; - for (let i in history) { - let separator = (i !== 0 && i !== historyLen) ? '
' : ''; - - render += ` - ${separator}${history[i]["banner"] ? - `
- `+ - ` -
` : ''} - - - ` - } - render = cleanHTML(render); - cache['0'] = render; - return render; -} diff --git a/api/src/modules/pageRender/page.js b/api/src/modules/pageRender/page.js deleted file mode 100644 index 2c166177..00000000 --- a/api/src/modules/pageRender/page.js +++ /dev/null @@ -1,666 +0,0 @@ -import { services as s, version, repo, donations, supportedAudio, links, env } from "../config.js"; -import { getCommitInfo } from "../sub/currentCommit.js"; -import loc from "../../localization/manager.js"; -import emoji from "../emoji.js"; -import changelogManager from "../changelog/changelogManager.js"; - -import { - checkbox, - collapsibleList, - explanation, - footerButtons, - multiPagePopup, - popup, - popupWithBottomButtons, - sep, - settingsCategory, - switcher, - socialLink, - socialLinks, - urgentNotice, - keyboardShortcuts, - webLoc, - sponsoredList, - betaTag, - linkSVG -} from "./elements.js"; - -let com = getCommitInfo(); - -let enabledServices = Object.keys(s).filter(p => s[p].enabled).sort().map((p) => { - return `
• ${s[p].alias ? s[p].alias : p}` -}).join('').substring(4) - -let donate = `` -let donateLinks = `` -let audioFormats = supportedAudio.map((p) => { - return { "action": p } -}) -audioFormats.unshift({ "action": "best" }) -for (let i in donations["links"]) { - donateLinks += `REPLACEME ${i}` -} -let extr = '' -for (let i in donations["crypto"]) { - donate += `
${i} (REPLACEME)
${donations["crypto"][i]}
` - extr = ' top-margin' -} - -export default function(obj) { - const t = (str, replace) => { - return loc(obj.lang, str, replace) - } - - audioFormats[0]["text"] = t('SettingsAudioFormatBest'); - - try { - return ` - - - - - - - ${t("AppTitleCobalt")} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${env.plausibleHostname ? - `` - : ''} - - - - ${multiPagePopup({ - name: "about", - closeAria: t('AccessibilityGoBack'), - tabs: [{ - name: "about", - title: `${emoji("🐲")} ${t('AboutTab')}`, - content: popup({ - name: "about", - header: { - aboveTitle: { - text: t('MadeWithLove'), - url: repo - }, - closeAria: t('AccessibilityGoBack'), - title: `${emoji("🔮", 30)} ${t('TitlePopupAbout')}` - }, - body: [{ - text: t('AboutSummary') - }, { - text: collapsibleList([{ - name: "services", - title: `${emoji("🔗")} ${t("CollapseServices")}`, - body: `${enabledServices}` - + `
${t("SupportNotAffiliated")}` - + `${obj.lang === "ru" ? `
${t("SupportMetaNoticeRU")}` : ''}` - + `
` - + `${t("ServicesNote")}` - }, { - name: "keyboard", - title: `${emoji("⌨")} ${t("CollapseKeyboard")}`, - body: - `${t("KeyboardShortcutsIntro")} - ${keyboardShortcuts([{ - items: [{ - combo: "Shift+D", - name: t("PasteFromClipboard") - }, { - combo: "Shift+K", - name: t("ModeToggleAuto") - }, { - combo: "Shift+L", - name: t("ModeToggleAudio") - }] - }, { - items: [{ - combo: "⌘/Ctrl+V", - name: t("KeyboardShortcutQuickPaste") - }, { - combo: "Esc", - name: t("KeyboardShortcutClear") - }, { - combo: "Esc", - name: t("KeyboardShortcutClosePopup") - }] - }, { - items: [{ - combo: "Shift+B", - name: t("AboutTab") - }, { - combo: "Shift+N", - name: t("ChangelogTab") - }, { - combo: "Shift+M", - name: t("TitlePopupSettings") - }] - }])}` - }, { - name: "support", - title: `${emoji("❤️‍🩹")} ${t("CollapseSupport")}`, - body: `${t("SupportSelfTroubleshooting")}` - + `${socialLink(emoji("📢"), t("StatusPage"), links.statusPage)}` - + `${socialLink(emoji("🔧"), t("TroubleshootingGuide"), links.troubleshootingGuide)}` - + `
` - + `${t("FollowSupport")}` - + `${socialLinks(obj.lang)}` - + `
` - + `${t("SourceCode")}` - + `${socialLink(emoji("🐙"), repo.replace("https://github.com/", ''), repo)}` - }, { - name: "privacy", - title: `${emoji("🔒")} ${t("CollapsePrivacy")}`, - body: t("PrivacyPolicy") + `${ - env.plausibleHostname ? `

${t("AnalyticsDescription")}` : '' - }` - }, { - name: "legal", - title: `${emoji("📑")} ${t("CollapseLegal")}`, - body: t("FairUse") - }]) - }, - ...(env.showSponsors ? - [{ - text: t("SponsoredBy"), - classes: ["sponsored-by-text"], - nopadding: true - }, { - text: sponsoredList(), - raw: true - }] : [] - )] - }) - }, { - name: "changelog", - title: `${emoji("🎉")} ${t('ChangelogTab')}`, - content: popup({ - name: "changelog", - header: { - closeAria: t('AccessibilityGoBack'), - title: `${emoji("🪄", 30)} ${t('TitlePopupChangelog')}` - }, - body: [{ - text: `
${t('ChangelogLastMajor')}
`, - raw: true - }, { - text: (() => { - const banner = changelogManager('banner'); - if (!banner) return ''; - return `
- -
`; - })(), - raw: true - }, { - text: changelogManager("version"), - classes: ["changelog-tags"], - nopadding: true - }, { - text: changelogManager("title"), - classes: ["changelog-subtitle"], - nopadding: true - }, { - text: changelogManager("content") - }, { - text: sep(), - raw: true - },{ - text: `#${obj.hash}`, - classes: ["changelog-tags"], - nopadding: true - }, { - text: com[0], - classes: ["changelog-subtitle"], - nopadding: true - }, { - text: com[1] - }, { - text: `
${t('ChangelogOlder')}
`, - raw: true - }, { - text: ` -
- -
`, - raw: true - }] - }) - }, { - name: "donate", - title: `${emoji("💖")} ${t('DonationsTab')}`, - content: popup({ - name: "donate", - header: { - closeAria: t('AccessibilityGoBack'), - title: emoji("💸", 30) + t('TitlePopupDonate') - }, - body: [{ - text: `
${t('DonateSub')}
`, - raw: true - }, { - text: ` -
- -
`, - raw: true - }, { - text: t('DonateExplanation') - }, { - text: donateLinks.replace(/REPLACEME/g, t('DonateVia')), - raw: true - }, { - text: t('DonateLinksDescription'), - classes: ["explanation"] - }, { - text: sep(), - raw: true - }, { - text: donate.replace(/REPLACEME/g, t('ClickToCopy')), - classes: ["desc-padding"] - }] - }) - }], - })} - ${multiPagePopup({ - name: "settings", - closeAria: t('AccessibilityGoBack'), - header: { - aboveTitle: { - text: `v.${version}-${obj.hash} (${obj.branch})`, - url: `${repo}/commit/${obj.hash}` - }, - title: `${emoji("⚙️", 30)} ${t('TitlePopupSettings')}` - }, - tabs: [{ - name: "video", - title: `${emoji("🎬")} ${t('SettingsVideoTab')}`, - content: settingsCategory({ - name: "downloads", - title: t('SettingsQualitySubtitle'), - body: switcher({ - name: "vQuality", - explanation: t('SettingsQualityDescription'), - items: [{ - action: "max", - text: "8k+" - }, { - action: "2160", - text: "4k" - }, { - action: "1440", - text: "1440p" - }, { - action: "1080", - text: "1080p" - }, { - action: "720", - text: "720p" - }, { - action: "480", - text: "480p" - }, { - action: "360", - text: "360p" - }, { - action: "240", - text: "240p" - }, { - action: "144", - text: "144p" - }] - }) - }) - + settingsCategory({ - name: "codec", - title: t('SettingsCodecSubtitle'), - body: switcher({ - name: "vCodec", - explanation: t('SettingsCodecDescription'), - items: [{ - action: "h264", - text: "h264 (mp4)" - }, { - action: "av1", - text: "av1 (mp4)" - }, { - action: "vp9", - text: "vp9 (webm)" - }] - }) - }) - + settingsCategory({ - name: "twitter", - title: "twitter", - body: checkbox([{ - action: "twitterGif", - name: t("SettingsTwitterGif"), - padding: "no-margin" - }]) - + explanation(t('SettingsTwitterGifDescription')) - }) - + settingsCategory({ - name: "tiktok", - title: "tiktok", - body: checkbox([{ - action: "tiktokH265", - name: t("SettingsTikTokH265"), - padding: "no-margin" - }]) - + explanation(t('SettingsTikTokH265Description')) - }) - }, { - name: "audio", - title: `${emoji("🎶")} ${t('SettingsAudioTab')}`, - content: settingsCategory({ - name: "general", - title: t('SettingsFormatSubtitle'), - body: switcher({ - name: "aFormat", - explanation: t('SettingsAudioFormatDescription'), - items: audioFormats - }) - + sep(0) - + checkbox([{ - action: "muteAudio", - name: t("SettingsVideoMute"), - padding: "no-margin" - }]) - + explanation(t('SettingsVideoMuteExplanation')) - }) - + settingsCategory({ - name: "youtube-dub", - title: t("SettingsAudioDub"), - body: checkbox([{ - action: "ytDub", - name: t("SettingsYoutubeDub"), - padding: "no-margin" - }]) - + explanation(t('SettingsYoutubeDubDescription')) - }) - + settingsCategory({ - name: "tiktok-audio", - title: "tiktok", - body: checkbox([{ - action: "fullTikTokAudio", - name: t("SettingsAudioFullTikTok"), - padding: "no-margin" - }]) - + explanation(t('SettingsAudioFullTikTokDescription')) - }) - }, { - name: "other", - title: `${emoji("🪅")} ${t('SettingsOtherTab')}`, - content: settingsCategory({ - name: "appearance", - title: t('SettingsAppearanceSubtitle'), - body: switcher({ - name: "theme", - items: [{ - action: "auto", - text: t('SettingsThemeAuto') - }, { - action: "dark", - text: t('SettingsThemeDark') - }, { - action: "light", - text: t('SettingsThemeLight') - }] - }) - }) - + settingsCategory({ - name: "filename", - title: t('FilenameTitle'), - body: switcher({ - name: "filenamePattern", - items: [{ - action: "classic", - text: t('FilenamePatternClassic') - }, { - action: "basic", - text: t('FilenamePatternBasic') - }, { - action: "pretty", - text: t('FilenamePatternPretty') - }, { - action: "nerdy", - text: t('FilenamePatternNerdy') - }] - }) - + `
-
- ${emoji('🎞️', 32, 1, 1)} -
-
${t('Preview')}
-
-
-
-
- ${emoji('🎧', 32, 1, 1)} -
-
${t('Preview')}
-
-
-
-
` - + explanation(t('FilenameDescription')) - }) - + settingsCategory({ - name: "accessibility", - title: t('Accessibility'), - body: checkbox([{ - action: "alwaysVisibleButton", - name: t("SettingsKeepDownloadButton"), - aria: t("AccessibilityKeepDownloadButton") - }, { - action: "reduceTransparency", - name: t("SettingsReduceTransparency") - }, { - action: "disableAnimations", - name: t("SettingsDisableAnimations"), - padding: "no-margin" - }]) - }) - + (() => { - if (env.plausibleHostname) { - return settingsCategory({ - name: "privacy", - title: t('PrivateAnalytics'), - body: checkbox([{ - action: "plausible_ignore", - name: t("SettingsDisableAnalytics"), - padding: "no-margin" - }]) - + explanation(t('SettingsAnalyticsExplanation')) - }) - } - return '' - })() - + settingsCategory({ - name: "miscellaneous", - title: t('Miscellaneous'), - body: checkbox([{ - action: "downloadPopup", - name: t("SettingsEnableDownloadPopup"), - aria: t("AccessibilityEnableDownloadPopup") - }, { - action: "disableMetadata", - name: t("SettingsDisableMetadata") - }]) - }) - }] - })} - ${popupWithBottomButtons({ - name: "picker", - closeAria: t('AccessibilityGoBack'), - header: { - title: `${emoji("🧮", 30)}
`, - explanation: `
`, - }, - buttons: [`${t('ImagePickerDownloadAudio')}`], - content: '
' - })} - - - - - - - - -` - } catch (err) { - return `${t('ErrorPageRenderFail', obj.hash)}`; - } -} From 2575b0c14524e36a26e0ec6ee44743486a4972ad Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 21:32:00 +0600 Subject: [PATCH 341/775] api: remove web mode & variables --- api/src/cobalt.js | 7 ++---- api/src/modules/config.js | 46 ++++++++++----------------------------- 2 files changed, 14 insertions(+), 39 deletions(-) diff --git a/api/src/cobalt.js b/api/src/cobalt.js index 473c9b5b..d3f21255 100644 --- a/api/src/cobalt.js +++ b/api/src/cobalt.js @@ -6,7 +6,7 @@ import express from "express"; import { Bright, Green, Red } from "./modules/sub/consoleText.js"; import { getCurrentBranch, shortCommit } from "./modules/sub/currentCommit.js"; import { loadLoc } from "./localization/manager.js"; -import { mode } from "./modules/config.js" +import { env } from "./modules/config.js" import path from 'path'; import { fileURLToPath } from 'url'; @@ -23,12 +23,9 @@ app.disable('x-powered-by'); await loadLoc(); -if (mode === 'API') { +if (env.apiURL) { const { runAPI } = await import('./core/api.js'); runAPI(express, app, gitCommit, gitBranch, __dirname) -} else if (mode === 'WEB') { - const { runWeb } = await import('./core/web.js'); - await runWeb(express, app, gitCommit, gitBranch, __dirname) } else { console.log( Red(`cobalt wasn't configured yet or configuration is invalid.\n`) diff --git a/api/src/modules/config.js b/api/src/modules/config.js index 662d8b05..4817931f 100644 --- a/api/src/modules/config.js +++ b/api/src/modules/config.js @@ -13,22 +13,18 @@ Object.values(servicesConfigJson.config).forEach(service => { ) }) -const - apiURL = process.env.API_URL || '', - - // WEB mode related environment variables - webEnvs = { - webPort: process.env.WEB_PORT || 9001, - webURL: process.env.WEB_URL || '', - showSponsors: !!process.env.SHOW_SPONSORS, - isBeta: !!process.env.IS_BETA, - plausibleHostname: process.env.PLAUSIBLE_HOSTNAME, - apiURL - }, - - // API mode related environment variables - apiEnvs = { - apiURL, +export const + services = servicesConfigJson.config, + hlsExceptions = servicesConfigJson.hlsExceptions, + audioIgnore = servicesConfigJson.audioIgnore, + version = packageJson.version, + genericUserAgent = config.genericUserAgent, + repo = packageJson.bugs.url.replace('/issues', ''), + ffmpegArgs = config.ffmpegArgs, + supportedAudio = config.supportedAudio, + links = config.links, + env = { + apiURL: process.env.API_URL || '', apiPort: process.env.API_PORT || 9000, apiName: process.env.API_NAME || 'unknown', @@ -52,21 +48,3 @@ const externalProxy: process.env.API_EXTERNAL_PROXY, } - -export const - services = servicesConfigJson.config, - hlsExceptions = servicesConfigJson.hlsExceptions, - audioIgnore = servicesConfigJson.audioIgnore, - version = packageJson.version, - genericUserAgent = config.genericUserAgent, - repo = packageJson.bugs.url.replace('/issues', ''), - authorInfo = config.authorInfo, - donations = config.donations, - ffmpegArgs = config.ffmpegArgs, - supportedAudio = config.supportedAudio, - celebrations = config.celebrations, - links = config.links, - sponsors = config.sponsors, - mode = (apiURL && !webEnvs.webURL) ? 'API' : - (webEnvs.webURL && apiURL) ? 'WEB' : undefined, - env = mode === 'API' ? apiEnvs : webEnvs \ No newline at end of file From 012fadd2f0b91eb06102e52f369ce39a0bed61e9 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 21:33:59 +0600 Subject: [PATCH 342/775] api: remove `API_NAME` env variable & from server info --- api/src/core/api.js | 1 - api/src/modules/config.js | 1 - 2 files changed, 2 deletions(-) diff --git a/api/src/core/api.js b/api/src/core/api.js index 5f4ee804..3ce0265b 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -32,7 +32,6 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { version: version, commit: gitCommit, branch: gitBranch, - name: env.apiName, url: env.apiURL, cors: Number(env.corsWildcard), startTime: `${startTimestamp}` diff --git a/api/src/modules/config.js b/api/src/modules/config.js index 4817931f..ad20521a 100644 --- a/api/src/modules/config.js +++ b/api/src/modules/config.js @@ -26,7 +26,6 @@ export const env = { apiURL: process.env.API_URL || '', apiPort: process.env.API_PORT || 9000, - apiName: process.env.API_NAME || 'unknown', listenAddress: process.env.API_LISTEN_ADDRESS, freebindCIDR: process.platform === 'linux' && process.env.FREEBIND_CIDR, From f66ae63d57bb4379bb859a6b776841b3acb2b984 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 22:35:49 +0600 Subject: [PATCH 343/775] api/core: remove favicon --- api/src/core/api.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/core/api.js b/api/src/core/api.js index 3ce0265b..5930c8b4 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -198,11 +198,11 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { }) app.get('/favicon.ico', (req, res) => { - res.sendFile(`${__dirname}/src/front/icons/favicon.ico`) + res.status(404).end(); }) app.get('/*', (req, res) => { - res.redirect('/api/serverInfo') + res.redirect('/api/serverInfo'); }) randomizeCiphers(); From dd30973601709513088adb7c86eef3c6b3ded69f Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 2 Aug 2024 22:35:56 +0600 Subject: [PATCH 344/775] package: update version to 10.0.0 --- api/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/package.json b/api/package.json index f41b27cb..7cafdf4f 100644 --- a/api/package.json +++ b/api/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.15", + "version": "10.0.0", "author": "imput", "exports": "./src/cobalt.js", "type": "module", From 3fdf266ad03d35a9745902db17c49eccd5ccaf54 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Fri, 2 Aug 2024 16:37:23 +0000 Subject: [PATCH 345/775] youtube: periodically refresh innertube player --- .../modules/processing/services/youtube.js | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/api/src/modules/processing/services/youtube.js b/api/src/modules/processing/services/youtube.js index d3ee5602..9bfc3919 100644 --- a/api/src/modules/processing/services/youtube.js +++ b/api/src/modules/processing/services/youtube.js @@ -6,7 +6,9 @@ import { env } from "../../config.js"; import { cleanString } from "../../sub/utils.js"; import { getCookie, updateCookieValues } from "../cookie/manager.js"; -const ytBase = Innertube.create().catch(e => e); +const PLAYER_REFRESH_PERIOD = 1000 * 60 * 15; // ms + +let innertube, lastRefreshedAt; const codecMatch = { h264: { @@ -48,11 +50,12 @@ const transformSessionData = (cookie) => { } const cloneInnertube = async (customFetch) => { - const innertube = await ytBase; - if (innertube instanceof Error) { - if (innertube?.message?.endsWith("decipher algorithm")) { - return { error: "ErrorYoutubeDecipher" } - } else throw innertube; + const shouldRefreshPlayer = lastRefreshedAt + PLAYER_REFRESH_PERIOD < new Date(); + if (!innertube || shouldRefreshPlayer) { + innertube = await Innertube.create({ + fetch: customFetch + }); + lastRefreshedAt = +new Date(); } const session = new Session( @@ -97,13 +100,19 @@ const cloneInnertube = async (customFetch) => { } export default async function(o) { - const yt = await cloneInnertube( - (input, init) => fetch(input, { - ...init, - dispatcher: o.dispatcher - }) - ); - if (yt.error) return yt; + let yt; + try { + yt = await cloneInnertube( + (input, init) => fetch(input, { + ...init, + dispatcher: o.dispatcher + }) + ); + } catch(e) { + if (e.message?.endsWith("decipher algorithm")) { + return { error: "ErrorYoutubeDecipher" } + } else throw e; + } const quality = o.quality === "max" ? "9000" : o.quality; From aff22e85605e840af9fb667c91d9e35d63a3c77f Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 13:51:09 +0600 Subject: [PATCH 346/775] api: remove localization, renovate error response --- api/src/cobalt.js | 3 - api/src/core/api.js | 20 ++- api/src/localization/languages/en.json | 166 ------------------ api/src/localization/languages/ru.json | 165 ----------------- api/src/localization/manager.js | 51 ------ api/src/modules/config.js | 2 - api/src/modules/processing/match.js | 23 ++- .../modules/processing/matchActionDecider.js | 12 +- api/src/modules/processing/request.js | 38 ++-- 9 files changed, 60 insertions(+), 420 deletions(-) delete mode 100644 api/src/localization/languages/en.json delete mode 100644 api/src/localization/languages/ru.json delete mode 100644 api/src/localization/manager.js diff --git a/api/src/cobalt.js b/api/src/cobalt.js index d3f21255..33ed953d 100644 --- a/api/src/cobalt.js +++ b/api/src/cobalt.js @@ -5,7 +5,6 @@ import express from "express"; import { Bright, Green, Red } from "./modules/sub/consoleText.js"; import { getCurrentBranch, shortCommit } from "./modules/sub/currentCommit.js"; -import { loadLoc } from "./localization/manager.js"; import { env } from "./modules/config.js" import path from 'path'; @@ -21,8 +20,6 @@ const __dirname = path.dirname(__filename).slice(0, -4); app.disable('x-powered-by'); -await loadLoc(); - if (env.apiURL) { const { runAPI } = await import('./core/api.js'); runAPI(express, app, gitCommit, gitBranch, __dirname) diff --git a/api/src/core/api.js b/api/src/core/api.js index 5930c8b4..74ea0307 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -7,7 +7,6 @@ import { env, version } from "../modules/config.js"; import { generateHmac, generateSalt } from "../modules/sub/crypto.js"; import { Bright, Cyan } from "../modules/sub/consoleText.js"; import { languageCode } from "../modules/sub/utils.js"; -import loc from "../localization/manager.js"; import { createResponse, normalizeRequest, getIP } from "../modules/processing/request.js"; import { verifyStream, getInternalStream } from "../modules/stream/manage.js"; @@ -45,8 +44,14 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { keyGenerator: req => generateHmac(getIP(req), ipSalt), handler: (req, res) => { return res.status(429).json({ - "status": "rate-limit", - "text": loc(languageCode(req), 'ErrorRateLimit', env.rateLimitWindow) + status: "error", + error: { + code: "ErrorRateLimit", + context: { + limit: env.rateLimitWindow + }, + text: "ErrorRateLimit" // temporary backwards compatibility + } }); } }) @@ -92,7 +97,10 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { if (err) { return res.status(400).json({ status: "error", - text: "invalid json body" + error: { + code: "error.body.invalid", + }, + text: "invalid json body", // temporary backwards compatibility }); } @@ -103,8 +111,8 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { const request = req.body; const lang = languageCode(req); - const fail = (t) => { - const { status, body } = createResponse("error", { t: loc(lang, t) }); + const fail = (code) => { + const { status, body } = createResponse("error", { code }); res.status(status).json(body); } diff --git a/api/src/localization/languages/en.json b/api/src/localization/languages/en.json deleted file mode 100644 index 8db4585b..00000000 --- a/api/src/localization/languages/en.json +++ /dev/null @@ -1,166 +0,0 @@ -{ - "name": "english", - "substrings": { - "ContactLink": "check the status page or create an issue on github" - }, - "strings": { - "AppTitleCobalt": "cobalt", - "LinkInput": "paste the link here", - "AboutSummary": "cobalt is your go-to place for downloads from social and media platforms. zero ads, trackers, or other creepy bullshit. simply paste a share link and you're ready to rock!", - "EmbedBriefDescription": "save what you love. no ads, trackers, or other creepy bullshit.", - "MadeWithLove": "made with <3 by imput", - "AccessibilityInputArea": "link input area", - "AccessibilityOpenAbout": "open about popup", - "AccessibilityDownloadButton": "download button", - "AccessibilityOpenSettings": "open settings popup", - "AccessibilityOpenDonate": "open donation popup", - "TitlePopupAbout": "what's cobalt?", - "TitlePopupSettings": "settings", - "TitlePopupChangelog": "what's new?", - "TitlePopupDonate": "support cobalt", - "TitlePopupDownload": "how to save?", - "ErrorSomethingWentWrong": "something went wrong and i couldn't get anything for you. try again, but if issue persists, {ContactLink}.", - "ErrorUnsupported": "it seems like this service is not supported yet or your link is invalid. have you pasted the right link?", - "ErrorBrokenLink": "{s} is supported, but something is wrong with your link. maybe you didn't copy it fully?", - "ErrorNoLink": "i can't guess what you want to download! please give me a link :(", - "ErrorPageRenderFail": "if you're reading this, then there's something wrong with the page renderer. please {ContactLink}. make sure to provide the domain this error is present on and current commit hash ({s}). thank you in advance :D", - "ErrorRateLimit": "you're making too many requests. try again in {s} seconds!", - "ErrorCouldntFetch": "i couldn't find anything about this link. check if it works and try again! some content may be region restricted, so keep that in mind.", - "ErrorLengthLimit": "i can't process videos longer than {s} minutes, so pick something shorter instead!", - "ErrorBadFetch": "something went wrong when i tried getting info about your link. are you sure it works? check if it does, and try again.", - "ErrorNoInternet": "there's no internet or cobalt api is temporarily unavailable. check your connection and try again.", - "ErrorCantConnectToServiceAPI": "i couldn't connect to the service api. maybe it's down, or cobalt got blocked. try again, but if error persists, {ContactLink}.", - "ErrorEmptyDownload": "i don't see anything i could download by your link. try a different one!", - "ErrorLiveVideo": "this is a live video, i am yet to learn how to look into future. wait for the stream to finish and try again!", - "SettingsAppearanceSubtitle": "appearance", - "SettingsThemeSubtitle": "theme", - "SettingsFormatSubtitle": "format", - "SettingsQualitySubtitle": "quality", - "SettingsThemeAuto": "auto", - "SettingsThemeLight": "light", - "SettingsThemeDark": "dark", - "SettingsKeepDownloadButton": "keep >> visible", - "AccessibilityKeepDownloadButton": "keep the download button always visible", - "SettingsEnableDownloadPopup": "ask how to save", - "AccessibilityEnableDownloadPopup": "ask what to do with downloads", - "SettingsQualityDescription": "if selected quality isn't available, closest one is used instead.", - "NoScriptMessage": "cobalt uses javascript for api requests and interactive interface. you have to allow javascript to use this site. there are no pesty scripts, pinky promise.", - "DownloadPopupDescriptionIOS": "how to save to photos:\n1. add save to photos shortcut.\n2. press \"share\" button above this text.\n3. select \"save to photos\" in the share sheet.\n\nhow to save to files:\n1. add save to files shortcut.\n2. press \"share\" button above this text.\n3. select \"save to files\" in the share sheet.\n4. select a folder to save the file to and press \"open\".\n\nboth shortcuts can only be used from the cobalt web app.", - "DownloadPopupDescription": "download button opens a new tab with requested file. you can disable this popup in settings.", - "ClickToCopy": "press to copy", - "Download": "download", - "CopyURL": "copy", - "AboutTab": "about", - "ChangelogTab": "changelog", - "DonationsTab": "donations", - "SettingsVideoTab": "video", - "SettingsAudioTab": "audio", - "SettingsOtherTab": "other", - "ChangelogLastMajor": "current version & commit", - "AccessibilityModeToggle": "toggle download mode", - "DonateLinksDescription": "this is the best way to donate if you want me to receive your donation directly.", - "SettingsAudioFormatBest": "best", - "SettingsAudioFormatDescription": "when \"best\" format is selected, you get audio the way it is on service's side. it's not re-encoded. everything else will be re-encoded.", - "Keyphrase": "save what you love", - "ErrorPopupCloseButton": "got it", - "ErrorLengthAudioConvert": "i can't convert audio longer than {s} minutes. pick \"best\" format if you want to avoid limitations!", - "SettingsAudioFullTikTok": "full audio", - "SettingsAudioFullTikTokDescription": "downloads original sound used in the video without any additional changes by the post's author.", - "ErrorCantGetID": "i couldn't get the full info from the shortened link. make sure it works or try a full one! if issue persists, {ContactLink}.", - "ErrorNoVideosInTweet": "i couldn't find any media content in this tweet. try another one!", - "ImagePickerTitle": "pick images to download", - "ImagePickerDownloadAudio": "download audio", - "ImagePickerExplanationPC": "right click an image to save it.", - "ImagePickerExplanationPhone": "press and hold an image to save it.", - "ErrorNoUrlReturned": "i didn't get a download link from the server. this should never happen. try again, but if it still doesn't work, {ContactLink}.", - "ErrorUnknownStatus": "i received a response i can't process. this should never happen. try again, but if it still doesn't work, {ContactLink}.", - "PasteFromClipboard": "paste", - "ChangelogOlder": "previous versions", - "ChangelogPressToExpand": "expand", - "Miscellaneous": "miscellaneous", - "ModeToggleAuto": "auto", - "ModeToggleAudio": "audio", - "MediaPickerTitle": "pick what to save", - "MediaPickerExplanationPC": "click or right click to download what you want.", - "MediaPickerExplanationPhone": "press or press and hold to download what you want.", - "TwitterSpaceWasntRecorded": "this twitter space wasn't recorded, so there's nothing to download. try another one!", - "ErrorCantProcess": "i couldn't process your request :(\nyou can try again, but if issue persists, please {ContactLink}.", - "ChangelogPressToHide": "collapse", - "Donate": "donate", - "DonateSub": "help it stay online", - "DonateExplanation": "cobalt doesn't shove ads in your face and doesn't sell your personal data, meaning that it's completely free to use for everyone. but development and maintenance of a media-heavy service used by over 1 million people is quite costly. both in terms of time and money.\n\nif cobalt helped you in the past and you want to keep it growing and evolving, you can return the favor by making a donation!\n\nyour donation will help all cobalt users: educators, students, content creators, artists, musicians, and many, many more!\n\nin past, donations have let cobalt:\n*; increase stability and uptime to nearly 100%.\n*; speed up ALL downloads, especially heavier ones.\n*; open the api for free public use.\n*; withstand several huge user influxes with 0 downtime.\n*; add resource-intensive features (such as gif conversion).\n*; continue improving our infrastructure.\n*; keep developers happy.\n\nevery cent matters and is extremely appreciated, you can truly make a difference!\n\nif you can't donate, share cobalt with a friend! we don't get ads anywhere, so cobalt is spread by word of mouth.\nsharing is the easiest way to help achieve the goal of better internet for everyone.", - "DonateVia": "donate via", - "SettingsVideoMute": "mute audio", - "SettingsVideoMuteExplanation": "removes audio from video downloads when possible.", - "ErrorSoundCloudNoClientId": "i couldn't get the temporary token that's required to download songs from soundcloud. try again, but if issue persists, {ContactLink}.", - "CollapseServices": "supported services", - "CollapseSupport": "support & source code", - "CollapsePrivacy": "privacy policy", - "ServicesNote": "this list is not final and keeps expanding over time, make sure to check it once in a while!", - "FollowSupport": "keep in touch with cobalt for news, support, and more:", - "SourceCode": "explore source code, report issues, star or fork the repo:", - "PrivacyPolicy": "cobalt's privacy policy is simple: no data about you is ever collected or stored. zero, zilch, nada, nothing.\nwhat you download is solely your business, not mine or anyone else's.\n\nif your download requires rendering, then data about requested content is encrypted and temporarily stored in server's RAM. it's necessary for this feature to function.\n\nencrypted data is stored for 90 seconds and then permanently removed.\n\nstored data is only possible to decrypt with unique encryption keys from your download link. furthermore, the official cobalt codebase doesn't provide a way to read temporarily stored data outside of processing functions.\n\nyou can check cobalt's source code yourself and see that everything is as stated.", - "ErrorYTUnavailable": "this youtube video is unavailable. it could be visibility or region restricted. try another one!", - "ErrorYTTryOtherCodec": "i couldn't find anything to download with your settings. try another codec or quality in settings!", - "SettingsCodecSubtitle": "youtube codec", - "SettingsCodecDescription": "h264: best support across apps/platforms, average detail level. max quality is 1080p.\nav1: best quality, small file size, most detail. supports 8k & HDR.\nvp9: same quality as av1, but file is x2 bigger. supports 4k & HDR.\n\npick h264 if you want best compatibility.\npick av1 if you want best quality and efficiency.", - "SettingsAudioDub": "youtube audio track", - "ShareURL": "share", - "ErrorTweetUnavailable": "couldn't find anything about this tweet. this could be because its visibility is limited. try another one!", - "PopupCloseDone": "done", - "Accessibility": "accessibility", - "SettingsReduceTransparency": "reduce transparency", - "SettingsDisableAnimations": "disable animations", - "FeatureErrorGeneric": "your browser doesn't allow or support this feature. check if there are any updates available and try again!", - "ClipboardErrorFirefox": "you're using firefox where all clipboard reading functionality is disabled.\n\nyou can fix this by following steps listed here!\n\n...or you can paste the link manually instead.", - "ClipboardErrorNoPermission": "cobalt can't access the most recent item in your clipboard without your permission.\n\nif you don't want to give access, just paste the link manually instead.\n\nif you do, go to site settings and enable the clipboard permission.", - "SupportSelfTroubleshooting": "experiencing issues? try one of these first:", - "AccessibilityGoBack": "go back and close the popup", - "CollapseKeyboard": "keyboard shortcuts", - "KeyboardShortcutsIntro": "use cobalt even faster with keyboard shortcuts:", - "KeyboardShortcutQuickPaste": "paste the link", - "KeyboardShortcutClear": "clear link input area", - "KeyboardShortcutClosePopup": "close all popups", - "CollapseLegal": "terms and ethics", - "FairUse": "cobalt is a web tool that makes it easier to download content from the internet and takes zero liability. processing servers work like limited proxies, so no media content is ever cached or stored.\n\nyou (end user) are responsible for what you download, how you use and distribute that content. please be mindful when using content of others and always credit original creators.\n\nwhen used in education purposes (lecture, homework, etc) please attach the source link.\n\nfair use and credits benefit everyone.", - "SettingsDisableMetadata": "don't add metadata", - "NewDomainWelcomeTitle": "hey there!", - "NewDomainWelcome": "cobalt is moving! same features, same owner, simply a more rememberable domain. and still no ads.\n\ncobalt.tools is the new main domain, aka where you are now. make sure to update your bookmarks and reinstall the web app!", - "DataTransferSuccess": "btw, your settings have been transferred automatically :)", - "DataTransferError": "something went wrong when transferring your preferences. you'll have to open settings and configure cobalt by hand.", - "SupportNotAffiliated": "cobalt is not affiliated with any services listed above.", - "SponsoredBy": "sponsored by", - "FilenameTitle": "file name style", - "FilenamePatternClassic": "classic", - "FilenamePatternPretty": "pretty", - "FilenamePatternBasic": "basic", - "FilenamePatternNerdy": "nerdy", - "FilenameDescription": "classic: default cobalt file name pattern.\nbasic: title and basic info in brackets.\npretty: title and info in brackets.\nnerdy: title and all info in brackets.\n\nsome services don’t support rich file names and always use the classic style.", - "Preview": "preview", - "FilenamePreviewVideoTitle": "Video Title", - "FilenamePreviewAudioTitle": "Audio Title", - "FilenamePreviewAudioAuthor": "Audio Author", - "StatusPage": "service status page", - "TroubleshootingGuide": "self-troubleshooting guide", - "DonateImageDescription": "cat sleeping on a laptop keyboard and typing letters repeatedly", - "SettingsTwitterGif": "convert gifs to .gif", - "SettingsTwitterGifDescription": "converting looping videos to .gif reduces quality and majorly increases file size. if you want best efficiency, keep this setting off.", - "ErrorTweetProtected": "this tweet is from a private account, so i can't see it. try another one!", - "ErrorTweetNSFW": "this tweet contains sensitive content, so i can't see it. try another one!", - "PrivateAnalytics": "private analytics", - "SettingsDisableAnalytics": "opt out of private analytics", - "SettingsAnalyticsExplanation": "enable if you don't want to be included in anonymous traffic stats. read more about this in about > privacy policy (tl;dr: nothing about you is ever stored or tracked, no cookies are used).", - "AnalyticsDescription": "cobalt uses a self-hosted plausible instance to get an approximate number of how many people use it.\n\nplausible is fully compliant with GDPR, CCPA and PECR, doesn't use cookies, and never stores any identifiable info, not even your ip address.\n\nall data is aggregated and never personalized. nothing about what you download is ever saved anywhere. it's used just for anonymous traffic stats, nothing more.\n\nplausible is fully open source, just like cobalt, and if you want to learn more about it, you can do so here. if you wish to opt out of traffic stats, you can do it in settings > other.", - "SettingsTikTokH265": "prefer h265", - "SettingsTikTokH265Description": "download 1080p videos from tiktok in h265/hevc format when available.", - "SettingsYoutubeDub": "use browser language", - "SettingsYoutubeDubDescription": "uses your browser's default language for youtube dubbed audio tracks. works even if cobalt ui isn't translated to your language.", - "ErrorInvalidContentType": "invalid content type header", - "UpdateOneMillion": "1 million users and blazing speed", - "ErrorYTAgeRestrict": "this youtube video is age-restricted, so i can't see it. try another one!", - "ErrorYTLogin": "couldn't get this youtube video because it requires an account to view.\n\nthis limitation is done by google to seemingly stop scraping, affecting all 3rd party tools and even their own clients.\n\ntry again, but if issue persists, {ContactLink}.", - "ErrorYTRateLimit": "i got rate limited by youtube. try again in a few seconds, but if issue persists, {ContactLink}.", - "ErrorInvalidAcceptHeader": "invalid accept header", - "ErrorYoutubeDecipher": "youtube updated its decipher algorithm, so i can't get the video info. try again, but if it still doesn't work, please create an issue on github." - } -} diff --git a/api/src/localization/languages/ru.json b/api/src/localization/languages/ru.json deleted file mode 100644 index 083d7bbc..00000000 --- a/api/src/localization/languages/ru.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "name": "русский", - "substrings": { - "ContactLink": "глянь статус серверов или напиши о проблеме на github" - }, - "strings": { - "AppTitleCobalt": "кобальт", - "LinkInput": "вставь ссылку сюда", - "AboutSummary": "кобальт - твой друг при скачивании контента из соцсетей и других сервисов. никакой рекламы, трекеров и прочего мусора. вставляешь ссылку и получаешь файл. всё. ничего лишнего.", - "EmbedBriefDescription": "сохраняй то, что любишь. без рекламы, трекеров и лишней мороки.", - "MadeWithLove": "сделано с любовью <3", - "AccessibilityInputArea": "зона вставки ссылки", - "AccessibilityOpenAbout": "открыть окно с инфой", - "AccessibilityDownloadButton": "кнопка скачивания", - "AccessibilityOpenSettings": "открыть настройки", - "AccessibilityOpenDonate": "сделать пожертвование", - "TitlePopupAbout": "что за кобальт?", - "TitlePopupSettings": "настройки", - "TitlePopupChangelog": "что нового?", - "TitlePopupDonate": "поддержи кобальт", - "TitlePopupDownload": "как сохранить?", - "ErrorSomethingWentWrong": "что-то пошло совсем не так и у меня не получилось ничего для тебя достать. попробуй ещё раз, но если так и не получится, {ContactLink}.", - "ErrorUnsupported": "с твоей ссылкой что-то не так или же этот сервис ещё не поддерживается. может быть, ты вставил не ту ссылку?", - "ErrorBrokenLink": "{s} поддерживается, но с твоей ссылкой что-то не так. может быть, ты её не полностью скопировал?", - "ErrorNoLink": "пока что я не умею угадывать, что ты хочешь скачать. дай мне, пожалуйста, ссылку :(", - "ErrorPageRenderFail": "если ты видишь этот текст, значит что-то не так с рендером страницы. пожалуйста, {ContactLink}. также приложи домен, на котором присутсвует эта ошибка, и хэш коммита ({s}). спасибо :)", - "ErrorRateLimit": "ты делаешь слишком много запросов. попробуй ещё раз через {s} секунд!", - "ErrorCouldntFetch": "у меня не получилось ничего найти по этой ссылке. убедись, что она работает, и попробуй ещё раз. некоторый контент может быть залочен на регион.", - "ErrorLengthLimit": "я не могу обрабатывать видео длиннее чем {s} минут(ы), так что скачай что-нибудь покороче!", - "ErrorBadFetch": "произошла какая-то ошибка при получении данных по твоей ссылке. убедись, что она работает, и попробуй ещё раз.", - "ErrorNoInternet": "не получилось подключиться к серверу. проверь подключение к интернету и попробуй ещё раз!", - "ErrorCantConnectToServiceAPI": "у меня не получилось подключиться к серверу этого сервиса. возможно он лежит, или же кобальт заблокировали. попробуй ещё раз, но если так и не получится, {ContactLink}.", - "ErrorEmptyDownload": "я не нашёл того, что могу скачать. попробуй другую ссылку!", - "ErrorLiveVideo": "я пока что не умею заглядывать в будущее, поэтому дождись окончания прямого эфира, и потом уже скачивай видео!", - "SettingsAppearanceSubtitle": "внешний вид", - "SettingsThemeSubtitle": "тема", - "SettingsFormatSubtitle": "формат", - "SettingsQualitySubtitle": "качество", - "SettingsThemeAuto": "авто", - "SettingsThemeLight": "светлый", - "SettingsThemeDark": "тёмный", - "SettingsKeepDownloadButton": "всегда показывать >>", - "AccessibilityKeepDownloadButton": "всегда показывать кнопку скачивания на экране", - "SettingsEnableDownloadPopup": "выбор метода скачивания", - "AccessibilityEnableDownloadPopup": "спрашивать, что делать с загрузками", - "SettingsQualityDescription": "если выбранное качество недоступно, то выбирается ближайшее к нему.", - "NoScriptMessage": "кобальт использует javascript для обработки ссылок и интерактивного интерфейса. ты должен разрешить использование javascript, чтобы пользоваться сайтом. тут нет никаких зловредных скриптов, обещаю.", - "DownloadPopupDescriptionIOS": "как сохранить в фото:\n1. добавь этот сценарий siri: save to photos.\n2. нажми \"поделиться\" выше этого текста.\n3. выбери \"save to photos\" в открывшемся окне.\n\nкак сохранить в файлы:\n1. добавь этот сценарий siri: save to files.\n2. нажми \"поделиться\" выше этого текста.\n3. выбери \"save to files\" в открывшемся окне.\n4. выбери папку для сохранения файла и нажми \"открыть\".\n\nоба сценария работают только вместе с веб-приложением кобальта.", - "DownloadPopupDescription": "кнопка скачивания открывает новое окно с файлом. ты можешь отключить выбор метода скачивания файла в настройках.", - "ClickToCopy": "нажми, чтобы скопировать", - "Download": "скачать", - "CopyURL": "скопировать", - "AboutTab": "о сайте", - "ChangelogTab": "изменения", - "DonationsTab": "донаты", - "SettingsVideoTab": "видео", - "SettingsAudioTab": "аудио", - "SettingsOtherTab": "другое", - "ChangelogLastMajor": "текущая версия и коммит (на английском)", - "AccessibilityModeToggle": "переключить режим скачивания", - "DonateLinksDescription": "это лучший способ отправить донат, если ты хочешь, чтобы я получил его лично.", - "SettingsAudioFormatBest": "лучший", - "SettingsAudioFormatDescription": "когда выбран \"лучший\", ты получишь аудио без каких-либо изменений. такое, какое оно есть на стороне сервиса. если же выбрано что-то другое, то аудио будет немного сжато.", - "Keyphrase": "сохраняй то, что любишь", - "ErrorPopupCloseButton": "ясно", - "ErrorLengthAudioConvert": "я не могу конвертировать аудио дольше чем {s} минут(ы). выбери \"лучший\" формат, чтобы обойти ограничения.", - "SettingsAudioFullTikTok": "полное аудио", - "SettingsAudioFullTikTokDescription": "скачивает оригинальный звук, использованный в видео, без каких-либо изменений от автора поста.", - "ErrorCantGetID": "у меня не получилось достать инфу по этой короткой ссылке. попробуй полную ссылку, а если так и не получится, то {ContactLink}.", - "ErrorNoVideosInTweet": "я не смог найти никакого медиа контента в этом твите. попробуй другой!", - "ImagePickerTitle": "выбери картинки для скачивания", - "ImagePickerDownloadAudio": "скачать звук", - "ImagePickerExplanationPC": "нажми правой кнопкой мыши на картинку, чтобы её сохранить.", - "ImagePickerExplanationPhone": "зажми и удерживай картинку, чтобы её сохранить.", - "ErrorNoUrlReturned": "я не получил ссылку для скачивания от сервера. такого происходить не должно. попробуй ещё раз, а если не поможет, то {ContactLink}.", - "ErrorUnknownStatus": "сервер ответил мне чем-то непонятным. такого происходить не должно. попробуй ещё раз, а если не поможет, то {ContactLink}.", - "PasteFromClipboard": "вставить", - "ChangelogOlder": "предыдущие версии (тоже на английском)", - "ChangelogPressToExpand": "раскрыть", - "Miscellaneous": "разное", - "ModeToggleAuto": "авто", - "ModeToggleAudio": "аудио", - "MediaPickerTitle": "выбери, что сохранить", - "MediaPickerExplanationPC": "кликни то, что хочешь скачать. также можно скачать правой кнопки мыши.", - "MediaPickerExplanationPhone": "нажми, или нажми и удерживай, чтобы скачать.", - "MediaPickerExplanationPhoneIOS": "нажми и удерживай, затем скрой превью и выбери \"загрузить файл по ссылке\", чтобы скачать.", - "TwitterSpaceWasntRecorded": "мне нечего скачать, так как этот twitter space не был записан. попробуй другой!", - "ErrorCantProcess": "я не смог обработать твой запрос :(\nты можешь попробовать ещё раз, но если не поможет, то {ContactLink}.", - "ChangelogPressToHide": "скрыть", - "Donate": "донаты", - "DonateSub": "ты можешь помочь!", - "DonateExplanation": "кобальт не пихает рекламу тебе в лицо и не продаёт твои личные данные, а значит работает совершенно бесплатно для всех. но разработка и поддержка медиа сервиса, которым пользуются более миллиона людей, обходится довольно затратно.\n\nесли кобальт тебе помог и ты хочешь, чтобы он продолжал расти и развиваться, то это можно сделать через донаты!\n\nтвой донат поможет всем, кто пользуется кобальтом: преподавателям, студентам, музыкантам, художникам, контент-мейкерам и многим-многим другим!\n\nв прошлом донаты помогли кобальту:\n*; повысить стабильность и аптайм почти до 100%.\n*; ускорить ВСЕ загрузки, особенно наиболее тяжёлые.\n*; открыть api для бесплатного использования.\n*; выдержать несколько огромных наплывов пользователей без перебоев.\n*; добавить ресурсоемкие фичи (например конвертацию в gif).\n*; продолжать улучшать нашу инфраструктуру.\n*; радовать разработчиков.\n\nкаждый донат невероятно ценится и помогает кобальту развиваться!\n\nесли ты не можешь отправить донат, то поделись кобальтом с другом! мы нигде не размещаем рекламу, поэтому кобальт распространяется из уст в уста.\nподелиться - самый простой способ помочь достичь цели лучшего интернета для всех.", - "DonateVia": "открыть", - "SettingsVideoMute": "убрать аудио", - "SettingsVideoMuteExplanation": "убирает звук при загрузке видео, но только когда это возможно.", - "ErrorSoundCloudNoClientId": "мне не удалось достать временный токен, который необходим для скачивания аудио из soundcloud. попробуй ещё раз, но если так и не получится, {ContactLink}.", - "CollapseServices": "что поддерживается?", - "CollapseSupport": "поддержка и исходный код", - "CollapsePrivacy": "политика конфиденциальности", - "ServicesNote": "этот список далеко не финальный и постоянно пополняется, заглядывай сюда почаще!", - "FollowSupport": "подписывайся на соц.сети кобальта для новостей и поддержки:", - "SourceCode": "шарься в исходнике, пиши о проблемах, или же форкай репозиторий:", - "PrivacyPolicy": "политика конфиденциальности кобальта довольно проста: никакие данные о тебе никогда не собираются и не хранятся. нуль, ноль, нада, ничего.\nто, что ты скачиваешь, - твоё личное дело, а не чьё-либо ещё.\n\nесли твоей загрузке требуется рендер, то зашифрованные данные о ней временно хранятся в ОЗУ сервера. это необходимо для работы данной функции.\n\nзашифрованные данные хранятся в течение 90 секунд и затем безвозвратно удаляются.\n\ncохранённые данные можно расшифровать только с помощью уникальных ключей шифрования из твоей ссылки на скачивание. кроме того, официальная кодовая база кобальта не предусматривает возможности чтения эти данные вне функций обработки.\n\nты всегда можешь посмотреть исходный код кобальта и убедиться, что всё так, как заявлено.", - "ErrorYTUnavailable": "это видео недоступно. возможно оно ограничено по доступу или региону. попробуй другое!", - "ErrorYTTryOtherCodec": "я не нашёл того, что мог бы скачать с твоими настройками. попробуй другой кодек или качество в настройках!", - "SettingsCodecSubtitle": "кодек для youtube видео", - "SettingsCodecDescription": "h264: лучшая совместимость, средний уровень детализированности. максимальное качество - 1080p.\nav1: лучшее качество, маленький размер файла, наибольшее количество деталей. поддерживает 8k и HDR.\nvp9: такая же детализированность, как и у av1, но файл в 2 раза больше. поддерживает 4k и HDR.\n\nвыбирай h264, если тебе нужна наилучшая совместимость.\nвыбирай av1, если ты хочешь лучшее качество и эффективность.", - "SettingsAudioDub": "звуковая дорожка для youtube видео", - "ShareURL": "поделиться", - "ErrorTweetUnavailable": "не смог найти что-либо об этом твите. возможно его видимость ограничена. попробуй другой!", - "PopupCloseDone": "готово", - "Accessibility": "общедоступность", - "SettingsReduceTransparency": "уменьшить прозрачность", - "SettingsDisableAnimations": "убрать анимации", - "FeatureErrorGeneric": "твой браузер не разрешает или не поддерживает эту функцию. проверь наличие обновлений и попробуй ещё раз!", - "ClipboardErrorFirefox": "ты используешь firefox в котором все функции чтения из буфера обмена отключены по умолчанию.\n\nно это можно исправить следуя шагам, описанным здесь\n\n...или же ты можешь просто вставить ссылку вручную.", - "ClipboardErrorNoPermission": "кобальт не может прочитать последний элемент в буфере обмена без твоего разрешения.\n\nесли ты не хочешь давать доступ, просто вставь ссылку вручную.\n\nну а если хочешь, то открой настройки сайта и разреши доступ на чтение буфера обмена.", - "SupportSelfTroubleshooting": "возникли проблемы? попробуй сначала что-то из этого:", - "AccessibilityGoBack": "вернуться назад и закрыть окно", - "CollapseKeyboard": "горячие клавиши", - "KeyboardShortcutsIntro": "пользуйся кобальтом ещё быстрее с горячими клавишами:", - "KeyboardShortcutQuickPaste": "вставить ссылку", - "KeyboardShortcutClear": "очистить зону вставки ссылки", - "KeyboardShortcutClosePopup": "закрыть все окна", - "CollapseLegal": "принципы и этика", - "FairUse": "кобальт - это веб инструмент для облегчения скачивания контента из интернета. сервера обработки работают как ограниченные прокси, так что ничего никогда не сохраняется или кэшируется.\n\nкобальт не несёт никакой ответственности, только ты (конечный пользователь) несёшь ответственность за то, что скачиваешь, как используешь и распространяешь скачанный контент. будь сознателен при использовании чужого контента и всегда указывай авторов!\n\nприкладывай ссылку на источник при использовании в образовательных целях (лекции, домашние задания и т.п.)\n\nчестное использование и указание авторства выгодно всем.", - "SettingsDisableMetadata": "не добавлять метаданные", - "NewDomainWelcomeTitle": "привет!", - "NewDomainWelcome": "кобальт переезжает! те же функции, тот же владелец, просто более запоминающийся домен. по-прежнему без рекламы.\n\ncobalt.tools - новый основной домен, т.е. где ты сейчас находишься. не забудь обновить закладки и переустановить веб-приложение!", - "DataTransferSuccess": "кстати, твои настройки были перенесены автоматически :)", - "DataTransferError": "при переносе настроек что-то пошло не так. придётся зайти в настройки и настроить кобальт вручную.", - "SupportNotAffiliated": "кобальт не аффилирован ни с одним из перечисленных выше сервисов.", - "SupportMetaNoticeRU": "деятельность meta platforms inc. (владелец instagram) запрещена на территории россии.", - "SponsoredBy": "спонсируется", - "FilenameTitle": "стиль названий файлов", - "FilenamePatternClassic": "классический", - "FilenamePatternPretty": "красивый", - "FilenamePatternBasic": "простой", - "FilenamePatternNerdy": "полный", - "FilenameDescription": "классический: стандартный стиль названия файлов кобальта.\nпростой: название и основная инфа в скобках.\nкрасивый: название и инфа в скобках.\nполный: название и вся инфа в скобках.\n\nнекоторые сервисы не поддерживают красивые имена файлов и всегда используют классический стиль.", - "Preview": "превью", - "FilenamePreviewVideoTitle": "Название Видео", - "FilenamePreviewAudioTitle": "Название Аудио", - "FilenamePreviewAudioAuthor": "Автор Аудио", - "StatusPage": "статус серверов", - "TroubleshootingGuide": "гайд по устранению проблем", - "DonateImageDescription": "кошка спит на клавиатуре ноутбука и многократно печатает буквы", - "SettingsTwitterGif": "конвертировать гифки в .gif", - "SettingsTwitterGifDescription": "конвертирование зацикленного видео в .gif снижает качество и значительно увеличивает размер файла. если важна максимальная эффективность, то не используй эту функцию.", - "ErrorTweetProtected": "этот твит из закрытого аккаунта, поэтому я не могу его увидеть. попробуй другой!", - "ErrorTweetNSFW": "этот твит содержит деликатный контент, поэтому я не могу его увидеть. попробуй другой!", - "PrivateAnalytics": "приватная аналитика", - "SettingsDisableAnalytics": "отключить приватную аналитику", - "SettingsAnalyticsExplanation": "включи, если не хочешь быть частью анонимной статистики трафика. подробнее об этом можно прочитать в политике конфиденциальности (tl;dr: ничего о тебе или твоих действиях не хранится и не отслеживается, даже куки нет).", - "AnalyticsDescription": "кобальт использует собственный инстанс plausible чтобы иметь приблизительное представление о том, сколько людей им пользуются.\n\nplausible полностью соответствует GDPR, CCPA и PECR, не использует куки и никогда не хранит никакой идентифицируемой информации, даже ip-адрес.\n\nвсе данные агрегируются и никогда не персонализируются. ничего о том, что ты скачиваешь, никогда не сохраняется. это просто анонимная статистика трафика, ничего больше.\n\nplausible также как и кобальт имеет открытый исходный код, и, если ты хочешь узнать о нём больше, то это можно сделать здесь. а если же ты хочешь исключить себя из статистики, то это можно сделать в настройках > другое.", - "SettingsTikTokH265": "предпочитать h265", - "SettingsTikTokH265Description": "скачивает видео с tiktok в 1080p и h265/hevc, когда это возможно.", - "SettingsYoutubeDub": "использовать язык браузера", - "SettingsYoutubeDubDescription": "использует главный язык браузера для аудиодорожек на youtube. работает даже если кобальт не переведён в твой язык.", - "UpdateOneMillion": "миллион и невероятная скорость", - "ErrorYTAgeRestrict": "это видео ограничено по возрасту, поэтому я не могу его скачать. попробуй другое!", - "ErrorYTLogin": "не удалось получить это видео с youtube, т. к. для его просмотра требуется учетная запись.\n\nтакое ограничение сделано google, чтобы, по-видимому, помешать скрапингу, но в итоге ломает сторонние программы и даже собственные клиенты.\n\nпопробуй ещё раз, но если проблема останется, то {ContactLink}.", - "ErrorYTRateLimit": "youtube ограничил мне частоту запросов. попробуй ещё раз через несколько секунд, но если проблема останется, то {ContactLink}." - } -} diff --git a/api/src/localization/manager.js b/api/src/localization/manager.js deleted file mode 100644 index 2344241b..00000000 --- a/api/src/localization/manager.js +++ /dev/null @@ -1,51 +0,0 @@ -import * as fs from "fs"; -import { links, repo } from "../modules/config.js"; -import { loadJSON } from "../modules/sub/loadFromFs.js"; - -const locPath = './src/localization/languages'; - -let loc = {} -let languages = []; - -export async function loadLoc() { - const files = await fs.promises.readdir(locPath).catch(() => []); - files.forEach(file => { - loc[file.split('.')[0]] = loadJSON(`${locPath}/${file}`); - languages.push(file.split('.')[0]) - }); -} - -export function replaceBase(s) { - return s - .replace(/\n/g, '
') - .replace(/{saveToGalleryShortcut}/g, links.saveToGalleryShortcut) - .replace(/{saveToFilesShortcut}/g, links.saveToFilesShortcut) - .replace(/{repo}/g, repo) - .replace(/{statusPage}/g, links.statusPage) - .replace(/\*;/g, "•"); -} -export function replaceAll(lang, str, string, replacement) { - let s = replaceBase(str[string]) - if (replacement) s = s.replace(/{s}/g, replacement); - if (s.match('{')) { - Object.keys(loc[lang]["substrings"]).forEach(sub => { - s = replaceBase(s.replace(`{${sub}}`, loc[lang]["substrings"][sub])) - }); - } - return s -} -export default function(lang, string, replacement) { - try { - if (!Object.keys(loc).includes(lang)) lang = 'en'; - let str = loc[lang]["strings"]; - if (str && str[string]) { - return replaceAll(lang, str, string, replacement) - } else { - str = loc["en"]["strings"]; - return replaceAll(lang, str, string, replacement) - } - } catch (e) { - return `!!${string}!!` - } -} -export const languageList = languages; diff --git a/api/src/modules/config.js b/api/src/modules/config.js index ad20521a..4a3a63ed 100644 --- a/api/src/modules/config.js +++ b/api/src/modules/config.js @@ -19,10 +19,8 @@ export const audioIgnore = servicesConfigJson.audioIgnore, version = packageJson.version, genericUserAgent = config.genericUserAgent, - repo = packageJson.bugs.url.replace('/issues', ''), ffmpegArgs = config.ffmpegArgs, supportedAudio = config.supportedAudio, - links = config.links, env = { apiURL: process.env.API_URL || '', apiPort: process.env.API_PORT || 9000, diff --git a/api/src/modules/processing/match.js b/api/src/modules/processing/match.js index 6e600cf0..ce69f30b 100644 --- a/api/src/modules/processing/match.js +++ b/api/src/modules/processing/match.js @@ -2,7 +2,6 @@ import { strict as assert } from "node:assert"; import { env } from '../config.js'; import { createResponse } from "../processing/request.js"; -import loc from "../../localization/manager.js"; import { testers } from "./servicesPatternTesters.js"; import matchActionDecider from "./matchActionDecider.js"; @@ -51,12 +50,15 @@ export default async function(host, patternMatch, lang, obj) { if (!testers[host]) { return createResponse("error", { - t: loc(lang, 'ErrorUnsupported') + code: "ErrorUnsupported" }); } if (!(testers[host](patternMatch))) { return createResponse("error", { - t: loc(lang, 'ErrorBrokenLink', host) + code: "ErrorBrokenLink", + context: { + service: host + } }); } @@ -208,7 +210,7 @@ export default async function(host, patternMatch, lang, obj) { break; default: return createResponse("error", { - t: loc(lang, 'ErrorUnsupported') + code: "ErrorUnsupported" }); } @@ -217,14 +219,14 @@ export default async function(host, patternMatch, lang, obj) { if (r.error && r.critical) { return createResponse("critical", { - t: loc(lang, r.error) + code: r.error }) } + if (r.error) { return createResponse("error", { - t: Array.isArray(r.error) - ? loc(lang, r.error[0], r.error[1]) - : loc(lang, r.error) + code: r.error, + context: response?.context }) } @@ -236,7 +238,10 @@ export default async function(host, patternMatch, lang, obj) { ) } catch { return createResponse("error", { - t: loc(lang, 'ErrorBadFetch', host) + code: "ErrorBadFetch", + context: { + service: host + } }) } } diff --git a/api/src/modules/processing/matchActionDecider.js b/api/src/modules/processing/matchActionDecider.js index 7643d491..6284f665 100644 --- a/api/src/modules/processing/matchActionDecider.js +++ b/api/src/modules/processing/matchActionDecider.js @@ -1,6 +1,5 @@ import { audioIgnore, services, supportedAudio } from "../config.js"; import { createResponse } from "../processing/request.js"; -import loc from "../../localization/manager.js"; import createFilename from "./createFilename.js"; import { createStream } from "../stream/manage.js"; @@ -38,7 +37,9 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di switch (action) { default: - return createResponse("error", { t: loc(lang, 'ErrorEmptyDownload') }); + return createResponse("error", { + code: "ErrorEmptyDownload" + }); case "photo": responseType = "redirect"; @@ -145,9 +146,10 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di break; case "audio": - if (audioIgnore.includes(host) - || (host === "reddit" && r.typeId === "redirect")) { - return createResponse("error", { t: loc(lang, 'ErrorEmptyDownload') }) + if (audioIgnore.includes(host) || (host === "reddit" && r.typeId === "redirect")) { + return createResponse("error", { + code: "ErrorEmptyDownload" + }) } let processType = "render", diff --git a/api/src/modules/processing/request.js b/api/src/modules/processing/request.js index f2f58c65..0bee1691 100644 --- a/api/src/modules/processing/request.js +++ b/api/src/modules/processing/request.js @@ -23,12 +23,16 @@ const apiVar = { } export function createResponse(responseType, responseData) { - const internalError = (text) => { + const internalError = (code) => { + let error = code || "Internal Server Error"; return { status: 500, body: { status: "error", - text: text || "Internal Server Error", + error: { + code: code || "Internal Server Error", + }, + text: error, // temporary backwards compatibility critical: true } } @@ -37,7 +41,7 @@ export function createResponse(responseType, responseData) { try { let status = 200, response = {}; - + switch(responseType) { case "error": status = 400; @@ -50,22 +54,30 @@ export function createResponse(responseType, responseData) { switch (responseType) { case "error": + response = { + error: { + code: responseData.code, + context: responseData?.context, + }, + text: responseData.code, // temporary backwards compatibility + } + break; case "success": case "rate-limit": response = { - text: responseData.t + text: responseData.t, } break; case "redirect": response = { - url: responseData.u + url: responseData.u, } break; case "stream": response = { - url: createStream(responseData) + url: createStream(responseData), } break; @@ -74,19 +86,19 @@ export function createResponse(responseType, responseData) { audio = false; if (responseData.service === "tiktok") { - audio = responseData.u - pickerType = "images" + audio = responseData.u; + pickerType = "images"; } response = { pickerType: pickerType, picker: responseData.picker, - audio: audio + audio: audio, } break; - case "critical": - return internalError(responseData.t) - default: + case "critical": + return internalError(responseData.code); + default: throw "unreachable" } return { @@ -117,7 +129,7 @@ export function normalizeRequest(request) { twitterGif: false, tiktokH265: false } - + const requestKeys = Object.keys(request); const templateKeys = Object.keys(template); From 5ce208f1a575ecd17d1edfa60b5f251d177e39dd Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 10:38:57 +0200 Subject: [PATCH 347/775] ci: run tests on all branches --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4ac2daf3..0dd28cb9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,7 +3,6 @@ name: Run tests on: pull_request: push: - branches: [ current ] jobs: check-lockfile: From dd831e13e89bfc5a37246280e41468a3d1d8c4bd Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 14:47:13 +0600 Subject: [PATCH 348/775] api: flatten code directories, better filenames, remove old files --- api/package.json | 3 +- api/src/cobalt.js | 8 +- api/src/{modules => }/config.js | 29 +++-- api/src/config.json | 103 ------------------ api/src/core/api.js | 20 ++-- api/src/{modules/sub => misc}/alias-envs.js | 2 +- .../consoleText.js => misc/console-text.js} | 0 api/src/{modules/sub => misc}/crypto.js | 0 .../current-commit.js} | 0 .../loadFromFs.js => misc/load-from-fs.js} | 0 .../sub => misc}/randomize-ciphers.js | 0 api/src/{modules/test.js => misc/run-test.js} | 6 +- api/src/{modules/sub => misc}/utils.js | 0 .../{modules => }/processing/cookie/cookie.js | 0 .../processing/cookie/manager.js | 2 +- .../create-filename.js} | 0 .../match-action.js} | 4 +- api/src/{modules => }/processing/match.js | 6 +- api/src/{modules => }/processing/request.js | 4 +- .../service-config.json} | 0 .../service-patterns.js} | 4 +- .../processing/services/bilibili.js | 0 .../processing/services/dailymotion.js | 0 .../processing/services/facebook.js | 0 .../processing/services/instagram.js | 0 .../{modules => }/processing/services/loom.js | 0 .../{modules => }/processing/services/ok.js | 2 +- .../processing/services/pinterest.js | 2 +- .../processing/services/reddit.js | 0 .../processing/services/rutube.js | 2 +- .../processing/services/snapchat.js | 2 +- .../processing/services/soundcloud.js | 2 +- .../processing/services/streamable.js | 0 .../processing/services/tiktok.js | 0 .../processing/services/tumblr.js | 0 .../processing/services/twitch.js | 2 +- .../processing/services/twitter.js | 0 .../processing/services/vimeo.js | 2 +- .../{modules => }/processing/services/vine.js | 0 .../{modules => }/processing/services/vk.js | 2 +- .../processing/services/youtube.js | 2 +- api/src/{modules => }/processing/url.js | 3 +- api/src/{modules => }/stream/internal-hls.js | 0 api/src/{modules => }/stream/internal.js | 6 +- api/src/{modules => }/stream/manage.js | 4 +- api/src/{modules => }/stream/shared.js | 2 +- api/src/{modules => }/stream/stream.js | 0 api/src/{modules => }/stream/types.js | 2 +- api/src/util/generate-youtube-tokens.js | 2 +- api/src/{modules => util}/setup.js | 4 +- api/src/util/test-ci.js | 14 +-- api/src/util/test.js | 16 +-- api/src/util/testFilenamePresets.js | 70 ------------ 53 files changed, 83 insertions(+), 249 deletions(-) rename api/src/{modules => }/config.js (56%) delete mode 100644 api/src/config.json rename api/src/{modules/sub => misc}/alias-envs.js (94%) rename api/src/{modules/sub/consoleText.js => misc/console-text.js} (100%) rename api/src/{modules/sub => misc}/crypto.js (100%) rename api/src/{modules/sub/currentCommit.js => misc/current-commit.js} (100%) rename api/src/{modules/sub/loadFromFs.js => misc/load-from-fs.js} (100%) rename api/src/{modules/sub => misc}/randomize-ciphers.js (100%) rename api/src/{modules/test.js => misc/run-test.js} (86%) rename api/src/{modules/sub => misc}/utils.js (100%) rename api/src/{modules => }/processing/cookie/cookie.js (100%) rename api/src/{modules => }/processing/cookie/manager.js (97%) rename api/src/{modules/processing/createFilename.js => processing/create-filename.js} (100%) rename api/src/{modules/processing/matchActionDecider.js => processing/match-action.js} (98%) rename api/src/{modules => }/processing/match.js (98%) rename api/src/{modules => }/processing/request.js (97%) rename api/src/{modules/processing/servicesConfig.json => processing/service-config.json} (100%) rename api/src/{modules/processing/servicesPatternTesters.js => processing/service-patterns.js} (96%) rename api/src/{modules => }/processing/services/bilibili.js (100%) rename api/src/{modules => }/processing/services/dailymotion.js (100%) rename api/src/{modules => }/processing/services/facebook.js (100%) rename api/src/{modules => }/processing/services/instagram.js (100%) rename api/src/{modules => }/processing/services/loom.js (100%) rename api/src/{modules => }/processing/services/ok.js (97%) rename api/src/{modules => }/processing/services/pinterest.js (98%) rename api/src/{modules => }/processing/services/reddit.js (100%) rename api/src/{modules => }/processing/services/rutube.js (98%) rename api/src/{modules => }/processing/services/snapchat.js (98%) rename api/src/{modules => }/processing/services/soundcloud.js (98%) rename api/src/{modules => }/processing/services/streamable.js (100%) rename api/src/{modules => }/processing/services/tiktok.js (100%) rename api/src/{modules => }/processing/services/tumblr.js (100%) rename api/src/{modules => }/processing/services/twitch.js (98%) rename api/src/{modules => }/processing/services/twitter.js (100%) rename api/src/{modules => }/processing/services/vimeo.js (98%) rename api/src/{modules => }/processing/services/vine.js (100%) rename api/src/{modules => }/processing/services/vk.js (97%) rename api/src/{modules => }/processing/services/youtube.js (99%) rename api/src/{modules => }/processing/url.js (99%) rename api/src/{modules => }/stream/internal-hls.js (100%) rename api/src/{modules => }/stream/internal.js (99%) rename api/src/{modules => }/stream/manage.js (97%) rename api/src/{modules => }/stream/shared.js (99%) rename api/src/{modules => }/stream/stream.js (100%) rename api/src/{modules => }/stream/types.js (99%) rename api/src/{modules => util}/setup.js (97%) delete mode 100644 api/src/util/testFilenamePresets.js diff --git a/api/package.json b/api/package.json index 7cafdf4f..f55ceb4a 100644 --- a/api/package.json +++ b/api/package.json @@ -10,9 +10,8 @@ }, "scripts": { "start": "node src/cobalt", - "setup": "node src/modules/setup", + "setup": "node src/util/setup", "test": "node src/util/test", - "build": "node src/modules/buildStatic", "token:youtube": "node src/util/generate-youtube-tokens" }, "repository": { diff --git a/api/src/cobalt.js b/api/src/cobalt.js index 33ed953d..53a5d71d 100644 --- a/api/src/cobalt.js +++ b/api/src/cobalt.js @@ -1,11 +1,11 @@ import "dotenv/config"; -import "./modules/sub/alias-envs.js"; +import "./misc/alias-envs.js"; import express from "express"; -import { Bright, Green, Red } from "./modules/sub/consoleText.js"; -import { getCurrentBranch, shortCommit } from "./modules/sub/currentCommit.js"; -import { env } from "./modules/config.js" +import { Bright, Green, Red } from "./misc/console-text.js"; +import { getCurrentBranch, shortCommit } from "./misc/current-commit.js"; +import { env } from "./config.js" import path from 'path'; import { fileURLToPath } from 'url'; diff --git a/api/src/modules/config.js b/api/src/config.js similarity index 56% rename from api/src/modules/config.js rename to api/src/config.js index 4a3a63ed..0f9bf07d 100644 --- a/api/src/modules/config.js +++ b/api/src/config.js @@ -1,9 +1,8 @@ import UrlPattern from "url-pattern"; -import { loadJSON } from "./sub/loadFromFs.js"; +import { loadJSON } from "./misc/load-from-fs.js"; -const config = loadJSON("./src/config.json"); const packageJson = loadJSON("./package.json"); -const servicesConfigJson = loadJSON("./src/modules/processing/servicesConfig.json"); +const servicesConfigJson = loadJSON("./src/processing/service-config.json"); Object.values(servicesConfigJson.config).forEach(service => { service.patterns = service.patterns.map( @@ -14,13 +13,23 @@ Object.values(servicesConfigJson.config).forEach(service => { }) export const + version = packageJson.version, + + genericUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + supportedAudio = ["mp3", "ogg", "wav", "opus"], + ffmpegArgs = { + webm: ["-c:v", "copy", "-c:a", "copy"], + mp4: ["-c:v", "copy", "-c:a", "copy", "-movflags", "faststart+frag_keyframe+empty_moov"], + copy: ["-c:a", "copy"], + audio: ["-ar", "48000", "-ac", "2", "-b:a", "320k"], + m4a: ["-movflags", "frag_keyframe+empty_moov"], + gif: ["-vf", "scale=-1:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse", "-loop", "0"] + }, + services = servicesConfigJson.config, hlsExceptions = servicesConfigJson.hlsExceptions, audioIgnore = servicesConfigJson.audioIgnore, - version = packageJson.version, - genericUserAgent = config.genericUserAgent, - ffmpegArgs = config.ffmpegArgs, - supportedAudio = config.supportedAudio, + env = { apiURL: process.env.API_URL || '', apiPort: process.env.API_PORT || 9000, @@ -33,15 +42,15 @@ export const cookiePath: process.env.COOKIE_PATH, - rateLimitWindow: (process.env.RATELIMIT_WINDOW && parseInt(process.env.RATELIMIT_WINDOW)) || 60, + rateLimitWindow: (process.env.RATELIMIT_WINDOW && parseInt(process.env.RATELIMIT_WINDOW)) || 60, rateLimitMax: (process.env.RATELIMIT_MAX && parseInt(process.env.RATELIMIT_MAX)) || 20, durationLimit: (process.env.DURATION_LIMIT && parseInt(process.env.DURATION_LIMIT)) || 10800, streamLifespan: 90, processingPriority: process.platform !== 'win32' - && process.env.PROCESSING_PRIORITY - && parseInt(process.env.PROCESSING_PRIORITY), + && process.env.PROCESSING_PRIORITY + && parseInt(process.env.PROCESSING_PRIORITY), externalProxy: process.env.API_EXTERNAL_PROXY, } diff --git a/api/src/config.json b/api/src/config.json deleted file mode 100644 index 640fb2f5..00000000 --- a/api/src/config.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "genericUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", - "authorInfo": { - "support": { - "default": { - "email": { - "emoji": "📧", - "url": "mailto:support@cobalt.tools", - "name": "support@cobalt.tools" - }, - "twitter": { - "emoji": "🐦", - "url": "https://twitter.com/justusecobalt", - "name": "@justusecobalt" - }, - "discord": { - "emoji": "👾", - "url": "https://discord.gg/pQPt8HBUPu", - "name": "cobalt discord server" - } - }, - "ru": { - "telegram": { - "emoji": "📬", - "url": "https://t.me/justusecobalt_ru", - "name": "канал в telegram" - }, - "email": { - "emoji": "📧", - "url": "mailto:support@cobalt.tools", - "name": "support@cobalt.tools" - } - } - } - }, - "donations": { - "crypto": { - "monero": "4B1SNB6s8Pq1hxjNeKPEe8Qa8EP3zdL16Sqsa7QDoJcUecKQzEj9BMxWnEnTGu12doKLJBKRDUqnn6V9qfSdXpXi3Nw5Uod", - "litecoin": "ltc1qvp0xhrk2m7pa6p6z844qcslfyxv4p3vf95rhna", - "ethereum": "0x4B4cF23051c78c7A7E0eA09d39099621c46bc302", - "usdt-erc20": "0x4B4cF23051c78c7A7E0eA09d39099621c46bc302", - "usdt-trc20": "TVbx7YT3rBfu931Gxko6pRfXtedYqbgnBB", - "bitcoin": "bc1qlvcnlnyzfsgnuxyxsv3k0p0q0yln0azjpadyx4", - "bitcoin-alt": "18PKf6N2cHrmSzz9ZzTSvDd2jAkqGC7SxA", - "ton": "UQA3SO-hHZq1oCCT--u6or6ollB8fd2o52aD8mXiLk9iDZd3" - }, - "links": { - "boosty": "https://boosty.to/wukko/donate" - } - }, - "links": { - "saveToGalleryShortcut": "https://www.icloud.com/shortcuts/14e9aebf04b24156acc34ceccf7e6fcd", - "saveToFilesShortcut": "https://www.icloud.com/shortcuts/2134cd9d4d6b41448b2201f933542b2e", - "statusPage": "https://status.cobalt.tools/", - "troubleshootingGuide": "https://github.com/imputnet/cobalt/blob/current/docs/troubleshooting.md" - }, - "celebrations": { - "01-01": "🎄", - "02-17": "😺", - "02-22": "😺", - "03-01": "😺", - "03-08": "💪", - "05-26": "🎂", - "08-08": "😺", - "08-26": "🐶", - "10-29": "😺", - "10-30": "🎃", - "10-31": "🎃", - "11-01": "🕯️", - "11-02": "🕯️", - "12-20": "🎄", - "12-21": "🎄", - "12-22": "🎄", - "12-23": "🎄", - "12-24": "🎄", - "12-25": "🎄", - "12-26": "🎄", - "12-27": "🎄", - "12-28": "🎄", - "12-29": "🎄", - "12-30": "🎄", - "12-31": "🎄" - }, - "supportedAudio": ["mp3", "ogg", "wav", "opus"], - "ffmpegArgs": { - "webm": ["-c:v", "copy", "-c:a", "copy"], - "mp4": ["-c:v", "copy", "-c:a", "copy", "-movflags", "faststart+frag_keyframe+empty_moov"], - "copy": ["-c:a", "copy"], - "audio": ["-ar", "48000", "-ac", "2", "-b:a", "320k"], - "m4a": ["-movflags", "frag_keyframe+empty_moov"], - "gif": ["-vf", "scale=-1:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse", "-loop", "0"] - }, - "sponsors": [{ - "name": "royale", - "fullName": "RoyaleHosting", - "url": "https://royalehosting.net/?partner=cobalt", - "logo": { - "width": 605, - "height": 136, - "scale": 5 - } - }] -} diff --git a/api/src/core/api.js b/api/src/core/api.js index 74ea0307..ebdedb55 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -2,18 +2,18 @@ import cors from "cors"; import rateLimit from "express-rate-limit"; import { setGlobalDispatcher, ProxyAgent } from "undici"; -import { env, version } from "../modules/config.js"; +import { env, version } from "../config.js"; -import { generateHmac, generateSalt } from "../modules/sub/crypto.js"; -import { Bright, Cyan } from "../modules/sub/consoleText.js"; -import { languageCode } from "../modules/sub/utils.js"; +import { generateHmac, generateSalt } from "../misc/crypto.js"; +import { Bright, Cyan } from "../misc/console-text.js"; +import { languageCode } from "../misc/utils.js"; -import { createResponse, normalizeRequest, getIP } from "../modules/processing/request.js"; -import { verifyStream, getInternalStream } from "../modules/stream/manage.js"; -import { randomizeCiphers } from '../modules/sub/randomize-ciphers.js'; -import { extract } from "../modules/processing/url.js"; -import match from "../modules/processing/match.js"; -import stream from "../modules/stream/stream.js"; +import { createResponse, normalizeRequest, getIP } from "../processing/request.js"; +import { verifyStream, getInternalStream } from "../stream/manage.js"; +import { randomizeCiphers } from '../misc/randomize-ciphers.js'; +import { extract } from "../processing/url.js"; +import match from "../processing/match.js"; +import stream from "../stream/stream.js"; const acceptRegex = /^application\/json(; charset=utf-8)?$/; diff --git a/api/src/modules/sub/alias-envs.js b/api/src/misc/alias-envs.js similarity index 94% rename from api/src/modules/sub/alias-envs.js rename to api/src/misc/alias-envs.js index 24f6a856..5facb14b 100644 --- a/api/src/modules/sub/alias-envs.js +++ b/api/src/misc/alias-envs.js @@ -1,4 +1,4 @@ -import { Red } from "./consoleText.js"; +import { Red } from "./console-text.js"; const mapping = { apiPort: 'API_PORT', diff --git a/api/src/modules/sub/consoleText.js b/api/src/misc/console-text.js similarity index 100% rename from api/src/modules/sub/consoleText.js rename to api/src/misc/console-text.js diff --git a/api/src/modules/sub/crypto.js b/api/src/misc/crypto.js similarity index 100% rename from api/src/modules/sub/crypto.js rename to api/src/misc/crypto.js diff --git a/api/src/modules/sub/currentCommit.js b/api/src/misc/current-commit.js similarity index 100% rename from api/src/modules/sub/currentCommit.js rename to api/src/misc/current-commit.js diff --git a/api/src/modules/sub/loadFromFs.js b/api/src/misc/load-from-fs.js similarity index 100% rename from api/src/modules/sub/loadFromFs.js rename to api/src/misc/load-from-fs.js diff --git a/api/src/modules/sub/randomize-ciphers.js b/api/src/misc/randomize-ciphers.js similarity index 100% rename from api/src/modules/sub/randomize-ciphers.js rename to api/src/misc/randomize-ciphers.js diff --git a/api/src/modules/test.js b/api/src/misc/run-test.js similarity index 86% rename from api/src/modules/test.js rename to api/src/misc/run-test.js index 75bdab26..455e3dfd 100644 --- a/api/src/modules/test.js +++ b/api/src/misc/run-test.js @@ -1,6 +1,6 @@ -import { normalizeRequest } from "../modules/processing/request.js"; -import match from "./processing/match.js"; -import { extract } from "./processing/url.js"; +import { normalizeRequest } from "../processing/request.js"; +import match from "../processing/match.js"; +import { extract } from "../processing/url.js"; export async function runTest(url, params, expect) { const normalized = normalizeRequest({ url, ...params }); diff --git a/api/src/modules/sub/utils.js b/api/src/misc/utils.js similarity index 100% rename from api/src/modules/sub/utils.js rename to api/src/misc/utils.js diff --git a/api/src/modules/processing/cookie/cookie.js b/api/src/processing/cookie/cookie.js similarity index 100% rename from api/src/modules/processing/cookie/cookie.js rename to api/src/processing/cookie/cookie.js diff --git a/api/src/modules/processing/cookie/manager.js b/api/src/processing/cookie/manager.js similarity index 97% rename from api/src/modules/processing/cookie/manager.js rename to api/src/processing/cookie/manager.js index 2b997d96..25bf9c90 100644 --- a/api/src/modules/processing/cookie/manager.js +++ b/api/src/processing/cookie/manager.js @@ -1,7 +1,7 @@ import Cookie from './cookie.js'; import { readFile, writeFile } from 'fs/promises'; import { parse as parseSetCookie, splitCookiesString } from 'set-cookie-parser'; -import { env } from '../../../modules/config.js' +import { env } from '../../config.js'; const WRITE_INTERVAL = 60000, cookiePath = env.cookiePath, diff --git a/api/src/modules/processing/createFilename.js b/api/src/processing/create-filename.js similarity index 100% rename from api/src/modules/processing/createFilename.js rename to api/src/processing/create-filename.js diff --git a/api/src/modules/processing/matchActionDecider.js b/api/src/processing/match-action.js similarity index 98% rename from api/src/modules/processing/matchActionDecider.js rename to api/src/processing/match-action.js index 6284f665..d5c58013 100644 --- a/api/src/modules/processing/matchActionDecider.js +++ b/api/src/processing/match-action.js @@ -1,6 +1,6 @@ import { audioIgnore, services, supportedAudio } from "../config.js"; -import { createResponse } from "../processing/request.js"; -import createFilename from "./createFilename.js"; +import { createResponse } from "./request.js"; +import createFilename from "./create-filename.js"; import { createStream } from "../stream/manage.js"; export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, disableMetadata, filenamePattern, toGif, requestIP) { diff --git a/api/src/modules/processing/match.js b/api/src/processing/match.js similarity index 98% rename from api/src/modules/processing/match.js rename to api/src/processing/match.js index ce69f30b..381c9b98 100644 --- a/api/src/modules/processing/match.js +++ b/api/src/processing/match.js @@ -1,10 +1,10 @@ import { strict as assert } from "node:assert"; -import { env } from '../config.js'; +import { env } from "../config.js"; import { createResponse } from "../processing/request.js"; -import { testers } from "./servicesPatternTesters.js"; -import matchActionDecider from "./matchActionDecider.js"; +import { testers } from "./service-patterns.js"; +import matchActionDecider from "./match-action.js"; import bilibili from "./services/bilibili.js"; import reddit from "./services/reddit.js"; diff --git a/api/src/modules/processing/request.js b/api/src/processing/request.js similarity index 97% rename from api/src/modules/processing/request.js rename to api/src/processing/request.js index 0bee1691..899fcc44 100644 --- a/api/src/modules/processing/request.js +++ b/api/src/processing/request.js @@ -1,8 +1,8 @@ import ipaddr from "ipaddr.js"; -import { normalizeURL } from "../processing/url.js"; +import { normalizeURL } from "./url.js"; import { createStream } from "../stream/manage.js"; -import { verifyLanguageCode } from "../sub/utils.js"; +import { verifyLanguageCode } from "../misc/utils.js"; const apiVar = { allowed: { diff --git a/api/src/modules/processing/servicesConfig.json b/api/src/processing/service-config.json similarity index 100% rename from api/src/modules/processing/servicesConfig.json rename to api/src/processing/service-config.json diff --git a/api/src/modules/processing/servicesPatternTesters.js b/api/src/processing/service-patterns.js similarity index 96% rename from api/src/modules/processing/servicesPatternTesters.js rename to api/src/processing/service-patterns.js index 48f953c1..e8d169d5 100644 --- a/api/src/modules/processing/servicesPatternTesters.js +++ b/api/src/processing/service-patterns.js @@ -31,8 +31,8 @@ export const testers = { || patternMatch.shortLink?.length <= 32, "snapchat": (patternMatch) => - (patternMatch.username?.length <= 32 && (!patternMatch.storyId || patternMatch.storyId?.length <= 255)) - || patternMatch.spotlightId?.length <= 255 + (patternMatch.username?.length <= 32 && (!patternMatch.storyId || patternMatch.storyId?.length <= 255)) + || patternMatch.spotlightId?.length <= 255 || patternMatch.shortLink?.length <= 16, "streamable": (patternMatch) => diff --git a/api/src/modules/processing/services/bilibili.js b/api/src/processing/services/bilibili.js similarity index 100% rename from api/src/modules/processing/services/bilibili.js rename to api/src/processing/services/bilibili.js diff --git a/api/src/modules/processing/services/dailymotion.js b/api/src/processing/services/dailymotion.js similarity index 100% rename from api/src/modules/processing/services/dailymotion.js rename to api/src/processing/services/dailymotion.js diff --git a/api/src/modules/processing/services/facebook.js b/api/src/processing/services/facebook.js similarity index 100% rename from api/src/modules/processing/services/facebook.js rename to api/src/processing/services/facebook.js diff --git a/api/src/modules/processing/services/instagram.js b/api/src/processing/services/instagram.js similarity index 100% rename from api/src/modules/processing/services/instagram.js rename to api/src/processing/services/instagram.js diff --git a/api/src/modules/processing/services/loom.js b/api/src/processing/services/loom.js similarity index 100% rename from api/src/modules/processing/services/loom.js rename to api/src/processing/services/loom.js diff --git a/api/src/modules/processing/services/ok.js b/api/src/processing/services/ok.js similarity index 97% rename from api/src/modules/processing/services/ok.js rename to api/src/processing/services/ok.js index 33847cd8..8f177043 100644 --- a/api/src/modules/processing/services/ok.js +++ b/api/src/processing/services/ok.js @@ -1,5 +1,5 @@ import { genericUserAgent, env } from "../../config.js"; -import { cleanString } from "../../sub/utils.js"; +import { cleanString } from "../../misc/utils.js"; const resolutions = { "ultra": "2160", diff --git a/api/src/modules/processing/services/pinterest.js b/api/src/processing/services/pinterest.js similarity index 98% rename from api/src/modules/processing/services/pinterest.js rename to api/src/processing/services/pinterest.js index 3e9e1d32..5a5f9438 100644 --- a/api/src/modules/processing/services/pinterest.js +++ b/api/src/processing/services/pinterest.js @@ -33,7 +33,7 @@ export default async function(o) { let imageLink = [...html.matchAll(imageRegex)] .map(([, link]) => link) .find(a => a.endsWith('.jpg') || a.endsWith('.gif')); - + if (imageLink) return { urls: imageLink, isPhoto: true diff --git a/api/src/modules/processing/services/reddit.js b/api/src/processing/services/reddit.js similarity index 100% rename from api/src/modules/processing/services/reddit.js rename to api/src/processing/services/reddit.js diff --git a/api/src/modules/processing/services/rutube.js b/api/src/processing/services/rutube.js similarity index 98% rename from api/src/modules/processing/services/rutube.js rename to api/src/processing/services/rutube.js index 325e9ccc..c162eaf5 100644 --- a/api/src/modules/processing/services/rutube.js +++ b/api/src/processing/services/rutube.js @@ -1,7 +1,7 @@ import HLS from 'hls-parser'; import { env } from "../../config.js"; -import { cleanString } from '../../sub/utils.js'; +import { cleanString } from '../../misc/utils.js'; async function requestJSON(url) { try { diff --git a/api/src/modules/processing/services/snapchat.js b/api/src/processing/services/snapchat.js similarity index 98% rename from api/src/modules/processing/services/snapchat.js rename to api/src/processing/services/snapchat.js index a93f0933..1c1eaf6d 100644 --- a/api/src/modules/processing/services/snapchat.js +++ b/api/src/processing/services/snapchat.js @@ -1,5 +1,5 @@ import { genericUserAgent } from "../../config.js"; -import { getRedirectingURL } from "../../sub/utils.js"; +import { getRedirectingURL } from "../../misc/utils.js"; import { extract, normalizeURL } from "../url.js"; const SPOTLIGHT_VIDEO_REGEX = //; diff --git a/api/src/modules/processing/services/soundcloud.js b/api/src/processing/services/soundcloud.js similarity index 98% rename from api/src/modules/processing/services/soundcloud.js rename to api/src/processing/services/soundcloud.js index c36ec61d..82852b8f 100644 --- a/api/src/modules/processing/services/soundcloud.js +++ b/api/src/processing/services/soundcloud.js @@ -1,5 +1,5 @@ import { env } from "../../config.js"; -import { cleanString } from "../../sub/utils.js"; +import { cleanString } from "../../misc/utils.js"; const cachedID = { version: '', diff --git a/api/src/modules/processing/services/streamable.js b/api/src/processing/services/streamable.js similarity index 100% rename from api/src/modules/processing/services/streamable.js rename to api/src/processing/services/streamable.js diff --git a/api/src/modules/processing/services/tiktok.js b/api/src/processing/services/tiktok.js similarity index 100% rename from api/src/modules/processing/services/tiktok.js rename to api/src/processing/services/tiktok.js diff --git a/api/src/modules/processing/services/tumblr.js b/api/src/processing/services/tumblr.js similarity index 100% rename from api/src/modules/processing/services/tumblr.js rename to api/src/processing/services/tumblr.js diff --git a/api/src/modules/processing/services/twitch.js b/api/src/processing/services/twitch.js similarity index 98% rename from api/src/modules/processing/services/twitch.js rename to api/src/processing/services/twitch.js index 13cee19f..5712178c 100644 --- a/api/src/modules/processing/services/twitch.js +++ b/api/src/processing/services/twitch.js @@ -1,5 +1,5 @@ import { env } from "../../config.js"; -import { cleanString } from '../../sub/utils.js'; +import { cleanString } from '../../misc/utils.js'; const gqlURL = "https://gql.twitch.tv/gql"; const clientIdHead = { "client-id": "kimne78kx3ncx6brgo4mv6wki5h1ko" }; diff --git a/api/src/modules/processing/services/twitter.js b/api/src/processing/services/twitter.js similarity index 100% rename from api/src/modules/processing/services/twitter.js rename to api/src/processing/services/twitter.js diff --git a/api/src/modules/processing/services/vimeo.js b/api/src/processing/services/vimeo.js similarity index 98% rename from api/src/modules/processing/services/vimeo.js rename to api/src/processing/services/vimeo.js index 30ee3368..a9f02040 100644 --- a/api/src/modules/processing/services/vimeo.js +++ b/api/src/processing/services/vimeo.js @@ -1,5 +1,5 @@ import { env } from "../../config.js"; -import { cleanString, merge } from '../../sub/utils.js'; +import { cleanString, merge } from '../../misc/utils.js'; import HLS from "hls-parser"; diff --git a/api/src/modules/processing/services/vine.js b/api/src/processing/services/vine.js similarity index 100% rename from api/src/modules/processing/services/vine.js rename to api/src/processing/services/vine.js diff --git a/api/src/modules/processing/services/vk.js b/api/src/processing/services/vk.js similarity index 97% rename from api/src/modules/processing/services/vk.js rename to api/src/processing/services/vk.js index e95f12be..a3ddd615 100644 --- a/api/src/modules/processing/services/vk.js +++ b/api/src/processing/services/vk.js @@ -1,5 +1,5 @@ import { genericUserAgent, env } from "../../config.js"; -import { cleanString } from "../../sub/utils.js"; +import { cleanString } from "../../misc/utils.js"; const resolutions = ["2160", "1440", "1080", "720", "480", "360", "240"]; diff --git a/api/src/modules/processing/services/youtube.js b/api/src/processing/services/youtube.js similarity index 99% rename from api/src/modules/processing/services/youtube.js rename to api/src/processing/services/youtube.js index 9bfc3919..5dd40ee1 100644 --- a/api/src/modules/processing/services/youtube.js +++ b/api/src/processing/services/youtube.js @@ -3,7 +3,7 @@ import { fetch } from "undici"; import { Innertube, Session } from "youtubei.js"; import { env } from "../../config.js"; -import { cleanString } from "../../sub/utils.js"; +import { cleanString } from "../../misc/utils.js"; import { getCookie, updateCookieValues } from "../cookie/manager.js"; const PLAYER_REFRESH_PERIOD = 1000 * 60 * 15; // ms diff --git a/api/src/modules/processing/url.js b/api/src/processing/url.js similarity index 99% rename from api/src/modules/processing/url.js rename to api/src/processing/url.js index 180ec6ee..a2b9cd7d 100644 --- a/api/src/modules/processing/url.js +++ b/api/src/processing/url.js @@ -54,6 +54,7 @@ function aliasURL(url) { url = new URL(`https://bilibili.com/_tv${url.pathname}`); } break; + case "b23": if (url.hostname === 'b23.tv' && parts.length === 2) { url = new URL(`https://bilibili.com/_shortLink/${parts[1]}`) @@ -179,4 +180,4 @@ export function extract(url) { } return { host, patternMatch }; -} \ No newline at end of file +} diff --git a/api/src/modules/stream/internal-hls.js b/api/src/stream/internal-hls.js similarity index 100% rename from api/src/modules/stream/internal-hls.js rename to api/src/stream/internal-hls.js diff --git a/api/src/modules/stream/internal.js b/api/src/stream/internal.js similarity index 99% rename from api/src/modules/stream/internal.js rename to api/src/stream/internal.js index 7a155a9a..253f98bb 100644 --- a/api/src/modules/stream/internal.js +++ b/api/src/stream/internal.js @@ -28,7 +28,7 @@ async function* readChunks(streamInfo, size) { if (received < expected / 2n) { closeRequest(streamInfo.controller); } - + for await (const data of chunk.body) { yield data; } @@ -64,7 +64,7 @@ async function handleYoutubeStream(streamInfo, res) { } signal.addEventListener('abort', abortGenerator); - + const stream = Readable.from(generator); for (const headerName of ['content-type', 'content-length']) { @@ -119,4 +119,4 @@ export function internalStream(streamInfo, res) { } return handleGenericStream(streamInfo, res); -} \ No newline at end of file +} diff --git a/api/src/modules/stream/manage.js b/api/src/stream/manage.js similarity index 97% rename from api/src/modules/stream/manage.js rename to api/src/stream/manage.js index af041a67..24270144 100644 --- a/api/src/modules/stream/manage.js +++ b/api/src/stream/manage.js @@ -3,7 +3,7 @@ import { randomBytes } from "crypto"; import { nanoid } from "nanoid"; import { setMaxListeners } from "node:events"; -import { decryptStream, encryptStream, generateHmac } from "../sub/crypto.js"; +import { decryptStream, encryptStream, generateHmac } from "../misc/crypto.js"; import { env } from "../config.js"; import { strict as assert } from "assert"; import { closeRequest } from "./shared.js"; @@ -83,7 +83,7 @@ export function createInternalStream(url, obj = {}) { let controller = obj.controller; if (!controller) { - controller = new AbortController(); + controller = new AbortController(); setMaxListeners(Infinity, controller.signal); } diff --git a/api/src/modules/stream/shared.js b/api/src/stream/shared.js similarity index 99% rename from api/src/modules/stream/shared.js rename to api/src/stream/shared.js index fd7d1569..91e1ac2f 100644 --- a/api/src/modules/stream/shared.js +++ b/api/src/stream/shared.js @@ -42,4 +42,4 @@ export function pipe(from, to, done) { .on('close', done); from.pipe(to); -} \ No newline at end of file +} diff --git a/api/src/modules/stream/stream.js b/api/src/stream/stream.js similarity index 100% rename from api/src/modules/stream/stream.js rename to api/src/stream/stream.js diff --git a/api/src/modules/stream/types.js b/api/src/stream/types.js similarity index 99% rename from api/src/modules/stream/types.js rename to api/src/stream/types.js index 071cb6d0..f566a196 100644 --- a/api/src/modules/stream/types.js +++ b/api/src/stream/types.js @@ -3,7 +3,7 @@ import ffmpeg from "ffmpeg-static"; import { spawn } from "child_process"; import { create as contentDisposition } from "content-disposition-header"; -import { metadataManager } from "../sub/utils.js"; +import { metadataManager } from "../misc/utils.js"; import { destroyInternalStream } from "./manage.js"; import { env, ffmpegArgs, hlsExceptions } from "../config.js"; import { getHeaders, closeRequest, closeResponse, pipe } from "./shared.js"; diff --git a/api/src/util/generate-youtube-tokens.js b/api/src/util/generate-youtube-tokens.js index ab877f96..5585705a 100644 --- a/api/src/util/generate-youtube-tokens.js +++ b/api/src/util/generate-youtube-tokens.js @@ -1,5 +1,5 @@ import { Innertube } from 'youtubei.js'; -import { Red } from '../modules/sub/consoleText.js' +import { Red } from '../misc/console-text.js' const bail = (...msg) => { console.error(...msg); diff --git a/api/src/modules/setup.js b/api/src/util/setup.js similarity index 97% rename from api/src/modules/setup.js rename to api/src/util/setup.js index 137f6271..7796ea22 100644 --- a/api/src/modules/setup.js +++ b/api/src/util/setup.js @@ -1,7 +1,7 @@ import { existsSync, unlinkSync, appendFileSync } from "fs"; import { createInterface } from "readline"; -import { Cyan, Bright } from "./sub/consoleText.js"; -import { loadJSON } from "./sub/loadFromFs.js"; +import { Cyan, Bright } from "./misc/console-text.js"; +import { loadJSON } from "./misc/load-from-fs.js"; import { execSync } from "child_process"; const { version } = loadJSON("./package.json"); diff --git a/api/src/util/test-ci.js b/api/src/util/test-ci.js index ed6962c7..6559aadc 100644 --- a/api/src/util/test-ci.js +++ b/api/src/util/test-ci.js @@ -1,11 +1,10 @@ -import { env } from "../modules/config.js"; -import { runTest } from "../modules/test.js"; -import { loadLoc } from "../localization/manager.js"; -import { loadJSON } from "../modules/sub/loadFromFs.js"; -import { Red, Bright } from "../modules/sub/consoleText.js"; +import { env } from "../config.js"; +import { runTest } from "../misc/run-test.js"; +import { loadJSON } from "../misc/load-from-fs.js"; +import { Red, Bright } from "../misc/console-text.js"; const tests = loadJSON('./src/util/tests.json'); -const services = loadJSON('./src/modules/processing/servicesConfig.json'); +const services = loadJSON('./src/processing/service-config.json'); // services that are known to frequently fail due to external // factors (e.g. rate limiting) @@ -38,7 +37,6 @@ switch (action) { console.error('no such service:', service); } - await loadLoc(); env.streamLifespan = 10000; env.apiURL = 'http://x'; @@ -78,4 +76,4 @@ switch (action) { default: console.error('invalid action:', action); process.exitCode = 1; -} \ No newline at end of file +} diff --git a/api/src/util/test.js b/api/src/util/test.js index 294ff7e7..2a2c084c 100644 --- a/api/src/util/test.js +++ b/api/src/util/test.js @@ -1,12 +1,12 @@ import "dotenv/config"; -import "../modules/sub/alias-envs.js"; +import "../misc/alias-envs.js"; -import { services } from "../modules/config.js"; -import { extract } from "../modules/processing/url.js"; -import match from "../modules/processing/match.js"; -import { loadJSON } from "../modules/sub/loadFromFs.js"; -import { normalizeRequest } from "../modules/processing/request.js"; -import { env } from "../modules/config.js"; +import { services } from "../config.js"; +import { extract } from "../processing/url.js"; +import match from "../processing/match.js"; +import { loadJSON } from "../misc/load-from-fs.js"; +import { normalizeRequest } from "../processing/request.js"; +import { env } from "../config.js"; env.apiURL = 'http://localhost:9000' let tests = loadJSON('./src/util/tests.json'); @@ -29,7 +29,7 @@ for (let i in services) { console.log(`\nRunning tests for ${i}...\n`) for (let k = 0; k < tests[i].length; k++) { let test = tests[i][k]; - + console.log(`Running test ${k+1}: ${test.name}`); console.log('params:'); let params = {...{url: test.url}, ...test.params}; diff --git a/api/src/util/testFilenamePresets.js b/api/src/util/testFilenamePresets.js deleted file mode 100644 index ba088cb0..00000000 --- a/api/src/util/testFilenamePresets.js +++ /dev/null @@ -1,70 +0,0 @@ -import createFilename from "../modules/processing/createFilename.js"; - -let tests = [ - { - f: { - service: 'youtube', - id: 'MMK3L4W70g4', - title: "Loossemble (루셈블) - 'Sensitive' MV", - author: 'Loossemble', - youtubeDubName: false, - qualityLabel: '2160p', - resolution: '3840x2160', - extension: 'webm', - youtubeFormat: 'vp9' - }, - isAudioOnly: false, - isAudioMuted: false - }, - { - f: { - service: 'youtube', - id: 'MMK3L4W70g4', - title: "Loossemble (루셈블) - 'Sensitive' MV", - author: 'Loossemble', - youtubeDubName: false, - qualityLabel: '2160p', - resolution: '3840x2160', - extension: 'webm', - youtubeFormat: 'vp9' - }, - isAudioOnly: true, - isAudioMuted: false - }, - { - f: { - service: 'youtube', - id: 'MMK3L4W70g4', - title: "Loossemble (루셈블) - 'Sensitive' MV", - author: 'Loossemble', - youtubeDubName: false, - qualityLabel: '2160p', - resolution: '3840x2160', - extension: 'webm', - youtubeFormat: 'vp9' - }, - isAudioOnly: false, - isAudioMuted: true - }, - { - f: { - service: 'vimeo', - id: 'MMK3L4W70g4', - title: "Loossemble (루셈블) - 'Sensitive' MV", - author: 'Loossemble', - qualityLabel: '2160p', - resolution: '3840x2160', - extension: 'mp4' - }, - isAudioOnly: false, - isAudioMuted: true - } -] - -for (let i = 0; i < tests.length; i++) { - console.log(`---${i}---`) - console.log(createFilename(tests[i].f, "classic", tests[i].isAudioOnly, tests[i].isAudioMuted)) - console.log(createFilename(tests[i].f, "basic", tests[i].isAudioOnly, tests[i].isAudioMuted)) - console.log(createFilename(tests[i].f, "pretty", tests[i].isAudioOnly, tests[i].isAudioMuted)) - console.log(createFilename(tests[i].f, "nerdy", tests[i].isAudioOnly, tests[i].isAudioMuted)) -} From 559e8448e5f0c88597d092999fc568342f30b835 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 08:59:57 +0000 Subject: [PATCH 349/775] repo: add static build to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 05a7c403..b408b65c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ desktop.ini # node node_modules +# static build +build + # secrets .env .env.* From 0ffea2d886c0cbca91488189d922c901f01b0025 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 15:02:59 +0600 Subject: [PATCH 350/775] api/match: pass action parameters as object --- api/src/processing/match-action.js | 7 +++---- api/src/processing/match.js | 17 +++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/api/src/processing/match-action.js b/api/src/processing/match-action.js index d5c58013..d6ec98ca 100644 --- a/api/src/processing/match-action.js +++ b/api/src/processing/match-action.js @@ -3,7 +3,7 @@ import { createResponse } from "./request.js"; import createFilename from "./create-filename.js"; import { createStream } from "../stream/manage.js"; -export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, disableMetadata, filenamePattern, toGif, requestIP) { +export default function({ r, host, audioFormat, isAudioOnly, isAudioMuted, disableMetadata, filenameStyle, toGif, requestIP }) { let action, responseType = "stream", defaultParams = { @@ -11,12 +11,11 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di headers: r.headers, service: host, filename: r.filenameAttributes ? - createFilename(r.filenameAttributes, filenamePattern, isAudioOnly, isAudioMuted) : r.filename, + createFilename(r.filenameAttributes, filenameStyle, isAudioOnly, isAudioMuted) : r.filename, fileMetadata: !disableMetadata ? r.fileMetadata : false, requestIP }, - params = {}, - audioFormat = String(userFormat); + params = {}; if (r.isPhoto) action = "photo"; else if (r.picker) action = "picker" diff --git a/api/src/processing/match.js b/api/src/processing/match.js index 381c9b98..fd40010d 100644 --- a/api/src/processing/match.js +++ b/api/src/processing/match.js @@ -4,7 +4,7 @@ import { env } from "../config.js"; import { createResponse } from "../processing/request.js"; import { testers } from "./service-patterns.js"; -import matchActionDecider from "./match-action.js"; +import matchAction from "./match-action.js"; import bilibili from "./services/bilibili.js"; import reddit from "./services/reddit.js"; @@ -230,12 +230,17 @@ export default async function(host, patternMatch, lang, obj) { }) } - return matchActionDecider( - r, host, obj.aFormat, isAudioOnly, - lang, isAudioMuted, disableMetadata, - obj.filenamePattern, obj.twitterGif, + return matchAction({ + r, + host, + audioFormat: obj.audioFormat, + isAudioOnly, + isAudioMuted, + disableMetadata, + filenameStyle: obj.filenamePattern, + toGif: obj.twitterGif, requestIP - ) + }) } catch { return createResponse("error", { code: "ErrorBadFetch", From 8e7b63ade609a339e88fd588fd2c23f14b39b7bd Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 15:05:00 +0600 Subject: [PATCH 351/775] api/match: fix audio format variable typo --- api/src/processing/match.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/processing/match.js b/api/src/processing/match.js index fd40010d..c40d89bc 100644 --- a/api/src/processing/match.js +++ b/api/src/processing/match.js @@ -233,7 +233,7 @@ export default async function(host, patternMatch, lang, obj) { return matchAction({ r, host, - audioFormat: obj.audioFormat, + audioFormat: obj.aFormat, isAudioOnly, isAudioMuted, disableMetadata, From 0e0ad7cb0e8743163e217470c162f8059b506fe3 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:27:56 +0000 Subject: [PATCH 352/775] api/load-from-fs: always load files from root of api folder --- api/src/misc/load-from-fs.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/src/misc/load-from-fs.js b/api/src/misc/load-from-fs.js index 0fab6057..25ae23bf 100644 --- a/api/src/misc/load-from-fs.js +++ b/api/src/misc/load-from-fs.js @@ -1,12 +1,20 @@ import * as fs from "fs"; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const root = join( + dirname(fileURLToPath(import.meta.url)), + '../../' +); export function loadJSON(path) { try { - return JSON.parse(fs.readFileSync(path, 'utf-8')) + return JSON.parse(fs.readFileSync(join(root, path), 'utf-8')) } catch { return false } } + export function loadFile(path) { try { return fs.readFileSync(path, 'utf-8') From 6d817f149e9f41bb7cd90878f38e4488f9b21fc8 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:28:59 +0000 Subject: [PATCH 353/775] api/load-from-fs: refactor loadFile, use in loadJSON --- api/src/misc/load-from-fs.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/api/src/misc/load-from-fs.js b/api/src/misc/load-from-fs.js index 25ae23bf..f91a20cb 100644 --- a/api/src/misc/load-from-fs.js +++ b/api/src/misc/load-from-fs.js @@ -9,16 +9,12 @@ const root = join( export function loadJSON(path) { try { - return JSON.parse(fs.readFileSync(join(root, path), 'utf-8')) + return JSON.parse(loadFile(path)) } catch { return false } } export function loadFile(path) { - try { - return fs.readFileSync(path, 'utf-8') - } catch { - return false - } + return fs.readFileSync(join(root, path), 'utf-8') } From 350e1d4d4f62beca9fb872cf6a729b88faca2b95 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:29:29 +0000 Subject: [PATCH 354/775] ci: update tests for new cobalt --- .github/test.sh | 30 ++++++++++++------------------ .github/workflows/test.yml | 10 +++------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/.github/test.sh b/.github/test.sh index 80de1fcd..4ae96541 100755 --- a/.github/test.sh +++ b/.github/test.sh @@ -18,14 +18,15 @@ test_api() { -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ - -d '{"url":"https://vine.co/v/huwVJIEJW50", "isAudioOnly": true}') + -d '{"url":"https://www.tiktok.com/@fatfatmillycat/video/7195741644585454894"}') - echo "$API_RESPONSE" + echo "API_RESPONSE=$API_RESPONSE" STATUS=$(echo "$API_RESPONSE" | jq -r .status) STREAM_URL=$(echo "$API_RESPONSE" | jq -r .url) [ "$STATUS" = stream ] || exit 1; + S=$(curl -I -m 3 "$STREAM_URL") - CONTENT_LENGTH=$(curl -I -m 3 "$STREAM_URL" \ + CONTENT_LENGTH=$(echo "$S" \ | grep -i content-length \ | cut -d' ' -f2 \ | tr -d '\r') @@ -37,34 +38,27 @@ test_api() { fi } -test_web() { - waitport 3001 - curl -m 3 http://127.0.0.1:3001/onDemand?blockId=0 \ - | grep -q '"status":"success"' -} - setup_api() { export API_PORT=3000 export API_URL=http://localhost:3000 - timeout 10 npm run start + timeout 10 pnpm run --prefix api start & + API_PID=$! } setup_web() { - export WEB_PORT=3001 - export WEB_URL=http://localhost:3001 - export API_URL=http://localhost:3000 - timeout 5 npm run start + pnpm run --prefix web build } cd "$(git rev-parse --show-toplevel)" -npm i +pnpm install --frozen-lockfile if [ "$1" = "api" ]; then - setup_api & + setup_api test_api + [ "$API_PID" != "" ] \ + && kill "$API_PID" elif [ "$1" = "web" ]; then - setup_web & - test_web + setup_web else echo "usage: $0 " >&2 exit 1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0dd28cb9..652f2a47 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,11 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Check that lockfile does not need an update - run: | - cp package-lock.json before.json - npm ci - npm i --package-lock-only - diff before.json package-lock.json + run: pnpm install --frozen-lockfile test-web: name: web sanity check @@ -45,7 +41,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - id: checkServices - run: npm ci && echo "service_list=$(node src/util/test-ci get-services)" >> "$GITHUB_OUTPUT" + run: npm ci && echo "service_list=$(node api/src/util/test-ci get-services)" >> "$GITHUB_OUTPUT" test-services: needs: check-services @@ -58,4 +54,4 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - - run: npm ci && node src/util/test-ci run-tests-for ${{ matrix.service }} \ No newline at end of file + - run: npm ci && node api/src/util/test-ci run-tests-for ${{ matrix.service }} \ No newline at end of file From e50b4b0328d50fe056c4292a0171eb1361f84f25 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:31:59 +0000 Subject: [PATCH 355/775] repo: set up package.json in root --- package.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 00000000..e55c9cae --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "name": "cobalt", + "packageManager": "pnpm@9.6.0", + "engines": { + "pnpm": ">=9" + } +} \ No newline at end of file From 2beacce70d051f7e7a93849e9fdfb40838cc47e0 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:32:42 +0000 Subject: [PATCH 356/775] ci: use pnpm in tests --- .github/workflows/test.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 652f2a47..f99af1c2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,6 +11,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 - name: Check that lockfile does not need an update run: pnpm install --frozen-lockfile @@ -20,6 +21,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 - name: Run test script run: .github/test.sh web @@ -29,6 +31,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 - name: Run test script run: .github/test.sh api @@ -40,8 +43,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 - id: checkServices - run: npm ci && echo "service_list=$(node api/src/util/test-ci get-services)" >> "$GITHUB_OUTPUT" + run: pnpm i --frozen-lockfile && echo "service_list=$(node api/src/util/test-ci get-services)" >> "$GITHUB_OUTPUT" test-services: needs: check-services @@ -54,4 +58,5 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - - run: npm ci && node api/src/util/test-ci run-tests-for ${{ matrix.service }} \ No newline at end of file + - uses: pnpm/action-setup@v4 + - run: pnpm i --frozen-lockfile && node api/src/util/test-ci run-tests-for ${{ matrix.service }} \ No newline at end of file From 786fd0555eaaf63645241c9a04c91cfc642a2f2d Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:50:24 +0000 Subject: [PATCH 357/775] ci: use node v20 for web build, clean up --- .github/workflows/test.yml | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f99af1c2..639df4c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,8 +9,7 @@ jobs: name: check lockfile correctness runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - name: Check that lockfile does not need an update run: pnpm install --frozen-lockfile @@ -19,21 +18,20 @@ jobs: name: web sanity check runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts - uses: pnpm/action-setup@v4 - - name: Run test script - run: .github/test.sh web + - run: .github/test.sh web test-api: name: api sanity check runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - name: Run test script - run: .github/test.sh api + - run: .github/test.sh api check-services: name: test service functionality @@ -41,8 +39,7 @@ jobs: outputs: services: ${{ steps.checkServices.outputs.service_list }} steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - id: checkServices run: pnpm i --frozen-lockfile && echo "service_list=$(node api/src/util/test-ci get-services)" >> "$GITHUB_OUTPUT" @@ -56,7 +53,6 @@ jobs: service: ${{ fromJson(needs.check-services.outputs.services) }} name: "test service: ${{ matrix.service }}" steps: - - name: Checkout repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - run: pnpm i --frozen-lockfile && node api/src/util/test-ci run-tests-for ${{ matrix.service }} \ No newline at end of file From 18b3daf90f877e2f17d783bbf0f9eaf213d49fbe Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:50:42 +0000 Subject: [PATCH 358/775] web/package: lower minimum node version, replace npm with pnpm --- web/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/package.json b/web/package.json index 710e92a3..9a936988 100644 --- a/web/package.json +++ b/web/package.json @@ -12,8 +12,8 @@ }, "license": "CC-BY-NC-SA-4.0", "engines": { - "node": ">=20.9", - "npm": ">=9" + "node": ">=20", + "pnpm": ">=9" }, "repository": { "type": "git", From 3a2504ae8757d8c7621e5e2c177bf72654265be4 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 09:52:46 +0000 Subject: [PATCH 359/775] ci: fix invalid node version for web --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 639df4c7..e49e342c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: lts + node-version: 'lts/*' - uses: pnpm/action-setup@v4 - run: .github/test.sh web From 332eae16b276bc8afc70c83c5783533395dbb1db Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 16:27:20 +0600 Subject: [PATCH 360/775] api: convert service config to JS and remove it from main config --- api/src/config.js | 14 -- api/src/processing/match-action.js | 4 +- api/src/processing/service-config.js | 197 +++++++++++++++++++++++++ api/src/processing/service-config.json | 142 ------------------ api/src/processing/url.js | 2 +- api/src/stream/types.js | 3 +- api/src/util/test-ci.js | 3 +- api/src/util/test.js | 2 +- 8 files changed, 206 insertions(+), 161 deletions(-) create mode 100644 api/src/processing/service-config.js delete mode 100644 api/src/processing/service-config.json diff --git a/api/src/config.js b/api/src/config.js index 0f9bf07d..32b65d7a 100644 --- a/api/src/config.js +++ b/api/src/config.js @@ -1,16 +1,6 @@ -import UrlPattern from "url-pattern"; import { loadJSON } from "./misc/load-from-fs.js"; const packageJson = loadJSON("./package.json"); -const servicesConfigJson = loadJSON("./src/processing/service-config.json"); - -Object.values(servicesConfigJson.config).forEach(service => { - service.patterns = service.patterns.map( - pattern => new UrlPattern(pattern, { - segmentValueCharset: UrlPattern.defaultOptions.segmentValueCharset + '@\\.' - }) - ) -}) export const version = packageJson.version, @@ -26,10 +16,6 @@ export const gif: ["-vf", "scale=-1:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse", "-loop", "0"] }, - services = servicesConfigJson.config, - hlsExceptions = servicesConfigJson.hlsExceptions, - audioIgnore = servicesConfigJson.audioIgnore, - env = { apiURL: process.env.API_URL || '', apiPort: process.env.API_PORT || 9000, diff --git a/api/src/processing/match-action.js b/api/src/processing/match-action.js index d6ec98ca..80f63b41 100644 --- a/api/src/processing/match-action.js +++ b/api/src/processing/match-action.js @@ -1,4 +1,6 @@ -import { audioIgnore, services, supportedAudio } from "../config.js"; +import { supportedAudio } from "../config.js"; +import { audioIgnore, services } from "./service-config.js"; + import { createResponse } from "./request.js"; import createFilename from "./create-filename.js"; import { createStream } from "../stream/manage.js"; diff --git a/api/src/processing/service-config.js b/api/src/processing/service-config.js new file mode 100644 index 00000000..68164ace --- /dev/null +++ b/api/src/processing/service-config.js @@ -0,0 +1,197 @@ +import UrlPattern from "url-pattern"; + +export const audioIgnore = ["vk", "ok", "loom"]; +export const hlsExceptions = ["dailymotion", "vimeo", "rutube"]; + +export const services = { + bilibili: { + enabled: true, + patterns: [ + "video/:comId", + "_shortLink/:comShortLink", + "_tv/:lang/video/:tvId", + "_tv/video/:tvId" + ], + subdomains: ["m"], + }, + dailymotion: { + enabled: true, + patterns: ["video/:id"], + }, + facebook: { + enabled: true, + patterns: [ + "_shortLink/:shortLink", + ":username/videos/:caption/:id", + ":username/videos/:id", + "reel/:id", + "share/:shareType/:id" + ], + subdomains: ["web"], + altDomains: ["fb.watch"], + }, + instagram: { + enabled: true, + patterns: [ + "reels/:postId", + ":username/reel/:postId", + "reel/:postId", + "p/:postId", + ":username/p/:postId", + "tv/:postId", + "stories/:username/:storyId" + ], + altDomains: ["ddinstagram.com"], + }, + loom: { + enabled: true, + patterns: ["share/:id"], + }, + ok: { + enabled: true, + patterns: [ + "video/:id", + "videoembed/:id" + ], + tld: "ru", + }, + pinterest: { + enabled: true, + patterns: [ + "pin/:id", + "pin/:id/:garbage", + "url_shortener/:shortLink" + ], + }, + reddit: { + enabled: true, + patterns: [ + "r/:sub/comments/:id/:title", + "user/:user/comments/:id/:title" + ], + subdomains: "*", + }, + rutube: { + enabled: true, + patterns: [ + "video/:id", + "play/embed/:id", + "shorts/:id", + "yappy/:yappyId", + "video/private/:id?p=:key", + "video/private/:id" + ], + tld: "ru", + }, + snapchat: { + enabled: true, + patterns: [ + ":shortLink", + "spotlight/:spotlightId", + "add/:username/:storyId", + "u/:username/:storyId", + "add/:username", + "u/:username" + ], + subdomains: ["t", "story"], + }, + soundcloud: { + enabled: true, + patterns: [ + ":author/:song/s-:accessKey", + ":author/:song", + ":shortLink" + ], + subdomains: ["on", "m"], + }, + streamable: { + enabled: true, + patterns: [ + ":id", + "o/:id", + "e/:id", + "s/:id" + ], + }, + tiktok: { + enabled: true, + patterns: [ + ":user/video/:postId", + ":id", + "t/:id", + ":user/photo/:postId", + "v/:id.html" + ], + subdomains: ["vt", "vm", "m"], + }, + tumblr: { + enabled: true, + patterns: [ + "post/:id", + "blog/view/:user/:id", + ":user/:id", + ":user/:id/:trackingId" + ], + subdomains: "*", + }, + twitch: { + enabled: true, + patterns: [":channel/clip/:clip"], + tld: "tv", + }, + twitter: { + enabled: true, + patterns: [ + ":user/status/:id", + ":user/status/:id/video/:index", + ":user/status/:id/photo/:index", + ":user/status/:id/mediaviewer", + ":user/status/:id/mediaViewer" + ], + subdomains: ["mobile"], + altDomains: ["x.com", "vxtwitter.com", "fixvx.com"], + }, + vine: { + enabled: true, + patterns: ["v/:id"], + tld: "co", + }, + vimeo: { + enabled: true, + patterns: [ + ":id", + "video/:id", + ":id/:password", + "/channels/:user/:id" + ], + subdomains: ["player"], + bestAudio: "mp3", + }, + vk: { + enabled: true, + patterns: [ + "video:userId_:videoId", + "clip:userId_:videoId", + "clips:duplicate?z=clip:userId_:videoId" + ], + subdomains: ["m"], + }, + youtube: { + enabled: true, + patterns: [ + "watch?v=:id", + "embed/:id", + "watch/:id" + ], + subdomains: ["music", "m"], + bestAudio: "opus", + } +} + +Object.values(services).forEach(service => { + service.patterns = service.patterns.map( + pattern => new UrlPattern(pattern, { + segmentValueCharset: UrlPattern.defaultOptions.segmentValueCharset + '@\\.' + }) + ) +}) diff --git a/api/src/processing/service-config.json b/api/src/processing/service-config.json deleted file mode 100644 index 6955a946..00000000 --- a/api/src/processing/service-config.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "audioIgnore": ["vk", "ok", "loom"], - "hlsExceptions": ["dailymotion", "vimeo", "rutube"], - "config": { - "bilibili": { - "alias": "bilibili.com & bilibili.tv", - "patterns": [ - "video/:comId", "_shortLink/:comShortLink", - "_tv/:lang/video/:tvId", "_tv/video/:tvId" - ], - "subdomains": ["m"], - "enabled": true - }, - "reddit": { - "alias": "reddit videos & gifs", - "patterns": ["r/:sub/comments/:id/:title", "user/:user/comments/:id/:title"], - "subdomains": "*", - "enabled": true - }, - "twitter": { - "alias": "twitter videos & voice", - "altDomains": ["x.com", "vxtwitter.com", "fixvx.com"], - "subdomains": ["mobile"], - "patterns": [ - ":user/status/:id", - ":user/status/:id/video/:index", - ":user/status/:id/photo/:index", - ":user/status/:id/mediaviewer", - ":user/status/:id/mediaViewer" - ], - "enabled": true - }, - "vk": { - "alias": "vk video & clips", - "patterns": ["video:userId_:videoId", "clip:userId_:videoId", "clips:duplicate?z=clip:userId_:videoId"], - "subdomains": ["m"], - "enabled": true - }, - "ok": { - "alias": "ok video", - "tld": "ru", - "patterns": ["video/:id", "videoembed/:id"], - "enabled": true - }, - "youtube": { - "alias": "youtube videos, shorts & music", - "patterns": ["watch?v=:id", "embed/:id", "watch/:id"], - "subdomains": ["music", "m"], - "bestAudio": "opus", - "enabled": true - }, - "tumblr": { - "alias": "tumblr video & audio", - "patterns": ["post/:id", "blog/view/:user/:id", ":user/:id", ":user/:id/:trackingId"], - "subdomains": "*", - "enabled": true - }, - "tiktok": { - "alias": "tiktok videos, photos & audio", - "patterns": [":user/video/:postId", ":id", "t/:id", ":user/photo/:postId", "v/:id.html"], - "subdomains": ["vt", "vm", "m"], - "enabled": true - }, - "vimeo": { - "patterns": [":id", "video/:id", ":id/:password", "/channels/:user/:id"], - "subdomains": ["player"], - "bestAudio": "mp3", - "enabled": true - }, - "soundcloud": { - "patterns": [":author/:song/s-:accessKey", ":author/:song", ":shortLink"], - "subdomains": ["on", "m"], - "enabled": true - }, - "instagram": { - "alias": "instagram posts & reels", - "altDomains": ["ddinstagram.com"], - "patterns": [ - "reels/:postId", ":username/reel/:postId", "reel/:postId", "p/:postId", ":username/p/:postId", - "tv/:postId", "stories/:username/:storyId" - ], - "enabled": true - }, - "vine": { - "alias": "vine archive", - "tld": "co", - "patterns": ["v/:id"], - "enabled": true - }, - "pinterest": { - "alias": "pinterest (all media)", - "patterns": ["pin/:id", "pin/:id/:garbage", "url_shortener/:shortLink"], - "enabled": true - }, - "streamable": { - "alias": "streamable.com", - "patterns": [":id", "o/:id", "e/:id", "s/:id"], - "enabled": true - }, - "twitch": { - "alias": "twitch clips", - "tld": "tv", - "patterns": [":channel/clip/:clip"], - "enabled": true - }, - "rutube": { - "alias": "rutube videos", - "tld": "ru", - "patterns": ["video/:id", "play/embed/:id", "shorts/:id", "yappy/:yappyId", "video/private/:id?p=:key", "video/private/:id"], - "enabled": true - }, - "dailymotion": { - "alias": "dailymotion videos", - "patterns": ["video/:id"], - "enabled": true - }, - "snapchat": { - "alias": "snapchat stories & spotlights", - "subdomains": ["t", "story"], - "patterns": [":shortLink", "spotlight/:spotlightId", "add/:username/:storyId", "u/:username/:storyId", "add/:username", "u/:username"], - "enabled": true - }, - "loom": { - "alias": "loom videos", - "patterns": ["share/:id"], - "enabled": true - }, - "facebook": { - "alias": "facebook videos", - "altDomains": ["fb.watch"], - "subdomains": ["web"], - "patterns": [ - "_shortLink/:shortLink", - ":username/videos/:caption/:id", - ":username/videos/:id", - "reel/:id", - "share/:shareType/:id" - ], - "enabled": true - } - } -} diff --git a/api/src/processing/url.js b/api/src/processing/url.js index a2b9cd7d..a9313e25 100644 --- a/api/src/processing/url.js +++ b/api/src/processing/url.js @@ -1,4 +1,4 @@ -import { services } from "../config.js"; +import { services } from "./service-config.js"; import { strict as assert } from "node:assert"; import psl from "psl"; diff --git a/api/src/stream/types.js b/api/src/stream/types.js index f566a196..b12e5de8 100644 --- a/api/src/stream/types.js +++ b/api/src/stream/types.js @@ -3,9 +3,10 @@ import ffmpeg from "ffmpeg-static"; import { spawn } from "child_process"; import { create as contentDisposition } from "content-disposition-header"; +import { env, ffmpegArgs } from "../config.js"; import { metadataManager } from "../misc/utils.js"; import { destroyInternalStream } from "./manage.js"; -import { env, ffmpegArgs, hlsExceptions } from "../config.js"; +import { hlsExceptions } from "../processing/service-config.js"; import { getHeaders, closeRequest, closeResponse, pipe } from "./shared.js"; function toRawHeaders(headers) { diff --git a/api/src/util/test-ci.js b/api/src/util/test-ci.js index 6559aadc..1c9a7011 100644 --- a/api/src/util/test-ci.js +++ b/api/src/util/test-ci.js @@ -3,8 +3,9 @@ import { runTest } from "../misc/run-test.js"; import { loadJSON } from "../misc/load-from-fs.js"; import { Red, Bright } from "../misc/console-text.js"; +import { services } from "../processing/service-config.js"; + const tests = loadJSON('./src/util/tests.json'); -const services = loadJSON('./src/processing/service-config.json'); // services that are known to frequently fail due to external // factors (e.g. rate limiting) diff --git a/api/src/util/test.js b/api/src/util/test.js index 2a2c084c..c0097964 100644 --- a/api/src/util/test.js +++ b/api/src/util/test.js @@ -1,7 +1,7 @@ import "dotenv/config"; import "../misc/alias-envs.js"; -import { services } from "../config.js"; +import { services } from "../processing/service-config.js"; import { extract } from "../processing/url.js"; import match from "../processing/match.js"; import { loadJSON } from "../misc/load-from-fs.js"; From 0a411196e94a0952893c79f970ab297cab2100cf Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 16:33:36 +0600 Subject: [PATCH 361/775] api/config: clean up (better formatting) --- api/src/config.js | 67 +++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/api/src/config.js b/api/src/config.js index 32b65d7a..634b2d7b 100644 --- a/api/src/config.js +++ b/api/src/config.js @@ -2,41 +2,50 @@ import { loadJSON } from "./misc/load-from-fs.js"; const packageJson = loadJSON("./package.json"); -export const - version = packageJson.version, +const version = packageJson.version; - genericUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", - supportedAudio = ["mp3", "ogg", "wav", "opus"], - ffmpegArgs = { - webm: ["-c:v", "copy", "-c:a", "copy"], - mp4: ["-c:v", "copy", "-c:a", "copy", "-movflags", "faststart+frag_keyframe+empty_moov"], - copy: ["-c:a", "copy"], - audio: ["-ar", "48000", "-ac", "2", "-b:a", "320k"], - m4a: ["-movflags", "frag_keyframe+empty_moov"], - gif: ["-vf", "scale=-1:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse", "-loop", "0"] - }, +const genericUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"; +const supportedAudio = ["mp3", "ogg", "wav", "opus"]; +const ffmpegArgs = { + webm: ["-c:v", "copy", "-c:a", "copy"], + mp4: ["-c:v", "copy", "-c:a", "copy", "-movflags", "faststart+frag_keyframe+empty_moov"], + copy: ["-c:a", "copy"], + audio: ["-ar", "48000", "-ac", "2", "-b:a", "320k"], + m4a: ["-movflags", "frag_keyframe+empty_moov"], + gif: ["-vf", "scale=-1:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse", "-loop", "0"] +} - env = { - apiURL: process.env.API_URL || '', - apiPort: process.env.API_PORT || 9000, +const env = { + apiURL: process.env.API_URL || '', + apiPort: process.env.API_PORT || 9000, - listenAddress: process.env.API_LISTEN_ADDRESS, - freebindCIDR: process.platform === 'linux' && process.env.FREEBIND_CIDR, + listenAddress: process.env.API_LISTEN_ADDRESS, + freebindCIDR: process.platform === 'linux' && process.env.FREEBIND_CIDR, - corsWildcard: process.env.CORS_WILDCARD !== '0', - corsURL: process.env.CORS_URL, + corsWildcard: process.env.CORS_WILDCARD !== '0', + corsURL: process.env.CORS_URL, - cookiePath: process.env.COOKIE_PATH, + cookiePath: process.env.COOKIE_PATH, - rateLimitWindow: (process.env.RATELIMIT_WINDOW && parseInt(process.env.RATELIMIT_WINDOW)) || 60, - rateLimitMax: (process.env.RATELIMIT_MAX && parseInt(process.env.RATELIMIT_MAX)) || 20, + rateLimitWindow: (process.env.RATELIMIT_WINDOW && parseInt(process.env.RATELIMIT_WINDOW)) || 60, + rateLimitMax: (process.env.RATELIMIT_MAX && parseInt(process.env.RATELIMIT_MAX)) || 20, - durationLimit: (process.env.DURATION_LIMIT && parseInt(process.env.DURATION_LIMIT)) || 10800, - streamLifespan: 90, + durationLimit: (process.env.DURATION_LIMIT && parseInt(process.env.DURATION_LIMIT)) || 10800, + streamLifespan: 90, - processingPriority: process.platform !== 'win32' - && process.env.PROCESSING_PRIORITY - && parseInt(process.env.PROCESSING_PRIORITY), + processingPriority: process.platform !== 'win32' + && process.env.PROCESSING_PRIORITY + && parseInt(process.env.PROCESSING_PRIORITY), - externalProxy: process.env.API_EXTERNAL_PROXY, - } + externalProxy: process.env.API_EXTERNAL_PROXY, +} + +export { + env, + + genericUserAgent, + supportedAudio, + ffmpegArgs, + + version, +} From 417a21ea9155025cbeec16575ea9bec06ee4ab08 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 16:36:01 +0600 Subject: [PATCH 362/775] ci: fix service config retrieval --- api/src/util/test-ci.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/util/test-ci.js b/api/src/util/test-ci.js index 1c9a7011..7c515d9e 100644 --- a/api/src/util/test-ci.js +++ b/api/src/util/test-ci.js @@ -14,7 +14,7 @@ const finnicky = new Set(['bilibili', 'instagram', 'youtube']) const action = process.argv[2]; switch (action) { case "get-services": - const fromConfig = Object.keys(services.config); + const fromConfig = Object.keys(services); const missingTests = fromConfig.filter( service => !tests[service] || tests[service].length === 0 From bef9b5b172ae3a475f4fd550dcb99e65238040ca Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 16:50:57 +0600 Subject: [PATCH 363/775] snapchat: add support for android short links --- api/src/processing/match.js | 5 +---- api/src/processing/service-config.js | 3 ++- api/src/processing/services/snapchat.js | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/src/processing/match.js b/api/src/processing/match.js index c40d89bc..89579524 100644 --- a/api/src/processing/match.js +++ b/api/src/processing/match.js @@ -193,10 +193,7 @@ export default async function(host, patternMatch, lang, obj) { r = await dailymotion(patternMatch); break; case "snapchat": - r = await snapchat({ - hostname: url.hostname, - ...patternMatch - }); + r = await snapchat(patternMatch); break; case "loom": r = await loom({ diff --git a/api/src/processing/service-config.js b/api/src/processing/service-config.js index 68164ace..192e59fe 100644 --- a/api/src/processing/service-config.js +++ b/api/src/processing/service-config.js @@ -91,7 +91,8 @@ export const services = { "add/:username/:storyId", "u/:username/:storyId", "add/:username", - "u/:username" + "u/:username", + "t/:shortLink", ], subdomains: ["t", "story"], }, diff --git a/api/src/processing/services/snapchat.js b/api/src/processing/services/snapchat.js index 1c1eaf6d..00efaa9d 100644 --- a/api/src/processing/services/snapchat.js +++ b/api/src/processing/services/snapchat.js @@ -69,7 +69,7 @@ async function getStory(username, storyId) { export default async function (obj) { let params = obj; - if (obj.hostname === 't.snapchat.com' && obj.shortLink) { + if (obj.shortLink) { const link = await getRedirectingURL(`https://t.snapchat.com/${obj.shortLink}`); if (!link?.startsWith('https://www.snapchat.com/')) { From 0d20ffc004d3d8e49ef07ca6d46d20630651e22b Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 21:27:14 +0600 Subject: [PATCH 364/775] packages: add version-info package --- packages/version-info/index.d.ts | 6 +++ packages/version-info/index.js | 73 ++++++++++++++++++++++++++++++ packages/version-info/package.json | 18 ++++++++ pnpm-workspace.yaml | 1 + 4 files changed, 98 insertions(+) create mode 100644 packages/version-info/index.d.ts create mode 100644 packages/version-info/index.js create mode 100644 packages/version-info/package.json diff --git a/packages/version-info/index.d.ts b/packages/version-info/index.d.ts new file mode 100644 index 00000000..a6ee9d71 --- /dev/null +++ b/packages/version-info/index.d.ts @@ -0,0 +1,6 @@ +declare module "@imput/version-info" { + export function getCommit(): Promise; + export function getBranch(): Promise; + export function getRemote(): Promise; + export function getVersion(): Promise; +} diff --git a/packages/version-info/index.js b/packages/version-info/index.js new file mode 100644 index 00000000..0df3b855 --- /dev/null +++ b/packages/version-info/index.js @@ -0,0 +1,73 @@ +import { existsSync } from 'node:fs'; +import { join, parse } from 'node:path'; +import { cwd } from 'node:process'; +import { readFile } from 'node:fs/promises'; + +const findFile = (file) => { + let dir = cwd(); + + while (dir !== parse(dir).root) { + if (existsSync(join(dir, file))) { + return dir; + } + + dir = join(dir, '../'); + } +} + +const root = findFile('.git'); +const pack = findFile('package.json'); +if (!root) { + throw 'no git repository root found'; +} else if (!pack) { + throw 'no package root found'; +} + +const readGit = (filename) => readFile(join(root, filename), 'utf8'); + +export const getCommit = async () => { + return (await readGit('.git/logs/HEAD')) + ?.split('\n') + ?.filter(String) + ?.pop() + ?.split(' ')[1]; +} + +export const getBranch = async () => { + if (process.env.CF_PAGES_BRANCH) { + return process.env.CF_PAGES_BRANCH; + } + + return (await readGit('.git/HEAD')) + ?.replace(/^ref: refs\/heads\//, '') + ?.trim(); +} + +export const getRemote = async () => { + let remote = (await readGit('.git/config')) + ?.split('\n') + ?.find(line => line.includes('url = ')) + ?.split('url = ')[1]; + + if (remote?.startsWith('git@')) { + remote = remote.split(':')[1]; + } else if (remote?.startsWith('http')) { + remote = new URL(remote).pathname.substring(1); + } + + remote = remote?.replace(/\.git$/, ''); + + if (!remote) { + throw 'could not parse remote'; + } + + return remote; +} + +export const getVersion = async () => { + const { version } = JSON.parse( + await readFile(join(pack, 'package.json'), 'utf8') + ); + + return version; +} diff --git a/packages/version-info/package.json b/packages/version-info/package.json new file mode 100644 index 00000000..e82a6201 --- /dev/null +++ b/packages/version-info/package.json @@ -0,0 +1,18 @@ +{ + "name": "@imput/version-info", + "version": "1.0.0", + "description": "helper package for cobalt that provides commit info & version from package file.", + "main": "index.js", + "types": "index.d.ts", + "type": "module", + "repository": { + "type": "git", + "url": "git+https://github.com/imputnet/cobalt.git" + }, + "author": "imput", + "license": "AGPL-3.0", + "bugs": { + "url": "https://github.com/imputnet/cobalt/issues" + }, + "homepage": "https://github.com/imputnet/cobalt#readme" +} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 8c71ee3e..d7ab6cba 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - "api" - "web" + - "packages/*" From 40425ad3bf1136912a480d35c496139319a51107 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 21:34:02 +0600 Subject: [PATCH 365/775] api: use version-info package & clean up start message --- api/package.json | 1 + api/src/cobalt.js | 12 ++++------- api/src/config.js | 8 -------- api/src/core/api.js | 37 +++++++++++++++++++++++++--------- api/src/misc/current-commit.js | 23 --------------------- api/src/misc/load-from-fs.js | 8 ++++---- pnpm-lock.yaml | 7 +++++++ 7 files changed, 43 insertions(+), 53 deletions(-) delete mode 100644 api/src/misc/current-commit.js diff --git a/api/package.json b/api/package.json index f55ceb4a..a8416bb8 100644 --- a/api/package.json +++ b/api/package.json @@ -24,6 +24,7 @@ }, "homepage": "https://github.com/imputnet/cobalt#readme", "dependencies": { + "@imput/version-info": "workspace:^", "content-disposition-header": "0.6.0", "cors": "^2.8.5", "dotenv": "^16.0.1", diff --git a/api/src/cobalt.js b/api/src/cobalt.js index 53a5d71d..eec452cc 100644 --- a/api/src/cobalt.js +++ b/api/src/cobalt.js @@ -3,17 +3,13 @@ import "./misc/alias-envs.js"; import express from "express"; -import { Bright, Green, Red } from "./misc/console-text.js"; -import { getCurrentBranch, shortCommit } from "./misc/current-commit.js"; -import { env } from "./config.js" - import path from 'path'; import { fileURLToPath } from 'url'; -const app = express(); +import { env } from "./config.js" +import { Bright, Green, Red } from "./misc/console-text.js"; -const gitCommit = shortCommit(); -const gitBranch = getCurrentBranch(); +const app = express(); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename).slice(0, -4); @@ -22,7 +18,7 @@ app.disable('x-powered-by'); if (env.apiURL) { const { runAPI } = await import('./core/api.js'); - runAPI(express, app, gitCommit, gitBranch, __dirname) + runAPI(express, app, __dirname) } else { console.log( Red(`cobalt wasn't configured yet or configuration is invalid.\n`) diff --git a/api/src/config.js b/api/src/config.js index 634b2d7b..19e859f3 100644 --- a/api/src/config.js +++ b/api/src/config.js @@ -1,9 +1,3 @@ -import { loadJSON } from "./misc/load-from-fs.js"; - -const packageJson = loadJSON("./package.json"); - -const version = packageJson.version; - const genericUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"; const supportedAudio = ["mp3", "ogg", "wav", "opus"]; const ffmpegArgs = { @@ -46,6 +40,4 @@ export { genericUserAgent, supportedAudio, ffmpegArgs, - - version, } diff --git a/api/src/core/api.js b/api/src/core/api.js index ebdedb55..f69442eb 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -2,7 +2,9 @@ import cors from "cors"; import rateLimit from "express-rate-limit"; import { setGlobalDispatcher, ProxyAgent } from "undici"; -import { env, version } from "../config.js"; +import { getCommit, getBranch, getRemote, getVersion } from "@imput/version-info"; + +import { env } from "../config.js"; import { generateHmac, generateSalt } from "../misc/crypto.js"; import { Bright, Cyan } from "../misc/console-text.js"; @@ -15,6 +17,14 @@ import { extract } from "../processing/url.js"; import match from "../processing/match.js"; import stream from "../stream/stream.js"; +const git = { + branch: await getBranch(), + commit: await getCommit(), + remote: await getRemote(), +} + +const version = await getVersion(); + const acceptRegex = /^application\/json(; charset=utf-8)?$/; const ipSalt = generateSalt(); @@ -23,17 +33,16 @@ const corsConfig = env.corsWildcard ? {} : { optionsSuccessStatus: 200 } -export function runAPI(express, app, gitCommit, gitBranch, __dirname) { +export function runAPI(express, app, __dirname) { const startTime = new Date(); const startTimestamp = startTime.getTime(); const serverInfo = { version: version, - commit: gitCommit, - branch: gitBranch, - url: env.apiURL, + git, cors: Number(env.corsWildcard), - startTime: `${startTimestamp}` + url: env.apiURL, + startTime: `${startTimestamp}`, } const apiLimiter = rateLimit({ @@ -226,10 +235,18 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { app.listen(env.apiPort, env.listenAddress, () => { console.log(`\n` + - `${Cyan("cobalt")} API ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` + - `Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` + - `URL: ${Cyan(`${env.apiURL}`)}\n` + - `Port: ${env.apiPort}\n` + Bright(Cyan("cobalt ")) + Bright("API ^_^") + "\n" + + + "~~~~~~\n" + + Bright("version: ") + version + "\n" + + Bright("commit: ") + git.commit + "\n" + + Bright("branch: ") + git.branch + "\n" + + Bright("remote: ") + git.remote + "\n" + + Bright("start time: ") + startTime.toUTCString() + "\n" + + "~~~~~~\n" + + + Bright("url: ") + Bright(Cyan(env.apiURL)) + "\n" + + Bright("port: ") + env.apiPort + "\n" ) }) } diff --git a/api/src/misc/current-commit.js b/api/src/misc/current-commit.js deleted file mode 100644 index f3c145f5..00000000 --- a/api/src/misc/current-commit.js +++ /dev/null @@ -1,23 +0,0 @@ -import { execSync } from "child_process"; - -let commit, commitInfo, branch; - -export function shortCommit() { - if (commit) return commit; - let c = execSync('git rev-parse --short HEAD').toString().trim(); - commit = c; - return c -} -export function getCommitInfo() { - if (commitInfo) return commitInfo; - let d = execSync(`git show -s --format='%s;;;%B'`).toString().trim().replace(/[\r\n]/gm, '\n').split(';;;'); - d[1] = d[1].replace(d[0], '').trim().toString().replace(/[\r\n]/gm, '
'); - commitInfo = d; - return d -} -export function getCurrentBranch() { - if (branch) return branch; - let b = execSync('git branch --show-current').toString().trim(); - branch = b; - return b -} diff --git a/api/src/misc/load-from-fs.js b/api/src/misc/load-from-fs.js index f91a20cb..4357b8dc 100644 --- a/api/src/misc/load-from-fs.js +++ b/api/src/misc/load-from-fs.js @@ -7,6 +7,10 @@ const root = join( '../../' ); +export function loadFile(path) { + return fs.readFileSync(join(root, path), 'utf-8') +} + export function loadJSON(path) { try { return JSON.parse(loadFile(path)) @@ -14,7 +18,3 @@ export function loadJSON(path) { return false } } - -export function loadFile(path) { - return fs.readFileSync(join(root, path), 'utf-8') -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cda1121c..9e57dcb0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,8 +6,13 @@ settings: importers: + .: {} + api: dependencies: + '@imput/version-info': + specifier: workspace:^ + version: link:../packages/version-info content-disposition-header: specifier: 0.6.0 version: 0.6.0 @@ -61,6 +66,8 @@ importers: specifier: ^0.2.2 version: 0.2.2 + packages/version-info: {} + web: dependencies: '@fontsource-variable/noto-sans-mono': From 3bd1a008555801636f7d3e606caa2b602460cbaa Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 21:51:05 +0600 Subject: [PATCH 366/775] api: renovate endpoints no more redundant "/api" path --- api/src/core/api.js | 20 ++++++++++---------- api/src/stream/manage.js | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/api/src/core/api.js b/api/src/core/api.js index f69442eb..319c7a63 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -78,7 +78,7 @@ export function runAPI(express, app, __dirname) { app.set('trust proxy', ['loopback', 'uniquelocal']); - app.use('/api', cors({ + app.use('/', cors({ methods: ['GET', 'POST'], exposedHeaders: [ 'Ratelimit-Limit', @@ -89,8 +89,8 @@ export function runAPI(express, app, __dirname) { ...corsConfig, })) - app.use('/api/json', apiLimiter); - app.use('/api/stream', apiLimiterStream); + app.use('/', apiLimiter); + app.use('/stream', apiLimiterStream); app.use((req, res, next) => { try { @@ -101,8 +101,8 @@ export function runAPI(express, app, __dirname) { next(); }) - app.use('/api/json', express.json({ limit: 1024 })); - app.use('/api/json', (err, _, res, next) => { + app.use('/', express.json({ limit: 1024 })); + app.use('/', (err, _, res, next) => { if (err) { return res.status(400).json({ status: "error", @@ -116,7 +116,7 @@ export function runAPI(express, app, __dirname) { next(); }); - app.post('/api/json', async (req, res) => { + app.post('/', async (req, res) => { const request = req.body; const lang = languageCode(req); @@ -159,7 +159,7 @@ export function runAPI(express, app, __dirname) { } }) - app.get('/api/stream', (req, res) => { + app.get('/stream', (req, res) => { const id = String(req.query.id); const exp = String(req.query.exp); const sig = String(req.query.sig); @@ -188,7 +188,7 @@ export function runAPI(express, app, __dirname) { return stream(res, streamInfo); }) - app.get('/api/istream', (req, res) => { + app.get('/istream', (req, res) => { if (!req.ip.endsWith('127.0.0.1')) { return res.sendStatus(403); } @@ -210,7 +210,7 @@ export function runAPI(express, app, __dirname) { return stream(res, { type: 'internal', ...streamInfo }); }) - app.get('/api/serverInfo', (_, res) => { + app.get('/', (_, res) => { return res.status(200).json(serverInfo); }) @@ -219,7 +219,7 @@ export function runAPI(express, app, __dirname) { }) app.get('/*', (req, res) => { - res.redirect('/api/serverInfo'); + res.redirect('/'); }) randomizeCiphers(); diff --git a/api/src/stream/manage.js b/api/src/stream/manage.js index 24270144..07ee7f07 100644 --- a/api/src/stream/manage.js +++ b/api/src/stream/manage.js @@ -50,7 +50,7 @@ export function createStream(obj) { encryptStream(streamData, iv, secret) ) - let streamLink = new URL('/api/stream', env.apiURL); + let streamLink = new URL('/stream', env.apiURL); const params = { 'id': streamID, @@ -100,7 +100,7 @@ export function createInternalStream(url, obj = {}) { dispatcher }; - let streamLink = new URL('/api/istream', `http://127.0.0.1:${env.apiPort}`); + let streamLink = new URL('/istream', `http://127.0.0.1:${env.apiPort}`); streamLink.searchParams.set('id', streamID); const cleanup = () => { From edbea16b91d507129423980ba24229a1067c55f7 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 21:51:46 +0600 Subject: [PATCH 367/775] ci/test.sh: update api endpoint --- .github/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/test.sh b/.github/test.sh index 4ae96541..c3bc1fb7 100755 --- a/.github/test.sh +++ b/.github/test.sh @@ -13,8 +13,8 @@ waitport() { test_api() { waitport 3000 - curl -m 3 http://localhost:3000/api/serverInfo - API_RESPONSE=$(curl -m 3 http://localhost:3000/api/json \ + curl -m 3 http://localhost:3000/ + API_RESPONSE=$(curl -m 3 http://localhost:3000/ \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ From e58bca0cdd11c79c2f231146a65bfd3ddee8c219 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 22:05:50 +0600 Subject: [PATCH 368/775] api: remove alias mapping for deprecated env variables --- api/src/cobalt.js | 1 - api/src/misc/alias-envs.js | 23 ----------------------- api/src/util/test.js | 1 - 3 files changed, 25 deletions(-) delete mode 100644 api/src/misc/alias-envs.js diff --git a/api/src/cobalt.js b/api/src/cobalt.js index eec452cc..c548e792 100644 --- a/api/src/cobalt.js +++ b/api/src/cobalt.js @@ -1,5 +1,4 @@ import "dotenv/config"; -import "./misc/alias-envs.js"; import express from "express"; diff --git a/api/src/misc/alias-envs.js b/api/src/misc/alias-envs.js deleted file mode 100644 index 5facb14b..00000000 --- a/api/src/misc/alias-envs.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Red } from "./console-text.js"; - -const mapping = { - apiPort: 'API_PORT', - apiURL: 'API_URL', - apiName: 'API_NAME', - cors: 'CORS_WILDCARD', - cookiePath: 'COOKIE_PATH', - webPort: 'WEB_PORT', - webURL: 'WEB_URL', - showSponsors: 'SHOW_SPONSORS', - isBeta: 'IS_BETA' -} - -for (const [ oldEnv, newEnv ] of Object.entries(mapping)) { - if (process.env[oldEnv] && !process.env[newEnv]) { - process.env[newEnv] = process.env[oldEnv]; - console.error(`${Red('[!]')} ${oldEnv} is deprecated and will be removed in a future version.`); - console.error(` You should use ${newEnv} instead.`); - console.error(); - delete process.env[oldEnv]; - } -} diff --git a/api/src/util/test.js b/api/src/util/test.js index c0097964..704473f4 100644 --- a/api/src/util/test.js +++ b/api/src/util/test.js @@ -1,5 +1,4 @@ import "dotenv/config"; -import "../misc/alias-envs.js"; import { services } from "../processing/service-config.js"; import { extract } from "../processing/url.js"; From c57dce6806ce0d870cb5910ce057c55df35fd800 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 22:07:14 +0600 Subject: [PATCH 369/775] docs/examples/compose: remove web example --- docs/examples/docker-compose.example.yml | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/docs/examples/docker-compose.example.yml b/docs/examples/docker-compose.example.yml index fcbcfc63..45f6dd39 100644 --- a/docs/examples/docker-compose.example.yml +++ b/docs/examples/docker-compose.example.yml @@ -31,30 +31,6 @@ services: #volumes: #- ./cookies.json:/cookies.json - cobalt-web: - image: ghcr.io/imputnet/cobalt:7 - restart: unless-stopped - container_name: cobalt-web - - init: true - - # if container doesn't run detached on your machine, uncomment the next line - #tty: true - - ports: - - 9001:9001/tcp - # if you're using a reverse proxy, uncomment the next line and remove the one above (9001:9001/tcp): - #- 127.0.0.1:9001:9001 - - environment: - # replace https://cobalt.tools/ with your instance's target url in same format - WEB_URL: "https://cobalt.tools/" - # replace https://api.cobalt.tools/ with preferred api instance url - API_URL: "https://api.cobalt.tools/" - - labels: - - com.centurylinklabs.watchtower.scope=cobalt - # update the cobalt image automatically with watchtower watchtower: image: ghcr.io/containrrr/watchtower From f227abf6cbb93741a97135d6e976bd833c08c8f9 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 22:09:35 +0600 Subject: [PATCH 370/775] docs/examples/compose: remove version top-level element --- docs/examples/docker-compose.example.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/examples/docker-compose.example.yml b/docs/examples/docker-compose.example.yml index 45f6dd39..af91f1b7 100644 --- a/docs/examples/docker-compose.example.yml +++ b/docs/examples/docker-compose.example.yml @@ -1,5 +1,3 @@ -version: '3.5' - services: cobalt-api: image: ghcr.io/imputnet/cobalt:7 From c751837ed8fc050cb7765c73b7a25fda9ebf875f Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 16:46:12 +0000 Subject: [PATCH 371/775] api/package: change name to `@imput/cobalt-api` --- api/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/package.json b/api/package.json index a8416bb8..7336447a 100644 --- a/api/package.json +++ b/api/package.json @@ -1,5 +1,5 @@ { - "name": "cobalt", + "name": "@imput/cobalt-api", "description": "save what you love", "version": "10.0.0", "author": "imput", From 985f6e385d27a225b29ff121fb174c9cf0267c86 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 16:12:29 +0000 Subject: [PATCH 372/775] docker: update dockerfile to use pnpm features --- .dockerignore | 21 +++++++++++++++++++++ Dockerfile | 32 +++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..b408b65c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,21 @@ +# OS directory info files +.DS_Store +desktop.ini + +# node +node_modules + +# static build +build + +# secrets +.env +.env.* +!.env.example +cookies.json + +# docker +docker-compose.yml + +# ide +.vscode diff --git a/Dockerfile b/Dockerfile index 0896c116..e933c468 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,25 @@ -FROM node:18-bullseye-slim +FROM node:20-bullseye-slim AS base +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" + +FROM base AS build +WORKDIR /app +COPY . /app + +RUN corepack enable +RUN apt-get update && \ + apt-get install -y python3 build-essential + +RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ + pnpm install --prod --frozen-lockfile + +RUN pnpm deploy --filter=@imput/cobalt-api --prod /prod/api + +FROM base AS api WORKDIR /app -COPY package*.json ./ +COPY --from=build /prod/api /app +COPY --from=build /app/.git /app/.git -RUN apt-get update && \ - apt-get install -y git python3 build-essential && \ - npm ci && \ - npm cache clean --force && \ - apt purge --autoremove -y python3 build-essential && \ - rm -rf ~/.cache/ /var/lib/apt/lists/* - -COPY . . EXPOSE 9000 -CMD [ "node", "src/cobalt" ] +CMD [ "node", "src/cobalt" ] \ No newline at end of file From a7ab4a97060c6c45dc8504a69947ff9081fe2ccb Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 16:28:43 +0000 Subject: [PATCH 373/775] version-info: don't throw on import if git does not exist --- packages/version-info/index.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/version-info/index.js b/packages/version-info/index.js index 0df3b855..3ac1bd3e 100644 --- a/packages/version-info/index.js +++ b/packages/version-info/index.js @@ -17,13 +17,14 @@ const findFile = (file) => { const root = findFile('.git'); const pack = findFile('package.json'); -if (!root) { - throw 'no git repository root found'; -} else if (!pack) { - throw 'no package root found'; -} -const readGit = (filename) => readFile(join(root, filename), 'utf8'); +const readGit = (filename) => { + if (!root) { + throw 'no git repository root found'; + } + + return readFile(join(root, filename), 'utf8'); +} export const getCommit = async () => { return (await readGit('.git/logs/HEAD')) @@ -65,6 +66,10 @@ export const getRemote = async () => { } export const getVersion = async () => { + if (!pack) { + throw 'no package root found'; + } + const { version } = JSON.parse( await readFile(join(pack, 'package.json'), 'utf8') ); From d419fd35b0c36c73ded54139306f017e9ebea0ac Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 16:46:45 +0000 Subject: [PATCH 374/775] ci: add build action for `develop` tag --- .github/workflows/docker-develop.yml | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .github/workflows/docker-develop.yml diff --git a/.github/workflows/docker-develop.yml b/.github/workflows/docker-develop.yml new file mode 100644 index 00000000..e89eeae0 --- /dev/null +++ b/.github/workflows/docker-develop.yml @@ -0,0 +1,55 @@ +name: Build Docker development image + +on: + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Get release metadata + id: release-meta + run: | + version=$(cat package.json | jq -r .version) + echo "commit_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + echo "major_version=$(echo "$version" | cut -d. -f1)" >> $GITHUB_OUTPUT + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + tags: type=raw,value=develop + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max From 5ea71ee58e7ce3e38b5794009b891558d52ead2c Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 23:06:32 +0600 Subject: [PATCH 375/775] api: update post parameters they're now way easier to read --- api/src/core/api.js | 16 +++--- api/src/processing/match-action.js | 6 +-- api/src/processing/match.js | 81 +++++++++++++++++++----------- api/src/processing/request.js | 48 +++++++++--------- 4 files changed, 88 insertions(+), 63 deletions(-) diff --git a/api/src/core/api.js b/api/src/core/api.js index 319c7a63..c7ce57b9 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -137,7 +137,10 @@ export function runAPI(express, app, __dirname) { return fail('ErrorNoLink'); } - request.dubLang = request.dubLang ? lang : false; + if (request.youtubeDubBrowserLang) { + request.youtubeDubLang = lang; + } + const normalizedRequest = normalizeRequest(request); if (!normalizedRequest) { return fail('ErrorCantProcess'); @@ -150,7 +153,7 @@ export function runAPI(express, app, __dirname) { try { const result = await match( - parsed.host, parsed.patternMatch, lang, normalizedRequest + parsed.host, parsed.patternMatch, normalizedRequest ); res.status(result.status).json(result.body); @@ -171,19 +174,16 @@ export function runAPI(express, app, __dirname) { const checkSafeLength = sig.length === 43 && sec.length === 43 && iv.length === 22; if (!checkQueries || !checkBaseLength || !checkSafeLength) { - return res.sendStatus(400); + return res.status(400).end(); } - // rate limit probe, will not return json after 8.0 if (req.query.p) { - return res.status(200).json({ - status: "continue" - }) + return res.status(200).end(); } const streamInfo = verifyStream(id, sig, exp, sec, iv); if (!streamInfo?.service) { - return res.sendStatus(streamInfo.status); + return res.status(streamInfo.status).end(); } return stream(res, streamInfo); }) diff --git a/api/src/processing/match-action.js b/api/src/processing/match-action.js index 80f63b41..6da7780b 100644 --- a/api/src/processing/match-action.js +++ b/api/src/processing/match-action.js @@ -5,7 +5,7 @@ import { createResponse } from "./request.js"; import createFilename from "./create-filename.js"; import { createStream } from "../stream/manage.js"; -export default function({ r, host, audioFormat, isAudioOnly, isAudioMuted, disableMetadata, filenameStyle, toGif, requestIP }) { +export default function({ r, host, audioFormat, isAudioOnly, isAudioMuted, disableMetadata, filenameStyle, twitterGif, requestIP }) { let action, responseType = "stream", defaultParams = { @@ -21,9 +21,9 @@ export default function({ r, host, audioFormat, isAudioOnly, isAudioMuted, disab if (r.isPhoto) action = "photo"; else if (r.picker) action = "picker" - else if (r.isGif && toGif) action = "gif"; - else if (isAudioMuted) action = "muteVideo"; + else if (r.isGif && twitterGif) action = "gif"; else if (isAudioOnly) action = "audio"; + else if (isAudioMuted) action = "muteVideo"; else if (r.isM3U8) action = "m3u8"; else action = "video"; diff --git a/api/src/processing/match.js b/api/src/processing/match.js index 89579524..e730b55b 100644 --- a/api/src/processing/match.js +++ b/api/src/processing/match.js @@ -29,7 +29,7 @@ import facebook from "./services/facebook.js"; let freebind; -export default async function(host, patternMatch, lang, obj) { +export default async function(host, patternMatch, obj) { const { url } = obj; assert(url instanceof URL); let dispatcher, requestIP; @@ -45,7 +45,8 @@ export default async function(host, patternMatch, lang, obj) { try { let r, - isAudioOnly = !!obj.isAudioOnly, + isAudioOnly = obj.downloadMode === "audio", + isAudioMuted = obj.downloadMode === "mute", disableMetadata = !!obj.disableMetadata; if (!testers[host]) { @@ -71,41 +72,47 @@ export default async function(host, patternMatch, lang, obj) { dispatcher }); break; + case "vk": r = await vk({ userId: patternMatch.userId, videoId: patternMatch.videoId, - quality: obj.vQuality + quality: obj.videoQuality }); break; + case "ok": r = await ok({ id: patternMatch.id, - quality: obj.vQuality + quality: obj.videoQuality }); break; + case "bilibili": r = await bilibili(patternMatch); break; + case "youtube": let fetchInfo = { id: patternMatch.id.slice(0, 11), - quality: obj.vQuality, - format: obj.vCodec, - isAudioOnly: isAudioOnly, - isAudioMuted: obj.isAudioMuted, - dubLang: obj.dubLang, + quality: obj.videoQuality, + format: obj.youtubeVideoCodec, + isAudioOnly, + isAudioMuted, + dubLang: obj.youtubeDubLang, dispatcher } - if (url.hostname === 'music.youtube.com' || isAudioOnly === true) { + if (url.hostname === "music.youtube.com" || isAudioOnly) { fetchInfo.quality = "max"; fetchInfo.format = "vp9"; - fetchInfo.isAudioOnly = true + fetchInfo.isAudioOnly = true; + fetchInfo.isAudioMuted = false; } r = await youtube(fetchInfo); break; + case "reddit": r = await reddit({ sub: patternMatch.sub, @@ -113,15 +120,17 @@ export default async function(host, patternMatch, lang, obj) { user: patternMatch.user }); break; + case "tiktok": r = await tiktok({ postId: patternMatch.postId, id: patternMatch.id, - fullAudio: obj.isTTFullAudio, - isAudioOnly: isAudioOnly, + fullAudio: obj.tiktokFullAudio, + isAudioOnly, h265: obj.tiktokH265 }); break; + case "tumblr": r = await tumblr({ id: patternMatch.id, @@ -129,90 +138,106 @@ export default async function(host, patternMatch, lang, obj) { url }); break; + case "vimeo": r = await vimeo({ id: patternMatch.id.slice(0, 11), password: patternMatch.password, - quality: obj.vQuality, - isAudioOnly: isAudioOnly + quality: obj.videoQuality, + isAudioOnly, }); break; + case "soundcloud": isAudioOnly = true; + isAudioMuted = false; r = await soundcloud({ url, author: patternMatch.author, song: patternMatch.song, - format: obj.aFormat, + format: obj.audioFormat, shortLink: patternMatch.shortLink || false, accessKey: patternMatch.accessKey || false }); break; + case "instagram": r = await instagram({ ...patternMatch, - quality: obj.vQuality, + quality: obj.videoQuality, dispatcher }) break; + case "vine": r = await vine({ id: patternMatch.id }); break; + case "pinterest": r = await pinterest({ id: patternMatch.id, shortLink: patternMatch.shortLink || false }); break; + case "streamable": r = await streamable({ id: patternMatch.id, - quality: obj.vQuality, - isAudioOnly: isAudioOnly, + quality: obj.videoQuality, + isAudioOnly, }); break; + case "twitch": r = await twitch({ clipId: patternMatch.clip || false, - quality: obj.vQuality, - isAudioOnly: obj.isAudioOnly + quality: obj.videoQuality, + isAudioOnly, }); break; + case "rutube": r = await rutube({ id: patternMatch.id, yappyId: patternMatch.yappyId, key: patternMatch.key, - quality: obj.vQuality, - isAudioOnly: isAudioOnly + quality: obj.videoQuality, + isAudioOnly, }); break; + case "dailymotion": r = await dailymotion(patternMatch); break; + case "snapchat": r = await snapchat(patternMatch); break; + case "loom": r = await loom({ id: patternMatch.id }); break; + case "facebook": r = await facebook({ ...patternMatch }); break; + default: return createResponse("error", { code: "ErrorUnsupported" }); } - if (r.isAudioOnly) isAudioOnly = true; - let isAudioMuted = isAudioOnly ? false : obj.isAudioMuted; + if (r.isAudioOnly) { + isAudioOnly = true; + isAudioMuted = false; + } if (r.error && r.critical) { return createResponse("critical", { @@ -230,12 +255,12 @@ export default async function(host, patternMatch, lang, obj) { return matchAction({ r, host, - audioFormat: obj.aFormat, + audioFormat: obj.audioFormat, isAudioOnly, isAudioMuted, disableMetadata, - filenameStyle: obj.filenamePattern, - toGif: obj.twitterGif, + filenameStyle: obj.filenameStyle, + twitterGif: obj.twitterGif, requestIP }) } catch { diff --git a/api/src/processing/request.js b/api/src/processing/request.js index 899fcc44..e90d17d2 100644 --- a/api/src/processing/request.js +++ b/api/src/processing/request.js @@ -4,21 +4,21 @@ import { normalizeURL } from "./url.js"; import { createStream } from "../stream/manage.js"; import { verifyLanguageCode } from "../misc/utils.js"; -const apiVar = { - allowed: { - vCodec: ["h264", "av1", "vp9"], - vQuality: ["max", "4320", "2160", "1440", "1080", "720", "480", "360", "240", "144"], - aFormat: ["best", "mp3", "ogg", "wav", "opus"], - filenamePattern: ["classic", "pretty", "basic", "nerdy"] +const apiRequest = { + option: { + audioFormat: ["best", "mp3", "ogg", "wav", "opus"], + downloadMode: ["auto", "audio", "mute"], + filenameStyle: ["classic", "pretty", "basic", "nerdy"], + videoQuality: ["max", "4320", "2160", "1440", "1080", "720", "480", "360", "240", "144"], + youtubeVideoCodec: ["h264", "av1", "vp9"], }, - booleanOnly: [ - "isAudioOnly", - "isTTFullAudio", - "isAudioMuted", - "dubLang", + boolean: [ "disableMetadata", + "tiktokFullAudio", + "tiktokH265", "twitterGif", - "tiktokH265" + "youtubeDubBrowserLang", + "youtubeDubLang" ] } @@ -116,16 +116,16 @@ export function createResponse(responseType, responseData) { export function normalizeRequest(request) { try { let template = { + audioFormat: "mp3", url: normalizeURL(decodeURIComponent(request.url)), - vCodec: "h264", - vQuality: "720", - aFormat: "mp3", - filenamePattern: "classic", - isAudioOnly: false, - isTTFullAudio: false, - isAudioMuted: false, + youtubeVideoCodec: "h264", + videoQuality: "720", + filenameStyle: "classic", + downloadMode: "auto", + tiktokFullAudio: false, disableMetadata: false, - dubLang: false, + youtubeDubBrowserLang: false, + youtubeDubLang: false, twitterGif: false, tiktokH265: false } @@ -142,16 +142,16 @@ export function normalizeRequest(request) { const item = request[key]; if (String(key) !== "url" && templateKeys.includes(key)) { - if (apiVar.booleanOnly.includes(key)) { + if (apiRequest.boolean.includes(key)) { template[key] = !!item; - } else if (apiVar.allowed[key] && apiVar.allowed[key].includes(item)) { + } else if (apiRequest.option[key] && apiRequest.option[key].includes(item)) { template[key] = String(item) } } } - if (template.dubLang) - template.dubLang = verifyLanguageCode(request.dubLang); + if (template.youtubeDubBrowserLang) + template.youtubeDubLang = verifyLanguageCode(request.youtubeDubLang); return template } catch { From 0a28b4091fef205a487d771e68a9aed56cfb9590 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 3 Aug 2024 23:08:59 +0600 Subject: [PATCH 376/775] api/youtube: small indentation fix --- api/src/processing/services/youtube.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/processing/services/youtube.js b/api/src/processing/services/youtube.js index 5dd40ee1..e82b9563 100644 --- a/api/src/processing/services/youtube.js +++ b/api/src/processing/services/youtube.js @@ -110,7 +110,7 @@ export default async function(o) { ); } catch(e) { if (e.message?.endsWith("decipher algorithm")) { - return { error: "ErrorYoutubeDecipher" } + return { error: "ErrorYoutubeDecipher" } } else throw e; } From 94c2545ca62aa1dc68e6b5cadc9f7f31fcd8f21a Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 17:10:59 +0000 Subject: [PATCH 377/775] api/serverInfo: make cors into boolean --- api/src/core/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/core/api.js b/api/src/core/api.js index c7ce57b9..fee4007d 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -40,7 +40,7 @@ export function runAPI(express, app, __dirname) { const serverInfo = { version: version, git, - cors: Number(env.corsWildcard), + cors: env.corsWildcard, url: env.apiURL, startTime: `${startTimestamp}`, } From 168c1bdbbbcb4e5ecf53ccdb5901786e58d35503 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 3 Aug 2024 17:33:53 +0000 Subject: [PATCH 378/775] api/test: update tests to use new request format --- api/src/misc/run-test.js | 2 +- api/src/util/tests.json | 2529 ++++++++++++++++++++------------------ 2 files changed, 1328 insertions(+), 1203 deletions(-) diff --git a/api/src/misc/run-test.js b/api/src/misc/run-test.js index 455e3dfd..ef3d5f51 100644 --- a/api/src/misc/run-test.js +++ b/api/src/misc/run-test.js @@ -14,7 +14,7 @@ export async function runTest(url, params, expect) { } const result = await match( - parsed.host, parsed.patternMatch, "en", normalized + parsed.host, parsed.patternMatch, normalized ); let error = []; diff --git a/api/src/util/tests.json b/api/src/util/tests.json index ab6a1e6a..48ae3eab 100644 --- a/api/src/util/tests.json +++ b/api/src/util/tests.json @@ -1,1273 +1,1398 @@ { - "twitter": [{ - "name": "regular video", - "url": "https://twitter.com/X/status/1697304622749086011", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": false + "twitter": [ + { + "name": "regular video", + "url": "https://twitter.com/X/status/1697304622749086011", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "video with mobile web mediaviewer", - "url": "https://twitter.com/X/status/1697304622749086011/mediaViewer?currentTweet=1697304622749086011¤tTweetUser=X¤tTweet=1697304622749086011¤tTweetUser=X", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "embedded twitter video", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "video with mobile web mediaviewer", + "url": "https://twitter.com/X/status/1697304622749086011/mediaViewer?currentTweet=1697304622749086011¤tTweetUser=X¤tTweet=1697304622749086011¤tTweetUser=X", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "mixed media (image + gif)", - "url": "https://twitter.com/sky_mj26/status/1807756010712428565", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "embedded twitter video", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "picker" - } - }, { - "name": "picker: mixed media (3 videos)", - "url": "https://twitter.com/DankGameAlert/status/1584726006094794774", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "mixed media (image + gif)", + "url": "https://twitter.com/sky_mj26/status/1807756010712428565", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "picker" + } }, - "expected": { - "code": 200, - "status": "picker" - } - }, { - "name": "audio from embedded twitter video (mp3, isAudioOnly)", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "aFormat": "mp3", - "isAudioOnly": true, - "isAudioMuted": false + { + "name": "picker: mixed media (3 videos)", + "url": "https://twitter.com/DankGameAlert/status/1584726006094794774", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "picker" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "audio from embedded twitter video (best, isAudioOnly)", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "aFormat": "best", - "isAudioOnly": true, - "isAudioMuted": false + { + "name": "audio from embedded twitter video (mp3, isAudioOnly)", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "audio from embedded twitter video (ogg, isAudioOnly, isAudioMuted)", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "aFormat": "best", - "isAudioOnly": true, - "isAudioMuted": true + { + "name": "audio from embedded twitter video (best, isAudioOnly)", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "audio", + "audioFormat": "best" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "muted embedded twitter video", - "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": true + { + "name": "audio from embedded twitter video (ogg, isAudioOnly, isAudioMuted)", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "audio", + "audioFormat": "best" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "retweeted video", - "url": "https://twitter.com/uwukko/status/1696901469633421344", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "age restricted video", - "url": "https://twitter.com/FckyeahCharli/status/1650987582749065220", - "params": {}, - "canFail": true, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "twitter voice + x.com link", - "url": "https://x.com/eggsaladscreams/status/1693089534886506756?s=46", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "vxtwitter link", - "url": "https://vxtwitter.com/dustbin_nie/status/1624596567188717568?s=20", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "post with 1 image", - "url": "https://x.com/PopCrave/status/1815960083475423235", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "post with 4 images", - "url": "https://x.com/PopCrave/status/1816260887147114696", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }, { - "name": "retweeted video, isAudioOnly", - "url": "https://twitter.com/hugekiwinuts/status/1618671150829309953?s=46&t=gItGzgwGQQJJaJrO6qc1Pg", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": true + { + "name": "muted embedded twitter video", + "url": "https://twitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": { + "downloadMode": "mute", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "inexistent post", - "url": "https://twitter.com/test/status/9487653", - "params": { - "aFormat": "best", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "retweeted video", + "url": "https://twitter.com/uwukko/status/1696901469633421344", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 400, - "status": "error" - } - }, { - "name": "post with no media content", - "url": "https://twitter.com/elonmusk/status/1604617643973124097?s=20", - "params": { - "aFormat": "best", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "age restricted video", + "url": "https://twitter.com/FckyeahCharli/status/1650987582749065220", + "params": {}, + "canFail": true, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 400, - "status": "error" - } - }], - "soundcloud": [{ - "name": "public song (best)", - "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", - "params": { - "aFormat": "best", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "twitter voice + x.com link", + "url": "https://x.com/eggsaladscreams/status/1693089534886506756?s=46", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "public song (mp3, isAudioMuted)", - "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": true + { + "name": "vxtwitter link", + "url": "https://vxtwitter.com/dustbin_nie/status/1624596567188717568?s=20", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "private song", - "url": "https://soundcloud.com/4kayy/unhappy-new-year-prod4kay/s-9bKbvwLdRWG", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "post with 1 image", + "url": "https://x.com/PopCrave/status/1815960083475423235", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "private song (wav, isAudioMuted)", - "url": "https://soundcloud.com/4kayy/unhappy-new-year-prod4kay/s-9bKbvwLdRWG", - "params": { - "aFormat": "wav", - "isAudioOnly": false, - "isAudioMuted": true + { + "name": "post with 4 images", + "url": "https://x.com/PopCrave/status/1816260887147114696", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "private song (ogg, isAudioMuted, isAudioOnly)", - "url": "https://soundcloud.com/4kayy/unhappy-new-year-prod4kay/s-9bKbvwLdRWG", - "params": { - "aFormat": "ogg", - "isAudioOnly": true, - "isAudioMuted": true + { + "name": "retweeted video, isAudioOnly", + "url": "https://twitter.com/hugekiwinuts/status/1618671150829309953?s=46&t=gItGzgwGQQJJaJrO6qc1Pg", + "params": { + "downloadMode": "mute", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "on.soundcloud link", - "url": "https://on.soundcloud.com/wLZre", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "on.soundcloud link, different stream type", - "url": "https://on.soundcloud.com/AG4c", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "no opus audio, fallback to mp3", - "url": "https://soundcloud.com/frums/credits", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }], - "youtube": [{ - "name": "4k video (h264, 1440)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "h264", - "vQuality": "1440" + { + "name": "inexistent post", + "url": "https://twitter.com/test/status/9487653", + "params": { + "audioFormat": "best" + }, + "expected": { + "code": 400, + "status": "error" + } }, - "expected": { - "code": 200, - "status": "stream" + { + "name": "post with no media content", + "url": "https://twitter.com/elonmusk/status/1604617643973124097?s=20", + "params": { + "audioFormat": "best" + }, + "expected": { + "code": 400, + "status": "error" + } } - }, { - "name": "4k video (vp9, 720)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "vp9", - "vQuality": "720" + ], + "soundcloud": [ + { + "name": "public song (best)", + "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", + "params": { + "audioFormat": "best" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "4k video (av1, max)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "av1", - "vQuality": "max" + { + "name": "public song (mp3, isAudioMuted)", + "url": "https://soundcloud.com/l2share77/loona-butterfly?utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing", + "params": { + "downloadMode": "mute", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "4k video (h264, 720)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "h264", - "vQuality": "720" + { + "name": "private song", + "url": "https://soundcloud.com/4kayy/unhappy-new-year-prod4kay/s-9bKbvwLdRWG", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "4k video (vp9, max, isAudioMuted)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "vp9", - "vQuality": "max", - "isAudioMuted": true + { + "name": "private song (wav, isAudioMuted)", + "url": "https://soundcloud.com/4kayy/unhappy-new-year-prod4kay/s-9bKbvwLdRWG", + "params": { + "downloadMode": "mute", + "audioFormat": "wav" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "4k video (h264, max, isAudioMuted)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "h264", - "vQuality": "max", - "isAudioMuted": true + { + "name": "private song (ogg, isAudioMuted, isAudioOnly)", + "url": "https://soundcloud.com/4kayy/unhappy-new-year-prod4kay/s-9bKbvwLdRWG", + "params": { + "downloadMode": "audio", + "audioFormat": "ogg" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "4k video (av1, max, isAudioMuted, isAudioOnly, mp3)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "av1", - "vQuality": "max", - "aFormat": "mp3", - "isAudioOnly": true, - "isAudioMuted": true + { + "name": "on.soundcloud link", + "url": "https://on.soundcloud.com/wLZre", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "4k video (av1, max, isAudioMuted, isAudioOnly, best)", - "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", - "params": { - "vCodec": "av1", - "vQuality": "max", - "aFormat": "best", - "isAudioOnly": true, - "isAudioMuted": true + { + "name": "on.soundcloud link, different stream type", + "url": "https://on.soundcloud.com/AG4c", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" + { + "name": "no opus audio, fallback to mp3", + "url": "https://soundcloud.com/frums/credits", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } } - }, { - "name": "music (mp3, isAudioOnly, isAudioMuted)", - "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", - "params": { - "aFormat": "mp3", - "isAudioOnly": true, - "isAudioMuted": true + ], + "youtube": [ + { + "name": "4k video (h264, 1440)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "h264", + "videoQuality": "1440" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "music (mp3)", - "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", - "params": { - "aFormat": "mp3", - "isAudioOnly": false, - "isAudioMuted": false + { + "name": "4k video (vp9, 720)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "vp9", + "videoQuality": "720" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "audio bitrate higher than video, no vp9 video in response (mp3, isAudioOnly)", - "url": "https://www.youtube.com/watch?v=t5nC_ucYBrc", - "params": { - "aFormat": "mp3", - "isAudioOnly": true + { + "name": "4k video (av1, max)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "av1", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "audio bitrate higher than video, no vp9 video in response (vp9)", - "url": "https://www.youtube.com/watch?v=t5nC_ucYBrc", - "params": { - "vCodec": "vp9" + { + "name": "4k video (h264, 720)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "youtubeVideoCodec": "h264", + "videoQuality": "720" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 400, - "status": "error" - } - }, { - "name": "short, defaults", - "url": "https://www.youtube.com/shorts/r5FpeOJItbw", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "vr 360, av1, max", - "url": "https://www.youtube.com/watch?v=hEdzv7D4CbQ", - "params": { - "vCodec": "vp9", - "vQuality": "max" + { + "name": "4k video (vp9, max, isAudioMuted)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "mute", + "youtubeVideoCodec": "vp9", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "live link, defaults", - "url": "https://www.youtube.com/live/ENxZS6PUDuI?feature=shared", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "inexistent video", - "url": "https://youtube.com/watch?v=gnjuHYWGEW", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }], - "vk": [{ - "name": "clip, defaults", - "url": "https://vk.com/clip-57274055_456239788", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "clip, 360", - "url": "https://vk.com/clip-57274055_456239788", - "params": { - "vQuality": "360" + { + "name": "4k video (h264, max, isAudioMuted)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "mute", + "youtubeVideoCodec": "h264", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "clip different link, max", - "url": "https://vk.com/clips-57274055?z=clip-57274055_456239788", - "params": { - "vQuality": "max" + { + "name": "4k video (av1, max, isAudioMuted, isAudioOnly, mp3)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3", + "youtubeVideoCodec": "av1", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "video, defaults", - "url": "https://vk.com/video-57274055_456239399", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "4k video", - "url": "https://vk.com/video-1112285_456248465", - "params": { - "vQuality": "max" + { + "name": "4k video (av1, max, isAudioMuted, isAudioOnly, best)", + "url": "https://www.youtube.com/watch?v=vPwaXytZcgI", + "params": { + "downloadMode": "audio", + "audioFormat": "best", + "youtubeVideoCodec": "av1", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "ancient video (fallback to 240p)", - "url": "https://vk.com/video-1959_28496479", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "inexistent video", - "url": "https://vk.com/video-53333333_456233333", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }], - "tiktok": [{ - "name": "long link video", - "url": "https://www.tiktok.com/@fatfatmillycat/video/7195741644585454894", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "images", - "url": "https://www.tiktok.com/@matryoshk4/video/7231234675476532526", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }, { - "name": "long link inexistent", - "url": "https://www.tiktok.com/@blablabla/video/7120851458451417478", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, { - "name": "short link inexistent", - "url": "https://vt.tiktok.com/2p4ewa7/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }], - "bilibili": [{ - "name": "1080p video", - "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "1080p video muted", - "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", - "params": { - "isAudioMuted": true + { + "name": "music (mp3, isAudioOnly, isAudioMuted)", + "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "1080p vertical video", - "url": "https://www.bilibili.com/video/BV1uu411z7VV/", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "1080p vertical video muted", - "url": "https://www.bilibili.com/video/BV1uu411z7VV/", - "params": { - "isAudioMuted": true + { + "name": "music (mp3)", + "url": "https://music.youtube.com/watch?v=5rGTsvZCEdk&feature=share", + "params": { + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "b23.tv shortlink", - "url": "https://b23.tv/lbMyOI9", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, - { - "name": "bilibili.tv link", - "url": "https://www.bilibili.tv/en/video/4789599404426256", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }], - "tumblr": [{ - "name": "at.tumblr link", - "url": "https://at.tumblr.com/music/704177038274281472/n7x7pr7x4w2b", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "user subdomain link", - "url": "https://garfield-69.tumblr.com/post/696499862852780032", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "web app link", - "url": "https://www.tumblr.com/rongzhi/707729381162958848/english-added-by-me?source=share", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "tumblr audio", - "url": "https://www.tumblr.com/zedneon/737815079301562368/zedneon-ft-mr-sauceman-tech-n9ne-speed-of?source=share", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "tumblr video converted to audio", - "url": "https://garfield-69.tumblr.com/post/696499862852780032", - "params": { - "isAudioOnly": true + { + "name": "audio bitrate higher than video, no vp9 video in response (mp3, isAudioOnly)", + "url": "https://www.youtube.com/watch?v=t5nC_ucYBrc", + "params": { + "downloadMode": "audio", + "audioFormat": "mp3" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }], - "vimeo": [{ - "name": "4k progressive", - "url": "https://vimeo.com/288386543", - "params": { - "vQuality": "2160" + { + "name": "audio bitrate higher than video, no vp9 video in response (vp9)", + "url": "https://www.youtube.com/watch?v=t5nC_ucYBrc", + "params": { + "youtubeVideoCodec": "vp9" + }, + "expected": { + "code": 400, + "status": "error" + } }, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "720p progressive", - "url": "https://vimeo.com/288386543", - "params": { - "vQuality": "720" + { + "name": "short, defaults", + "url": "https://www.youtube.com/shorts/r5FpeOJItbw", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "1080p dash parcel", - "url": "https://vimeo.com/967252742", - "params": { - "vQuality": "1440" + { + "name": "vr 360, av1, max", + "url": "https://www.youtube.com/watch?v=hEdzv7D4CbQ", + "params": { + "youtubeVideoCodec": "vp9", + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "720p dash parcel", - "url": "https://vimeo.com/967252742", - "params": { - "vQuality": "360" + { + "name": "live link, defaults", + "url": "https://www.youtube.com/live/ENxZS6PUDuI?feature=shared", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "redirect" + { + "name": "inexistent video", + "url": "https://youtube.com/watch?v=gnjuHYWGEW", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } } - }, { - "name": "private video", - "url": "https://vimeo.com/903115595/f14d06da38", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "mature video", - "url": "https://vimeo.com/973212054", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }], - "reddit": [{ - "name": "video with audio", - "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "video with audio (isAudioOnly)", - "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", - "params": { - "isAudioOnly": true + ], + "vk": [ + { + "name": "clip, defaults", + "url": "https://vk.com/clip-57274055_456239788", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "video with audio (isAudioMuted)", - "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", - "params": { - "isAudioMuted": true + { + "name": "clip, 360", + "url": "https://vk.com/clip-57274055_456239788", + "params": { + "videoQuality": "360" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "video without audio", - "url": "https://www.reddit.com/r/catvideos/comments/ftoeo7/luna_doesnt_want_to_be_bothered_while_shes_napping/?utm_source=share&utm_medium=web2x&context=3", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "actual gif, not looping video", - "url": "https://www.reddit.com/r/whenthe/comments/109wqy1/god_really_did_some_trolling/?utm_source=share&utm_medium=web2x&context=3", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "different audio link, live render", - "url": "https://www.reddit.com/r/TikTokCringe/comments/15hce91/asian_daddy_kink/", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }], - "instagram": [{ - "name": "single photo post", - "url": "https://www.instagram.com/p/CwIgW8Yu5-I/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "various picker (photos + video)", - "url": "https://www.instagram.com/p/CvYrSgnsKjv/", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }, { - "name": "reel", - "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular video", - "url": "https://www.instagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "reel (isAudioOnly)", - "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", - "params": { - "isAudioOnly": true + { + "name": "clip different link, max", + "url": "https://vk.com/clips-57274055?z=clip-57274055_456239788", + "params": { + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "reel (isAudioMuted)", - "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", - "params": { - "isAudioMuted": true + { + "name": "video, defaults", + "url": "https://vk.com/video-57274055_456239399", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "inexistent reel", - "url": "https://www.instagram.com/reel/XXXXXXXXXX/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, { - "name": "inexistent post", - "url": "https://www.instagram.com/p/XXXXXXXXXX/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, { - "name": "post info in an array (for whatever reason??)", - "url": "https://www.instagram.com/reel/CrVB9tatUDv/?igshid=blaBlABALALbLABULLSHIT==", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "prone to get rate limited", - "url": "https://www.instagram.com/reel/CrO-T7Qo6rq/?igshid=fuckYouNoTrackingIdForYou==", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "ddinstagram link", - "url": "https://ddinstagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "d.ddinstagram.com link", - "url": "https://d.ddinstagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "g.ddinstagram.com link", - "url": "https://g.ddinstagram.com/p/CmCVWoIr9OH/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }], - "vine": [{ - "name": "regular vine link (9+10=21)", - "url": "https://vine.co/v/huwVJIEJW50", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular vine link (isAudioOnly)", - "url": "https://vine.co/v/huwVJIEJW50", - "params": { - "isAudioOnly": true + { + "name": "4k video", + "url": "https://vk.com/video-1112285_456248465", + "params": { + "videoQuality": "max" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "regular vine link (isAudioMuted)", - "url": "https://vine.co/v/huwVJIEJW50", - "params": { - "isAudioMuted": true + { + "name": "ancient video (fallback to 240p)", + "url": "https://vk.com/video-1959_28496479", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" + { + "name": "inexistent video", + "url": "https://vk.com/video-53333333_456233333", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } } - }], - "pinterest": [{ - "name": "regular video", - "url": "https://www.pinterest.com/pin/70437485604616/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular video (isAudioOnly)", - "url": "https://www.pinterest.com/pin/70437485604616/", - "params": { - "isAudioOnly": true + ], + "tiktok": [ + { + "name": "long link video", + "url": "https://www.tiktok.com/@fatfatmillycat/video/7195741644585454894", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "regular video (isAudioMuted)", - "url": "https://www.pinterest.com/pin/70437485604616/", - "params": { - "isAudioMuted": true + { + "name": "images", + "url": "https://www.tiktok.com/@matryoshk4/video/7231234675476532526", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "regular video (.ca TLD)", - "url": "https://www.pinterest.ca/pin/70437485604616/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "story", - "url": "https://www.pinterest.com/pin/gadget-cool-products-amazon-product-technology-kitchen-gadgets--1084663891475263837/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular picture", - "url": "https://www.pinterest.com/pin/412994228343400946/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular picture (.ca TLD)", - "url": "https://www.pinterest.ca/pin/412994228343400946/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular gif", - "url": "https://www.pinterest.com/pin/814447913881127862/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular gif (.ca TLD)", - "url": "https://www.pinterest.ca/pin/814447913881127862/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }], - "streamable": [{ - "name": "regular video", - "url": "https://streamable.com/p9cln4", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "embedded link", - "url": "https://streamable.com/e/rsmo56", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "regular video (isAudioOnly)", - "url": "https://streamable.com/p9cln4", - "params": { - "isAudioOnly": true + { + "name": "long link inexistent", + "url": "https://www.tiktok.com/@blablabla/video/7120851458451417478", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } }, - "expected": { - "code": 200, - "status": "stream" + { + "name": "short link inexistent", + "url": "https://vt.tiktok.com/2p4ewa7/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } } - }, { - "name": "regular video (isAudioMuted)", - "url": "https://streamable.com/p9cln4", - "params": { - "isAudioMuted": true + ], + "bilibili": [ + { + "name": "1080p video", + "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "inexistent video", - "url": "https://streamable.com/XXXXXX", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }], - "twitch": [{ - "name": "clip", - "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "clip (isAudioOnly)", - "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", - "params": { - "isAudioOnly": true + { + "name": "1080p video muted", + "url": "https://www.bilibili.com/video/BV18i4y1m7xV/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "clip (isAudioMuted)", - "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", - "params": { - "isAudioMuted": true + { + "name": "1080p vertical video", + "url": "https://www.bilibili.com/video/BV1uu411z7VV/", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }], - "rutube": [{ - "name": "regular video", - "url": "https://rutube.ru/video/b2f6c27649907c2fde0af411b03825eb/", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "vertical video (isAudioMuted)", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": { - "isAudioMuted": true + { + "name": "1080p vertical video muted", + "url": "https://www.bilibili.com/video/BV1uu411z7VV/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "russian region lock", - "url": "https://rutube.ru/video/b521653b4f71ece57b8ff54e57ca9b82/", - "params": {}, - "expected": { - "code": 400, - "status": "error" - } - }, { - "name": "vertical video", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "yappy", - "url": "https://rutube.ru/yappy/c8c32bf7aee04412837656ea26c2b25b/", - "canFail": true, - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "shorts", - "url": "https://rutube.ru/shorts/935c1afafd0e7d52836d671967d53dac/", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "vertical video (isAudioOnly)", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": { - "isAudioOnly": true + { + "name": "b23.tv shortlink", + "url": "https://b23.tv/lbMyOI9", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, - "expected": { - "code": 200, - "status": "stream" + { + "name": "bilibili.tv link", + "url": "https://www.bilibili.tv/en/video/4789599404426256", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } } - }, { - "name": "vertical video (isAudioMuted)", - "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", - "params": { - "isAudioMuted": true + ], + "tumblr": [ + { + "name": "at.tumblr link", + "url": "https://at.tumblr.com/music/704177038274281472/n7x7pr7x4w2b", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "private video", - "url": "https://rutube.ru/video/private/1161415be0e686214bb2a498165cab3e/?p=_IL1G8RSnKutunnTYwhZ5A", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }], - "ok": [{ - "name": "regular video", - "url": "https://ok.ru/video/7204071410346", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }], - "dailymotion": [{ - "name": "regular video", - "url": "https://www.dailymotion.com/video/x8t1eho", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "private video", - "url": "https://www.dailymotion.com/video/k41fZWpx2TaAORA2nok", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "dai.ly shortened link", - "url": "https://dai.ly/k41fZWpx2TaAORA2nok", - "params": {}, - "expected": { - "code": 200, - "status": "stream" - } - }], - "snapchat": [{ - "name": "spotlight", - "url": "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYdWxucG9pZmNqAY46j0a5AY46j0YbAAAAAQ", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "shortlinked spotlight", - "url": "https://t.snapchat.com/4ZsiBLDi", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "story", - "url": "https://www.snapchat.com/add/bazerkmakane", - "params": {}, - "expected": { - "code": 200, - "status": "picker" - } - }], - "loom": [{ - "name": "1080p video", - "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" - } - }, { - "name": "1080p video (muted)", - "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", - "params": { - "isAudioMuted": true + { + "name": "user subdomain link", + "url": "https://garfield-69.tumblr.com/post/696499862852780032", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 200, - "status": "stream" - } - }, { - "name": "1080p video (audio only)", - "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", - "params": { - "isAudioOnly": true + { + "name": "web app link", + "url": "https://www.tumblr.com/rongzhi/707729381162958848/english-added-by-me?source=share", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } }, - "expected": { - "code": 400, - "status": "error" + { + "name": "tumblr audio", + "url": "https://www.tumblr.com/zedneon/737815079301562368/zedneon-ft-mr-sauceman-tech-n9ne-speed-of?source=share", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "tumblr video converted to audio", + "url": "https://garfield-69.tumblr.com/post/696499862852780032", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } } - }], - "facebook": [{ - "name": "direct video with username and id", - "url": "https://web.facebook.com/100048111287134/videos/1157798148685638/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" + ], + "vimeo": [ + { + "name": "4k progressive", + "url": "https://vimeo.com/288386543", + "params": { + "videoQuality": "2160" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "720p progressive", + "url": "https://vimeo.com/288386543", + "params": { + "videoQuality": "720" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "1080p dash parcel", + "url": "https://vimeo.com/967252742", + "params": { + "videoQuality": "1440" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "720p dash parcel", + "url": "https://vimeo.com/967252742", + "params": { + "videoQuality": "360" + }, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "private video", + "url": "https://vimeo.com/903115595/f14d06da38", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "mature video", + "url": "https://vimeo.com/973212054", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } } - }, { - "name": "direct video with id as query param", - "url": "https://web.facebook.com/watch/?v=883839773514682&ref=sharing", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" + ], + "reddit": [ + { + "name": "video with audio", + "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "video with audio (isAudioOnly)", + "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "video with audio (isAudioMuted)", + "url": "https://www.reddit.com/r/TikTokCringe/comments/wup1fg/id_be_escaping_at_the_first_chance_i_got/?utm_source=share&utm_medium=web2x&context=3", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "video without audio", + "url": "https://www.reddit.com/r/catvideos/comments/ftoeo7/luna_doesnt_want_to_be_bothered_while_shes_napping/?utm_source=share&utm_medium=web2x&context=3", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "actual gif, not looping video", + "url": "https://www.reddit.com/r/whenthe/comments/109wqy1/god_really_did_some_trolling/?utm_source=share&utm_medium=web2x&context=3", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "different audio link, live render", + "url": "https://www.reddit.com/r/TikTokCringe/comments/15hce91/asian_daddy_kink/", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } } - }, { - "name": "direct video with caption", - "url": "https://web.facebook.com/wood57/videos/𝐒𝐞𝐛𝐚𝐬𝐤𝐨𝐦-𝐟𝐮𝐥𝐥/883839773514682", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" + ], + "instagram": [ + { + "name": "single photo post", + "url": "https://www.instagram.com/p/CwIgW8Yu5-I/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "various picker (photos + video)", + "url": "https://www.instagram.com/p/CvYrSgnsKjv/", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } + }, + { + "name": "reel", + "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular video", + "url": "https://www.instagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "reel (isAudioOnly)", + "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "reel (isAudioMuted)", + "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "inexistent reel", + "url": "https://www.instagram.com/reel/XXXXXXXXXX/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "inexistent post", + "url": "https://www.instagram.com/p/XXXXXXXXXX/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "post info in an array (for whatever reason??)", + "url": "https://www.instagram.com/reel/CrVB9tatUDv/?igshid=blaBlABALALbLABULLSHIT==", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "prone to get rate limited", + "url": "https://www.instagram.com/reel/CrO-T7Qo6rq/?igshid=fuckYouNoTrackingIdForYou==", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "ddinstagram link", + "url": "https://ddinstagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "d.ddinstagram.com link", + "url": "https://d.ddinstagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "g.ddinstagram.com link", + "url": "https://g.ddinstagram.com/p/CmCVWoIr9OH/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } } - }, { - "name": "shortlink video", - "url": "https://fb.watch/r1K6XHMfGT/", - "canFail": true, - "params": {}, - "expected": { - "code": 200, - "status": "redirect" + ], + "vine": [ + { + "name": "regular vine link (9+10=21)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular vine link (isAudioOnly)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "regular vine link (isAudioMuted)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } } - }, { - "name": "reel video", - "url": "https://web.facebook.com/reel/730293269054758", - "canFail": true, - "params": {}, - "expected": { - "code": 200, - "status": "redirect" + ], + "pinterest": [ + { + "name": "regular video", + "url": "https://www.pinterest.com/pin/70437485604616/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular video (isAudioOnly)", + "url": "https://www.pinterest.com/pin/70437485604616/", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "regular video (isAudioMuted)", + "url": "https://www.pinterest.com/pin/70437485604616/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "regular video (.ca TLD)", + "url": "https://www.pinterest.ca/pin/70437485604616/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "story", + "url": "https://www.pinterest.com/pin/gadget-cool-products-amazon-product-technology-kitchen-gadgets--1084663891475263837/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular picture", + "url": "https://www.pinterest.com/pin/412994228343400946/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular picture (.ca TLD)", + "url": "https://www.pinterest.ca/pin/412994228343400946/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular gif", + "url": "https://www.pinterest.com/pin/814447913881127862/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular gif (.ca TLD)", + "url": "https://www.pinterest.ca/pin/814447913881127862/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } } - }, { - "name": "shared video link", - "url": "https://www.facebook.com/share/v/NEf87jbPTvFE8LsL/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" + ], + "streamable": [ + { + "name": "regular video", + "url": "https://streamable.com/p9cln4", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "embedded link", + "url": "https://streamable.com/e/rsmo56", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "regular video (isAudioOnly)", + "url": "https://streamable.com/p9cln4", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "regular video (isAudioMuted)", + "url": "https://streamable.com/p9cln4", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "inexistent video", + "url": "https://streamable.com/XXXXXX", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } } - }, { - "name": "shared video link v2", - "url": "https://web.facebook.com/share/r/JFZfPVgLkiJQmWrr/", - "params": {}, - "expected": { - "code": 200, - "status": "redirect" + ], + "twitch": [ + { + "name": "clip", + "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "clip (isAudioOnly)", + "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "clip (isAudioMuted)", + "url": "https://twitch.tv/rtgame/clip/TubularInventiveSardineCorgiDerp-PM47mJQQ2vsL5B5G", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } } - }] -} + ], + "rutube": [ + { + "name": "regular video", + "url": "https://rutube.ru/video/b2f6c27649907c2fde0af411b03825eb/", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "vertical video (isAudioMuted)", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "russian region lock", + "url": "https://rutube.ru/video/b521653b4f71ece57b8ff54e57ca9b82/", + "params": {}, + "expected": { + "code": 400, + "status": "error" + } + }, + { + "name": "vertical video", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "yappy", + "url": "https://rutube.ru/yappy/c8c32bf7aee04412837656ea26c2b25b/", + "canFail": true, + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "shorts", + "url": "https://rutube.ru/shorts/935c1afafd0e7d52836d671967d53dac/", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "vertical video (isAudioOnly)", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "vertical video (isAudioMuted)", + "url": "https://rutube.ru/video/18a281399b96f9184c647455a86f6724/", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "private video", + "url": "https://rutube.ru/video/private/1161415be0e686214bb2a498165cab3e/?p=_IL1G8RSnKutunnTYwhZ5A", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + } + ], + "ok": [ + { + "name": "regular video", + "url": "https://ok.ru/video/7204071410346", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + } + ], + "dailymotion": [ + { + "name": "regular video", + "url": "https://www.dailymotion.com/video/x8t1eho", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "private video", + "url": "https://www.dailymotion.com/video/k41fZWpx2TaAORA2nok", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "dai.ly shortened link", + "url": "https://dai.ly/k41fZWpx2TaAORA2nok", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } + } + ], + "snapchat": [ + { + "name": "spotlight", + "url": "https://www.snapchat.com/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYdWxucG9pZmNqAY46j0a5AY46j0YbAAAAAQ", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shortlinked spotlight", + "url": "https://t.snapchat.com/4ZsiBLDi", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "story", + "url": "https://www.snapchat.com/add/bazerkmakane", + "params": {}, + "expected": { + "code": 200, + "status": "picker" + } + } + ], + "loom": [ + { + "name": "1080p video", + "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "1080p video (muted)", + "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", + "params": { + "downloadMode": "mute" + }, + "expected": { + "code": 200, + "status": "stream" + } + }, + { + "name": "1080p video (audio only)", + "url": "https://www.loom.com/share/313bf71d20ca47b2a35b6634cefdb761", + "params": { + "downloadMode": "audio" + }, + "expected": { + "code": 400, + "status": "error" + } + } + ], + "facebook": [ + { + "name": "direct video with username and id", + "url": "https://web.facebook.com/100048111287134/videos/1157798148685638/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "direct video with id as query param", + "url": "https://web.facebook.com/watch/?v=883839773514682&ref=sharing", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "direct video with caption", + "url": "https://web.facebook.com/wood57/videos/𝐒𝐞𝐛𝐚𝐬𝐤𝐨𝐦-𝐟𝐮𝐥𝐥/883839773514682", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shortlink video", + "url": "https://fb.watch/r1K6XHMfGT/", + "canFail": true, + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "reel video", + "url": "https://web.facebook.com/reel/730293269054758", + "canFail": true, + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shared video link", + "url": "https://www.facebook.com/share/v/NEf87jbPTvFE8LsL/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, + { + "name": "shared video link v2", + "url": "https://web.facebook.com/share/r/JFZfPVgLkiJQmWrr/", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + } + ] +} \ No newline at end of file From aba444ec8b6e8215a9c5fb958cebde858a64fb7c Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 4 Aug 2024 00:43:24 +0600 Subject: [PATCH 379/775] web: updated api endpoint & params, default instance override - dialogs can be undismissable now (impossible to click away by pressing the bg behind it) - added security warning about api override - moved default api url to env - added new processing settings page --- web/i18n/en/dialog.json | 6 +- web/i18n/en/settings.json | 7 +- .../components/dialog/DialogContainer.svelte | 3 +- web/src/components/dialog/PickerDialog.svelte | 3 +- web/src/components/dialog/SavingDialog.svelte | 3 +- web/src/components/dialog/SmallDialog.svelte | 3 +- web/src/lib/api.ts | 85 ++++++++++++++++--- web/src/lib/download.ts | 2 +- web/src/lib/env.ts | 5 +- web/src/lib/settings/defaults.ts | 6 +- web/src/lib/types/dialog.ts | 1 + web/src/lib/types/settings.ts | 10 ++- web/src/routes/settings/+layout.svelte | 8 ++ .../routes/settings/processing/+page.svelte | 15 ++++ 14 files changed, 134 insertions(+), 23 deletions(-) create mode 100644 web/src/routes/settings/processing/+page.svelte diff --git a/web/i18n/en/dialog.json b/web/i18n/en/dialog.json index 13b5cf3e..6e9bb72e 100644 --- a/web/i18n/en/dialog.json +++ b/web/i18n/en/dialog.json @@ -8,6 +8,7 @@ "button.share": "share", "button.copy": "copy", "button.import": "import", + "button.continue": "continue", "reset.title": "reset all settings?", "reset.body": "are you sure you want to reset all settings? this action is immediate and irreversible.", @@ -22,5 +23,8 @@ "safety.title": "important safety notice", - "import.body": "importing unknown or corrupted files may unexpectedly alter or break cobalt functionality. only import files that you've personally exported and haven't modified. if you were asked to import this file by someone - don't do it.\n\nwe are not responsible for any harm caused by importing unknown setting files." + "import.body": "importing unknown or corrupted files may unexpectedly alter or break cobalt functionality. only import files that you've personally exported and haven't modified. if you were asked to import this file by someone - don't do it.\n\nwe are not responsible for any harm caused by importing unknown setting files.", + + "api.override.title": "processing instance override", + "api.override.body": "{{ value }} is now the processing instance. if you don't trust it, press \"cancel\" and it'll be ignored.\n\nyou can change your choice later in processing settings." } diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 4fc304af..fd38252f 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -6,6 +6,7 @@ "page.download": "downloading", "page.advanced": "advanced", "page.debug": "debug information", + "page.processing": "processing", "section.general": "general", "section.save": "save", @@ -103,5 +104,9 @@ "advanced.data": "settings data", "advanced.reset": "reset all settings", "advanced.import": "import", - "advanced.export": "export" + "advanced.export": "export", + + "processing.override": "default instance override", + "processing.override.title": "use instance-provided processing server", + "processing.override.description": "cobalt will use the processing server from DEFAULT_API when this is enabled." } diff --git a/web/src/components/dialog/DialogContainer.svelte b/web/src/components/dialog/DialogContainer.svelte index 3bb682e6..993efd7c 100644 --- a/web/src/components/dialog/DialogContainer.svelte +++ b/web/src/components/dialog/DialogContainer.svelte @@ -5,6 +5,7 @@ import DialogBackdropClose from "$components/dialog/DialogBackdropClose.svelte"; export let id: string; + export let dismissable = true; let dialogParent: HTMLDialogElement; @@ -32,5 +33,5 @@ - + {}} /> diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index 0f75f989..1fa5f5f5 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -16,6 +16,7 @@ export let id: string; export let items: Optional = undefined; export let buttons: Optional = undefined; + export let dismissable = true; let dialogDescription = "dialog.picker.description."; @@ -30,7 +31,7 @@ let close: () => void; - +
void; @@ -31,7 +32,7 @@ } - +