diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml new file mode 100644 index 0000000..1114426 --- /dev/null +++ b/.github/workflows/build-docs.yml @@ -0,0 +1,58 @@ +name: Build documentation website + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.x" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Run lint check + run: bun flint:check + + - name: Build website + env: + SITE_URL_OVERRIDE: ${{ format('https://{0}.github.io/{1}', github.repository_owner, github.event.repository.name) }} + run: bun build:all + + - name: Upload artifact + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + uses: actions/upload-pages-artifact@v3 + with: + path: build + + deploy: + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9aa6fba --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build +/generated + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..1150662 --- /dev/null +++ b/biome.json @@ -0,0 +1,44 @@ +{ + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**/*.js", + "**/*.cjs", + "**/*.mjs", + "**/*.ts", + "**/*.cts", + "**/*.mts", + "**/*.json", + "**/*.jsonc", + "!node_modules", + "!.claude", + "!.svelte-kit", + "!build", + "!repositories" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "tab", + "lineWidth": 100 + }, + "linter": { + "enabled": true + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "semicolons": "always" + } + }, + "json": { + "formatter": { + "indentStyle": "tab" + } + } +} diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..e929907 --- /dev/null +++ b/bun.lock @@ -0,0 +1,895 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "revanced-documentation", + "dependencies": { + "@sveltejs/adapter-static": "^3.0.10", + "mdsvex": "^0.12.6", + "minisearch": "^7.2.0", + "rehype-autolink-headings": "^7.1.0", + "rehype-sanitize": "^6.0.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "sass": "^1.97.3", + "sharp": "^0.34.5", + "shiki": "^3.22.0", + "svelte-sitemap": "^2.7.1", + "unified": "^11.0.5", + }, + "devDependencies": { + "@biomejs/biome": "^2.3.14", + "@commitlint/cli": "^20.4.1", + "@commitlint/config-conventional": "^20.4.1", + "@iconify-json/mdi": "^1.2.3", + "@sveltejs/kit": "^2.50.1", + "@sveltejs/vite-plugin-svelte": "^6.2.4", + "fast-glob": "^3.3.3", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "lefthook": "^2.1.0", + "mdast-util-to-string": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "svelte": "^5.48.2", + "svelte-check": "^4.3.5", + "typescript": "^5.9.3", + "unist-util-visit": "^5.1.0", + "unplugin-icons": "^23.0.1", + "vite": "^7.3.1", + }, + }, + }, + "packages": { + "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], + + "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@biomejs/biome": ["@biomejs/biome@2.3.14", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.14", "@biomejs/cli-darwin-x64": "2.3.14", "@biomejs/cli-linux-arm64": "2.3.14", "@biomejs/cli-linux-arm64-musl": "2.3.14", "@biomejs/cli-linux-x64": "2.3.14", "@biomejs/cli-linux-x64-musl": "2.3.14", "@biomejs/cli-win32-arm64": "2.3.14", "@biomejs/cli-win32-x64": "2.3.14" }, "bin": { "biome": "bin/biome" } }, "sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.14", "", { "os": "linux", "cpu": "x64" }, "sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.14", "", { "os": "linux", "cpu": "x64" }, "sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.14", "", { "os": "win32", "cpu": "x64" }, "sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ=="], + + "@commitlint/cli": ["@commitlint/cli@20.4.1", "", { "dependencies": { "@commitlint/format": "^20.4.0", "@commitlint/lint": "^20.4.1", "@commitlint/load": "^20.4.0", "@commitlint/read": "^20.4.0", "@commitlint/types": "^20.4.0", "tinyexec": "^1.0.0", "yargs": "^17.0.0" }, "bin": { "commitlint": "./cli.js" } }, "sha512-uuFKKpc7OtQM+6SRqT+a4kV818o1pS+uvv/gsRhyX7g4x495jg+Q7P0+O9VNGyLXBYP0syksS7gMRDJKcekr6A=="], + + "@commitlint/config-conventional": ["@commitlint/config-conventional@20.4.1", "", { "dependencies": { "@commitlint/types": "^20.4.0", "conventional-changelog-conventionalcommits": "^9.1.0" } }, "sha512-0YUvIeBtpi86XriqrR+TCULVFiyYTIOEPjK7tTRMxjcBm1qlzb+kz7IF2WxL6Fq5DaundG8VO37BNgMkMTBwqA=="], + + "@commitlint/config-validator": ["@commitlint/config-validator@20.4.0", "", { "dependencies": { "@commitlint/types": "^20.4.0", "ajv": "^8.11.0" } }, "sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w=="], + + "@commitlint/ensure": ["@commitlint/ensure@20.4.1", "", { "dependencies": { "@commitlint/types": "^20.4.0", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", "lodash.startcase": "^4.4.0", "lodash.upperfirst": "^4.3.1" } }, "sha512-WLQqaFx1pBooiVvBrA1YfJNFqZF8wS/YGOtr5RzApDbV9tQ52qT5VkTsY65hFTnXhW8PcDfZLaknfJTmPejmlw=="], + + "@commitlint/execute-rule": ["@commitlint/execute-rule@20.0.0", "", {}, "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw=="], + + "@commitlint/format": ["@commitlint/format@20.4.0", "", { "dependencies": { "@commitlint/types": "^20.4.0", "picocolors": "^1.1.1" } }, "sha512-i3ki3WR0rgolFVX6r64poBHXM1t8qlFel1G1eCBvVgntE3fCJitmzSvH5JD/KVJN/snz6TfaX2CLdON7+s4WVQ=="], + + "@commitlint/is-ignored": ["@commitlint/is-ignored@20.4.1", "", { "dependencies": { "@commitlint/types": "^20.4.0", "semver": "^7.6.0" } }, "sha512-In5EO4JR1lNsAv1oOBBO24V9ND1IqdAJDKZiEpdfjDl2HMasAcT7oA+5BKONv1pRoLG380DGPE2W2RIcUwdgLA=="], + + "@commitlint/lint": ["@commitlint/lint@20.4.1", "", { "dependencies": { "@commitlint/is-ignored": "^20.4.1", "@commitlint/parse": "^20.4.1", "@commitlint/rules": "^20.4.1", "@commitlint/types": "^20.4.0" } }, "sha512-g94LrGl/c6UhuhDQqNqU232aslLEN2vzc7MPfQTHzwzM4GHNnEAwVWWnh0zX8S5YXecuLXDwbCsoGwmpAgPWKA=="], + + "@commitlint/load": ["@commitlint/load@20.4.0", "", { "dependencies": { "@commitlint/config-validator": "^20.4.0", "@commitlint/execute-rule": "^20.0.0", "@commitlint/resolve-extends": "^20.4.0", "@commitlint/types": "^20.4.0", "cosmiconfig": "^9.0.0", "cosmiconfig-typescript-loader": "^6.1.0", "is-plain-obj": "^4.1.0", "lodash.mergewith": "^4.6.2", "picocolors": "^1.1.1" } }, "sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A=="], + + "@commitlint/message": ["@commitlint/message@20.4.0", "", {}, "sha512-B5lGtvHgiLAIsK5nLINzVW0bN5hXv+EW35sKhYHE8F7V9Uz1fR4tx3wt7mobA5UNhZKUNgB/+ldVMQE6IHZRyA=="], + + "@commitlint/parse": ["@commitlint/parse@20.4.1", "", { "dependencies": { "@commitlint/types": "^20.4.0", "conventional-changelog-angular": "^8.1.0", "conventional-commits-parser": "^6.2.1" } }, "sha512-XNtZjeRcFuAfUnhYrCY02+mpxwY4OmnvD3ETbVPs25xJFFz1nRo/25nHj+5eM+zTeRFvWFwD4GXWU2JEtoK1/w=="], + + "@commitlint/read": ["@commitlint/read@20.4.0", "", { "dependencies": { "@commitlint/top-level": "^20.4.0", "@commitlint/types": "^20.4.0", "git-raw-commits": "^4.0.0", "minimist": "^1.2.8", "tinyexec": "^1.0.0" } }, "sha512-QfpFn6/I240ySEGv7YWqho4vxqtPpx40FS7kZZDjUJ+eHxu3azfhy7fFb5XzfTqVNp1hNoI3tEmiEPbDB44+cg=="], + + "@commitlint/resolve-extends": ["@commitlint/resolve-extends@20.4.0", "", { "dependencies": { "@commitlint/config-validator": "^20.4.0", "@commitlint/types": "^20.4.0", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0" } }, "sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g=="], + + "@commitlint/rules": ["@commitlint/rules@20.4.1", "", { "dependencies": { "@commitlint/ensure": "^20.4.1", "@commitlint/message": "^20.4.0", "@commitlint/to-lines": "^20.0.0", "@commitlint/types": "^20.4.0" } }, "sha512-WtqypKEPbQEuJwJS4aKs0OoJRBKz1HXPBC9wRtzVNH68FLhPWzxXlF09hpUXM9zdYTpm4vAdoTGkWiBgQ/vL0g=="], + + "@commitlint/to-lines": ["@commitlint/to-lines@20.0.0", "", {}, "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw=="], + + "@commitlint/top-level": ["@commitlint/top-level@20.4.0", "", { "dependencies": { "escalade": "^3.2.0" } }, "sha512-NDzq8Q6jmFaIIBC/GG6n1OQEaHdmaAAYdrZRlMgW6glYWGZ+IeuXmiymDvQNXPc82mVxq2KiE3RVpcs+1OeDeA=="], + + "@commitlint/types": ["@commitlint/types@20.4.0", "", { "dependencies": { "conventional-commits-parser": "^6.2.1", "picocolors": "^1.1.1" } }, "sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.2", "", { "os": "android", "cpu": "arm64" }, "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.2", "", { "os": "android", "cpu": "x64" }, "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.2", "", { "os": "linux", "cpu": "arm" }, "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.2", "", { "os": "linux", "cpu": "x64" }, "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.2", "", { "os": "none", "cpu": "x64" }, "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="], + + "@iconify-json/mdi": ["@iconify-json/mdi@1.2.3", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg=="], + + "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], + + "@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="], + + "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="], + + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], + + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], + + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], + + "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], + + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], + + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], + + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], + + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + + "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], + + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], + + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], + + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], + + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], + + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], + + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], + + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@oozcitak/dom": ["@oozcitak/dom@1.15.10", "", { "dependencies": { "@oozcitak/infra": "1.0.8", "@oozcitak/url": "1.0.4", "@oozcitak/util": "8.3.8" } }, "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ=="], + + "@oozcitak/infra": ["@oozcitak/infra@1.0.8", "", { "dependencies": { "@oozcitak/util": "8.3.8" } }, "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg=="], + + "@oozcitak/url": ["@oozcitak/url@1.0.4", "", { "dependencies": { "@oozcitak/infra": "1.0.8", "@oozcitak/util": "8.3.8" } }, "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw=="], + + "@oozcitak/util": ["@oozcitak/util@8.3.8", "", {}, "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ=="], + + "@parcel/watcher": ["@parcel/watcher@2.5.6", "", { "dependencies": { "detect-libc": "^2.0.3", "is-glob": "^4.0.3", "node-addon-api": "^7.0.0", "picomatch": "^4.0.3" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.6", "@parcel/watcher-darwin-arm64": "2.5.6", "@parcel/watcher-darwin-x64": "2.5.6", "@parcel/watcher-freebsd-x64": "2.5.6", "@parcel/watcher-linux-arm-glibc": "2.5.6", "@parcel/watcher-linux-arm-musl": "2.5.6", "@parcel/watcher-linux-arm64-glibc": "2.5.6", "@parcel/watcher-linux-arm64-musl": "2.5.6", "@parcel/watcher-linux-x64-glibc": "2.5.6", "@parcel/watcher-linux-x64-musl": "2.5.6", "@parcel/watcher-win32-arm64": "2.5.6", "@parcel/watcher-win32-ia32": "2.5.6", "@parcel/watcher-win32-x64": "2.5.6" } }, "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ=="], + + "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.6", "", { "os": "android", "cpu": "arm64" }, "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A=="], + + "@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA=="], + + "@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg=="], + + "@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.6", "", { "os": "freebsd", "cpu": "x64" }, "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng=="], + + "@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.6", "", { "os": "linux", "cpu": "arm" }, "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ=="], + + "@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.6", "", { "os": "linux", "cpu": "arm" }, "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg=="], + + "@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA=="], + + "@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA=="], + + "@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ=="], + + "@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg=="], + + "@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q=="], + + "@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.6", "", { "os": "win32", "cpu": "ia32" }, "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g=="], + + "@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.6", "", { "os": "win32", "cpu": "x64" }, "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw=="], + + "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.1", "", { "os": "android", "cpu": "arm" }, "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.1", "", { "os": "android", "cpu": "arm64" }, "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.57.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.57.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.57.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.57.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.57.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.57.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.57.1", "", { "os": "none", "cpu": "arm64" }, "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.57.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.57.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA=="], + + "@shikijs/core": ["@shikijs/core@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA=="], + + "@shikijs/langs": ["@shikijs/langs@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA=="], + + "@shikijs/themes": ["@shikijs/themes@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g=="], + + "@shikijs/types": ["@shikijs/types@3.22.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + + "@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.8", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA=="], + + "@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.10", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew=="], + + "@sveltejs/kit": ["@sveltejs/kit@2.50.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.6.2", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-875hTUkEbz+MyJIxWbQjfMaekqdmEKUUfR7JyKcpfMRZqcGyrO9Gd+iS1D/Dx8LpE5FEtutWGOtlAh4ReSAiOA=="], + + "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@6.2.4", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "deepmerge": "^4.3.1", "magic-string": "^0.30.21", "obug": "^2.1.0", "vitefu": "^1.1.1" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA=="], + + "@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@5.0.2", "", { "dependencies": { "obug": "^2.1.0" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig=="], + + "@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="], + + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/node": ["@types/node@25.2.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], + + "array-ify": ["array-ify@1.0.0", "", {}, "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng=="], + + "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], + + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], + + "confbox": ["confbox@0.2.4", "", {}, "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ=="], + + "conventional-changelog-angular": ["conventional-changelog-angular@8.1.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w=="], + + "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@9.1.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-MnbEysR8wWa8dAEvbj5xcBgJKQlX/m0lhS8DsyAAWDHdfs2faDJxTgzRYlRYpXSe7UiKrIIlB4TrBKU9q9DgkA=="], + + "conventional-commits-parser": ["conventional-commits-parser@6.2.1", "", { "dependencies": { "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA=="], + + "cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="], + + "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], + + "cosmiconfig-typescript-loader": ["cosmiconfig-typescript-loader@6.2.0", "", { "dependencies": { "jiti": "^2.6.1" }, "peerDependencies": { "@types/node": "*", "cosmiconfig": ">=9", "typescript": ">=5" } }, "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ=="], + + "dargs": ["dargs@8.1.0", "", {}, "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "devalue": ["devalue@5.6.2", "", {}, "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], + + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], + + "esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + + "esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="], + + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + + "esrap": ["esrap@2.2.2", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-zA6497ha+qKvoWIK+WM9NAh5ni17sKZKhbS5B3PoYbBvaYHZWoS33zmFybmyqpn07RLUxSmn+RCls2/XF+d0oQ=="], + + "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-glob": ["fast-glob@3.3.3", "", { "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.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + + "fault": ["fault@2.0.1", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "format": ["format@0.2.2", "", {}, "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "git-raw-commits": ["git-raw-commits@4.0.0", "", { "dependencies": { "dargs": "^8.0.0", "meow": "^12.0.1", "split2": "^4.0.0" }, "bin": { "git-raw-commits": "cli.mjs" } }, "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ=="], + + "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], + + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="], + + "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="], + + "hast-util-heading-rank": ["hast-util-heading-rank@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA=="], + + "hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="], + + "hast-util-sanitize": ["hast-util-sanitize@5.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "unist-util-position": "^5.0.0" } }, "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "immutable": ["immutable@5.1.4", "", {}, "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], + + "ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="], + + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + + "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], + + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="], + + "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], + + "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], + + "lefthook": ["lefthook@2.1.0", "", { "optionalDependencies": { "lefthook-darwin-arm64": "2.1.0", "lefthook-darwin-x64": "2.1.0", "lefthook-freebsd-arm64": "2.1.0", "lefthook-freebsd-x64": "2.1.0", "lefthook-linux-arm64": "2.1.0", "lefthook-linux-x64": "2.1.0", "lefthook-openbsd-arm64": "2.1.0", "lefthook-openbsd-x64": "2.1.0", "lefthook-windows-arm64": "2.1.0", "lefthook-windows-x64": "2.1.0" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-+vS+yywGQW6CN1J1hbGkez//6ixGHIQqfxDN/d3JDm531w9GfGt2lAWTDfZTw/CEl80XsN0raFcnEraR3ldw9g=="], + + "lefthook-darwin-arm64": ["lefthook-darwin-arm64@2.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-u2hjHLQXWSFfzO7ln2n/uEydSzfC9sc5cDC7tvKSuOdhvBwaJ0AQ7ZeuqqCQ4YfVIJfYOom1SVE9CBd10FVyig=="], + + "lefthook-darwin-x64": ["lefthook-darwin-x64@2.1.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-zz5rcyrtOZpxon7uE+c0KC/o2ypJeLZql5CL0Y9oaTuECbmhfokm8glsGnyWstW/++PuMpZYYr/qsCJA5elxkQ=="], + + "lefthook-freebsd-arm64": ["lefthook-freebsd-arm64@2.1.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-+mXNCNuFHNGYLrDqYWDeHH7kWCLCJFPpspx5PAAm+PD37PRMZJrTqDbaNK9qCghC1tdmT4/Lvilf/ewXHPlaKw=="], + + "lefthook-freebsd-x64": ["lefthook-freebsd-x64@2.1.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-+AU2HD7szuDsUdHue/E3OnF84B2ae/h7CGKpuIUHJntgoJ4kxf89oDvq2/xl8kDCn9cT76UUjgeZUgFYLRj+6Q=="], + + "lefthook-linux-arm64": ["lefthook-linux-arm64@2.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-KM70eV1tsEib1/tk+3TFxIdH84EaYlIg5KTQWAg+LB1N23nTQ7lL4Dnh1je6f6KW4tf21nmoMUqsh0xvMkQk8Q=="], + + "lefthook-linux-x64": ["lefthook-linux-x64@2.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-6Bxmv+l7LiYq9W0IE6v2lmlRtBp6pisnlzhcouMGvH3rDwEGw11NAyRJZA3IPGEMAkIuhnlnVTUwAUzKomfJLg=="], + + "lefthook-openbsd-arm64": ["lefthook-openbsd-arm64@2.1.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-ppJNK0bBSPLC8gqksRw5zI/0uLeMA5cK+hmZ4ofcuGNmdrN1dfl2Tx84fdeef0NcQY0ii9Y3j3icIKngIoid/g=="], + + "lefthook-openbsd-x64": ["lefthook-openbsd-x64@2.1.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-8k9lQsMYqQGu4spaQ8RNSOJidxIcOyfaoF2FPZhthtBfRV3cgVFGrsQ0hbIi5pvQRGUlCqYuCN79qauXHmnL3Q=="], + + "lefthook-windows-arm64": ["lefthook-windows-arm64@2.1.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-0WN+grrxt9zP9NGRcztoPXcz25tteem91rfLWgQFab+50csJ47zldlsB7/eOS/eHG5mUg5g5NPR4XefnXtjOcQ=="], + + "lefthook-windows-x64": ["lefthook-windows-x64@2.1.0", "", { "os": "win32", "cpu": "x64" }, "sha512-XbO/5nAZQLpUn0tPpgCYfFBFJHnymSglQ73jD6wymNrR1j8I5EcXGlP6YcLhnZ83yzsdLC+gup+N6IqUeiyRdw=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "local-pkg": ["local-pkg@1.1.2", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", "quansync": "^0.2.11" } }, "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A=="], + + "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], + + "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="], + + "lodash.kebabcase": ["lodash.kebabcase@4.1.1", "", {}, "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="], + + "lodash.mergewith": ["lodash.mergewith@4.6.2", "", {}, "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="], + + "lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="], + + "lodash.startcase": ["lodash.startcase@4.4.0", "", {}, "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg=="], + + "lodash.upperfirst": ["lodash.upperfirst@4.3.1", "", {}, "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], + + "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], + + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="], + + "mdast-util-frontmatter": ["mdast-util-frontmatter@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "escape-string-regexp": "^5.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-extension-frontmatter": "^2.0.0" } }, "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA=="], + + "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], + + "mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="], + + "mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="], + + "mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="], + + "mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "markdown-table": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="], + + "mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="], + + "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], + + "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "mdsvex": ["mdsvex@0.12.6", "", { "dependencies": { "@types/mdast": "^4.0.4", "@types/unist": "^2.0.3", "prism-svelte": "^0.4.7", "prismjs": "^1.17.1", "unist-util-visit": "^2.0.1", "vfile-message": "^2.0.4" }, "peerDependencies": { "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" } }, "sha512-pupx2gzWh3hDtm/iDW4WuCpljmyHbHi34r7ktOqpPGvyiM4MyfNgdJ3qMizXdgCErmvYC9Nn/qyjePy+4ss9Wg=="], + + "meow": ["meow@12.1.1", "", {}, "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], + + "micromark-extension-frontmatter": ["micromark-extension-frontmatter@2.0.0", "", { "dependencies": { "fault": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg=="], + + "micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="], + + "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="], + + "micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="], + + "micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="], + + "micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="], + + "micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="], + + "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="], + + "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], + + "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "minisearch": ["minisearch@7.2.0", "", {}, "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg=="], + + "mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="], + + "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="], + + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + + "oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="], + + "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="], + + "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], + + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], + + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + + "prism-svelte": ["prism-svelte@0.4.7", "", {}, "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ=="], + + "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], + + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + + "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + + "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + + "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "rehype-autolink-headings": ["rehype-autolink-headings@7.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-heading-rank": "^3.0.0", "hast-util-is-element": "^3.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw=="], + + "rehype-sanitize": ["rehype-sanitize@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-sanitize": "^5.0.0" } }, "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg=="], + + "rehype-slug": ["rehype-slug@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "github-slugger": "^2.0.0", "hast-util-heading-rank": "^3.0.0", "hast-util-to-string": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A=="], + + "remark-frontmatter": ["remark-frontmatter@5.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-frontmatter": "^2.0.0", "micromark-extension-frontmatter": "^2.0.0", "unified": "^11.0.0" } }, "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ=="], + + "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], + + "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], + + "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], + + "sass": ["sass@1.97.3", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg=="], + + "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], + + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "set-cookie-parser": ["set-cookie-parser@3.0.1", "", {}, "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q=="], + + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + + "shiki": ["shiki@3.22.0", "", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/engine-javascript": "3.22.0", "@shikijs/engine-oniguruma": "3.22.0", "@shikijs/langs": "3.22.0", "@shikijs/themes": "3.22.0", "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g=="], + + "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], + + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="], + + "svelte": ["svelte@5.49.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.2", "esm-env": "^1.2.1", "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-jj95WnbKbXsXXngYj28a4zx8jeZx50CN/J4r0CEeax2pbfdsETv/J1K8V9Hbu3DCXnpHz5qAikICuxEooi7eNQ=="], + + "svelte-check": ["svelte-check@4.3.6", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-uBkz96ElE3G4pt9E1Tw0xvBfIUQkeH794kDQZdAUk795UVMr+NJZpuFSS62vcmO/DuSalK83LyOwhgWq8YGU1Q=="], + + "svelte-sitemap": ["svelte-sitemap@2.7.1", "", { "dependencies": { "fast-glob": "^3.3.3", "minimist": "^1.2.8", "xmlbuilder2": "^3.1.1" }, "bin": { "svelte-sitemap": "index.js" } }, "sha512-9b6GAoaBZde3CCDvmfoDvRWLPAXeawg8MlcXyMmbf8Iu1HEOvVockagu+PiOhaKmyJE3Q9tnIZLaXlMdkfTxHA=="], + + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], + + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], + + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + + "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@2.0.3", "", { "dependencies": { "@types/unist": "^2.0.2" } }, "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="], + + "unplugin-icons": ["unplugin-icons@23.0.1", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/utils": "^3.1.0", "local-pkg": "^1.1.2", "obug": "^2.1.1", "unplugin": "^2.3.11" }, "peerDependencies": { "@svgr/core": ">=7.0.0", "@svgx/core": "^1.0.1", "@vue/compiler-sfc": "^3.0.2", "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["@svgr/core", "@svgx/core", "@vue/compiler-sfc", "svelte"] }, "sha512-rv0XEJepajKzDLvRUWASM8K+8+/CCfZn2jtogXqg6RIp7kpatRc/aFrVJn8ANQA09e++lPEEv9yX8cC9enc+QQ=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@2.0.4", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" } }, "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ=="], + + "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], + + "vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], + + "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], + + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "xmlbuilder2": ["xmlbuilder2@3.1.1", "", { "dependencies": { "@oozcitak/dom": "1.15.10", "@oozcitak/infra": "1.0.8", "@oozcitak/util": "8.3.8", "js-yaml": "3.14.1" } }, "sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "zimmerframe": ["zimmerframe@1.1.4", "", {}, "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "conventional-commits-parser/meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], + + "cosmiconfig/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "mdast-util-from-markdown/unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "mdsvex/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + + "mdsvex/unist-util-visit": ["unist-util-visit@2.0.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } }, "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q=="], + + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + + "unist-util-stringify-position/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + + "vfile/vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "vfile-message/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + + "cosmiconfig/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "mdsvex/unist-util-visit/unist-util-is": ["unist-util-is@4.1.0", "", {}, "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg=="], + + "mdsvex/unist-util-visit/unist-util-visit-parents": ["unist-util-visit-parents@3.1.1", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" } }, "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg=="], + + "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + + "vfile/vfile-message/unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + } +} diff --git a/commitlint.config.cjs b/commitlint.config.cjs new file mode 100644 index 0000000..4c73b71 --- /dev/null +++ b/commitlint.config.cjs @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], +}; diff --git a/docs/revanced-development/0_prerequisites.md b/docs/Development/0_prerequisites.md similarity index 92% rename from docs/revanced-development/0_prerequisites.md rename to docs/Development/0_prerequisites.md index ef61242..a3a8fdb 100644 --- a/docs/revanced-development/0_prerequisites.md +++ b/docs/Development/0_prerequisites.md @@ -8,6 +8,8 @@ Certain requirements are needed to be able to develop with ReVanced. - Java Development Kit 17 (e.g. [OpenJDK](https://jdk.java.net/archive/)) - Knowledge of Git, Gradle and how to set up and use multi-module Gradle projects +![Prerequisites setup overview screenshot](./aa.png) + ## ⏭️ Whats next The next section explains, how to set up a suitable development environment for ReVanced with [IntelliJ IDEA](https://www.jetbrains.com/idea/) diff --git a/docs/revanced-development/1_setup.md b/docs/Development/1_setup.md similarity index 100% rename from docs/revanced-development/1_setup.md rename to docs/Development/1_setup.md diff --git a/docs/revanced-development/README.md b/docs/Development/README.md similarity index 100% rename from docs/revanced-development/README.md rename to docs/Development/README.md diff --git a/docs/Development/aa.png b/docs/Development/aa.png new file mode 100644 index 0000000..54f54b1 Binary files /dev/null and b/docs/Development/aa.png differ diff --git a/docs/revanced-resources/questions.md b/docs/Resources/questions.md similarity index 100% rename from docs/revanced-resources/questions.md rename to docs/Resources/questions.md diff --git a/docs/revanced-resources/troubleshooting.md b/docs/Resources/troubleshooting.md similarity index 96% rename from docs/revanced-resources/troubleshooting.md rename to docs/Resources/troubleshooting.md index fde253a..42622d9 100644 --- a/docs/revanced-resources/troubleshooting.md +++ b/docs/Resources/troubleshooting.md @@ -82,7 +82,7 @@ Enable [Android Auto developer mode](https://developer.android.com/training/cars ## 32 YouTube or YouTube Music playback does not work -First ensure you are using the latest patches. You may be using outdated patches even if the app version has not changed. See [here](https://github.com/ReVanced/revanced-documentation/blob/main/docs/revanced-resources/questions.md#14-how-to-update-patched-apps) for additional information on updating. +First ensure you are using the latest patches. You may be using outdated patches even if the app version has not changed. See [here](questions.md#14-how-to-update-patched-apps) for additional information on updating. Search for existing issues [here](https://github.com/ReVanced/revanced-patches/issues?q=is%3Aissue%20state%3Aopen) as all known issues will have an existing issue. diff --git a/docs/revanced-cli b/docs/cli similarity index 100% rename from docs/revanced-cli rename to docs/cli diff --git a/docs/revanced-manager b/docs/manager similarity index 100% rename from docs/revanced-manager rename to docs/manager diff --git a/docs/revanced-patcher b/docs/patcher similarity index 100% rename from docs/revanced-patcher rename to docs/patcher diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..0848fd2 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,13 @@ +pre-commit: + parallel: true + commands: + check: + files: git diff --name-only --cached --diff-filter=AM + glob: "*.{js,ts,json}" + run: bunx biome check {files} + +commit-msg: + parallel: false + commands: + commitlint: + run: bunx commitlint --edit diff --git a/package.json b/package.json new file mode 100644 index 0000000..ab2d3d1 --- /dev/null +++ b/package.json @@ -0,0 +1,53 @@ +{ + "name": "revanced-documentation", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "generate:docs": "bun scripts/generate-docs-graph.ts", + "dev": "bunx --bun svelte-kit sync && bunx --bun vite dev", + "build:all": "bun run generate:docs && bun run build:llms && bun run build && bun run build:sitemap", + "build": "bunx --bun svelte-kit sync && bunx --bun vite build", + "build:llms": "bun scripts/build-llms.ts", + "build:sitemap": "bun scripts/build-sitemap.ts", + "preview": "bunx --bun vite preview", + "flint": "biome check --write .", + "flint:check": "biome check .", + "clint": "commitlint --edit" + }, + "devDependencies": { + "@biomejs/biome": "^2.3.14", + "@commitlint/cli": "^20.4.1", + "@commitlint/config-conventional": "^20.4.1", + "@iconify-json/mdi": "^1.2.3", + "@sveltejs/kit": "^2.50.1", + "@sveltejs/vite-plugin-svelte": "^6.2.4", + "fast-glob": "^3.3.3", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "lefthook": "^2.1.0", + "mdast-util-to-string": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "svelte": "^5.48.2", + "svelte-check": "^4.3.5", + "typescript": "^5.9.3", + "unist-util-visit": "^5.1.0", + "unplugin-icons": "^23.0.1", + "vite": "^7.3.1" + }, + "dependencies": { + "@sveltejs/adapter-static": "^3.0.10", + "mdsvex": "^0.12.6", + "minisearch": "^7.2.0", + "rehype-autolink-headings": "^7.1.0", + "rehype-sanitize": "^6.0.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "sass": "^1.97.3", + "sharp": "^0.34.5", + "shiki": "^3.22.0", + "svelte-sitemap": "^2.7.1", + "unified": "^11.0.5" + } +} diff --git a/scripts/build-llms.ts b/scripts/build-llms.ts new file mode 100644 index 0000000..8ad58ed --- /dev/null +++ b/scripts/build-llms.ts @@ -0,0 +1,73 @@ +import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; +import matter from 'gray-matter'; +import { DOCS_DIR, SITE_DESCRIPTION, SITE_TITLE } from '../site.config.js'; +import type { DocsGraph } from '../src/lib/core/types'; + +interface LlmsSourceDocument { + content: string; + includeInLlms: boolean; +} + +function parseLlmsSource(rawMarkdown: string): LlmsSourceDocument { + const parsed = matter(rawMarkdown); + const includeInLlms = parsed.data?.llms !== false; + return { + content: parsed.content.trim(), + includeInLlms, + }; +} + +function buildLlmsDocument( + graph: DocsGraph, + options: { title: string; description: string }, + readSourceMarkdown: (sourcePath: string) => string, +): string { + const docsByRoute = new Map(graph.docs.map((doc) => [doc.routePath, doc])); + const parts: string[] = [`# ${options.title}`, '', options.description, '']; + + for (const section of graph.sections) { + const sectionParts: string[] = []; + + for (const routePath of section.pages) { + const doc = docsByRoute.get(routePath); + if (!doc) { + throw new Error(`Missing docs graph node for route '${routePath}'`); + } + + const source = parseLlmsSource(readSourceMarkdown(doc.sourcePath)); + if (!source.includeInLlms || !source.content) { + continue; + } + + sectionParts.push(`### ${doc.title}`, `Source: ${doc.routePath}`, '', source.content, ''); + } + + if (sectionParts.length === 0) { + continue; + } + + parts.push('---', `## ${section.title}`, '', ...sectionParts); + } + + return `${parts.join('\n').trimEnd()}\n`; +} + +const graphPath = join(process.cwd(), '.svelte-kit/generated/docs-graph.json'); +const graph = JSON.parse(readFileSync(graphPath, 'utf-8')) as DocsGraph; + +const llmsDocument = buildLlmsDocument( + graph, + { + title: SITE_TITLE, + description: SITE_DESCRIPTION, + }, + (sourcePath) => { + const sourceAbsolutePath = join(process.cwd(), DOCS_DIR, sourcePath); + return readFileSync(sourceAbsolutePath, 'utf-8'); + }, +); + +const outDir = join(process.cwd(), 'build'); +mkdirSync(outDir, { recursive: true }); +writeFileSync(join(outDir, 'llms.txt'), llmsDocument); diff --git a/scripts/build-sitemap.ts b/scripts/build-sitemap.ts new file mode 100644 index 0000000..a16cccc --- /dev/null +++ b/scripts/build-sitemap.ts @@ -0,0 +1,3 @@ +import { SITE_URL } from '../site.config.js'; + +await Bun.$`bunx svelte-sitemap --domain ${SITE_URL}`; diff --git a/scripts/generate-docs-graph.ts b/scripts/generate-docs-graph.ts new file mode 100644 index 0000000..61cfca4 --- /dev/null +++ b/scripts/generate-docs-graph.ts @@ -0,0 +1,939 @@ +import { + existsSync, + mkdirSync, + readFileSync, + realpathSync, + statSync, + writeFileSync, +} from 'node:fs'; +import path from 'node:path'; +import fg from 'fast-glob'; +import GithubSlugger from 'github-slugger'; +import matter from 'gray-matter'; +import type { Heading, Image, Link, Root, RootContent } from 'mdast'; +import { toString as mdastToString } from 'mdast-util-to-string'; +import MiniSearch from 'minisearch'; +import remarkFrontmatter from 'remark-frontmatter'; +import remarkGfm from 'remark-gfm'; +import remarkParse from 'remark-parse'; +import sharp from 'sharp'; +import { unified } from 'unified'; +import { visit } from 'unist-util-visit'; +import { + DOCS_DIR, + DOCS_SECTIONS, + GITHUB_EDIT_BASE_URL, + HEADER_BUTTONS, + LOGO_ASSET_PATH, + ORG_NAME, + SITE_DESCRIPTION, + SITE_NAME, + SITE_THEME_COLOR, + SITE_TITLE, + SITE_URL, +} from '../site.config.js'; +import { + type ParsedDocHref, + parseLocalAssetHref, + parseMarkdownDocHref, + resolveDocRelativePath, +} from '../src/lib/core/href-utils'; +import type { + DocNode, + DocsGraph, + SearchSection, + SectionNode, + TableOfContentsHeading, +} from '../src/lib/core/types'; + +const SEARCH_SETTINGS = { + fuzzy: 0.15, + prefix: true, + combineWith: 'AND' as const, + snippetMaxLength: 140, + snippetContextChars: 40, + ellipsis: '...', + highlightTag: 'mark', + maxIndexTextLength: 600, +}; + +const GENERATED_DIR = '.svelte-kit/generated'; +const DOCS_GRAPH_PATH = `${GENERATED_DIR}/docs-graph.json`; +const DOCS_RUNTIME_GRAPH_PATH = `${GENERATED_DIR}/docs-runtime-graph.json`; +const SEARCH_INDEX_PATH = `${GENERATED_DIR}/search-index.json`; +const SITE_PUBLIC_CONFIG_PATH = `${GENERATED_DIR}/site-public.json`; +const ROOT_SECTION_ID = '_root'; + +interface SearchDoc { + id: number; + title: string; + section: string; + sectionId: string; + sectionIcon: string; + url: string; + anchor: string; + text: string; +} + +interface TempDocNode { + doc: DocNode; + parsedLinks: ParsedDocHref[]; + parsedAssets: ParsedDocHref[]; + headingAnchors: Set; +} + +interface ValidationReporter { + report: (message: string) => void; + assertNoIssues: () => void; +} + +interface FrontmatterInput { + title?: unknown; + description?: unknown; + sidebar?: unknown; + sidebar_label?: unknown; + sidebar_position?: unknown; + sidebar_order?: unknown; + slug?: unknown; +} + +function hasOwnSection(sectionId: string): boolean { + return Object.hasOwn(DOCS_SECTIONS, sectionId); +} + +function resolveSectionId(dirName: string): string { + return dirName !== ROOT_SECTION_ID && hasOwnSection(dirName) ? dirName : ROOT_SECTION_ID; +} + +function getSectionConfig(sectionId: string) { + const section = DOCS_SECTIONS[sectionId as keyof typeof DOCS_SECTIONS]; + invariant(Boolean(section), `Missing section definition for '${sectionId}'`); + return section; +} + +function compareSectionOrder(a: string, b: string): number { + return getSectionConfig(a).order - getSectionConfig(b).order; +} + +const parseProcessor = unified().use(remarkParse).use(remarkGfm).use(remarkFrontmatter, ['yaml']); + +function invariant(condition: boolean, message: string): asserts condition { + if (!condition) throw new Error(message); +} + +function isInsideDirectory(root: string, candidate: string): boolean { + const relative = path.relative(root, candidate); + return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative)); +} + +function resolveAndAssertWorkspacePath(cwd: string, absolutePath: string): string { + const resolvedPath = realpathSync(absolutePath); + invariant( + isInsideDirectory(cwd, resolvedPath), + `Resolved path points outside workspace: ${absolutePath} -> ${resolvedPath}`, + ); + return resolvedPath; +} + +async function readImageMetadata( + absolutePath: string, +): Promise<{ width: number; height: number } | null> { + try { + const metadata = await sharp(absolutePath).metadata(); + if ( + typeof metadata.width === 'number' && + typeof metadata.height === 'number' && + metadata.width > 0 && + metadata.height > 0 + ) { + return { + width: metadata.width, + height: metadata.height, + }; + } + } catch (error) { + if (process.env.DEBUG_DOCS_GRAPH === '1') { + console.warn( + `[docs-graph] Failed to read image metadata for '${absolutePath}':`, + error instanceof Error ? error.message : String(error), + ); + } + } + + return null; +} + +function normalizeToPosix(filePath: string): string { + return filePath.replace(/\\/g, '/'); +} + +function stripMarkdownExtension(filePath: string): string { + return filePath.replace(/\.md$/i, ''); +} + +function slugify(value: string): string { + return value + .normalize('NFKD') + .replace(/[\u0300-\u036f]/g, '') + .replace(/[^\p{L}\p{N}\s_-]/gu, '') + .trim() + .toLowerCase() + .replace(/[_\s]+/g, '-') + .replace(/-{2,}/g, '-') + .replace(/^-|-$/g, ''); +} + +function slugifyPath(value: string, sourcePath: string): string { + const normalized = value.replace(/^\/+|\/+$/g, ''); + invariant(normalized.length > 0, `Invalid empty slug override in '${sourcePath}'`); + + const segments = normalized.split('/').filter(Boolean); + const slugSegments: string[] = []; + for (const segment of segments) { + const slugged = slugify(segment); + invariant( + slugged.length > 0, + `Slug segment '${segment}' in '${sourcePath}' produced an empty slug (contains only special characters or emoji)`, + ); + slugSegments.push(slugged); + } + + const slug = slugSegments.join('/'); + invariant(slug.length > 0, `Invalid slug generated from '${value}' in '${sourcePath}'`); + return slug; +} + +function titleCase(value: string): string { + return value.replace(/[_-]/g, ' ').replace(/\b\w/g, (char) => char.toUpperCase()); +} + +function walkMarkdown(dir: string): string[] { + if (!existsSync(dir)) return []; + return fg + .sync('**/*.md', { + cwd: dir, + absolute: true, + onlyFiles: true, + followSymbolicLinks: true, + }) + .sort((a, b) => a.localeCompare(b)); +} + +function walkAssets(dir: string): string[] { + if (!existsSync(dir)) return []; + return fg + .sync('**/*', { + cwd: dir, + absolute: true, + onlyFiles: true, + followSymbolicLinks: true, + ignore: ['**/*.md'], + }) + .sort((a, b) => a.localeCompare(b)); +} + +function toPlainText(root: Root): string { + return mdastToString(root).replace(/\s+/g, ' ').trim(); +} + +function deriveDocLocation( + sourcePath: string, + slugOverride: string | null, +): { + sectionId: string; + contentSlug: string; + slug: string; + routePath: string; + category: string; +} { + const withoutExt = stripMarkdownExtension(sourcePath); + const parts = withoutExt.split('/').filter(Boolean); + invariant(parts.length > 0, `Invalid docs path: ${sourcePath}`); + + let sectionId = ROOT_SECTION_ID; + let contentSlug: string; + let category = ''; + + if (parts.length === 1) { + contentSlug = parts[0]; + } else { + const topLevelDir = parts[0]; + sectionId = resolveSectionId(topLevelDir); + + if (sectionId === ROOT_SECTION_ID) { + contentSlug = parts.join('/'); + category = topLevelDir; + } else { + contentSlug = parts.slice(1).join('/'); + category = parts.length === 2 ? '' : parts.slice(1, -1).join(' / '); + } + } + + const slugSource = slugOverride ?? contentSlug; + const slug = slugifyPath(slugSource, sourcePath); + const routePath = sectionId === ROOT_SECTION_ID ? `/${slug}` : `/${sectionId}/${slug}`; + + return { + sectionId, + contentSlug, + slug, + routePath, + category, + }; +} + +function extractFrontmatter( + raw: string, + sourcePath: string, +): { + body: string; + title: string | null; + sidebarLabel: string | null; + sidebarOrder: number | null; + description: string | null; + slug: string | null; +} { + const parsed = matter(raw); + const data = (parsed.data ?? {}) as FrontmatterInput; + + const sidebar = + data.sidebar && typeof data.sidebar === 'object' + ? (data.sidebar as Record) + : null; + + const title = typeof data.title === 'string' ? data.title.trim() : null; + const sidebarLabel = + (typeof sidebar?.label === 'string' + ? sidebar.label + : typeof data.sidebar_label === 'string' + ? data.sidebar_label + : null + )?.trim() ?? null; + const description = typeof data.description === 'string' ? data.description.trim() : null; + const slug = typeof data.slug === 'string' ? data.slug.trim() : null; + + let sidebarOrder: number | null = null; + const sidebarOrderRaw = sidebar?.order ?? data.sidebar_position ?? data.sidebar_order; + if (typeof sidebarOrderRaw === 'number' && Number.isFinite(sidebarOrderRaw)) { + sidebarOrder = sidebarOrderRaw; + } else if (typeof sidebarOrderRaw === 'string' && sidebarOrderRaw.trim() !== '') { + const numeric = Number(sidebarOrderRaw); + if (!Number.isFinite(numeric)) { + throw new Error( + `Invalid sidebar order in ${sourcePath}: expected a number, got ${JSON.stringify(sidebarOrderRaw)}`, + ); + } + sidebarOrder = numeric; + } + + return { + body: parsed.content, + title, + sidebarLabel, + sidebarOrder, + description, + slug, + }; +} + +function headingText(heading: Heading): string { + return mdastToString(heading).replace(/\s+/g, ' ').trim(); +} + +function headingSlugText(heading: Heading): string { + return mdastToString(heading); +} + +function extractHeadingsAndSections( + root: Root, + sourcePath: string, +): { + headings: TableOfContentsHeading[]; + searchSections: SearchSection[]; + headingAnchors: string[]; +} { + const slugger = new GithubSlugger(); + const headings: TableOfContentsHeading[] = []; + const headingIds = new Set(); + + const searchSections: SearchSection[] = []; + let currentHeading = ''; + let currentAnchor = ''; + let currentNodes: RootContent[] = []; + + const flush = () => { + if (currentNodes.length === 0 && currentHeading === '') return; + + const sectionRoot: Root = { type: 'root', children: currentNodes }; + const text = toPlainText(sectionRoot); + if (text) { + searchSections.push({ + heading: currentHeading, + anchor: currentAnchor, + text, + }); + } + }; + + for (const node of root.children) { + if (node.type === 'heading') { + flush(); + + const title = headingText(node); + const id = slugger.slug(headingSlugText(node)); + invariant(!headingIds.has(id), `Duplicate heading id '${id}' detected in '${sourcePath}'`); + headingIds.add(id); + + if (node.depth >= 2 && node.depth <= 6) { + headings.push({ + id, + title, + level: node.depth, + }); + } + + currentHeading = title; + currentAnchor = id; + currentNodes = []; + continue; + } + + currentNodes.push(node); + } + + flush(); + + return { headings, searchSections, headingAnchors: [...headingIds] }; +} + +function extractInternalLinks(root: Root): ParsedDocHref[] { + const links: ParsedDocHref[] = []; + visit(root, 'link', (node) => { + const link = node as Link; + if (typeof link.url !== 'string') return; + + const parsed = parseMarkdownDocHref(link.url); + if (parsed) links.push(parsed); + }); + + return links; +} + +function extractInternalAssets(root: Root): ParsedDocHref[] { + const assets: ParsedDocHref[] = []; + visit(root, 'image', (node) => { + const image = node as Image; + if (typeof image.url !== 'string') return; + + const parsed = parseLocalAssetHref(image.url); + if (parsed) assets.push(parsed); + }); + + return assets; +} + +function buildEditUrl(sectionId: string, sourcePath: string): string { + const section = getSectionConfig(sectionId); + const repo = section.repo; + if (sectionId === ROOT_SECTION_ID) { + return `${GITHUB_EDIT_BASE_URL}/${repo.name}/edit/${repo.branch}/${repo.docsPath}/${sourcePath}`; + } + + invariant( + sourcePath.startsWith(`${sectionId}/`), + `Source path '${sourcePath}' does not match section prefix '${sectionId}/'`, + ); + const repoRelativePath = sourcePath.slice(sectionId.length + 1); + return `${GITHUB_EDIT_BASE_URL}/${repo.name}/edit/${repo.branch}/${repo.docsPath}/${repoRelativePath}`; +} + +function extractPrimaryTitle(root: Root): string | null { + for (const node of root.children) { + if (node.type === 'heading' && node.depth === 1) { + const title = headingText(node); + if (title) return title; + } + } + return null; +} + +function decodeAnchor(hash: string): string { + try { + return decodeURIComponent(hash); + } catch { + return hash; + } +} + +async function collectAssets( + cwd: string, + docsDir: string, +): Promise<{ knownAssetPaths: Set; assetMetadata: DocsGraph['assetMetadata'] }> { + const assetFiles = walkAssets(docsDir); + const knownAssetPaths = new Set(); + const assetMetadata: DocsGraph['assetMetadata'] = {}; + + await Promise.all( + assetFiles.map(async (filePath) => { + const workspaceRealPath = resolveAndAssertWorkspacePath(cwd, filePath); + const sourcePath = normalizeToPosix(path.relative(docsDir, filePath)); + knownAssetPaths.add(sourcePath); + const metadata = await readImageMetadata(workspaceRealPath); + if (metadata) { + assetMetadata[sourcePath] = metadata; + } + }), + ); + + return { knownAssetPaths, assetMetadata }; +} + +function parseMarkdownFiles(cwd: string, docsDir: string): TempDocNode[] { + const markdownFiles = walkMarkdown(docsDir); + const temporaryDocs: TempDocNode[] = []; + const routeToSource = new Map(); + const sourceToRoute = new Map(); + + for (const filePath of markdownFiles) { + const workspaceRealFilePath = resolveAndAssertWorkspacePath(cwd, filePath); + const rawFile = readFileSync(filePath, 'utf-8'); + const relativePath = normalizeToPosix(path.relative(docsDir, filePath)); + const workspacePath = normalizeToPosix(path.relative(cwd, filePath)); + const workspaceRealPath = normalizeToPosix(path.relative(cwd, workspaceRealFilePath)); + + const frontmatter = extractFrontmatter(rawFile, relativePath); + const { sectionId, contentSlug, slug, routePath, category } = deriveDocLocation( + relativePath, + frontmatter.slug, + ); + const root = parseProcessor.parse(frontmatter.body) as Root; + const extracted = extractHeadingsAndSections(root, relativePath); + + const sourceWithoutExt = stripMarkdownExtension(relativePath); + const fileName = path.basename(sourceWithoutExt); + const pageTitle = frontmatter.title ?? extractPrimaryTitle(root) ?? titleCase(fileName); + const sidebarLabel = frontmatter.sidebarLabel ?? pageTitle; + + const routeConflict = routeToSource.get(routePath); + invariant( + !routeConflict, + `Duplicate route path '${routePath}' for '${relativePath}' and '${routeConflict}'`, + ); + routeToSource.set(routePath, relativePath); + + const sourceConflict = sourceToRoute.get(relativePath); + invariant(!sourceConflict, `Duplicate source path '${relativePath}'`); + sourceToRoute.set(relativePath, routePath); + + temporaryDocs.push({ + doc: { + sourcePath: relativePath, + workspacePath, + workspaceRealPath, + sectionId, + sectionTitle: getSectionConfig(sectionId).label, + contentSlug, + slug, + routePath, + category, + title: pageTitle, + sidebarLabel, + sidebarOrder: frontmatter.sidebarOrder, + description: frontmatter.description, + headings: extracted.headings, + searchSections: extracted.searchSections, + plainText: toPlainText(root), + editUrl: buildEditUrl(sectionId, relativePath), + }, + parsedLinks: extractInternalLinks(root), + parsedAssets: extractInternalAssets(root), + headingAnchors: new Set(extracted.headingAnchors), + }); + } + + return temporaryDocs; +} + +function createValidationReporter(): ValidationReporter { + const issues: string[] = []; + return { + report(message: string) { + issues.push(message); + }, + assertNoIssues() { + if (issues.length === 0) { + return; + } + throw new Error(issues.join('\n')); + }, + }; +} + +function validateReferences( + temporaryDocs: TempDocNode[], + knownAssetPaths: Set, + reporter: ValidationReporter, +): void { + const docsBySourcePath = new Map( + temporaryDocs.map((tempDoc) => [tempDoc.doc.sourcePath, tempDoc]), + ); + + for (const tempDoc of temporaryDocs) { + for (const link of tempDoc.parsedLinks) { + let resolvedSourcePath: string; + try { + resolvedSourcePath = resolveDocRelativePath(tempDoc.doc.sourcePath, link.targetPath); + } catch (error) { + reporter.report( + `Invalid markdown link in '${tempDoc.doc.sourcePath}': '${link.fullHref}' (${error instanceof Error ? error.message : String(error)})`, + ); + continue; + } + + const targetDoc = docsBySourcePath.get(resolvedSourcePath); + if (!targetDoc) { + reporter.report( + `Unresolved markdown link in '${tempDoc.doc.sourcePath}': '${link.fullHref}' resolves to '${resolvedSourcePath}'`, + ); + continue; + } + + if (link.hash) { + const targetAnchor = decodeAnchor(link.hash); + if (!targetDoc.headingAnchors.has(targetAnchor)) { + reporter.report( + `Unresolved markdown anchor in '${tempDoc.doc.sourcePath}': '${link.fullHref}' points to missing '#${targetAnchor}' in '${resolvedSourcePath}'`, + ); + } + } + } + + for (const asset of tempDoc.parsedAssets) { + let resolvedAssetPath: string; + try { + resolvedAssetPath = resolveDocRelativePath(tempDoc.doc.sourcePath, asset.targetPath); + } catch (error) { + reporter.report( + `Invalid image link in '${tempDoc.doc.sourcePath}': '${asset.fullHref}' (${error instanceof Error ? error.message : String(error)})`, + ); + continue; + } + + if (!knownAssetPaths.has(resolvedAssetPath)) { + reporter.report( + `Unresolved image link in '${tempDoc.doc.sourcePath}': '${asset.fullHref}' resolves to '${resolvedAssetPath}'`, + ); + } + } + } +} + +function organizeSections(temporaryDocs: TempDocNode[]): { + docs: DocNode[]; + sections: SectionNode[]; +} { + const docsBySection = new Map(); + for (const tempDoc of temporaryDocs) { + const sectionDocs = docsBySection.get(tempDoc.doc.sectionId); + if (sectionDocs) { + sectionDocs.push(tempDoc.doc); + continue; + } + docsBySection.set(tempDoc.doc.sectionId, [tempDoc.doc]); + } + + const orderedSectionIds = Object.keys(DOCS_SECTIONS) + .filter((sectionId) => docsBySection.has(sectionId)) + .sort(compareSectionOrder); + + const docs: DocNode[] = []; + const sections: SectionNode[] = []; + + for (const sectionId of orderedSectionIds) { + const sectionDocs = docsBySection.get(sectionId); + invariant(sectionDocs !== undefined, `Missing section docs for '${sectionId}'`); + sectionDocs.sort((a, b) => { + const aOrder = a.sidebarOrder ?? Number.POSITIVE_INFINITY; + const bOrder = b.sidebarOrder ?? Number.POSITIVE_INFINITY; + if (aOrder !== bOrder) return aOrder - bOrder; + return a.routePath.localeCompare(b.routePath); + }); + + docs.push(...sectionDocs); + + const sectionDef = getSectionConfig(sectionId); + sections.push({ + id: sectionId, + title: sectionDef.label, + order: sectionDef.order, + basePath: sectionId === ROOT_SECTION_ID ? '' : sectionId, + isPageAnchor: sectionId !== ROOT_SECTION_ID, + icon: sectionDef.icon, + pages: sectionDocs.map((doc) => doc.routePath), + }); + } + + return { docs, sections }; +} + +async function buildDocsGraph(cwd = process.cwd()): Promise { + const docsDir = path.join(cwd, DOCS_DIR); + + const [{ knownAssetPaths, assetMetadata }, temporaryDocs] = await Promise.all([ + collectAssets(cwd, docsDir), + Promise.resolve(parseMarkdownFiles(cwd, docsDir)), + ]); + + const reporter = createValidationReporter(); + validateReferences(temporaryDocs, knownAssetPaths, reporter); + reporter.assertNoIssues(); + + const { docs, sections } = organizeSections(temporaryDocs); + + return { + generatedAt: new Date().toISOString(), + docs, + sections, + assets: [...knownAssetPaths].sort((a, b) => a.localeCompare(b)), + assetMetadata, + }; +} + +const cwd = process.cwd(); +const graphOutputPath = path.join(cwd, DOCS_GRAPH_PATH); +const runtimeGraphOutputPath = path.join(cwd, DOCS_RUNTIME_GRAPH_PATH); +const searchIndexOutputPath = path.join(cwd, SEARCH_INDEX_PATH); +const sitePublicConfigOutputPath = path.join(cwd, SITE_PUBLIC_CONFIG_PATH); +const docsDir = path.join(cwd, DOCS_DIR); +const repoAssetsDir = path.join(cwd, 'assets'); +const configPath = path.resolve(cwd, 'site.config.ts'); +const force = process.argv.includes('--force'); + +const outputFiles = [ + graphOutputPath, + runtimeGraphOutputPath, + searchIndexOutputPath, + sitePublicConfigOutputPath, +]; + +function assertInsideWorkspace(targetPath: string): void { + const relative = path.relative(cwd, targetPath); + if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) { + return; + } + throw new Error(`Refusing to write outside workspace: ${targetPath}`); +} + +function writeJsonFile(outputPath: string, value: unknown): void { + assertInsideWorkspace(outputPath); + mkdirSync(path.dirname(outputPath), { recursive: true }); + writeFileSync(outputPath, `${JSON.stringify(value, null, 2)}\n`, 'utf-8'); +} + +function getLatestMtimeMs(paths: string[]): number { + let latest = 0; + for (const filePath of paths) { + if (!existsSync(filePath)) { + continue; + } + const mtimeMs = statSync(filePath).mtimeMs; + if (mtimeMs > latest) { + latest = mtimeMs; + } + } + return latest; +} + +function toWorkspaceRealPath(absolutePath: string): string { + const realPath = realpathSync(absolutePath); + assertInsideWorkspace(realPath); + return realPath; +} + +function collectGenerationInputs(): string[] { + const docsFiles = existsSync(docsDir) + ? fg.sync('**/*', { + cwd: docsDir, + absolute: true, + onlyFiles: true, + followSymbolicLinks: true, + }) + : []; + const docsDirectories = existsSync(docsDir) + ? [ + docsDir, + ...fg.sync('**/*', { + cwd: docsDir, + absolute: true, + onlyDirectories: true, + followSymbolicLinks: true, + }), + ] + : []; + + const repoAssetFiles = existsSync(repoAssetsDir) + ? fg.sync('**/*', { + cwd: repoAssetsDir, + absolute: true, + onlyFiles: true, + followSymbolicLinks: true, + }) + : []; + const repoAssetDirectories = existsSync(repoAssetsDir) + ? [ + repoAssetsDir, + ...fg.sync('**/*', { + cwd: repoAssetsDir, + absolute: true, + onlyDirectories: true, + followSymbolicLinks: true, + }), + ] + : []; + + const scriptFiles = [ + path.resolve(cwd, 'scripts/generate-docs-graph.ts'), + path.resolve(cwd, 'scripts/build-llms.ts'), + path.resolve(cwd, 'src/lib/core/href-utils.ts'), + configPath, + ] + .filter(existsSync) + .map(toWorkspaceRealPath); + + return [ + ...new Set([ + ...docsFiles.map(toWorkspaceRealPath), + ...docsDirectories.map(toWorkspaceRealPath), + ...repoAssetFiles.map(toWorkspaceRealPath), + ...repoAssetDirectories.map(toWorkspaceRealPath), + ...scriptFiles, + ]), + ]; +} + +function isGenerationUpToDate(): boolean { + for (const outputPath of outputFiles) { + if (!existsSync(outputPath)) { + return false; + } + } + + const inputs = collectGenerationInputs(); + if (inputs.length === 0) { + return false; + } + + const newestInput = getLatestMtimeMs(inputs); + if (newestInput === 0) { + return false; + } + + const oldestOutput = Math.min(...outputFiles.map((outputPath) => statSync(outputPath).mtimeMs)); + return oldestOutput >= newestInput; +} + +function buildSearchIndex(currentGraph: DocsGraph): string { + const sectionIconMap = new Map( + currentGraph.sections.map((section) => [section.id, section.icon]), + ); + const docs: SearchDoc[] = []; + let nextId = 1; + + for (const doc of currentGraph.docs) { + const sectionIcon = sectionIconMap.get(doc.sectionId) ?? ''; + + if (doc.searchSections.length === 0) { + if (!doc.plainText) continue; + docs.push({ + id: nextId++, + title: doc.title, + section: doc.sectionTitle, + sectionId: doc.sectionId, + sectionIcon, + url: doc.routePath, + anchor: '', + text: doc.plainText.slice(0, SEARCH_SETTINGS.maxIndexTextLength), + }); + continue; + } + + for (const section of doc.searchSections) { + docs.push({ + id: nextId++, + title: section.heading || doc.title, + section: `${doc.sectionTitle} › ${doc.title}`, + sectionId: doc.sectionId, + sectionIcon, + url: doc.routePath, + anchor: section.anchor, + text: section.text.slice(0, SEARCH_SETTINGS.maxIndexTextLength), + }); + } + } + + const ms = new MiniSearch({ + fields: ['title', 'text', 'section'], + storeFields: ['title', 'section', 'sectionId', 'sectionIcon', 'url', 'anchor', 'text'], + searchOptions: { + boost: { title: 4, section: 2, text: 1 }, + fuzzy: SEARCH_SETTINGS.fuzzy, + prefix: SEARCH_SETTINGS.prefix, + combineWith: SEARCH_SETTINGS.combineWith as 'AND' | 'OR' | 'AND_NOT', + }, + }); + + ms.addAll(docs); + return JSON.stringify(ms); +} + +function buildSitePublicConfig() { + const sectionIcons = Object.fromEntries( + Object.entries(DOCS_SECTIONS).map(([id, section]) => [id, { icon: section.icon }]), + ); + + return { + site: { + name: SITE_NAME, + org: ORG_NAME, + title: SITE_TITLE, + description: SITE_DESCRIPTION, + logoAssetPath: LOGO_ASSET_PATH, + headerButtons: HEADER_BUTTONS, + themeColor: SITE_THEME_COLOR, + }, + sections: sectionIcons, + siteUrl: SITE_URL, + }; +} + +function buildRuntimeDocsGraph(currentGraph: DocsGraph) { + return { + generatedAt: currentGraph.generatedAt, + docs: currentGraph.docs.map((doc) => ({ + sourcePath: doc.sourcePath, + sectionId: doc.sectionId, + sectionTitle: doc.sectionTitle, + contentSlug: doc.contentSlug, + slug: doc.slug, + routePath: doc.routePath, + category: doc.category, + title: doc.title, + sidebarLabel: doc.sidebarLabel, + headings: doc.headings, + editUrl: doc.editUrl, + })), + sections: currentGraph.sections, + }; +} + +if (!force && isGenerationUpToDate()) { + console.log('Docs artifacts are up to date'); + process.exit(0); +} + +const graph = await buildDocsGraph(cwd); + +writeJsonFile(graphOutputPath, graph); +writeJsonFile(runtimeGraphOutputPath, buildRuntimeDocsGraph(graph)); +writeJsonFile(sitePublicConfigOutputPath, buildSitePublicConfig()); +writeFileSync(searchIndexOutputPath, buildSearchIndex(graph), 'utf-8'); diff --git a/site.config.ts b/site.config.ts new file mode 100644 index 0000000..b5161b7 --- /dev/null +++ b/site.config.ts @@ -0,0 +1,79 @@ +export const DOCS_DIR = 'docs'; + +export const SITE_NAME = 'Documentation'; +export const ORG_NAME = 'ReVanced'; +export const SITE_TITLE = `${ORG_NAME} ${SITE_NAME}`; +export const SITE_DESCRIPTION = + 'ReVanced is a modular patcher for Android applications. This documentation covers the ReVanced Patcher, Manager, and CLI.'; +export const LOGO_ASSET_PATH = '/logo.svg'; +export const SITE_THEME_COLOR = '#1a191f'; + +function resolveSiteUrl(): string { + const raw = process.env.SITE_URL_OVERRIDE?.trim() || 'https://docs.revanced.app'; + let parsed: URL; + try { + parsed = new URL(raw); + } catch { + throw new Error(`Invalid SITE_URL_OVERRIDE value '${raw}'`); + } + if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') { + throw new Error(`SITE_URL_OVERRIDE must use http or https, got '${parsed.protocol}'`); + } + const pathname = parsed.pathname.replace(/\/+$/, ''); + return `${parsed.origin}${pathname === '/' ? '' : pathname}`; +} + +export const SITE_URL = resolveSiteUrl(); + +export const HEADER_BUTTONS = [ + { + href: 'https://github.com/ReVanced/revanced-documentation', + label: 'GitHub', + icon: 'github', + }, +]; + +export const GITHUB_EDIT_BASE_URL = 'https://github.com/ReVanced'; + +export const DOCS_SECTIONS = { + _root: { + label: 'General', + order: 0, + icon: 'home', + repo: { + name: 'revanced-documentation', + branch: 'main', + docsPath: 'docs', + }, + }, + patcher: { + label: 'Patcher', + order: 1, + icon: 'hammer', + repo: { + name: 'revanced-patcher', + branch: 'main', + docsPath: 'docs', + }, + }, + manager: { + label: 'Manager', + order: 2, + icon: 'cellphone', + repo: { + name: 'revanced-manager', + branch: 'main', + docsPath: 'docs', + }, + }, + cli: { + label: 'CLI', + order: 3, + icon: 'console', + repo: { + name: 'revanced-cli', + branch: 'main', + docsPath: 'docs', + }, + }, +} as const; diff --git a/src/_tokens.scss b/src/_tokens.scss new file mode 100644 index 0000000..9e22750 --- /dev/null +++ b/src/_tokens.scss @@ -0,0 +1,23 @@ +$bp-desktop: 1200px; +$bp-mobile: 768px; + +$header-height: 56px; +$toc-row-height: 60px; +$sidebar-width: 280px; +$toc-width: 240px; +$content-max-width: 850px; + +$layout-padding: 24px; +$layout-radius: 24px; + +$z-sidebar: 110; +$z-header: 40; +$z-header-mobile: 100; +$z-dropdown: 200; +$z-modal: 9999; +$z-toc: 50; + +$search-debounce-ms: 60; +$search-max-width: 560px; + +$anchor-offset: calc(#{$header-height} + 24px); diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 0000000..0e56cd2 --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,7 @@ +/// + +declare global { + namespace App {} +} + +export {}; diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..9955c0b --- /dev/null +++ b/src/app.html @@ -0,0 +1,21 @@ + + + + + + + + + + %sveltekit.head% + + + + + + + + +
%sveltekit.body%
+ + diff --git a/src/app.scss b/src/app.scss new file mode 100644 index 0000000..c898b94 --- /dev/null +++ b/src/app.scss @@ -0,0 +1,433 @@ +* { + box-sizing: inherit; + margin: 0; + padding: 0; + font-family: var(--main-font); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +html { + margin: 0; + padding: 0; + font-size: 100%; + box-sizing: border-box; + overflow-y: scroll; +} + +[id] { + scroll-margin-top: var(--docs-anchor-offset, 80px); +} + +body { + margin: 0; + padding: 0; + min-height: 100vh; + background-color: var(--background-one); +} + +html, +body { + max-width: 100%; +} + +.wrapper { + margin-inline: auto; + width: min(90%, 80rem); + margin-top: 2.6rem; +} + +:root { + --main-font: 'Manrope', sans-serif; + --mono-font: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; + --docs-anchor-offset: 80px; + + --text-one: hsl(206, 100%, 94%); + --text-ee: hsla(206, 100%, 94%, 60%); + --surface-one: hsl(206, 100%, 94%); + --primary: hsl(206, 100%, 81%); + --secondary: hsl(208, 75%, 82%); + --tertiary: hsla(205, 91%, 69%, 0.15); + + --background-one: hsl(252, 10%, 11%); + --surface-two: hsl(252, 10%, 11%); + --surface-three: hsl(210, 14%, 17%); + --surface-four: hsl(212, 19%, 19%); + --text-two: hsl(212, 19%, 19%); + --border: hsl(221, 17%, 26%); + --surface-five: hsl(221, 17%, 26%); + --text-three: hsl(226, 48%, 18%); + --text-four: hsl(208, 30%, 75%); + --surface-six: hsl(208, 30%, 75%); + --surface-seven: hsl(230, 9%, 13%); + --surface-eight: hsl(240, 9%, 13.5%); + --surface-nine: hsl(230, 9.5%, 17.5%); + + --red-one: hsl(333, 84%, 62%); + --red-two: hsl(357, 74%, 60%); + --red-three: hsl(2, 68%, 83%); + --yellow-one: hsl(59, 100%, 72%); + + --bezier-one: ease-out; + --drop-shadow-one: 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12), + 0px 2px 4px -1px rgba(0, 0, 0, 0.2); +} + +::selection { + background-color: var(--tertiary); +} + +.spinner { + display: inline-block; + width: var(--spinner-size, 18px); + height: var(--spinner-size, 18px); + border: 2px solid rgba(255, 255, 255, 0.2); + border-top-color: var(--primary); + border-radius: 50%; + animation: spinner-rotate 0.9s linear infinite; +} + +@keyframes spinner-rotate { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +.img-placeholder-wrapper { + position: relative; + display: inline-block; + overflow: hidden; + border-radius: 8px; + line-height: 0; + max-width: 100%; + border: 1px solid var(--border); + background-color: var(--surface-seven); +} + +.img-placeholder-wrapper .img-spinner { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 0; +} + +.img-placeholder-wrapper img { + position: relative; + z-index: 1; + display: block; + width: 100%; + height: auto; + object-fit: cover; +} + +mark { + background-color: var(--secondary); +} + +h1 { + color: var(--text-one); + line-height: 4rem; + font-size: 3.5rem; + font-weight: 700; + letter-spacing: -0.025em; +} + +h2 { + color: var(--text-four); + font-size: 2.5rem; + letter-spacing: -0.04rem; + font-weight: 600; +} + +h3 { + font-size: 1.25rem; + color: var(--secondary); + font-weight: 600; +} + +h4 { + color: var(--secondary); + font-weight: 400; + font-size: 1rem; + letter-spacing: 0.02rem; + line-height: 2rem; +} + +h5 { + color: var(--text-four); + font-weight: 400; + font-size: 0.9rem; + letter-spacing: 0.02rem; +} + +h6 { + color: var(--text-four); + font-weight: 500; + font-size: 0.85rem; +} + +h2, h3, h4, h5, h6 { + position: relative; + + .heading-anchor { + text-decoration: none; + margin-left: 0.35em; + opacity: 0; + } + + &:hover .heading-anchor { + opacity: 1; + } + + .heading-anchor-icon { + color: var(--primary); + font-weight: 400; + + text-decoration: none; + transition: none; + font-size: 0.8em; + } +} + +p { + color: var(--text-four); + font-weight: 400; + font-size: 1rem; + letter-spacing: 0.02rem; + line-height: 1.75rem; +} + +@media (max-width: 768px) { + h1 { + font-size: 2.6rem; + line-height: 3.75rem; + } + + h2 { + font-size: 2rem; + } +} + +::-webkit-scrollbar { + width: 5px; + height: 5px; + background-color: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: var(--primary); + background-clip: content-box; + border-radius: 100px; +} + +::-webkit-scrollbar-thumb:hover { + background-color: var(--surface-five); +} + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid var(--border); +} + +textarea { + resize: vertical; + field-sizing: content; +} + +input, +textarea { + padding: 1rem; + border-radius: 12px; + border: 1px solid var(--border); + background-color: transparent; + color: var(--secondary); +} + +input:focus, +textarea:focus { + outline: 1px solid var(--primary); +} + +.docs-content { + .markdown-content > h1:first-child { + display: none; + } + + .markdown-content > h2:first-of-type { + margin-top: 0; + } + + h1 { + font-size: 2.25rem; + font-weight: 700; + color: var(--text-one); + margin-bottom: 1rem; + line-height: 1.2; + } + + h2 { + font-size: 1.5rem; + font-weight: 600; + color: var(--text-one); + margin-top: 2.5rem; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 1px solid var(--tertiary); + } + + h3 { + font-size: 1.25rem; + font-weight: 600; + color: var(--text-one); + margin-top: 2rem; + margin-bottom: 0.75rem; + } + + h4, h5, h6 { + font-size: 1rem; + font-weight: 600; + color: var(--text-one); + margin-top: 1.5rem; + margin-bottom: 0.5rem; + } + + p { + color: var(--text-four); + line-height: 1.7; + margin-bottom: 1rem; + } + + a { + color: var(--primary); + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &.heading-anchor { + text-decoration: none; + } + + &.nav-card { + text-decoration: none; + color: inherit; + + &:hover { + text-decoration: none; + color: inherit; + } + } + } + + ul, ol { + color: var(--text-four); + margin-bottom: 1rem; + padding-left: 1.5rem; + } + + li { + margin-bottom: 0.5rem; + line-height: 1.6; + } + + code { + font-family: var(--mono-font); + background-color: var(--surface-three); + padding: 0.2em 0.4em; + border-radius: 4px; + font-size: 0.875em; + color: var(--primary); + } + + pre { + margin: 1.5rem 0; + border-radius: 8px; + overflow-x: auto; + } + + pre code { + background: transparent; + padding: 0; + font-size: 0.875rem; + color: inherit; + } + + .shiki { + padding: 1rem 1.25rem; + border-radius: 8px; + overflow-x: auto; + } + + table { + width: 100%; + border-collapse: separate; + border-spacing: 0; + margin: 1.5rem 0; + border: 1px solid var(--border); + border-radius: 12px; + overflow: hidden; + } + + th, td { + padding: 0.75rem 1rem; + text-align: left; + border-bottom: 1px solid var(--tertiary); + color: var(--text-four); + } + + tr:last-child td { + border-bottom: none; + } + + th { + font-weight: 600; + color: var(--text-one); + background-color: var(--surface-three); + } + + blockquote { + border-left: 4px solid var(--primary); + margin: 1.5rem 0; + padding: 1rem 1.5rem; + background-color: var(--tertiary); + border-radius: 0 8px 8px 0; + + p { + margin: 0; + color: var(--text-one); + } + } + + hr { + border: none; + border-top: 1px solid var(--tertiary); + margin: 2rem 0; + } + + strong { + font-weight: 600; + color: var(--text-one); + } + + img { + max-width: 100%; + height: auto; + border-radius: 8px; + } + + picture { + display: inline-block; + max-width: 100%; + } + + .img-placeholder-wrapper { + display: inline-block; + position: relative; + overflow: hidden; + border-radius: 8px; + line-height: 0; + max-width: 100%; + } +} diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte new file mode 100644 index 0000000..07fc86f --- /dev/null +++ b/src/lib/components/Button.svelte @@ -0,0 +1,111 @@ + + +{#if href && !disabled} + + {#if icon} + {@render icon()} + {/if} + {@render children()} + +{:else} + +{/if} + + diff --git a/src/lib/components/CopyCode.svelte b/src/lib/components/CopyCode.svelte new file mode 100644 index 0000000..39a59c3 --- /dev/null +++ b/src/lib/components/CopyCode.svelte @@ -0,0 +1,111 @@ + + +
+ {@render children()} +
+ + diff --git a/src/lib/components/PageAnchor.svelte b/src/lib/components/PageAnchor.svelte new file mode 100644 index 0000000..9339d96 --- /dev/null +++ b/src/lib/components/PageAnchor.svelte @@ -0,0 +1,100 @@ + + + +
+ {@render children()} +
+ {title} +
+ + \ No newline at end of file diff --git a/src/lib/components/SearchBar.svelte b/src/lib/components/SearchBar.svelte new file mode 100644 index 0000000..d5e7ae1 --- /dev/null +++ b/src/lib/components/SearchBar.svelte @@ -0,0 +1,564 @@ + + +{#snippet searchIcon(size: number)} + + {#if !indexReady && !indexError} + + {:else} + + {/if} + +{/snippet} + +{#snippet searchInput(size: number)} + 0 || query.trim().length > 0 || Boolean(indexError))} + /> +{/snippet} + +{#if mode === 'modal'} + +{:else} +
+
+ {@render searchIcon(18)} + {@render searchInput(14)} + {#if query} + + {/if} +
+ + {#if showDropdown && (indexError || (query.trim() && (results.length > 0 || hasSearched)))} +
+ {#if indexError} +
{indexError}
+ {:else} + (selectedIndex = i)} + /> + {/if} +
+ {/if} +
+{/if} + + diff --git a/src/lib/components/SearchResult.svelte b/src/lib/components/SearchResult.svelte new file mode 100644 index 0000000..bb4683d --- /dev/null +++ b/src/lib/components/SearchResult.svelte @@ -0,0 +1,111 @@ + + + + + diff --git a/src/lib/components/SearchResults.svelte b/src/lib/components/SearchResults.svelte new file mode 100644 index 0000000..f4ad3a6 --- /dev/null +++ b/src/lib/components/SearchResults.svelte @@ -0,0 +1,66 @@ + + +{#if results.length > 0} +
+ {#each results as hit, i} + onselect(hit)} + onhover={() => onhover(i)} + /> + {/each} +
+{:else if query.trim() && hasSearched} +
No results found for "{query}"
+{:else if showHint && !query.trim()} +
Start typing to search the documentation
+{/if} + + diff --git a/src/lib/components/SegmentedButton.svelte b/src/lib/components/SegmentedButton.svelte new file mode 100644 index 0000000..bb76585 --- /dev/null +++ b/src/lib/components/SegmentedButton.svelte @@ -0,0 +1,38 @@ + + +
+ {@render children()} +
+ + diff --git a/src/lib/components/Separator.svelte b/src/lib/components/Separator.svelte new file mode 100644 index 0000000..df0197b --- /dev/null +++ b/src/lib/components/Separator.svelte @@ -0,0 +1,25 @@ + + +
+ + \ No newline at end of file diff --git a/src/lib/components/Spinner.svelte b/src/lib/components/Spinner.svelte new file mode 100644 index 0000000..8fc751c --- /dev/null +++ b/src/lib/components/Spinner.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/config.ts b/src/lib/config.ts new file mode 100644 index 0000000..28f1e0d --- /dev/null +++ b/src/lib/config.ts @@ -0,0 +1,45 @@ +import type { Component } from 'svelte'; +import rawSitePublicConfig from '$generated/site-public.json'; +import type { SitePublicConfig } from '$lib/core/types'; +import IconCellphone from '~icons/mdi/cellphone'; +import IconConsole from '~icons/mdi/console'; +import IconGithub from '~icons/mdi/github'; +import IconHammer from '~icons/mdi/hammer'; +import IconHelpCircleOutline from '~icons/mdi/help-circle-outline'; +import IconHome from '~icons/mdi/home'; + +const config = rawSitePublicConfig as SitePublicConfig; + +export const SITE_URL = config.siteUrl; + +export const SITE_NAME = config.site.name; +export const ORG_NAME = config.site.org; +export const SITE_TITLE = config.site.title; +export const SITE_DESCRIPTION = config.site.description; +export const LOGO_ASSET_PATH = config.site.logoAssetPath; +export const HEADER_BUTTONS = config.site.headerButtons ?? []; +export const SITE_THEME_COLOR = config.site.themeColor; + +type IconComponent = Component<{ width?: number | string; height?: number | string }>; + +const iconComponents: Record = { + home: IconHome, + hammer: IconHammer, + cellphone: IconCellphone, + console: IconConsole, + github: IconGithub, + 'help-circle-outline': IconHelpCircleOutline, +}; + +const fallbackIcon: IconComponent = IconHelpCircleOutline; + +export const sectionIcons: Record = Object.fromEntries( + Object.entries(config.sections).map(([sectionId, section]) => [ + sectionId, + iconComponents[section.icon] ?? fallbackIcon, + ]), +); + +export function getIconComponent(name: string): IconComponent { + return iconComponents[name] ?? fallbackIcon; +} diff --git a/src/lib/core/graph.ts b/src/lib/core/graph.ts new file mode 100644 index 0000000..63f3205 --- /dev/null +++ b/src/lib/core/graph.ts @@ -0,0 +1,96 @@ +import rawGraph from '$generated/docs-runtime-graph.json'; +import type { RuntimeDocNode, RuntimeDocsGraph } from '$lib/core/types'; + +function invariant(condition: boolean, message: string): asserts condition { + if (!condition) { + throw new Error(message); + } +} + +function validateDocsGraph(input: unknown): RuntimeDocsGraph { + invariant(Boolean(input) && typeof input === 'object', 'Invalid docs runtime graph payload'); + + const graph = input as RuntimeDocsGraph; + invariant(Array.isArray(graph.docs), 'docs runtime graph is missing docs[]'); + invariant(Array.isArray(graph.sections), 'docs runtime graph is missing sections[]'); + + const sectionIds = new Set(); + for (const section of graph.sections) { + invariant( + typeof section.id === 'string' && section.id.length > 0, + 'Section id must be a non-empty string', + ); + invariant( + !sectionIds.has(section.id), + `Duplicate section id '${section.id}' in docs runtime graph`, + ); + sectionIds.add(section.id); + } + + const routePaths = new Set(); + for (const doc of graph.docs) { + invariant( + typeof doc.routePath === 'string' && doc.routePath.startsWith('/'), + `Invalid routePath for ${doc.sourcePath}`, + ); + invariant( + typeof doc.sourcePath === 'string' && doc.sourcePath.endsWith('.md'), + `Invalid sourcePath for ${doc.routePath}`, + ); + invariant( + sectionIds.has(doc.sectionId), + `Unknown section id '${doc.sectionId}' in docs runtime graph`, + ); + invariant( + !routePaths.has(doc.routePath), + `Duplicate route path '${doc.routePath}' in docs runtime graph`, + ); + routePaths.add(doc.routePath); + } + + const knownRoutes = new Set(graph.docs.map((doc) => doc.routePath)); + for (const section of graph.sections) { + for (const routePath of section.pages) { + invariant( + knownRoutes.has(routePath), + `Section '${section.id}' references unknown route '${routePath}'`, + ); + } + } + + return graph; +} + +let cached: { + graph: RuntimeDocsGraph; + byRoutePath: Map; + bySourcePath: Map; +} | null = null; + +function ensureLoaded() { + if (cached) return cached; + + const graph = validateDocsGraph(rawGraph); + cached = { + graph, + byRoutePath: new Map(graph.docs.map((doc) => [doc.routePath, doc])), + bySourcePath: new Map(graph.docs.map((doc) => [doc.sourcePath, doc])), + }; + return cached; +} + +export function getDocsGraph(): RuntimeDocsGraph { + return ensureLoaded().graph; +} + +export function getDocBySourcePath(sourcePath: string): RuntimeDocNode | undefined { + return ensureLoaded().bySourcePath.get(sourcePath); +} + +export function getDocByRoutePath(routePath: string): RuntimeDocNode | undefined { + return ensureLoaded().byRoutePath.get(routePath); +} + +export function getAllDocRoutes(): string[] { + return ensureLoaded().graph.docs.map((doc) => doc.routePath); +} diff --git a/src/lib/core/href-utils.ts b/src/lib/core/href-utils.ts new file mode 100644 index 0000000..ea7c598 --- /dev/null +++ b/src/lib/core/href-utils.ts @@ -0,0 +1,107 @@ +import path from 'node:path'; + +export interface ParsedDocHref { + fullHref: string; + targetPath: string; + hash: string; + query: string; +} + +export function normalizePath(value: string): string { + return value.replace(/\\/g, '/'); +} + +export function splitHref(href: string): { pathname: string; query: string; hash: string } { + let pathname = href; + let query = ''; + let hash = ''; + + const hashIndex = pathname.indexOf('#'); + if (hashIndex >= 0) { + hash = pathname.slice(hashIndex + 1); + pathname = pathname.slice(0, hashIndex); + } + + const queryIndex = pathname.indexOf('?'); + if (queryIndex >= 0) { + query = pathname.slice(queryIndex + 1); + pathname = pathname.slice(0, queryIndex); + } + + return { pathname, query, hash }; +} + +export function isExternalHref(href: string): boolean { + if (href.startsWith('//')) return true; + try { + const parsed = new URL(href); + return parsed.protocol.length > 0; + } catch { + return false; + } +} + +export function parseMarkdownDocHref(href: string): ParsedDocHref | null { + if (href.startsWith('#') || isExternalHref(href)) { + return null; + } + + const { pathname, query, hash } = splitHref(href); + if (!pathname) { + return null; + } + + const extension = path.posix.extname(pathname).toLowerCase(); + if (extension && extension !== '.md') { + return null; + } + + let targetPath = pathname; + if (!extension) { + targetPath = pathname.endsWith('/') ? `${pathname}README.md` : `${pathname}.md`; + } + + return { + fullHref: href, + targetPath, + query, + hash, + }; +} + +export function parseLocalAssetHref(href: string): ParsedDocHref | null { + if (href.startsWith('#') || href.startsWith('/') || isExternalHref(href)) { + return null; + } + + const { pathname, query, hash } = splitHref(href); + if (!pathname || pathname.toLowerCase().endsWith('.md')) { + return null; + } + + return { + fullHref: href, + targetPath: pathname, + query, + hash, + }; +} + +export function resolveDocRelativePath(currentSourcePath: string, targetPath: string): string { + const currentDir = path.posix.dirname(currentSourcePath); + const normalized = targetPath.startsWith('/') + ? path.posix.normalize(targetPath.slice(1)) + : path.posix.normalize(path.posix.join(currentDir, targetPath)); + + if (normalized.startsWith('../') || normalized === '..') { + throw new Error(`Relative path escapes docs root: ${targetPath}`); + } + + return normalized; +} + +export function withQueryAndHash(pathname: string, query: string, hash: string): string { + const queryPart = query ? `?${query}` : ''; + const hashPart = hash ? `#${hash}` : ''; + return `${pathname}${queryPart}${hashPart}`; +} diff --git a/src/lib/core/navigation.ts b/src/lib/core/navigation.ts new file mode 100644 index 0000000..e5c5f28 --- /dev/null +++ b/src/lib/core/navigation.ts @@ -0,0 +1,132 @@ +import type { + ClientDocsSection, + DocsPage, + DocsPagination, + DocsPaginationLink, + DocsSection, +} from '$lib/core/types'; +import { getDocByRoutePath, getDocsGraph } from './graph'; + +function routeSlug(routePath: string, basePath: string): string { + if (!basePath) { + return routePath.slice(1); + } + + const prefix = `/${basePath}/`; + if (!routePath.startsWith(prefix)) { + throw new Error(`Route '${routePath}' does not match section base path '${basePath}'`); + } + + return routePath.slice(prefix.length); +} + +function buildSectionPages(section: { basePath: string; pages: string[] }): DocsPage[] { + return section.pages.map((routePath) => { + const doc = getDocByRoutePath(routePath); + if (!doc) { + throw new Error(`Missing doc for route '${routePath}'`); + } + + return { + slug: routeSlug(routePath, section.basePath), + contentSlug: doc.contentSlug, + title: doc.sidebarLabel, + pageTitle: doc.title, + category: doc.category, + routePath: doc.routePath, + sourcePath: doc.sourcePath, + }; + }); +} + +let cached: { + navigation: DocsSection[]; + routeToPageInfo: Map; + paginationByRoute: Map; +} | null = null; + +function ensureBuilt() { + if (cached) return cached; + + const docsGraph = getDocsGraph(); + + const navigation: DocsSection[] = docsGraph.sections.map((section) => ({ + id: section.id, + title: section.title, + basePath: section.basePath, + isPageAnchor: section.isPageAnchor, + icon: section.icon, + order: section.order, + pages: buildSectionPages(section), + })); + + const routeToPageInfo = new Map(); + for (const section of navigation) { + for (const page of section.pages) { + routeToPageInfo.set(page.routePath, { section, page }); + } + } + + const orderedPages: DocsPaginationLink[] = navigation.flatMap((section) => + section.pages.map((page) => ({ + routePath: page.routePath, + title: page.title, + sectionId: section.id, + sectionTitle: section.title, + sectionIcon: section.icon, + })), + ); + + const paginationByRoute = new Map(); + for (let index = 0; index < orderedPages.length; index += 1) { + const current = orderedPages[index]; + if (!current) continue; + + paginationByRoute.set(current.routePath, { + prev: index > 0 ? (orderedPages[index - 1] ?? null) : null, + next: index < orderedPages.length - 1 ? (orderedPages[index + 1] ?? null) : null, + }); + } + + cached = { navigation, routeToPageInfo, paginationByRoute }; + return cached; +} + +function toClientSection(section: DocsSection): ClientDocsSection { + return { + id: section.id, + title: section.title, + basePath: section.basePath, + isPageAnchor: section.isPageAnchor, + icon: section.icon, + order: section.order, + pages: section.pages.map((page) => ({ + title: page.title, + category: page.category, + routePath: page.routePath, + })), + }; +} + +export function getPageInfoByRoutePath( + routePath: string, +): { section: DocsSection; page: DocsPage } | null { + return ensureBuilt().routeToPageInfo.get(routePath) ?? null; +} + +export function getPageInfo(slug: string[]): { section: DocsSection; page: DocsPage } | null { + const routePath = `/${slug.join('/')}`; + return getPageInfoByRoutePath(routePath); +} + +export function getDocsNavigation(): DocsSection[] { + return ensureBuilt().navigation; +} + +export function getClientDocsNavigation(): ClientDocsSection[] { + return ensureBuilt().navigation.map(toClientSection); +} + +export function getPaginationForRoute(routePath: string): DocsPagination { + return ensureBuilt().paginationByRoute.get(routePath) ?? { prev: null, next: null }; +} diff --git a/src/lib/core/route-data.ts b/src/lib/core/route-data.ts new file mode 100644 index 0000000..b54ce3a --- /dev/null +++ b/src/lib/core/route-data.ts @@ -0,0 +1,29 @@ +import { getDocBySourcePath } from '$lib/core/graph'; +import { getPageInfoByRoutePath, getPaginationForRoute } from '$lib/core/navigation'; +import type { DocsRouteData } from '$lib/core/types'; + +export function useDocsRouteData(slug: string[]): DocsRouteData | null { + const routePath = `/${slug.join('/')}`; + const pageInfo = getPageInfoByRoutePath(routePath); + if (!pageInfo) { + return null; + } + + const entry = getDocBySourcePath(pageInfo.page.sourcePath); + if (!entry) { + throw new Error(`Missing docs graph entry for ${pageInfo.page.sourcePath}`); + } + + return { + id: entry.sourcePath, + slug: routePath.slice(1), + routePath, + entry, + section: pageInfo.section, + page: pageInfo.page, + headings: entry.headings, + title: entry.title, + editUrl: entry.editUrl, + pagination: getPaginationForRoute(routePath), + }; +} diff --git a/src/lib/core/types.ts b/src/lib/core/types.ts new file mode 100644 index 0000000..f3bb151 --- /dev/null +++ b/src/lib/core/types.ts @@ -0,0 +1,171 @@ +export type IconName = string; + +export interface SitePublicConfigSite { + name: string; + org: string; + title: string; + description: string; + logoAssetPath: string; + headerButtons?: SitePublicConfigHeaderButton[]; + themeColor: string; +} + +export interface SitePublicConfigHeaderButton { + href: string; + label?: string; + icon?: IconName; +} + +export interface SitePublicConfigSection { + icon: IconName; +} + +export interface SitePublicConfig { + site: SitePublicConfigSite; + sections: Record; + siteUrl: string; +} + +export interface TableOfContentsHeading { + id: string; + title: string; + level: number; +} + +export interface SearchSection { + heading: string; + anchor: string; + text: string; +} + +export interface DocNode { + sourcePath: string; + workspacePath: string; + workspaceRealPath: string; + sectionId: string; + sectionTitle: string; + contentSlug: string; + slug: string; + routePath: string; + category: string; + title: string; + sidebarLabel: string; + sidebarOrder: number | null; + description: string | null; + headings: TableOfContentsHeading[]; + searchSections: SearchSection[]; + plainText: string; + editUrl: string; +} + +export interface RuntimeDocNode { + sourcePath: string; + sectionId: string; + sectionTitle: string; + contentSlug: string; + slug: string; + routePath: string; + category: string; + title: string; + sidebarLabel: string; + headings: TableOfContentsHeading[]; + editUrl: string; +} + +export interface SectionNode { + id: string; + title: string; + order: number; + basePath: string; + isPageAnchor: boolean; + icon: IconName; + pages: string[]; +} + +export interface AssetMetadataEntry { + width: number; + height: number; +} + +export interface DocsGraph { + generatedAt: string; + docs: DocNode[]; + sections: SectionNode[]; + assets: string[]; + assetMetadata: Record; +} + +export interface RuntimeDocsGraph { + generatedAt: string; + docs: RuntimeDocNode[]; + sections: SectionNode[]; +} + +export interface TableOfContentsItem { + id: string; + title: string; + level: number; + children?: TableOfContentsItem[]; +} + +export interface DocsPage { + slug: string; + contentSlug: string; + title: string; + pageTitle: string; + category: string; + routePath: string; + sourcePath: string; +} + +export interface DocsSection { + id: string; + title: string; + basePath: string; + isPageAnchor: boolean; + icon: IconName; + order: number; + pages: DocsPage[]; +} + +export interface ClientDocsPage { + title: string; + category: string; + routePath: string; +} + +export interface ClientDocsSection { + id: string; + title: string; + basePath: string; + isPageAnchor: boolean; + icon: IconName; + order: number; + pages: ClientDocsPage[]; +} + +export interface DocsPaginationLink { + routePath: string; + title: string; + sectionId: string; + sectionTitle: string; + sectionIcon: IconName; +} + +export interface DocsPagination { + prev: DocsPaginationLink | null; + next: DocsPaginationLink | null; +} + +export interface DocsRouteData { + id: string; + slug: string; + routePath: string; + entry: RuntimeDocNode; + section: DocsSection; + page: DocsPage; + headings: TableOfContentsHeading[]; + title: string; + editUrl: string; + pagination: DocsPagination; +} diff --git a/src/lib/layout/DocsHeader.svelte b/src/lib/layout/DocsHeader.svelte new file mode 100644 index 0000000..f4446cd --- /dev/null +++ b/src/lib/layout/DocsHeader.svelte @@ -0,0 +1,82 @@ + + +
+

{title}

+ + {#if showCopyButton} +
+ + + + +
+ {/if} +
+ + diff --git a/src/lib/layout/DocsSidebar.svelte b/src/lib/layout/DocsSidebar.svelte new file mode 100644 index 0000000..f0af00c --- /dev/null +++ b/src/lib/layout/DocsSidebar.svelte @@ -0,0 +1,158 @@ + + + + + diff --git a/src/lib/layout/Header.svelte b/src/lib/layout/Header.svelte new file mode 100644 index 0000000..459f1ef --- /dev/null +++ b/src/lib/layout/Header.svelte @@ -0,0 +1,349 @@ + + + + +{#if mobileSearchOpen} + mobileSearchOpen = false} /> +{/if} + + diff --git a/src/lib/layout/PageNavigation.svelte b/src/lib/layout/PageNavigation.svelte new file mode 100644 index 0000000..cf29fdc --- /dev/null +++ b/src/lib/layout/PageNavigation.svelte @@ -0,0 +1,126 @@ + + +{#if prevPage || nextPage} + +{/if} + + diff --git a/src/lib/layout/SidebarNavList.svelte b/src/lib/layout/SidebarNavList.svelte new file mode 100644 index 0000000..0ac651f --- /dev/null +++ b/src/lib/layout/SidebarNavList.svelte @@ -0,0 +1,124 @@ + + +{#snippet sectionGroups(groups: { category: string; pages: ClientDocsPage[] }[], fallbackLabel?: string)} + {#each groups as group (group.category)} + + {/each} +{/snippet} + + + + diff --git a/src/lib/layout/SidebarPageAnchors.svelte b/src/lib/layout/SidebarPageAnchors.svelte new file mode 100644 index 0000000..e6b6a78 --- /dev/null +++ b/src/lib/layout/SidebarPageAnchors.svelte @@ -0,0 +1,40 @@ + + +
+ {#each sections as section (section.id)} + {@const SectionIcon = sectionIcons[section.id]} + + {#if SectionIcon}{/if} + + {/each} +
+ + diff --git a/src/lib/layout/TableOfContents.svelte b/src/lib/layout/TableOfContents.svelte new file mode 100644 index 0000000..91d224a --- /dev/null +++ b/src/lib/layout/TableOfContents.svelte @@ -0,0 +1,220 @@ + + +{#if items.length > 0} + +{/if} + + diff --git a/src/lib/utils/copy.ts b/src/lib/utils/copy.ts new file mode 100644 index 0000000..8068eaf --- /dev/null +++ b/src/lib/utils/copy.ts @@ -0,0 +1,42 @@ +export async function copyToClipboard(text: string): Promise { + if (navigator.clipboard?.writeText) { + try { + await navigator.clipboard.writeText(text); + return true; + } catch (_error) {} + } + + const ta = Object.assign(document.createElement('textarea'), { + value: text, + style: 'position:fixed;top:0;left:0;opacity:0;pointer-events:none', + }); + document.body.appendChild(ta); + try { + ta.select(); + return document.execCommand('copy'); + } finally { + ta.remove(); + } +} + +export function createCopyStatus(setStatus: (message: string | null) => void, resetMs = 2000) { + let timer: ReturnType | null = null; + + function set(message: string) { + setStatus(message); + if (timer) clearTimeout(timer); + timer = setTimeout(() => { + setStatus(null); + timer = null; + }, resetMs); + } + + function clear() { + if (timer) { + clearTimeout(timer); + timer = null; + } + } + + return { set, clear }; +} diff --git a/src/lib/utils/paths.ts b/src/lib/utils/paths.ts new file mode 100644 index 0000000..424fd8b --- /dev/null +++ b/src/lib/utils/paths.ts @@ -0,0 +1,35 @@ +import { base, resolve } from '$app/paths'; + +function stripTrailingSlash(pathname: string): string { + if (pathname.length <= 1) { + return pathname || '/'; + } + return pathname.replace(/\/+$/, ''); +} + +function normalizedBasePath(): string { + const rawBase = base || '/'; + const basePath = rawBase.startsWith('/') ? rawBase : `/${rawBase}`; + return stripTrailingSlash(basePath); +} + +export function normalizePathname(pathname: string): string { + const normalizedPathname = stripTrailingSlash(pathname || '/'); + const normalizedRootHref = normalizedBasePath(); + + if (normalizedRootHref === '/') { + return normalizedPathname; + } + if (normalizedPathname === normalizedRootHref) { + return '/'; + } + if (normalizedPathname.startsWith(`${normalizedRootHref}/`)) { + return normalizedPathname.slice(normalizedRootHref.length) || '/'; + } + + return normalizedPathname; +} + +export function resolveRoutePath(routePath: string): string { + return resolve(routePath as `/${string}`); +} diff --git a/src/lib/utils/rehype-plugins.ts b/src/lib/utils/rehype-plugins.ts new file mode 100644 index 0000000..841d52d --- /dev/null +++ b/src/lib/utils/rehype-plugins.ts @@ -0,0 +1,277 @@ +import { existsSync, readFileSync, statSync } from 'node:fs'; +import path from 'node:path'; +import type { Element, Root as HastRoot, Parent } from 'hast'; +import { visit } from 'unist-util-visit'; +import type { VFile } from 'vfile'; +import { + normalizePath, + parseLocalAssetHref, + parseMarkdownDocHref, + resolveDocRelativePath, + withQueryAndHash, +} from '../core/href-utils.js'; + +type NodeProperties = Record; + +interface DocsGraphConfig { + docs: Array<{ + sourcePath: string; + routePath: string; + workspacePath: string; + workspaceRealPath: string; + }>; + assets: string[]; + assetMetadata: Record; +} + +interface DocsGraphContext { + sourceToRoute: Record; + filePathToSourcePath: Record; + assetPathSet: Set; + assetMetadataByPath: Record; +} + +function withBasePath(pathname: string, siteBasePath: string): string { + if (!siteBasePath || siteBasePath === '/') { + return pathname; + } + const normalizedBase = siteBasePath.endsWith('/') ? siteBasePath.slice(0, -1) : siteBasePath; + return `${normalizedBase}${pathname}`; +} + +function inferSourcePath( + filePath: string, + filePathToSourcePath: Record, +): string | null { + const normalized = normalizePath(filePath); + const cwdRelative = normalizePath(path.relative(process.cwd(), normalized)); + const candidates = [ + normalized, + normalized.replace(/^\.\//, ''), + cwdRelative, + cwdRelative.replace(/^\.\//, ''), + ]; + + const docsIndex = normalized.lastIndexOf('/docs/'); + if (docsIndex !== -1) { + candidates.push(normalized.slice(docsIndex + '/docs/'.length)); + } + + for (const candidate of candidates) { + const sourcePath = filePathToSourcePath[candidate]; + if (sourcePath) { + return sourcePath; + } + } + + return null; +} + +function getProperties(node: Element): NodeProperties { + if (!node.properties) { + node.properties = {}; + } + return node.properties as NodeProperties; +} + +function parseNumericDimension(value: unknown): number | null { + if (typeof value === 'number' && Number.isFinite(value) && value > 0) { + return value; + } + + if (typeof value !== 'string') { + return null; + } + + const normalized = value.trim().toLowerCase(); + if (!normalized || normalized.endsWith('%')) { + return null; + } + + const numericPart = normalized.endsWith('px') ? normalized.slice(0, -2).trim() : normalized; + const parsed = Number.parseFloat(numericPart); + return Number.isFinite(parsed) && parsed > 0 ? parsed : null; +} + +function createPlaceholderStyle(width: number | null, height: number | null): string | undefined { + if (!width || !height) { + return undefined; + } + + return [ + `width:min(100%,${width}px)`, + `max-width:${width}px`, + `aspect-ratio:${width}/${height}`, + ].join(';'); +} + +function wrapWithImagePlaceholder(node: Element): Element { + const properties = getProperties(node); + const width = parseNumericDimension(properties.width); + const height = parseNumericDimension(properties.height); + const style = createPlaceholderStyle(width, height); + + return { + type: 'element', + tagName: 'span', + properties: { + className: ['img-placeholder-wrapper'], + ...(style ? { style } : {}), + }, + children: [ + { + type: 'element', + tagName: 'span', + properties: { className: ['spinner', 'img-spinner'], 'aria-hidden': 'true' }, + children: [], + }, + node, + ], + }; +} + +interface RehypeDocLinksOptions { + docsGraphPath: string; + siteBasePath: string; + assetsPublicPath: string; +} + +let cachedGraphContext: DocsGraphContext | null = null; +let cachedGraphMtimeMs = -1; + +function loadGraphContext(docsGraphPath: string): DocsGraphContext { + if (!existsSync(docsGraphPath)) { + throw new Error( + `Missing docs graph at ${docsGraphPath}. Start dev/build so docs generation plugin can run.`, + ); + } + + const mtimeMs = statSync(docsGraphPath).mtimeMs; + if (cachedGraphContext && mtimeMs === cachedGraphMtimeMs) { + return cachedGraphContext; + } + + const docsGraph = JSON.parse(readFileSync(docsGraphPath, 'utf-8')) as DocsGraphConfig; + const sourceToRoute = Object.fromEntries( + docsGraph.docs.map((doc) => [doc.sourcePath, doc.routePath]), + ); + const filePathToSourcePath = Object.fromEntries( + docsGraph.docs.flatMap((doc) => [ + [doc.sourcePath, doc.sourcePath], + [`docs/${doc.sourcePath}`, doc.sourcePath], + [doc.workspacePath, doc.sourcePath], + [doc.workspaceRealPath, doc.sourcePath], + ]), + ); + const context: DocsGraphContext = { + sourceToRoute, + filePathToSourcePath, + assetPathSet: new Set(docsGraph.assets), + assetMetadataByPath: docsGraph.assetMetadata ?? {}, + }; + + cachedGraphContext = context; + cachedGraphMtimeMs = mtimeMs; + return context; +} + +export function rehypeDocLinks({ + docsGraphPath, + siteBasePath, + assetsPublicPath, +}: RehypeDocLinksOptions): (tree: HastRoot, vfile: VFile) => void { + return (tree: HastRoot, vfile: VFile) => { + const { sourceToRoute, filePathToSourcePath, assetPathSet, assetMetadataByPath } = + loadGraphContext(docsGraphPath); + const fileMeta = vfile as VFile & { filename?: string; path?: string }; + const filePath = fileMeta.filename || fileMeta.path || fileMeta.history?.[0]; + if (!filePath) { + return; + } + + const sourcePath = inferSourcePath(filePath, filePathToSourcePath); + if (!sourcePath || !sourceToRoute[sourcePath]) { + return; + } + + visit(tree, 'element', (node: Element, index, parent) => { + if (node.tagName === 'a') { + const properties = getProperties(node); + const href = properties.href; + if (typeof href === 'string') { + const parsed = parseMarkdownDocHref(href); + if (parsed) { + const resolvedSourcePath = resolveDocRelativePath(sourcePath, parsed.targetPath); + const routePath = sourceToRoute[resolvedSourcePath]; + if (!routePath) { + throw new Error( + `Unresolved markdown link '${href}' in '${sourcePath}' (resolved '${resolvedSourcePath}')`, + ); + } + + const routeWithBase = withBasePath(routePath, siteBasePath); + properties.href = withQueryAndHash(routeWithBase, parsed.query, parsed.hash); + } + } + return; + } + + if (node.tagName !== 'img') { + return; + } + + const properties = getProperties(node); + const src = properties.src; + if (typeof src !== 'string') { + return; + } + + let metadataAssetPath: string | null = null; + const parsedAsset = parseLocalAssetHref(src); + if (parsedAsset) { + const resolvedAssetPath = resolveDocRelativePath(sourcePath, parsedAsset.targetPath); + if (assetPathSet.has(resolvedAssetPath)) { + metadataAssetPath = resolvedAssetPath; + const normalizedAssetsPath = assetsPublicPath.replace(/\/+$/, ''); + const assetUrl = `${normalizedAssetsPath}/${resolvedAssetPath}`; + const assetWithBase = withBasePath(assetUrl, siteBasePath); + properties.src = withQueryAndHash(assetWithBase, parsedAsset.query, parsedAsset.hash); + } else if (resolvedAssetPath.startsWith('assets/')) { + const staticAssetPath = withBasePath(`/${resolvedAssetPath}`, siteBasePath); + properties.src = withQueryAndHash(staticAssetPath, parsedAsset.query, parsedAsset.hash); + } else { + throw new Error( + `Unresolved image link '${src}' in '${sourcePath}' (resolved '${resolvedAssetPath}')`, + ); + } + } + + if (metadataAssetPath) { + const metadata = assetMetadataByPath[metadataAssetPath]; + if (metadata) { + properties.width ??= metadata.width; + properties.height ??= metadata.height; + } + } + + properties.loading ??= 'lazy'; + properties.decoding ??= 'async'; + + const parentNode = parent as Parent | undefined; + if (!parentNode || typeof index !== 'number') { + return; + } + + const parentElement = parentNode as Element; + if (parentElement.type === 'element' && parentElement.tagName === 'picture') { + return; + } + + if (!Array.isArray(parentNode.children)) { + return; + } + + parentNode.children[index] = wrapWithImagePlaceholder(node); + }); + }; +} diff --git a/src/lib/utils/search.ts b/src/lib/utils/search.ts new file mode 100644 index 0000000..972d9f1 --- /dev/null +++ b/src/lib/utils/search.ts @@ -0,0 +1,171 @@ +import MiniSearch from 'minisearch'; +import { resolve } from '$app/paths'; + +const SEARCH_FUZZY = 0.15; +const SEARCH_PREFIX = true; +const SEARCH_COMBINE_WITH = 'AND' as const; +const SNIPPET_MAX_LENGTH = 140; +const SNIPPET_CONTEXT_CHARS = 40; +const SNIPPET_ELLIPSIS = '...'; +const HIGHLIGHT_TAG = 'mark'; + +const MINISEARCH_OPTIONS = { + fields: ['title', 'text', 'section'], + storeFields: ['title', 'section', 'sectionId', 'sectionIcon', 'url', 'anchor', 'text'], + searchOptions: { + boost: { title: 4, section: 2, text: 1 }, + fuzzy: SEARCH_FUZZY, + prefix: SEARCH_PREFIX, + combineWith: SEARCH_COMBINE_WITH, + }, +}; + +let instance: MiniSearch | null = null; +let loadPromise: Promise | null = null; + +export function getIndex(): MiniSearch | null { + return instance; +} + +export function isReady(): boolean { + return instance !== null; +} + +export async function ensureIndex(): Promise { + if (instance) return instance; + if (loadPromise) return loadPromise; + + loadPromise = (async () => { + try { + const res = await fetch(resolve('/search-index.json')); + if (!res.ok) throw new Error(`Failed to fetch search index: ${res.status}`); + const json = await res.text(); + instance = MiniSearch.loadJSON(json, MINISEARCH_OPTIONS); + return instance; + } catch (e) { + loadPromise = null; + console.error('Failed to load search index:', e); + throw e; + } + })(); + + return loadPromise; +} + +export interface SearchHit { + id: string; + title: string; + section: string; + sectionId: string; + sectionIcon: string; + url: string; + anchor: string; + text: string; + score: number; +} + +interface SearchIndexResult { + id: string | number; + title: string; + section: string; + sectionId: string; + sectionIcon?: string; + url: string; + anchor: string; + text: string; + score: number; +} + +export function search(query: string): SearchHit[] { + const ms = getIndex(); + if (!ms || !query.trim()) return []; + + const raw = ms.search(query, { + combineWith: SEARCH_COMBINE_WITH, + }); + + return raw.map((result) => { + const entry = result as unknown as SearchIndexResult; + return { + id: String(entry.id), + title: entry.title, + section: entry.section, + sectionId: entry.sectionId, + sectionIcon: entry.sectionIcon ?? '', + url: entry.url, + anchor: entry.anchor, + text: entry.text, + score: entry.score, + }; + }); +} + +function escapeHtml(str: string): string { + return str.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>'); +} + +function escapeRegex(text: string): string { + return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +function queryTerms(query: string): string[] { + return query.trim().toLowerCase().split(/\s+/).filter(Boolean); +} + +function matchRegex(query: string): RegExp | null { + const terms = query.trim().split(/\s+/).filter(Boolean); + if (terms.length === 0) return null; + + return new RegExp(`(${terms.map(escapeRegex).join('|')})`, 'gi'); +} + +export function highlightMatch(text: string, query: string): string { + const escaped = escapeHtml(text); + const regex = matchRegex(query); + if (!regex) return escaped; + return escaped.replace(regex, `<${HIGHLIGHT_TAG}>$1`); +} + +export function getSnippet(text: string, query: string, maxLen = SNIPPET_MAX_LENGTH): string { + const normalizedText = text.replace(/\s+/g, ' ').trim(); + if (!normalizedText) { + return ''; + } + + const snippetLength = maxLen > 0 ? maxLen : 1; + if (normalizedText.length <= snippetLength) { + return normalizedText; + } + + const lowerText = normalizedText.toLowerCase(); + const terms = queryTerms(query); + let matchIndex = 0; + + for (const term of terms) { + const index = lowerText.indexOf(term); + if (index >= 0) { + matchIndex = index; + break; + } + } + + let snippetStart = matchIndex - SNIPPET_CONTEXT_CHARS; + if (snippetStart < 0) { + snippetStart = 0; + } + + let snippetEnd = snippetStart + snippetLength; + if (snippetEnd > normalizedText.length) { + snippetEnd = normalizedText.length; + } + + let snippet = normalizedText.slice(snippetStart, snippetEnd).trim(); + if (snippetStart > 0) { + snippet = `${SNIPPET_ELLIPSIS}${snippet}`; + } + if (snippetEnd < normalizedText.length) { + snippet += SNIPPET_ELLIPSIS; + } + + return snippet; +} diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte new file mode 100644 index 0000000..d2a27fb --- /dev/null +++ b/src/routes/+error.svelte @@ -0,0 +1,51 @@ + + + + Error {page.status} | {SITE_TITLE} + + +
+ {page.status} +

{page.error?.message || 'Something went wrong'}

+ Back to home +
+ + diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..fa7834e --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,232 @@ + + + + + + + + + + +
+ +
+ + +
+ +
+ {#if isDocPage} + + {/if} +
+ {@render children()} +
+ {#if isDocPage} + + {/if} +
+
+
+ + {#if hasToc} + + {/if} +
+ + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..11dee91 --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,42 @@ + + + + {SITE_TITLE} + + + +
+

Welcome to {SITE_TITLE}

+
+ + diff --git a/src/routes/+page.ts b/src/routes/+page.ts new file mode 100644 index 0000000..189f71e --- /dev/null +++ b/src/routes/+page.ts @@ -0,0 +1 @@ +export const prerender = true; diff --git a/src/routes/[...slug]/+page.server.ts b/src/routes/[...slug]/+page.server.ts new file mode 100644 index 0000000..4feb2e7 --- /dev/null +++ b/src/routes/[...slug]/+page.server.ts @@ -0,0 +1,39 @@ +import { error } from '@sveltejs/kit'; +import { getAllDocRoutes } from '$lib/core/graph'; +import { useDocsRouteData } from '$lib/core/route-data'; +import type { PageServerLoad } from './$types'; + +export const prerender = true; + +export function entries() { + return getAllDocRoutes().map((route) => { + const slug = route.slice(1); + return { slug }; + }); +} + +export const load: PageServerLoad = ({ params }) => { + if (!params.slug) { + throw error(404, 'Page not found'); + } + + const slug = params.slug.split('/'); + const routeData = useDocsRouteData(slug); + if (!routeData) { + throw error(404, 'Page not found'); + } + + const sourcePath = routeData.page.sourcePath; + if (!sourcePath.endsWith('.md') || sourcePath.includes('..')) { + throw error(500, 'Invalid source path for docs page'); + } + + return { + sourcePath, + title: routeData.title, + section: routeData.section.title, + headings: routeData.headings, + editUrl: routeData.editUrl, + pagination: routeData.pagination, + }; +}; diff --git a/src/routes/[...slug]/+page.svelte b/src/routes/[...slug]/+page.svelte new file mode 100644 index 0000000..8bd02a7 --- /dev/null +++ b/src/routes/[...slug]/+page.svelte @@ -0,0 +1,16 @@ + + + + {data.title} - {data.section} | {SITE_TITLE} + + + + diff --git a/src/routes/[...slug]/+page.ts b/src/routes/[...slug]/+page.ts new file mode 100644 index 0000000..95d1b5c --- /dev/null +++ b/src/routes/[...slug]/+page.ts @@ -0,0 +1,24 @@ +import { error } from '@sveltejs/kit'; +import type { Component } from 'svelte'; +import type { PageLoad } from './$types'; + +const components = import.meta.glob('/docs/**/*.md'); + +export const load: PageLoad = async ({ data }) => { + const sourcePath = data.sourcePath; + if (typeof sourcePath !== 'string' || !sourcePath.endsWith('.md')) { + throw error(500, 'Missing source path for docs page'); + } + + const componentPath = `/docs/${sourcePath}`; + const loader = components[componentPath]; + if (!loader) { + throw error(404, 'Page content not found'); + } + + const component = (await loader()) as { default: Component }; + return { + ...data, + component: component.default, + }; +}; diff --git a/src/routes/search-index.json/+server.ts b/src/routes/search-index.json/+server.ts new file mode 100644 index 0000000..22f3d68 --- /dev/null +++ b/src/routes/search-index.json/+server.ts @@ -0,0 +1,37 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import type { RequestHandler } from './$types'; + +export const prerender = true; + +let cachedSearchIndex: string | null = null; + +function getSearchIndex(): string | null { + if (cachedSearchIndex !== null) { + return cachedSearchIndex; + } + + try { + cachedSearchIndex = readFileSync( + join(process.cwd(), '.svelte-kit/generated/search-index.json'), + 'utf-8', + ); + return cachedSearchIndex; + } catch { + return null; + } +} + +export const GET: RequestHandler = () => { + const searchIndex = getSearchIndex(); + if (searchIndex === null) { + return new Response(JSON.stringify({ error: 'Search index is not available yet.' }), { + status: 503, + headers: { 'Content-Type': 'application/json; charset=utf-8' }, + }); + } + + return new Response(searchIndex, { + headers: { 'Content-Type': 'application/json; charset=utf-8' }, + }); +}; diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..0a4ba62 Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/logo.png b/static/logo.png new file mode 100644 index 0000000..ba76d10 Binary files /dev/null and b/static/logo.png differ diff --git a/static/logo.svg b/static/logo.svg new file mode 100644 index 0000000..20b2a31 --- /dev/null +++ b/static/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..b6dd667 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,3 @@ +# allow crawling everything by default +User-agent: * +Disallow: diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..0708309 --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,152 @@ +import adapter from '@sveltejs/adapter-static'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import { mdsvex } from 'mdsvex'; +import rehypeAutolinkHeadings from 'rehype-autolink-headings'; +import rehypeSanitize from 'rehype-sanitize'; +import rehypeSlug from 'rehype-slug'; +import { createHighlighter } from 'shiki'; +import { SITE_URL } from './site.config.js'; +import { rehypeDocLinks } from './src/lib/utils/rehype-plugins.js'; + +const SHIKI_THEME = 'github-dark'; +const DOCS_ASSETS_PATH = '/assets/docs'; +const DOCS_GRAPH_PATH = '.svelte-kit/generated/docs-graph.json'; +const SVELTEKIT_OUT_DIR = '.svelte-kit'; +const SHIKI_LANGUAGES = [ + 'javascript', + 'typescript', + 'kotlin', + 'java', + 'bash', + 'json', + 'groovy', + 'svelte', + 'html', + 'css', + 'properties', + 'xml', + 'yaml', + 'shell', + 'markdown', +]; + +let highlighterPromise = null; + +function getSiteBasePath(siteUrl) { + const pathname = new URL(siteUrl).pathname.replace(/\/+$/, ''); + return pathname === '/' ? '' : pathname; +} + +const SITE_BASE_PATH = getSiteBasePath(SITE_URL); + +function getHighlighter() { + if (!highlighterPromise) { + highlighterPromise = createHighlighter({ + themes: [SHIKI_THEME], + langs: SHIKI_LANGUAGES, + }); + } + return highlighterPromise; +} + +function resolveLang(highlighter, lang) { + if (!lang) return 'text'; + try { + highlighter.getLanguage(lang); + return lang; + } catch { + return 'text'; + } +} + +function withBase(pathname) { + return `${SITE_BASE_PATH}${pathname}`; +} + +const config = { + extensions: ['.svelte', '.md'], + preprocess: [ + vitePreprocess(), + mdsvex({ + extensions: ['.md'], + rehypePlugins: [ + rehypeSanitize, + rehypeSlug, + [ + rehypeAutolinkHeadings, + { + behavior: 'append', + properties: { + className: ['heading-anchor'], + 'aria-label': 'Link to this section', + }, + content: [ + { + type: 'element', + tagName: 'span', + properties: { className: ['heading-anchor-icon'], 'aria-hidden': 'true' }, + children: [{ type: 'text', value: '#' }], + }, + ], + }, + ], + [ + rehypeDocLinks, + { + docsGraphPath: DOCS_GRAPH_PATH, + siteBasePath: SITE_BASE_PATH, + assetsPublicPath: DOCS_ASSETS_PATH, + }, + ], + ], + highlight: { + highlighter: async (code, lang) => { + const highlighter = await getHighlighter(); + const highlighted = highlighter.codeToHtml(code, { + lang: resolveLang(highlighter, lang), + theme: SHIKI_THEME, + }); + const wrapped = [ + '
', + '', + highlighted, + '
', + ].join(''); + const escaped = wrapped.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$'); + return `{@html \`${escaped}\`}`; + }, + }, + }), + ], + kit: { + outDir: SVELTEKIT_OUT_DIR, + alias: { + $generated: `${SVELTEKIT_OUT_DIR}/generated`, + }, + paths: { + base: SITE_BASE_PATH, + }, + inlineStyleThreshold: 0, + adapter: adapter({ + pages: 'build', + assets: 'build', + fallback: null, + precompress: true, + strict: true, + }), + prerender: { + handleHttpError: ({ path: prerenderPath, message }) => { + if (prerenderPath === withBase('/favicon.ico') || prerenderPath === withBase('/logo.png')) { + return; + } + if (prerenderPath.startsWith(withBase('/assets/'))) { + return; + } + throw new Error(message); + }, + handleMissingId: 'fail', + }, + }, +}; + +export default config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..845a586 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "rewriteRelativeImportExtensions": true, + "allowJs": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..a6dc9a2 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,215 @@ +import { spawn } from 'node:child_process'; +import { existsSync, readFileSync, statSync } from 'node:fs'; +import path from 'node:path'; +import { sveltekit } from '@sveltejs/kit/vite'; +import fg from 'fast-glob'; +import Icons from 'unplugin-icons/vite'; +import { defineConfig, type Plugin } from 'vite'; +import { DOCS_DIR } from './site.config.js'; + +const DOCS_ASSETS_PUBLIC_PATH = '/assets/docs'; +const DOCS_GRAPH_PATH = '.svelte-kit/generated/docs-graph.json'; +const SVELTEKIT_OUT_DIR = '.svelte-kit'; + +function docsArtifactsPlugin(): Plugin { + const normalizedOutDir = SVELTEKIT_OUT_DIR.split('/') + .join(path.sep) + .replace(/[/\\]+$/, ''); + const generatedDirSegment = `${path.sep}${normalizedOutDir}${path.sep}generated${path.sep}`; + let root = process.cwd(); + let generatedInitially = false; + let generationInProgress = false; + let pendingForceRun = false; + let debounceTimer: ReturnType | null = null; + + function shouldRegenerate(filePath: string): boolean { + const normalized = path.normalize(filePath); + if (normalized.includes(generatedDirSegment)) { + return false; + } + + const relative = path.relative(root, normalized); + if (relative.startsWith('..')) { + return false; + } + + return ( + relative === 'site.config.ts' || + relative.startsWith(`docs${path.sep}`) || + relative.startsWith(`assets${path.sep}`) || + relative.startsWith(`src${path.sep}lib${path.sep}core${path.sep}`) || + relative.startsWith(`scripts${path.sep}`) + ); + } + + function runGeneration(force: boolean): Promise { + const args = ['scripts/generate-docs-graph.ts']; + if (force) { + args.push('--force'); + } + + return new Promise((resolve, reject) => { + const child = spawn('bun', args, { + cwd: root, + stdio: 'inherit', + env: process.env, + }); + + child.on('error', reject); + child.on('close', (code) => { + if (code === 0) { + resolve(); + return; + } + reject(new Error(`Docs generation failed with exit code ${code ?? 1}`)); + }); + }); + } + + async function triggerGeneration( + force: boolean, + onSuccess: () => void, + onError: (error: unknown) => void, + ): Promise { + if (force) { + pendingForceRun = true; + } + if (generationInProgress) { + return; + } + + generationInProgress = true; + let shouldForce = force; + while (true) { + try { + await runGeneration(shouldForce); + } catch (error) { + generationInProgress = false; + onError(error); + return; + } + if (!pendingForceRun) { + break; + } + pendingForceRun = false; + shouldForce = true; + } + + generationInProgress = false; + onSuccess(); + } + + /** Serve a file from `sourceDir` for requests under the given URL prefix (dev only). */ + function serveFromDir(sourceDir: string) { + return (req: { url?: string }, res: { end: (data: Buffer) => void }, next: () => void) => { + const url = req.url?.split('?')[0]; + if (!url) return next(); + const relativePath = decodeURIComponent(url).replace(/^\/+/, ''); + const filePath = path.join(sourceDir, relativePath); + if ( + !filePath.startsWith(sourceDir) || + !existsSync(filePath) || + !statSync(filePath).isFile() + ) { + return next(); + } + res.end(readFileSync(filePath)); + }; + } + + return { + name: 'docs-artifacts', + configResolved(config) { + root = config.root; + }, + async buildStart() { + if (generatedInitially) { + return; + } + generatedInitially = true; + await runGeneration(false); + }, + configureServer(server) { + root = server.config.root; + + const docsDir = path.resolve(root, DOCS_DIR); + const repoAssetsDir = path.resolve(root, 'assets'); + + server.middlewares.use(DOCS_ASSETS_PUBLIC_PATH, serveFromDir(docsDir)); + + server.middlewares.use('/assets', serveFromDir(repoAssetsDir)); + + const onFileChange = (filePath: string) => { + if (!shouldRegenerate(filePath)) { + return; + } + if (debounceTimer) { + clearTimeout(debounceTimer); + } + debounceTimer = setTimeout(() => { + void triggerGeneration( + true, + () => server.ws.send({ type: 'full-reload' }), + (error) => + server.config.logger.error(error instanceof Error ? error.message : String(error)), + ); + }, 120); + }; + + server.watcher.on('add', onFileChange); + server.watcher.on('change', onFileChange); + server.watcher.on('unlink', onFileChange); + }, + generateBundle() { + const docsDir = path.resolve(root, DOCS_DIR); + const repoAssetsDir = path.resolve(root, 'assets'); + const graphPath = path.resolve(root, DOCS_GRAPH_PATH); + + if (existsSync(graphPath)) { + const graph = JSON.parse(readFileSync(graphPath, 'utf-8')); + const assets: string[] = graph.assets ?? []; + for (const assetPath of assets) { + const filePath = path.join(docsDir, assetPath); + if (!existsSync(filePath)) { + this.warn(`Doc asset not found: ${filePath} (referenced as '${assetPath}')`); + continue; + } + this.emitFile({ + type: 'asset', + fileName: `${DOCS_ASSETS_PUBLIC_PATH.replace(/^\//, '')}/${assetPath}`, + source: readFileSync(filePath), + }); + } + } + + if (existsSync(repoAssetsDir)) { + const repoAssets = fg.sync('**/*', { + cwd: repoAssetsDir, + onlyFiles: true, + followSymbolicLinks: true, + }); + for (const assetPath of repoAssets) { + const filePath = path.join(repoAssetsDir, assetPath); + this.emitFile({ + type: 'asset', + fileName: `assets/${assetPath.replace(/\\/g, '/')}`, + source: readFileSync(filePath), + }); + } + } + }, + }; +} + +const workspaceRoot = path.resolve(process.cwd()); +const docsRoot = path.resolve(workspaceRoot, 'docs'); +const repoAssetsRoot = path.resolve(workspaceRoot, 'assets'); + +export default defineConfig({ + server: { + fs: { + allow: [workspaceRoot, docsRoot, repoAssetsRoot], + }, + }, + plugins: [docsArtifactsPlugin(), Icons({ compiler: 'svelte' }), sveltekit()], +});