diff --git a/.github/workflows/site.yml b/.github/workflows/site.yml new file mode 100644 index 00000000..72e0a9f9 --- /dev/null +++ b/.github/workflows/site.yml @@ -0,0 +1,86 @@ +name: Site + +on: + push: + branches: + - main + paths: + - "site/**" + - "README.md" + - ".github/i18n/**" + - "web/src/app.css" + - "src/config.ts" + - "opencode-mem.example.jsonc" + - "web/public/favicon.*" + - ".github/workflows/site.yml" + pull_request: + paths: + - "site/**" + - "README.md" + - ".github/i18n/**" + - "web/src/app.css" + - "src/config.ts" + - "opencode-mem.example.jsonc" + - "web/public/favicon.*" + - ".github/workflows/site.yml" + schedule: + - cron: "17 3 * * *" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: site-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: build + runs-on: ubuntu-26.04 + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - uses: oven-sh/setup-bun@v2 + + - name: Install site dependencies + working-directory: site + run: bun install --frozen-lockfile + + - name: Build site + working-directory: site + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bun run build + + - name: Typecheck site + working-directory: site + run: bun run check + + - name: Check build output + working-directory: site + run: node scripts/check-dist.mjs + + - uses: actions/upload-pages-artifact@v5 + with: + path: site/dist + + deploy: + name: deploy + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' && github.repository == 'tickernelz/opencode-mem' + needs: build + runs-on: ubuntu-26.04 + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + concurrency: + group: pages + cancel-in-progress: false + steps: + - id: deployment + uses: actions/deploy-pages@v5 diff --git a/.prettierignore b/.prettierignore index baf94ba2..5ac02d1b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,3 +10,6 @@ yarn.lock .github *.min.js *.min.css +site/.astro +site/src/content/docs +site/src/generated diff --git a/eslint.config.js b/eslint.config.js index 7368140f..4015e109 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,6 +10,9 @@ export default ts.config( "dist/**", "node_modules/**", "out/**", + "site/.astro/**", + "site/dist/**", + "site/node_modules/**", "web/dist/**", "web/node_modules/**", ], diff --git a/site/.gitignore b/site/.gitignore new file mode 100644 index 00000000..157667e6 --- /dev/null +++ b/site/.gitignore @@ -0,0 +1,7 @@ +node_modules +dist +.astro +src/generated +src/content/docs +public/favicon.svg +public/favicon.ico diff --git a/site/astro.config.mjs b/site/astro.config.mjs new file mode 100644 index 00000000..4913ea28 --- /dev/null +++ b/site/astro.config.mjs @@ -0,0 +1,51 @@ +import { readFileSync } from "node:fs"; +import starlight from "@astrojs/starlight"; +import { defineConfig } from "astro/config"; + +const map = JSON.parse(readFileSync(new URL("./docs-map.json", import.meta.url), "utf8")); +const groups = [...new Set(map.pages.map((page) => page.group))]; +const sidebar = groups.map((label) => ({ + label, + items: map.pages + .filter((page) => page.group === label) + .map((page) => ({ slug: page.slug ? `docs/${page.slug}` : "docs" })), +})); + +export default defineConfig({ + site: "https://opencode-mem.zhafron.my.id", + base: "/", + trailingSlash: "always", + integrations: [ + starlight({ + title: "opencode-mem", + description: + "Long-term memory for OpenCode agents. Docs generated from the opencode-mem README.", + logo: { src: "./src/assets/brain.svg", alt: "" }, + favicon: "/favicon.svg", + social: [{ icon: "github", label: "GitHub", href: map.repository }], + defaultLocale: "root", + locales: { + root: { label: "English", lang: "en" }, + de: { label: "Deutsch", lang: "de" }, + zh: { label: "简体中文", lang: "zh-CN" }, + ar: { label: "العربية", lang: "ar", dir: "rtl" }, + tr: { label: "Türkçe", lang: "tr" }, + nl: { label: "Nederlands", lang: "nl" }, + }, + sidebar, + lastUpdated: true, + customCss: ["./src/generated/tokens.css", "./src/styles/fonts.css", "./src/styles/docs.css"], + components: { + Head: "./src/components/docs/Head.astro", + SiteTitle: "./src/components/docs/SiteTitle.astro", + }, + head: [ + { tag: "link", attrs: { rel: "icon", href: "/favicon.ico", sizes: "32x32" } }, + { + tag: "meta", + attrs: { property: "og:image", content: "https://opencode-mem.zhafron.my.id/og.png" }, + }, + ], + }), + ], +}); diff --git a/site/bun.lock b/site/bun.lock new file mode 100644 index 00000000..39837a12 --- /dev/null +++ b/site/bun.lock @@ -0,0 +1,872 @@ +{ + "lockfileVersion": 2, + "configVersion": 1, + "workspaces": { + "": { + "name": "opencode-mem-site", + "dependencies": { + "@astrojs/starlight": "0.42.8", + "@fontsource-variable/bricolage-grotesque": "5.3.0", + "@fontsource-variable/jetbrains-mono": "5.3.0", + "astro": "7.4.5", + "github-slugger": "2.0.0", + "sharp": "0.35.5", + }, + "devDependencies": { + "@astrojs/check": "0.9.12", + "typescript": "6.0.3", + }, + }, + }, + "packages": { + "@astrojs/astro2tsx": ["@astrojs/astro2tsx@0.1.3", "", { "dependencies": { "@emnapi/core": "1.11.3", "@napi-rs/wasm-runtime": "1.2.4" } }, "sha512-GMDC7Eo0myBUA/QLBl0u+OcegJ8LiBhccmNZR34KmprQNP8gQUJlWlOOZWUsxNA2rNS6GuPYcGDyLoPnjmn4/Q=="], + + "@astrojs/check": ["@astrojs/check@0.9.12", "", { "dependencies": { "@astrojs/language-server": "^2.17.3", "chokidar": "^5.0.0", "kleur": "^4.1.5", "yargs": "^18.2.0" }, "peerDependencies": { "typescript": "^5.0.0 || ^6.0.0" }, "bin": { "astro-check": "./bin/astro-check.js" } }, "sha512-hazpqxIfZWj2VhyPyR0pOEQ/IhFDM/2nIApL96zMXABdD8NrUKYDmhxTy7h+drTDl9MQG/Sd1ET/4amadVJUUA=="], + + "@astrojs/compiler-binding": ["@astrojs/compiler-binding@0.5.2", "", { "optionalDependencies": { "@astrojs/compiler-binding-android-arm64": "0.5.2", "@astrojs/compiler-binding-darwin-arm64": "0.5.2", "@astrojs/compiler-binding-darwin-x64": "0.5.2", "@astrojs/compiler-binding-linux-arm64-gnu": "0.5.2", "@astrojs/compiler-binding-linux-arm64-musl": "0.5.2", "@astrojs/compiler-binding-linux-x64-gnu": "0.5.2", "@astrojs/compiler-binding-linux-x64-musl": "0.5.2", "@astrojs/compiler-binding-wasm32-wasi": "0.5.2", "@astrojs/compiler-binding-win32-arm64-msvc": "0.5.2", "@astrojs/compiler-binding-win32-x64-msvc": "0.5.2" } }, "sha512-lEn76+0JcMQ5RDXU0wSMWJg2ZppiZvSULpghC29cfv4o9bhvWFDbQjsCtvjjXN9iVLFQ7fL3wTR2L2UU13mP8g=="], + + "@astrojs/compiler-binding-android-arm64": ["@astrojs/compiler-binding-android-arm64@0.5.2", "", { "os": "android", "cpu": "arm64" }, "sha512-kckIxon6Rm/Bxzh9mGPYpRRqUbToUQoHptCmpMmE+Yt0Xumq8CqrKUidyYhrBsrHVO7bxuRzzWUUqvpf+iYceQ=="], + + "@astrojs/compiler-binding-darwin-arm64": ["@astrojs/compiler-binding-darwin-arm64@0.5.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1ZG5Ar3dD8HtodX9XH1mRmE0qBXZlvjYXSFfpgFwocqfWnvhFuqtGUNseL8wgfImiRMztIjpQqlogQFQQtgiag=="], + + "@astrojs/compiler-binding-darwin-x64": ["@astrojs/compiler-binding-darwin-x64@0.5.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-+kl35S7hiHJ2cb7eujwEsPFYYuSgE11uEE2Z20lAJ+undpgulMcW+weQqFPOSSZccEKHOiLIY+kQHkb4e4092w=="], + + "@astrojs/compiler-binding-linux-arm64-gnu": ["@astrojs/compiler-binding-linux-arm64-gnu@0.5.2", "", { "os": "linux", "cpu": "arm64", "libc": "glibc" }, "sha512-BqlR0EHNQLPLwgL9+xogjsAc7zGf0cHho2CPdhv0P1yqbVMwGVaGAqrANP6VYAXCqSC43AF4Czcxc2n+oqdesg=="], + + "@astrojs/compiler-binding-linux-arm64-musl": ["@astrojs/compiler-binding-linux-arm64-musl@0.5.2", "", { "os": "linux", "cpu": "arm64", "libc": "musl" }, "sha512-GRGyby3AZWw5d6JQzidyxPyvGgHWsSusrpgKyFVpDTKctABF7L3Pd5V1cRJbV36/rcu+Eh292/wL7pF7MkmGkQ=="], + + "@astrojs/compiler-binding-linux-x64-gnu": ["@astrojs/compiler-binding-linux-x64-gnu@0.5.2", "", { "os": "linux", "cpu": "x64", "libc": "glibc" }, "sha512-9XAqGTMQAtIslMsjK3xdyY6OI9d59OZqcLBB6pvD/DcoR0daYswfrKx2azdDERDY4AqAnWPC7odVM1BmxYv3Vw=="], + + "@astrojs/compiler-binding-linux-x64-musl": ["@astrojs/compiler-binding-linux-x64-musl@0.5.2", "", { "os": "linux", "cpu": "x64", "libc": "musl" }, "sha512-jOViewGeTh9bSfS8vK72ECxoy2yvmA+Pd/ZcEvBI5c7+7IcfHwZ5qA4L9fRYuOhSrAifvQ2dV4vm1XAtloaWBw=="], + + "@astrojs/compiler-binding-wasm32-wasi": ["@astrojs/compiler-binding-wasm32-wasi@0.5.2", "", { "dependencies": { "@emnapi/core": "1.11.3", "@emnapi/runtime": "1.11.3", "@napi-rs/wasm-runtime": "^1.2.5" }, "cpu": "none" }, "sha512-Z7p64doar1uvR5C9Xs6j1CV9lGlPVQX7OQ2aAtZ/xKC5aGS6GB13nyc2UfQXTQLvZrvVwsyaflTQy6ziY5Bekw=="], + + "@astrojs/compiler-binding-win32-arm64-msvc": ["@astrojs/compiler-binding-win32-arm64-msvc@0.5.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Tr13bh+ahTWsjXjzctK7pFpWV+dUU4FtBfETlR7gO+ueex0F+RDch7eRr0YfKysaRhk9tWm14lsCJ5uWyFPNHQ=="], + + "@astrojs/compiler-binding-win32-x64-msvc": ["@astrojs/compiler-binding-win32-x64-msvc@0.5.2", "", { "os": "win32", "cpu": "x64" }, "sha512-SfKkI+jOQYLh6wojPvVPV0lFfQnxisweN9B+qCzRvZp7DHAuGif8Y0WcC5PUgN4jb8VKy57LggQDtggR46Du1g=="], + + "@astrojs/compiler-rs": ["@astrojs/compiler-rs@0.5.2", "", { "dependencies": { "@astrojs/compiler-binding": "0.5.2" } }, "sha512-IvwYLB8t1M86rKO4oPdBi9GP4gzXcgrVlNgocjwos1jeeUuEIV8d9Crn1PvYD/5IKteWOxpIHomf7e8iYlkE+Q=="], + + "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.13.0", "", { "dependencies": { "@types/hast": "^3.0.5", "@types/mdast": "^4.0.4", "picomatch": "^4.0.7", "retext-smartypants": "^6.2.0", "shiki": "^4.5.0", "smol-toml": "^1.9.1", "unified": "^11.0.5", "yaml": "^2.9.1" } }, "sha512-20jxQqnSmpskcGyad7N5l6Xf1gz0UCa6lNde44bEBdaXGpncEYfAZJ142r2ZgzBaG4dUyzGmhqZWv1INU2eiHQ=="], + + "@astrojs/language-server": ["@astrojs/language-server@2.17.3", "", { "dependencies": { "@astrojs/astro2tsx": "^0.1.2", "@astrojs/yaml2ts": "^0.2.4", "@volar/kit": "~2.4.28", "@volar/language-core": "~2.4.28", "@volar/language-server": "~2.4.28", "@volar/language-service": "~2.4.28", "muggle-string": "^0.4.1", "tinyglobby": "^0.2.17", "volar-service-css": "0.0.71", "volar-service-emmet": "0.0.71", "volar-service-html": "0.0.71", "volar-service-prettier": "0.0.71", "volar-service-typescript": "0.0.71", "volar-service-typescript-twoslash-queries": "0.0.71", "volar-service-yaml": "0.0.71", "vscode-html-languageservice": "^5.6.2", "vscode-uri": "^3.2.0" }, "peerDependencies": { "prettier": "^3.0.0", "prettier-plugin-astro": ">=0.11.0" }, "optionalPeers": ["prettier", "prettier-plugin-astro"], "bin": { "astro-ls": "./bin/nodeServer.js" } }, "sha512-QIAFu1e/4quJMTPdmBOm+ZPXc5NDGZE4/YQjgR3EgjhGLl/tdidaWJDr5WmO2lesVc+BW1qN/xNBURmuePDG2A=="], + + "@astrojs/markdown-satteri": ["@astrojs/markdown-satteri@0.4.6", "", { "dependencies": { "@astrojs/internal-helpers": "0.13.0", "@astrojs/prism": "4.1.2", "github-slugger": "^2.0.0", "satteri": "^0.10.5" } }, "sha512-6biKp2lEAYycF3jhv91br+Otyf4EgDFkF1oRL9ks0u/m/YRGmI7XkGQ2MgaM35DslT03f7NtozKtlqfBNkp6bw=="], + + "@astrojs/mdx": ["@astrojs/mdx@8.1.2", "", { "dependencies": { "@astrojs/internal-helpers": "0.13.0", "@astrojs/markdown-satteri": "0.4.6", "es-module-lexer": "^3.0.3" }, "peerDependencies": { "@astrojs/markdown-remark": "^7.3.0", "astro": "^7.2.10" }, "optionalPeers": ["@astrojs/markdown-remark"] }, "sha512-ZIUVfosVtK4SKcFrGOH+1+HwG0encjxQOxu76M9VuTqeQNZWQ//2eY2Iz+W1eq87AOT5JD4wOHyZ8xFwlcFteg=="], + + "@astrojs/prism": ["@astrojs/prism@4.1.2", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-jMrUEpFDarDO1KWPvVc9eSa8DSfwBlwEOHwX+8zvZQpiqXRGDxFnOXHsYqV6DP7w+0qIgTr98gS1GdQlm8ypWg=="], + + "@astrojs/sitemap": ["@astrojs/sitemap@3.7.4", "", { "dependencies": { "sitemap": "^9.0.0", "zod": "^4.3.6" } }, "sha512-LbKNC24bdUWcQf/pThB6qLlSqHojxGjZDURIzFocY8rlWnAn2t74nnhnK6S5x0NHriHoAduLEpVjRykmeGiVvA=="], + + "@astrojs/starlight": ["@astrojs/starlight@0.42.8", "", { "dependencies": { "@astrojs/markdown-satteri": "^0.4.0", "@astrojs/mdx": "^8.0.0", "@astrojs/sitemap": "^3.7.3", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.5", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.44.0", "bcp-47": "^2.1.0", "hast-util-format": "^1.1.0", "hast-util-select": "^6.0.4", "hast-util-to-html": "^9.0.5", "hast-util-to-string": "^3.0.1", "hastscript": "^9.0.1", "i18next": "^26.0.7", "js-yaml": "^4.1.1", "klona": "^2.0.6", "magic-string": "^1.2.3", "mdast-util-directive": "^3.1.0", "mdast-util-to-markdown": "^2.1.2", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.5.2", "remark-directive": "^4.0.0", "satteri": "^0.10.3", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@astrojs/markdown-remark": "^7.3.0", "astro": "^7.2.10" }, "optionalPeers": ["@astrojs/markdown-remark"] }, "sha512-BGP8bmTbdky4OFCV9BNWZedLuzONyUtz754q+hie+li/2TQ5XJ6nvfO8fhRhIMcCpUEsA5Ynf4qTTFf/ft/3Pg=="], + + "@astrojs/telemetry": ["@astrojs/telemetry@3.4.2", "", { "dependencies": { "ci-info": "^4.4.0", "dset": "^3.1.4", "is-docker": "^4.0.0", "package-manager-detector": "^1.9.0" } }, "sha512-2JOMRUxJrBSfiVDfeKLv1wBmvSIx1Y6u2YEO8awZ9qSq3u/rNAiUyFdOYi8dHv91kHrmYEQX7pRDw0J4xyj3UA=="], + + "@astrojs/yaml2ts": ["@astrojs/yaml2ts@0.2.4", "", { "dependencies": { "yaml": "^2.8.3" } }, "sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.11", "", {}, "sha512-snZbO7MEDOof+hvNa97EjEY7qD7h2kwvQr5AJC3ZhQudKW5dnej6k3kP9NQV88hJwaS8vDqRLFo9rivLEhle2g=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/parser": ["@babel/parser@7.29.12", "", { "dependencies": { "@babel/types": "^7.29.11" }, "bin": "./bin/babel-parser.js" }, "sha512-WJ7JBp/Q4+z/ImydtI7jS6NVco5++632ExBemSX+Ysb+G1lCwQ5BVo3SY+jGGOcZXI4ZccbZSUSJLNBW6eEpJg=="], + + "@babel/types": ["@babel/types@7.29.11", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.11", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-WCsemW40Cpc6gouC1SrY6PBaZ+oLRlEVY9XBvZBI7il/HyUrb2nJ505wE1MHEFyDZNnrWDEuy4jL50WVHfTTSQ=="], + + "@bruits/satteri-darwin-arm64": ["@bruits/satteri-darwin-arm64@0.10.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA=="], + + "@bruits/satteri-darwin-x64": ["@bruits/satteri-darwin-x64@0.10.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-IjnLe3nKspq6qaeqGgjT7MT8VrTV74yWRlaag7ZdNsI8TDAYZ0iPxMCo+9KQZHUk5EyVB+reBI/PFWL5KuFw9Q=="], + + "@bruits/satteri-linux-arm64-gnu": ["@bruits/satteri-linux-arm64-gnu@0.10.5", "", { "os": "linux", "cpu": "arm64", "libc": "glibc" }, "sha512-glkYXZCJywjP13v67eAyAMSJdF+ncvEbYvgi/wOtffL9tQ27lr/zsyzUfgs+ovjJ9d8JNQKiXeiArJcX8PJL9w=="], + + "@bruits/satteri-linux-arm64-musl": ["@bruits/satteri-linux-arm64-musl@0.10.5", "", { "os": "linux", "cpu": "arm64", "libc": "musl" }, "sha512-yWdgG1g17Nh2QyGVlFUxGRa3FEFwiMcpZEyMNWkbM3deC94cmVc+/i9OuyFpdKuWo3GkgoCtYVOoxk1uCnCZIA=="], + + "@bruits/satteri-linux-x64-gnu": ["@bruits/satteri-linux-x64-gnu@0.10.5", "", { "os": "linux", "cpu": "x64", "libc": "glibc" }, "sha512-FVaLoPT1fBgGl0J+AYebyyXJYBachGl8Oyyrf1lye4RTqCB4S0Gwkj1uM9RJyThUOvx5VUmAT1CnNh1SFHA+kw=="], + + "@bruits/satteri-linux-x64-musl": ["@bruits/satteri-linux-x64-musl@0.10.5", "", { "os": "linux", "cpu": "x64", "libc": "musl" }, "sha512-EHpVAx2bqW3GINHTKkljtxVfQmVDGWIuwOYOP5YghTj+0PkBa2o8oKPRtQ9Kbsr1Fye8jtUcDjhwj2jMNugZKg=="], + + "@bruits/satteri-wasm32-wasi": ["@bruits/satteri-wasm32-wasi@0.10.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.2.3" }, "cpu": "none" }, "sha512-ypz8c/Zmipxp4IoeDa228Gstv6TLzVmNs3yC6wKCoNSOjx1iwpgzu87Y3hTkXFdwChVGU85qeUDuOIarGUZQLw=="], + + "@bruits/satteri-win32-arm64-msvc": ["@bruits/satteri-win32-arm64-msvc@0.10.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-siTV88nb0LRqNpkL2gXboqCwVdq95sLtzMHS1/3eONV2gLbB3NAK46wmSMvCO/yquBvI2lvaFIfd8P12ecsxBw=="], + + "@bruits/satteri-win32-x64-msvc": ["@bruits/satteri-win32-x64-msvc@0.10.5", "", { "os": "win32", "cpu": "x64" }, "sha512-C3IfPvfvMXmlzBxaMPKFS1XiuV9pu2mC7YqkPk7PSvTgPZ8gbdASIpHpztDLvTTQjqZ0z1Ol8tK5X+V6XXC0wQ=="], + + "@capsizecss/unpack": ["@capsizecss/unpack@4.0.1", "", { "dependencies": { "fontkitten": "^1.0.3" } }, "sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ=="], + + "@clack/core": ["@clack/core@1.5.1", "", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ=="], + + "@clack/prompts": ["@clack/prompts@1.8.1", "", { "dependencies": { "@clack/core": "1.5.1", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ=="], + + "@ctrl/tinycolor": ["@ctrl/tinycolor@4.2.2", "", {}, "sha512-9rQHijqB2Rq6qOEC/xHaA6aPlsKGi5kmCQW50O1asn9g63XFeD5NmBwysriistW5Xx0JPafyD/TA7yk2S3pXGQ=="], + + "@emmetio/abbreviation": ["@emmetio/abbreviation@2.3.3", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA=="], + + "@emmetio/css-abbreviation": ["@emmetio/css-abbreviation@2.1.8", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw=="], + + "@emmetio/css-parser": ["@emmetio/css-parser@0.4.1", "", { "dependencies": { "@emmetio/stream-reader": "^2.2.0", "@emmetio/stream-reader-utils": "^0.1.0" } }, "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ=="], + + "@emmetio/html-matcher": ["@emmetio/html-matcher@1.3.0", "", { "dependencies": { "@emmetio/scanner": "^1.0.0" } }, "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ=="], + + "@emmetio/scanner": ["@emmetio/scanner@1.0.4", "", {}, "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA=="], + + "@emmetio/stream-reader": ["@emmetio/stream-reader@2.2.0", "", {}, "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw=="], + + "@emmetio/stream-reader-utils": ["@emmetio/stream-reader-utils@0.1.0", "", {}, "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A=="], + + "@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" } }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g=="], + + "@expressive-code/core": ["@expressive-code/core@0.44.3", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^7.0.2", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-pffktF0TJoxC08dgNcutl/0LcSnTrjF6vXR39qVpwZ0EyxpwO9zjI7dbni6sO7w3yHpRBO0voLFvhzB+EPJRsA=="], + + "@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.44.3", "", { "dependencies": { "@expressive-code/core": "^0.44.3" } }, "sha512-ysW4VXk9vXEliA99Ur6ApUepVtx74sPolp6o/j45BRjZQoL5O6kXKMhSP4koQLih8HbC5B3ImIvO+HKKhkv/oA=="], + + "@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.44.3", "", { "dependencies": { "@expressive-code/core": "^0.44.3", "shiki": "^4.0.2" } }, "sha512-jAibAZPG7lDmi61EFJADZjoSZzjHiwZZdbbgR/mTlWXM4ON/Pyo/9tB2vrqQNKylsci6jqtCi6idrwqQXF53xA=="], + + "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.44.3", "", { "dependencies": { "@expressive-code/core": "^0.44.3" } }, "sha512-4Ae2xRSDV5kdWPsi40xWbOtoihbzM0zLVjQKkDAnD5KzFXl+6/kd+VhuWOlTRVaJ5cqGk++vCbAaf0MR1XbZlw=="], + + "@fontsource-variable/bricolage-grotesque": ["@fontsource-variable/bricolage-grotesque@5.3.0", "", {}, "sha512-TLi9Q4hJjS2UvoTMRSS2nHu6c4R56lAw60NR9QYtVRCHn0XtsFpiEhNffZ8Glsoxu6wEEwLKBP8lb94J52PNBA=="], + + "@fontsource-variable/jetbrains-mono": ["@fontsource-variable/jetbrains-mono@5.3.0", "", {}, "sha512-F32xpS2NsGYoQi2ADSkKTgpJj7ozajsGgDJ8woTnqjmIB+dxDIqImjl4pXZVEExu8UFZ2ndhmX18EBS/hdz3Lw=="], + + "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], + + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.4" }, "os": "darwin", "cpu": "x64" }, "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw=="], + + "@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.5", "", { "dependencies": { "@img/sharp-wasm32": "0.35.5" }, "os": "freebsd" }, "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw=="], + + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw=="], + + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.4", "", { "os": "linux", "cpu": "arm", "libc": "glibc" }, "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.4", "", { "os": "linux", "cpu": "arm64", "libc": "glibc" }, "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.4", "", { "os": "linux", "cpu": "ppc64", "libc": "glibc" }, "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ=="], + + "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.4", "", { "os": "linux", "cpu": "none", "libc": "glibc" }, "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.4", "", { "os": "linux", "cpu": "s390x", "libc": "glibc" }, "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.4", "", { "os": "linux", "cpu": "x64", "libc": "glibc" }, "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.4", "", { "os": "linux", "cpu": "arm64", "libc": "musl" }, "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA=="], + + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.4", "", { "os": "linux", "cpu": "x64", "libc": "musl" }, "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg=="], + + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.4" }, "os": "linux", "cpu": "arm", "libc": "glibc" }, "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ=="], + + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.4" }, "os": "linux", "cpu": "arm64", "libc": "glibc" }, "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ=="], + + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.4" }, "os": "linux", "cpu": "ppc64", "libc": "glibc" }, "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA=="], + + "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.4" }, "os": "linux", "cpu": "none", "libc": "glibc" }, "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ=="], + + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.4" }, "os": "linux", "cpu": "s390x", "libc": "glibc" }, "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA=="], + + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.4" }, "os": "linux", "cpu": "x64", "libc": "glibc" }, "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog=="], + + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" }, "os": "linux", "cpu": "arm64", "libc": "musl" }, "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg=="], + + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.4" }, "os": "linux", "cpu": "x64", "libc": "musl" }, "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A=="], + + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.5", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ=="], + + "@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.5", "", { "dependencies": { "@img/sharp-wasm32": "0.35.5" }, "cpu": "none" }, "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q=="], + + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A=="], + + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.5", "", { "os": "win32", "cpu": "x64" }, "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.6.0", "", {}, "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw=="], + + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, "sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g=="], + + "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], + + "@oxc-project/types": ["@oxc-project/types@0.156.0", "", {}, "sha512-1Duyg48TdJNdyhEB8Xn1L36bT9Pv6GUtlKjHxOys8xkaF/rQq3XJE+bAurSK/AgIz5mGFsb77cn9Pb20+WCScw=="], + + "@pagefind/darwin-arm64": ["@pagefind/darwin-arm64@1.6.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-611gl64aqN12UcMyKPtZ8+vRWBKlJFSh2JgO8uScxa1Eyjo1dXz9r4wZuRno0yCUE/KN0FauEoKZ3KEwUYHCCg=="], + + "@pagefind/darwin-x64": ["@pagefind/darwin-x64@1.6.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-rd3ZbtuxyYqjASKZAPuIV7eeQQHJ7VYpoNKKG8CvglaD3g30eT5Nb7XGNLYwVReBsCccpkURwrGwWjSwr8nyQQ=="], + + "@pagefind/default-ui": ["@pagefind/default-ui@1.6.0", "", {}, "sha512-Wj93IzlLnaYYrMpOYrsqUerzA7+Vrs5Ri1U78hBh3zuKHNVkcjApNo5DUM99MzAam6f437VGG64jDenAObIt+w=="], + + "@pagefind/freebsd-x64": ["@pagefind/freebsd-x64@1.6.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d+sXqsaThszmPWGVDSRKqIz9GpZcj/bAksNZfg19asSxU0ogNPOMND4kV4giQvOjPFMsltUFf6hQJfoHQ6+hSQ=="], + + "@pagefind/linux-arm64": ["@pagefind/linux-arm64@1.6.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-SLB2I+XqCZma8NvIGIH8nyKblgKIxw5PmqsVtofWOKxNHhEtOEsddbqU+hsrNcT3EV0faM6UmKDHVIxcPYq29w=="], + + "@pagefind/linux-x64": ["@pagefind/linux-x64@1.6.0", "", { "os": "linux", "cpu": "x64" }, "sha512-IbMSx/+Vr/Xk0TTBlLkjgK+rvnbOXGmmb2/MKxQu99AR5DsqQoV3NKEA9PQz2tAhuCZjeD5xJBp4w5N5DHIC7Q=="], + + "@pagefind/windows-arm64": ["@pagefind/windows-arm64@1.6.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-wUrniW3REr7VWJHz6xE6F/p/AQgHDFpGZiY9sbWT71KfEijDE5Jnc37V8zc7cilV9h/QkwJGXoEP2+ZLwDmhtw=="], + + "@pagefind/windows-x64": ["@pagefind/windows-x64@1.6.0", "", { "os": "win32", "cpu": "x64" }, "sha512-cUA2+yXfbymdJllyMjY5YTBwuOgh0/H53Pn5fYKjDnDjk154Ft4U5RVj3TenWySPL/jG6zJfARUWSlyUyXHlZw=="], + + "@rolldown/binding-android-arm-eabi": ["@rolldown/binding-android-arm-eabi@1.2.16", "", { "os": "android", "cpu": "arm" }, "sha512-ia3DwAs0OsMGS7+IConptSiyk9pEXkOx/AbJ2n/lAGxH3QkWQus1t8d7gnAT38FCU2sQu8lUbeR6AiZFv4JxaA=="], + + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.16", "", { "os": "android", "cpu": "arm64" }, "sha512-kx5wBiMB6E7TEvpl2B9gjLU004BkvEm2Dr941BFjx/SontPwSzNuQUIoVKxHHoSjpFIfHMmcguyLOtyn0hObRg=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.2.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-qslZrXnKJU4cUpjoAmtAo/KQM9e2IRMlmpig6Zpwj+8KWxW8v+nkAf9216Bsek9lOC1jvg2yCjygCFo2f83msQ=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.2.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-FdF+y48ND13eAyM2mQn+85kvAqNlvRWROy2rhgA463X/0Gv4vGtazZtfaF1mRBLscYvtOlh4QnLjOWiFzX69OQ=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.2.16", "", { "os": "freebsd", "cpu": "x64" }, "sha512-ddjqFM5e95AgLbUPtKIS7V1KTVlA0RUgCVr5mn+/IEhsdy3pr+Vuj/HZ7nlMN2FyxIwUktOH1LEPIQXO1v9y1Q=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.2.16", "", { "os": "linux", "cpu": "arm" }, "sha512-tHdKWbFkFBI687iim3LIyIvyL7j66VvQYkDPss5Stn/qyE2tWkR1YD0dXmXPFKKqT/o5ZEJVsaRsWS2meQwGOA=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.2.16", "", { "os": "linux", "cpu": "arm64", "libc": "glibc" }, "sha512-FJiLGAblPBMlBEdbOqw6kW6QcXDWAf/oJu7gYs9ZJZwmg+K+/zjFLxPTIY9izJUzxzc24FHvmseyA0IvJSl17w=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.2.16", "", { "os": "linux", "cpu": "arm64", "libc": "musl" }, "sha512-hrJpblMsrQ58U9veWpbXzkhV5zStunds6HWLprqq1qauvgBr1E6P+24kLj6lSLI9vjRn/RYpjprhkHQPKGWpNg=="], + + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.2.16", "", { "os": "linux", "cpu": "ppc64", "libc": "glibc" }, "sha512-qJd/dC6j6CwLG9/s/RP2nb1RZ0GIgj7Ioj7x/SYa3RzjVrlzrmH0fhIOpfvqQDeIsdP0loi+kHaMhJzY1PBIaA=="], + + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.2.16", "", { "os": "linux", "cpu": "s390x", "libc": "glibc" }, "sha512-Vx7Xg5uUJuNcujJjI70OICaH0EYj80BtOLZTSN7uOYg8QOLlyKnaG0IW7Fn/J0IpJsaKzmDKMhOQv1JBM9m9vg=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.2.16", "", { "os": "linux", "cpu": "x64", "libc": "glibc" }, "sha512-TNKhgE3uJTsTzatUSSYt0Kgo+Oa2uSlSjz4r1aEIea7HX6ULBym4fAlYUhG1i6pjNf2njfCUAfKwr6C3E9Xg1w=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.2.16", "", { "os": "linux", "cpu": "x64", "libc": "musl" }, "sha512-7chXdpjXZ8qG0+mIxECN3cT9kvhZ3/oZhMX6Pp876P7CDrIy8nJswva6Mq357JR7eYXfuskwZxMeV1SzoZdHrA=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.2.16", "", { "os": "none", "cpu": "arm64" }, "sha512-Kwjt+7uNTJK5/MDkGWGVO2KQPnj8yAV75dMpfwyHZrJSXWHrniOB0aUEWlVYf3H1hOqFLIStLdM5QXq6bnKmOQ=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.2.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-/LH6WfjDRXXJz/p5xl4TmU+jpcnwcxbKEQBW/GZE0JHfN0lGIyTtsUEGaQ/q/GikkGJ2yLKe6pwm7AnEWO8pdw=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.2.16", "", { "os": "win32", "cpu": "x64" }, "sha512-1lv1KvX0Z871zfk7vw+dnXMMnHNyDwMzWG8Kv3HxDXMOhzCX4SHc7HK319fInP0i+0p9D8brkfzL7pJOaGl+tw=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], + + "@shikijs/core": ["@shikijs/core@4.6.0", "", { "dependencies": { "@shikijs/primitive": "4.6.0", "@shikijs/types": "4.6.0", "@shikijs/vscode-textmate": "^10.1.0", "@types/hast": "^3.0.5", "hast-util-to-html": "^9.0.6" } }, "sha512-bfd4OKgvoyXYiYmMRuleA656P4V7M/Du9lcTl38Ngm6KszMj7bq4J1IGZwSYR4c95Tv5UQALtYNWUwaI9UT3xw=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.6.0", "", { "dependencies": { "@shikijs/types": "4.6.0", "@shikijs/vscode-textmate": "^10.1.0", "oniguruma-to-es": "^4.3.6" } }, "sha512-K0oqxFoL+kEMdz89mHLFO15Tsbv3kFZ6WR1cXZKMvLSc+oqaM00A6pyga1qSeXB22dP0tTiSApRcGBaKWsEccg=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.6.0", "", { "dependencies": { "@shikijs/types": "4.6.0", "@shikijs/vscode-textmate": "^10.1.0" } }, "sha512-aggd6Q7SuJOXNnsUbfG2XesxBJKBMAw/PDTUo9PyRjMaaJJ2dNrI+q0C+25ARXAK9yLHAlwxc9oRT2u68YKZ7w=="], + + "@shikijs/langs": ["@shikijs/langs@4.6.0", "", { "dependencies": { "@shikijs/types": "4.6.0" } }, "sha512-1yMEX3oCVV54LUq/ovfpRkDQoYDkcvjSWFFa/YLUDMiSoRzMi2uxLJYbv41ahT8Lu9lFMaa7hecd3Q39trqUyg=="], + + "@shikijs/primitive": ["@shikijs/primitive@4.6.0", "", { "dependencies": { "@shikijs/types": "4.6.0", "@shikijs/vscode-textmate": "^10.1.0", "@types/hast": "^3.0.5" } }, "sha512-c54+TQEo9ToqgfL/AU8FpjnV09+GA9Oa7M5ROkkXteZfp5XzpAJGXjjvZQFQioJOwm/w/6Z3lIzQstAkl8coag=="], + + "@shikijs/themes": ["@shikijs/themes@4.6.0", "", { "dependencies": { "@shikijs/types": "4.6.0" } }, "sha512-qHAVAs80RiGD+IRuH9G+JPDOEc9A/kHsng4EzCUCwB9bLzW6Z0y9WETh2YyCcADJBmfrIaJ1Jp7KBNP6FHkgtQ=="], + + "@shikijs/types": ["@shikijs/types@4.6.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.1.0", "@types/hast": "^3.0.5" } }, "sha512-+ENG1adsKt/X7cRYw1Nl7BEpBmPOjmQ7bR/eGmHuMlT8gtOFf3KEi5l31DJYyAWhW6Y6bjP1plU7FmaxWGENFw=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.1.0", "", {}, "sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ=="], + + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.4", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A=="], + + "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], + + "@types/estree": ["@types/estree@1.0.10", "", {}, "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g=="], + + "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], + + "@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="], + + "@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="], + + "@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/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="], + + "@types/node": ["@types/node@24.19.2", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ=="], + + "@types/sax": ["@types/sax@1.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.4.0", "", {}, "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ=="], + + "@volar/kit": ["@volar/kit@2.4.30", "", { "dependencies": { "@volar/language-service": "2.4.30", "@volar/typescript": "2.4.30", "typesafe-path": "^0.2.2", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "<7" } }, "sha512-VocLtumfXnqnPQEWc9Yx7uC1uOh9gyjVNlrn2+6Zx/z9aM6yTLhPK8lSqM9Ilu81XRa48I00lcYJWLi2BLxx8Q=="], + + "@volar/language-core": ["@volar/language-core@2.4.30", "", { "dependencies": { "@volar/source-map": "2.4.30" } }, "sha512-73fjwEV8wat6aOZ6U/y/hqtE30ocrIWECg67b0txGczOMNw+MffLmvJ5fnFfN9drVUEYZzLdaNo6VAy6G6avMw=="], + + "@volar/language-server": ["@volar/language-server@2.4.30", "", { "dependencies": { "@volar/language-core": "2.4.30", "@volar/language-service": "2.4.30", "@volar/typescript": "2.4.30", "path-browserify": "^1.0.1", "request-light": "^0.7.0", "vscode-languageserver": "^9.0.1", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "<7" }, "optionalPeers": ["typescript"] }, "sha512-tcP9fzzUBbsLIFHhgnRU4ncQjMn9G9Vax0ffkQmdCrXVEYqRroUepmyC5AVgiju5bCiLD6a55qen5iOTQHkb3g=="], + + "@volar/language-service": ["@volar/language-service@2.4.30", "", { "dependencies": { "@volar/language-core": "2.4.30", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "<7" }, "optionalPeers": ["typescript"] }, "sha512-w/xDsASiqC71ggCOm7sTDXDNk/l72XEptodeRC68tgZ0e5QM4hM3zAqBGC7mBctvhrpYwKfMG+t9xcUo2hEFtA=="], + + "@volar/source-map": ["@volar/source-map@2.4.30", "", {}, "sha512-zym1ob/KwDDyN+0jGVtxwbxJSRRnUvv5HspCtz3yEfVVdCG4/dzxJktMGPAgemqRuVs81O0o/y0q3qOUErR8kg=="], + + "@volar/typescript": ["@volar/typescript@2.4.30", "", { "dependencies": { "@volar/language-core": "2.4.30", "@volar/language-service": "2.4.30", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "<7" }, "optionalPeers": ["typescript"] }, "sha512-/DgA5tgYFPfrLFuSjIMXMGHk1LQv2+P8eny6+BhGNzFJELWIW7UZlc56ZLIRFhLsPpMfIFxM8/HvOPBggrjTZg=="], + + "@vscode/emmet-helper": ["@vscode/emmet-helper@2.11.0", "", { "dependencies": { "emmet": "^2.4.3", "jsonc-parser": "^2.3.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.15.1", "vscode-uri": "^3.0.8" } }, "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw=="], + + "@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="], + + "ajv": ["ajv@8.20.0", "", { "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-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + + "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], + + "ajv-i18n": ["ajv-i18n@4.2.0", "", { "peerDependencies": { "ajv": "^8.0.0-beta.0" } }, "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg=="], + + "am-i-vibing": ["am-i-vibing@0.5.0", "", { "dependencies": { "process-ancestry": "^0.1.0" }, "bin": { "am-i-vibing": "dist/cli.mjs" } }, "sha512-KLcsDhqf1XRrJmJr+9I/C0EX2K+sGrAGZFgkmd84c8TJO9zJBu+/kFInjazu1KfJWFhWDKdRWkpBzEs7s35DVA=="], + + "ansi-regex": ["ansi-regex@6.5.0", "", {}, "sha512-zhvbbbdt1kbw7EJ9OQoxmQcuaNR9P5kTj7e/YdmOSU10aHWbycofJxA6jKfoEy3vlLdctOF9ZHaxLtmSm998wQ=="], + + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + + "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], + + "astro": ["astro@7.4.5", "", { "dependencies": { "@astrojs/compiler-rs": "^0.5.1", "@astrojs/internal-helpers": "0.13.0", "@astrojs/markdown-satteri": "0.4.6", "@astrojs/telemetry": "3.4.2", "@capsizecss/unpack": "^4.0.1", "@clack/prompts": "^1.8.1", "@oslojs/encoding": "^1.1.0", "am-i-vibing": "^0.5.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", "cookie": "^2.0.1", "devalue": "^6.0.2", "diff": "^9.0.0", "dset": "^3.1.4", "es-module-lexer": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.4.1", "get-tsconfig": "5.0.0-beta.6", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.3.0", "jsonc-parser": "^3.3.1", "magic-string": "^1.4.3", "magicast": "^0.5.5", "mrmime": "^2.0.1", "neotraverse": "^1.0.1", "obug": "^3.0.0", "p-limit": "^7.3.3", "p-queue": "^9.3.5", "package-manager-detector": "^1.9.0", "piccolore": "^0.1.3", "picomatch": "^4.0.7", "rolldown": "^1.2.14", "shiki": "^4.5.0", "smol-toml": "^1.9.1", "svgo": "^4.1.0", "tinyclip": "^1.0.3", "tinyexec": "^1.3.1", "tinyglobby": "^0.2.17", "tinyps": "^0.5.0", "ultrahtml": "^1.7.0", "unifont": "^1.0.3", "unstorage": "^1.17.5", "verkit": "^0.5.0", "vite": "^8.3.5", "vitefu": "^1.1.3", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", "zod": "^4.6.6" }, "optionalDependencies": { "sharp": "^0.35.4" }, "peerDependencies": { "@astrojs/markdown-remark": "^7.3.0" }, "optionalPeers": ["@astrojs/markdown-remark"], "bin": { "astro": "./bin/astro.mjs" } }, "sha512-n5lET11/qnrOWn4wNpXxD9g2VKkTIa162hHgrkMPChMQC5q/xh2lY2OerK5mpsEAFCNmXsYA7NISE+9Uo7Cxxg=="], + + "astro-expressive-code": ["astro-expressive-code@0.44.3", "", { "dependencies": { "rehype-expressive-code": "^0.44.3", "url-extras": "^0.1.0" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta || ^7.0.0" } }, "sha512-LUpQmmvzr90JXP5QIAopgdjlOKLuT3x0wlPAUpc4OZtPtFS8sbflPcGPpL/lG3pQuUCQV2CXUFgYNBYNu9tphA=="], + + "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], + + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + + "bcp-47": ["bcp-47@2.1.2", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-wsv86UuNFuPnVieKLyECTT+CP1WSAHeoIg5P3xu2kA9Z+7fVPoKt7dxzSeEhtJel0AI+NW3fIW3KtTKQKUCngg=="], + + "bcp-47-match": ["bcp-47-match@2.0.3", "", {}, "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ=="], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "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=="], + + "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], + + "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + + "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + + "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], + + "common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], + + "cookie": ["cookie@2.0.1", "", {}, "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w=="], + + "cookie-es": ["cookie-es@1.2.3", "", {}, "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw=="], + + "crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="], + + "css-select": ["css-select@6.0.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^7.0.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "nth-check": "^2.1.1" } }, "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw=="], + + "css-selector-parser": ["css-selector-parser@3.3.0", "", {}, "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g=="], + + "css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], + + "css-what": ["css-what@7.0.0", "", {}, "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ=="], + + "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + + "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "devalue": ["devalue@6.0.3", "", {}, "sha512-3woMEITftG1wKeO/4d/QXH1DVKctTSZg3jNGPpjp9hNr5Hos8MCFF5McTML5ZtgKDObm2R591B0spRp2IVernA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="], + + "direction": ["direction@2.0.1", "", { "bin": { "direction": "cli.js" } }, "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], + + "emmet": ["emmet@2.4.11", "", { "dependencies": { "@emmetio/abbreviation": "^2.3.3", "@emmetio/css-abbreviation": "^2.1.8" } }, "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "es-module-lexer": ["es-module-lexer@3.0.4", "", {}, "sha512-BldNY5mwkVu+cQ5Ymn3e6hB9Sx8XHx4ZevWbiUyZbfKxJxYO27Hf0wfzkxIaD5CAJMaGl3YspKELj0ff/7nCMA=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + + "expressive-code": ["expressive-code@0.44.3", "", { "dependencies": { "@expressive-code/core": "^0.44.3", "@expressive-code/plugin-frames": "^0.44.3", "@expressive-code/plugin-shiki": "^0.44.3", "@expressive-code/plugin-text-markers": "^0.44.3" } }, "sha512-7RGslhJTNt01pdn5I3QmVh5C8ZIiSm0A+ORQ9j9r39oOgJVKjn/7dXl9rMT/SqmFLE6pJkTYI7UjW0BxJnW7OQ=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], + + "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], + + "fast-uri": ["fast-uri@3.1.9", "", {}, "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ=="], + + "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="], + + "fnv1a-64": ["fnv1a-64@0.1.2", "", {}, "sha512-mJbcILTPybAR1jdOwt/lVv8N2cffeJFFP+gVbSAwLEx1ujXH27RpPd8Rokec/KX9c76UYIB6Co+H4lQzxPnJfA=="], + + "fontace": ["fontace@0.4.1", "", { "dependencies": { "fontkitten": "^1.0.2" } }, "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw=="], + + "fontkitten": ["fontkitten@1.0.3", "", { "dependencies": { "tiny-inflate": "^1.0.3" } }, "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin", "hasInstallScript": true }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-east-asian-width": ["get-east-asian-width@1.7.0", "", {}, "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q=="], + + "get-tsconfig": ["get-tsconfig@5.0.0-beta.6", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw=="], + + "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], + + "h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="], + + "hast-util-embedded": ["hast-util-embedded@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA=="], + + "hast-util-format": ["hast-util-format@1.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-minify-whitespace": "^1.0.0", "hast-util-phrasing": "^3.0.0", "hast-util-whitespace": "^3.0.0", "html-whitespace-sensitive-tag-names": "^3.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA=="], + + "hast-util-has-property": ["hast-util-has-property@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA=="], + + "hast-util-is-body-ok-link": ["hast-util-is-body-ok-link@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ=="], + + "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-minify-whitespace": ["hast-util-minify-whitespace@1.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-is-element": "^3.0.0", "hast-util-whitespace": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw=="], + + "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], + + "hast-util-phrasing": ["hast-util-phrasing@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-has-property": "^3.0.0", "hast-util-is-body-ok-link": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ=="], + + "hast-util-select": ["hast-util-select@6.0.4", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "bcp-47-match": "^2.0.0", "comma-separated-tokens": "^2.0.0", "css-selector-parser": "^3.0.0", "devlop": "^1.0.0", "direction": "^2.0.0", "hast-util-has-property": "^3.0.0", "hast-util-to-string": "^3.0.0", "hast-util-whitespace": "^3.0.0", "nth-check": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.6", "", { "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-1SZUxCN3TtJAE7e2BQN2MBHsoZ1gnmi9GoCP5Di59CSWptIezSAW09yDZyVbanb78V9eCwrKqdQsjtfVTxYHWA=="], + + "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], + + "hast-util-to-text": ["hast-util-to-text@4.0.3", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-5yrlWOvGFs6CqHriUpSsNrjzT/Tdo+IOQudbznxOn8K5qblp18MJyzOg8IgDOKQ8MYgQcJA7SusuCjSpDr8mSA=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "hastscript": ["hastscript@9.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-1ALZXSmCGmW3h8AMz4R4+QKSKFi7sNgXLVwmwB8FYVtl1CwQ3WDkSAEY/d5tp1g/vbQgq2s1WlHgfO3jbw1TsA=="], + + "html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "html-whitespace-sensitive-tag-names": ["html-whitespace-sensitive-tag-names@3.0.1", "", {}, "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA=="], + + "http-cache-semantics": ["http-cache-semantics@4.3.0", "", {}, "sha512-M5t5LlJpS1UHMjvwRQVdFHvPISGeLAxNcrWuJkeGh0KxsqCHZ1O3NXZU/8x7cD0BDcGW8kapxMKTvwlqrNkHkA=="], + + "i18next": ["i18next@26.7.1", "", { "peerDependencies": { "typescript": "^5 || ^6 || ^7" }, "optionalPeers": ["typescript"] }, "sha512-cX+3RRVczel/V2kCMTACckSGSpqgtWYEA6beXNYVms7dOQiHojdPYHD26lT4IKimNeoGWrLvtPgjftbRvmZJVw=="], + + "iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="], + + "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], + + "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], + + "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], + + "is-docker": ["is-docker@4.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA=="], + + "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "js-yaml": ["js-yaml@4.3.2", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + + "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], + + "klona": ["klona@2.0.6", "", {}, "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA=="], + + "lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.33.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.33.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.33.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.33.0", "", { "os": "linux", "cpu": "arm" }, "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.33.0", "", { "os": "linux", "cpu": "arm64", "libc": "glibc" }, "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.33.0", "", { "os": "linux", "cpu": "arm64", "libc": "musl" }, "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.33.0", "", { "os": "linux", "cpu": "x64", "libc": "glibc" }, "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.33.0", "", { "os": "linux", "cpu": "x64", "libc": "musl" }, "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.33.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.33.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + + "lru-cache": ["lru-cache@11.5.3", "", {}, "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg=="], + + "magic-string": ["magic-string@1.4.5", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.6.0" } }, "sha512-oLLC2+YvQUfAa+vxoufE/yc1icb87M9iXIRqAoR/2EhE/8cb3SF/+Gi0c2By1B+5Vz2e2vQtUvHiu1+63Znh+w=="], + + "magicast": ["magicast@0.5.5", "", { "dependencies": { "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7", "source-map-js": "^1.2.1" } }, "sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA=="], + + "mdast-util-directive": ["mdast-util-directive@3.2.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.2.0", "micromark-util-character": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0" } }, "sha512-Yxq+hH4pBEmtaLIJyMVcNbtBiCIKzdOK3HvDeM+JAqC8XVAT1e5PUYbHBpwFvQLIJuJfO2zCu7aNUXWoyZLmhw=="], + + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.1.0", "", { "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-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A=="], + + "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.2.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-character": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-ELNT5jYDUdx0B/hlUSSAiAEtvqkY3Oriwkp1KEYseF1Ccu4MnKkmE5yK3oE3WGT/Pq8VTE+XwP0GLL5pafY8yA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], + + "micromark": ["micromark@4.0.3", "", { "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-edit-map": "^1.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-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.4", "", { "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.1.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-edit-map": "^1.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.3" } }, "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w=="], + + "micromark-extension-directive": ["micromark-extension-directive@4.0.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "parse-entities": "^4.0.0" } }, "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg=="], + + "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.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q=="], + + "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-edit-map": ["micromark-util-edit-map@1.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q=="], + + "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.3", "", {}, "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg=="], + + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="], + + "nanoid": ["nanoid@3.3.20", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ=="], + + "neotraverse": ["neotraverse@1.0.1", "", {}, "sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w=="], + + "nlcst-to-string": ["nlcst-to-string@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0" } }, "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA=="], + + "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], + + "node-mock-http": ["node-mock-http@1.0.5", "", {}, "sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw=="], + + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "obug": ["obug@3.0.0", "", {}, "sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw=="], + + "ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], + + "oniguruma-parser": ["oniguruma-parser@0.12.2", "", {}, "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw=="], + + "oniguruma-to-es": ["oniguruma-to-es@4.3.6", "", { "dependencies": { "oniguruma-parser": "^0.12.2", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA=="], + + "p-limit": ["p-limit@7.3.3", "", { "dependencies": { "yocto-queue": "^1.2.1" } }, "sha512-SKgVvDU5TNIxQ4r30U75BNLC6a+6GOEjngrk/ysM5+Zu3oJuk1SC5ApzIzY/7PjCEjoVPMWJ0zho/4QUiEB7TQ=="], + + "p-queue": ["p-queue@9.3.5", "", { "dependencies": { "eventemitter3": "^5.0.4", "p-timeout": "^7.0.0" } }, "sha512-Lki/zhXFVmDhesBUn/yHRLW9Bte7mE7xoFHzTR8sIomV7a2z+LxYAPkGvdfidNiu4fKSfjtawixxSHcZci5QcQ=="], + + "p-timeout": ["p-timeout@7.0.2", "", {}, "sha512-prbX4Z3YszrFNgH+MW5Zoeq3baXrMtP/MQnFeET90UB/GtGcGDQ5Usg9OCy6ETjTTntOw1SL2z9fMPUppN3Guw=="], + + "package-manager-detector": ["package-manager-detector@1.9.0", "", {}, "sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA=="], + + "pagefind": ["pagefind@1.6.0", "", { "optionalDependencies": { "@pagefind/darwin-arm64": "1.6.0", "@pagefind/darwin-x64": "1.6.0", "@pagefind/freebsd-x64": "1.6.0", "@pagefind/linux-arm64": "1.6.0", "@pagefind/linux-x64": "1.6.0", "@pagefind/windows-arm64": "1.6.0", "@pagefind/windows-x64": "1.6.0" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-yeOd9EA0TUE1PUfbQIluBxzPadBG5/0BV48FAxwMVLkhZcOvwCz6TX4/a/Ofz97pF9/FwwT7CVbTC97BfmI+LQ=="], + + "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], + + "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="], + + "piccolore": ["piccolore@0.1.3", "", {}, "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.7", "", {}, "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA=="], + + "postcss": ["postcss@8.5.32", "", { "dependencies": { "nanoid": "^3.3.20", "picocolors": "^1.1.1", "source-map-js": "^1.2.2" } }, "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g=="], + + "postcss-nested": ["postcss-nested@7.0.2", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-5osppouFc0VR9/VYzYxO03VaDa3e8F23Kfd6/9qcZTUI8P58GIYlArOET2Wq0ywSl2o2PjELhYOFI4W7l5QHKw=="], + + "postcss-selector-parser": ["postcss-selector-parser@7.1.7", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-wWBro/7hJ40ye6TPiXkUQoXKCw23xSsjriUvqd7Uls9Sso3oLiON1flc18cCdnjgCRXw4fBVqUJJeOdDTh3P3g=="], + + "prettier": ["prettier@3.9.10", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA=="], + + "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], + + "process-ancestry": ["process-ancestry@0.1.0", "", {}, "sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg=="], + + "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], + + "radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="], + + "readdirp": ["readdirp@5.1.1", "", {}, "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA=="], + + "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-expressive-code": ["rehype-expressive-code@0.44.3", "", { "dependencies": { "expressive-code": "^0.44.3" } }, "sha512-vaVuQPobFXvmtcHXQ5uqXZlzuuPnLyIuZcX/03sX1U/Qfj9fZrPYI9w66OSr/PUx6alzRYmreEwgYBbsVx8HsA=="], + + "remark-directive": ["remark-directive@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", "micromark-extension-directive": "^4.0.0", "unified": "^11.0.0" } }, "sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA=="], + + "request-light": ["request-light@0.7.0", "", {}, "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + + "retext-smartypants": ["retext-smartypants@6.2.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "nlcst-to-string": "^4.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ=="], + + "rolldown": ["rolldown@1.2.16", "", { "dependencies": { "@oxc-project/types": "=0.156.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm-eabi": "1.2.16", "@rolldown/binding-android-arm64": "1.2.16", "@rolldown/binding-darwin-arm64": "1.2.16", "@rolldown/binding-darwin-x64": "1.2.16", "@rolldown/binding-freebsd-x64": "1.2.16", "@rolldown/binding-linux-arm-gnueabihf": "1.2.16", "@rolldown/binding-linux-arm64-gnu": "1.2.16", "@rolldown/binding-linux-arm64-musl": "1.2.16", "@rolldown/binding-linux-ppc64-gnu": "1.2.16", "@rolldown/binding-linux-s390x-gnu": "1.2.16", "@rolldown/binding-linux-x64-gnu": "1.2.16", "@rolldown/binding-linux-x64-musl": "1.2.16", "@rolldown/binding-openharmony-arm64": "1.2.16", "@rolldown/binding-win32-arm64-msvc": "1.2.16", "@rolldown/binding-win32-x64-msvc": "1.2.16" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-bWvlMpFKiTfDKfnK7FC2MPgPeWCf/Kpwsq49ApdW+FQaBZb6O6dZ4MAPbPUjp7hYQrw/RobqCzn64BRrQecGHw=="], + + "satteri": ["satteri@0.10.5", "", { "dependencies": { "@types/estree-jsx": "^1.0.5", "@types/hast": "^3.0.5", "@types/mdast": "^4.0.4", "@types/unist": "^3.0.3" }, "optionalDependencies": { "@bruits/satteri-darwin-arm64": "0.10.5", "@bruits/satteri-darwin-x64": "0.10.5", "@bruits/satteri-linux-arm64-gnu": "0.10.5", "@bruits/satteri-linux-arm64-musl": "0.10.5", "@bruits/satteri-linux-x64-gnu": "0.10.5", "@bruits/satteri-linux-x64-musl": "0.10.5", "@bruits/satteri-wasm32-wasi": "0.10.5", "@bruits/satteri-win32-arm64-msvc": "0.10.5", "@bruits/satteri-win32-x64-msvc": "0.10.5" } }, "sha512-Ao1LKpAEa9Wdg0otgbVKViZHEq9ebdXe4DMrp3s9vQAU0HNIuHnFEuMuOcm0ZIXyV0Yzxj91NvhLpvXZJO/5ZQ=="], + + "sax": ["sax@1.6.1", "", {}, "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q=="], + + "semver": ["semver@7.8.6", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw=="], + + "sharp": ["sharp@0.35.5", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.5", "@img/sharp-darwin-x64": "0.35.5", "@img/sharp-freebsd-wasm32": "0.35.5", "@img/sharp-libvips-darwin-arm64": "1.3.4", "@img/sharp-libvips-darwin-x64": "1.3.4", "@img/sharp-libvips-linux-arm": "1.3.4", "@img/sharp-libvips-linux-arm64": "1.3.4", "@img/sharp-libvips-linux-ppc64": "1.3.4", "@img/sharp-libvips-linux-riscv64": "1.3.4", "@img/sharp-libvips-linux-s390x": "1.3.4", "@img/sharp-libvips-linux-x64": "1.3.4", "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", "@img/sharp-libvips-linuxmusl-x64": "1.3.4", "@img/sharp-linux-arm": "0.35.5", "@img/sharp-linux-arm64": "0.35.5", "@img/sharp-linux-ppc64": "0.35.5", "@img/sharp-linux-riscv64": "0.35.5", "@img/sharp-linux-s390x": "0.35.5", "@img/sharp-linux-x64": "0.35.5", "@img/sharp-linuxmusl-arm64": "0.35.5", "@img/sharp-linuxmusl-x64": "0.35.5", "@img/sharp-webcontainers-wasm32": "0.35.5", "@img/sharp-win32-arm64": "0.35.5", "@img/sharp-win32-ia32": "0.35.5", "@img/sharp-win32-x64": "0.35.5" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g=="], + + "shiki": ["shiki@4.6.0", "", { "dependencies": { "@shikijs/core": "4.6.0", "@shikijs/engine-javascript": "4.6.0", "@shikijs/engine-oniguruma": "4.6.0", "@shikijs/langs": "4.6.0", "@shikijs/themes": "4.6.0", "@shikijs/types": "4.6.0", "@shikijs/vscode-textmate": "^10.1.0", "@types/hast": "^3.0.5" } }, "sha512-imjLsVHgPuWhvpU3P+zOekvMYqnel7QmKsFC4Sn0fCuAvaaalBsxwKEsrU8Ko5BdFnZA6Go/8a0RzahS634UgA=="], + + "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], + + "sitemap": ["sitemap@9.0.1", "", { "dependencies": { "@types/node": "^24.9.2", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.4.1" }, "bin": { "sitemap": "dist/esm/cli.js" } }, "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ=="], + + "smol-toml": ["smol-toml@1.9.1", "", {}, "sha512-j7WyPdf0CJoutMzMoPLF/bVXHtKZIT9Rb4eGeEbWw8X2t5oirjPgpL+OpaENZrILYaXqYwnVH+qgUwVbl+pUJQ=="], + + "source-map-js": ["source-map-js@1.2.2", "", {}, "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "std-env": ["std-env@4.3.0", "", {}, "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag=="], + + "string-width": ["string-width@8.3.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ=="], + + "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@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "svgo": ["svgo@4.1.0", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^6.0.0", "css-tree": "^3.0.1", "css-what": "^7.0.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "1.6.1" }, "bin": { "svgo": "bin/svgo.js" } }, "sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q=="], + + "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], + + "tinyclip": ["tinyclip@1.0.3", "", {}, "sha512-nTv2raKFMzGG6JJp0lpNDsRPdfFE6UHlu2rVEjXo8vkx1ZS3LW2CVXqIaLu8xZlu+6tbFs9V58Qc/Jmk/Ii7wA=="], + + "tinyexec": ["tinyexec@1.3.1", "", {}, "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA=="], + + "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], + + "tinyps": ["tinyps@0.5.1", "", {}, "sha512-B6Ykif5HflC3AdDkS4Zst/2muYVfeXoVMy+KorqH80s/1x4vunIORpNySH681X7fjj+dFM9MDKD6/Hsccjb87Q=="], + + "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.9.1", "", {}, "sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA=="], + + "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], + + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "typescript-auto-import-cache": ["typescript-auto-import-cache@0.3.6", "", { "dependencies": { "semver": "^7.3.8" } }, "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ=="], + + "ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="], + + "ultrahtml": ["ultrahtml@1.7.0", "", {}, "sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g=="], + + "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], + + "undici": ["undici@8.12.3", "", {}, "sha512-+fdndUTwBP86cVjihTp21hZHo7d6oj1c/47XPA3lL8mM0XHs+C4EkcjmgRsFnFk2f/UONGDy9ItBItmXsLOQHw=="], + + "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + + "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=="], + + "unifont": ["unifont@1.0.3", "", { "dependencies": { "css-tree": "^3.1.0", "fnv1a-64": "^0.1.2", "std-env": "^4.2.0", "undici": "^8.0.0" } }, "sha512-XGnEwj5sWdCbiBX01mWLSBncS0yMRjnLygau3IfdOlfjMacNIQvTGW4VH7pWBq+gGWArfSef/CensMLjMmIr/A=="], + + "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@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.2.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.1.0" } }, "sha512-fpsYs/VVoZxfGY9/j3FQpZmN8wdLJaV1Pt38AaJNZu9uKIHcFU3halCdBveEq1HGKO1OEfJY65w1zvoFV1b3qQ=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w=="], + + "unstorage": ["unstorage@1.17.6", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.11", "lru-cache": "^11.5.3", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.4" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-gjKtcmn/KwZuJZO9o2sc0esAQnhmTw0LviDHwevTXbJMYs0dRTp8ZEEWXHU0vTpzbN3cA0yxlTeyXssMp3zDqw=="], + + "url-extras": ["url-extras@0.1.0", "", {}, "sha512-8tzwTeXFPuX/5PHuCDQE5Dd9Ts4rwoq2t9aIT+HS4iAVpmj5l4Ao7Q+BuuFjvWRqrLswBhQDk8O96ZicgCqQqw=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "verkit": ["verkit@0.5.0", "", {}, "sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g=="], + + "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@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "vite": ["vite@8.3.5", "", { "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.7", "postcss": "^8.5.30", "rolldown": "~1.2.14", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.7.1 || ^0.8.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ=="], + + "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], + + "volar-service-css": ["volar-service-css@0.0.71", "", { "dependencies": { "vscode-css-languageservice": "^6.3.0", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-wRRFt9BpjMKCazcgOh67MSjUjiWUCAh99DyYSDIOTuxaRjEtDC7PpB0k1Y1wbJIW/pVtMUSVbpPo3UGSm0Byxw=="], + + "volar-service-emmet": ["volar-service-emmet@0.0.71", "", { "dependencies": { "@emmetio/css-parser": "^0.4.1", "@emmetio/html-matcher": "^1.3.0", "@vscode/emmet-helper": "^2.9.3", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-zqjzt6bN95e3CUstBm0PBFAJnrfz0ZAARka87fart46/gNCLLuP3Vujy8V/J8HEziTFLnfkgIASLFYPUhonJcA=="], + + "volar-service-html": ["volar-service-html@0.0.71", "", { "dependencies": { "vscode-html-languageservice": "^5.3.0", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-e8tHPhgQ7ooLfudAEIku+kgd9pWkq3SSz8RbnQDI1+Eb8wbenkLGHqoirLqz5ORLV6wIMr2Iv08RWBG5eOcgpw=="], + + "volar-service-prettier": ["volar-service-prettier@0.0.71", "", { "dependencies": { "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0", "prettier": "^2.2 || ^3.0" }, "optionalPeers": ["@volar/language-service", "prettier"] }, "sha512-Rz7JVH3qD108UCdmIEiZvOBNljMt2nLFdbN8AXcDfn7xD9F5I2aCIsDVqBbXw21PsnxG0b7MfwtNF+zPS/NKUg=="], + + "volar-service-typescript": ["volar-service-typescript@0.0.71", "", { "dependencies": { "path-browserify": "^1.0.1", "semver": "^7.6.2", "typescript-auto-import-cache": "^0.3.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-nls": "^5.2.0", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-yTtM/BVT6hoyEYnDtaCyAtNhdNeS/mhTTABlBOdw3NNiRBUin3IznFJpgfjer4c6RYopiPjjQjc9VFhxVl1mLw=="], + + "volar-service-typescript-twoslash-queries": ["volar-service-typescript-twoslash-queries@0.0.71", "", { "dependencies": { "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-9K2k72s4n7rV9s4bX0MyjbX9iBribvKZbBJKuEmTCZfeWJXs6Yh7bGpY4eoc7UufAjvpheBqwyZCOIPBvxCv0A=="], + + "volar-service-yaml": ["volar-service-yaml@0.0.71", "", { "dependencies": { "vscode-uri": "^3.0.8", "yaml-language-server": "~1.23.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-qYGWGuVpUTnZGu5P/CR4KLK4aIR8RrcVnmfZ2eRcj9q/I8VZCoC5yy9FtEvfNvnDp4MU17yhdJcvpQPIqhJS2Q=="], + + "vscode-css-languageservice": ["vscode-css-languageservice@6.3.10", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA=="], + + "vscode-html-languageservice": ["vscode-html-languageservice@5.6.2", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "^3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg=="], + + "vscode-json-languageservice": ["vscode-json-languageservice@4.1.8", "", { "dependencies": { "jsonc-parser": "^3.0.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.16.0", "vscode-nls": "^5.0.0", "vscode-uri": "^3.0.2" } }, "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg=="], + + "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], + + "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="], + + "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="], + + "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.16", "", {}, "sha512-qeNEuOi9a3qkqRf7Gfez2WL2VwlBTLCNekHBGO9kxPVUp9XuY15yfTJ9jwvOwKI0I2MhUUfZq95NSp+LK1CLQg=="], + + "vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="], + + "vscode-nls": ["vscode-nls@5.2.0", "", {}, "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="], + + "vscode-uri": ["vscode-uri@3.2.0", "", {}, "sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg=="], + + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + + "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yaml": ["yaml@2.9.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw=="], + + "yaml-language-server": ["yaml-language-server@1.23.0", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-i18n": "^4.2.0", "prettier": "^3.8.1", "request-light": "^0.5.7", "vscode-json-languageservice": "4.1.8", "vscode-languageserver": "^9.0.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.16.0", "vscode-uri": "^3.0.2", "yaml": "2.8.3" }, "bin": { "yaml-language-server": "bin/yaml-language-server" } }, "sha512-3qVyCOexLCWw06PQa5kRPwvMWMZ/eZeCRWUvgD6a0OkqL/4iCnxy2WumbWifa937Uo5xhyWJ0uxlU39ljhNh7A=="], + + "yargs": ["yargs@18.2.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^8.2.1", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w=="], + + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], + + "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], + + "zod": ["zod@4.6.7", "", {}, "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "@astrojs/compiler-binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], + + "@astrojs/compiler-binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.7", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || 2.0.0-beta.2 || 2.0.0-beta.3", "@emnapi/runtime": "^1.7.1 || 2.0.0-beta.2 || 2.0.0-beta.3" } }, "sha512-zJccwplOAbgfZju95IUHazLnx9RAPtPN2YGJXI6UbrgeaR9QfPjGrQL6ERkSAtnVCA4Q+83ApGyaX5zdpCaKkQ=="], + + "@bruits/satteri-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], + + "@bruits/satteri-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.7", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || 2.0.0-beta.2 || 2.0.0-beta.3", "@emnapi/runtime": "^1.7.1 || 2.0.0-beta.2 || 2.0.0-beta.3" } }, "sha512-zJccwplOAbgfZju95IUHazLnx9RAPtPN2YGJXI6UbrgeaR9QfPjGrQL6ERkSAtnVCA4Q+83ApGyaX5zdpCaKkQ=="], + + "@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], + + "@vscode/emmet-helper/jsonc-parser": ["jsonc-parser@2.3.1", "", {}, "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg=="], + + "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "cliui/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], + + "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + + "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], + + "yaml-language-server/yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], + + "@bruits/satteri-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], + + "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], + } +} diff --git a/site/docs-map.json b/site/docs-map.json new file mode 100644 index 00000000..fb4a2e36 --- /dev/null +++ b/site/docs-map.json @@ -0,0 +1,150 @@ +{ + "repository": "https://github.com/tickernelz/opencode-mem", + "source": "README.md", + "translations": { + "de": ".github/i18n/README.de.md", + "zh": ".github/i18n/README.zh.md", + "ar": ".github/i18n/README.ar.md", + "tr": ".github/i18n/README.tr.md", + "nl": ".github/i18n/README.nl.md" + }, + "untranslated": { + "Memory credential redaction": ["de", "zh", "ar", "tr", "nl"] + }, + "dropLines": ["^\\[!\\[", "^!\\[", "README\\.[a-z]{2}\\.md\\)"], + "configPages": ["configure/"], + "configSources": ["opencode-mem.example.jsonc", "src/config.ts"], + "pages": [ + { + "slug": "", + "group": "Start", + "title": "Overview", + "sections": ["OpenCode Memory", "Core Features"] + }, + { + "slug": "start/prerequisites", + "group": "Start", + "sections": ["Prerequisites", "Hardware / resource expectations"] + }, + { + "slug": "start/getting-started", + "group": "Start", + "sections": ["Getting Started", "Automatic memory context on OpenCode v2"] + }, + { + "slug": "start/local-checkout", + "group": "Start", + "sections": ["Using a local checkout"] + }, + { + "slug": "start/encryption", + "group": "Start", + "sections": ["Optional database encryption at rest"] + }, + { + "slug": "use/day-to-day", + "group": "Use", + "sections": ["How to use day-to-day", "Typical daily flow", "Automatic vs manual memory"] + }, + { + "slug": "use/memory-agents-skills", + "group": "Use", + "sections": ["Memory vs AGENTS.md vs Skills", "Shared Skills (V2)"] + }, + { + "slug": "use/auto-capture-and-profile", + "group": "Use", + "sections": ["Intelligent prompt-based memory extraction", "User profile"] + }, + { + "slug": "use/web-ui", + "group": "Use", + "sections": ["Web UI", "Health stats"] + }, + { + "slug": "use/examples", + "group": "Use", + "sections": ["Usage Examples"] + }, + { + "slug": "configure", + "group": "Configure", + "sections": ["Configuration Essentials"] + }, + { + "slug": "configure/auto-capture-provider", + "group": "Configure", + "sections": ["Auto-Capture AI Provider"] + }, + { + "slug": "configure/embeddings", + "group": "Configure", + "sections": ["Choosing / configuring embeddings"] + }, + { + "slug": "configure/markdown-vault", + "group": "Configure", + "sections": ["Markdown vault backend (`memoryBackend`)"] + }, + { + "slug": "configure/chat-message", + "group": "Configure", + "sections": ["Chat message capture and injection (`chatMessage`)"] + }, + { + "slug": "configure/update-on-capture", + "group": "Configure", + "sections": ["Update-on-capture (optional)"] + }, + { + "slug": "configure/dreaming", + "group": "Configure", + "sections": ["Dreaming (optional memory consolidation)"] + }, + { + "slug": "configure/memory-scope", + "group": "Configure", + "sections": ["Memory Scope"] + }, + { + "slug": "configure/web-ui-auth", + "group": "Configure", + "sections": ["Web UI HTTP Basic Auth"] + }, + { + "slug": "operate/credential-redaction", + "group": "Operate", + "sections": ["Memory credential redaction"] + }, + { + "slug": "operate/legacy-sqlite", + "group": "Operate", + "sections": ["Upgrading from legacy SQLite shards"] + }, + { + "slug": "operate/schema-migrations", + "group": "Operate", + "sections": ["Schema migrations"] + }, + { + "slug": "operate/nested-repos", + "group": "Operate", + "sections": ["Sharing One Project Memory Across Nested Repos"] + }, + { + "slug": "operate/moving-recovering", + "group": "Operate", + "sections": ["Moving or Recovering Project Memories"] + }, + { + "slug": "reference/subpath-exports", + "group": "Reference", + "sections": ["Public Subpath Exports", "`opencode-mem/tags`"] + }, + { + "slug": "reference/contributing", + "group": "Reference", + "sections": ["Development & Contribution", "License & Links"] + } + ] +} diff --git a/site/package.json b/site/package.json new file mode 100644 index 00000000..28bd3767 --- /dev/null +++ b/site/package.json @@ -0,0 +1,23 @@ +{ + "name": "opencode-mem-site", + "private": true, + "type": "module", + "scripts": { + "build": "node scripts/build-tokens.mjs && node scripts/build-docs.mjs && node scripts/fetch-numbers.mjs && astro build", + "dev": "node scripts/build-tokens.mjs && node scripts/build-docs.mjs && astro dev", + "preview": "astro preview", + "check": "astro check" + }, + "dependencies": { + "@astrojs/starlight": "0.42.8", + "@fontsource-variable/bricolage-grotesque": "5.3.0", + "@fontsource-variable/jetbrains-mono": "5.3.0", + "astro": "7.4.5", + "github-slugger": "2.0.0", + "sharp": "0.35.5" + }, + "devDependencies": { + "@astrojs/check": "0.9.12", + "typescript": "6.0.3" + } +} diff --git a/site/public/CNAME b/site/public/CNAME new file mode 100644 index 00000000..664cd7ce --- /dev/null +++ b/site/public/CNAME @@ -0,0 +1 @@ +opencode-mem.zhafron.my.id diff --git a/site/public/og.png b/site/public/og.png new file mode 100644 index 00000000..d56a4d51 Binary files /dev/null and b/site/public/og.png differ diff --git a/site/public/robots.txt b/site/public/robots.txt new file mode 100644 index 00000000..d46d8a96 --- /dev/null +++ b/site/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://opencode-mem.zhafron.my.id/sitemap-index.xml diff --git a/site/scripts/build-docs.mjs b/site/scripts/build-docs.mjs new file mode 100644 index 00000000..8f7d7f8d --- /dev/null +++ b/site/scripts/build-docs.mjs @@ -0,0 +1,239 @@ +import { execFileSync } from "node:child_process"; +import { mkdir, readFile, rm, writeFile } from "node:fs/promises"; +import { dirname, posix, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import GithubSlugger from "github-slugger"; + +const site = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +const repo = resolve(site, ".."); +const map = JSON.parse(await readFile(resolve(site, "docs-map.json"), "utf8")); +const outRoot = resolve(site, "src/content/docs"); +const failures = []; + +function parse(markdown) { + const lines = markdown.split("\n"); + const headings = []; + let fence = null; + lines.forEach((line, index) => { + const marker = line.match(/^\s*(`{3,}|~{3,})/); + if (marker) { + if (!fence) fence = marker[1]; + else if (marker[1][0] === fence[0] && marker[1].length >= fence.length) fence = null; + return; + } + if (fence) return; + const heading = line.match(/^(#{1,6})\s+(.+?)\s*#*\s*$/); + if (heading) headings.push({ level: heading[1].length, text: heading[2], line: index }); + }); + const slugger = new GithubSlugger(); + for (const [i, heading] of headings.entries()) { + heading.anchor = slugger.slug(heading.text); + const end = i + 1 < headings.length ? headings[i + 1].line : lines.length; + heading.body = lines.slice(heading.line + 1, end); + } + return headings; +} + +function lastChange(file) { + try { + return execFileSync("git", ["log", "-1", "--format=%cI", "--", file], { + cwd: repo, + encoding: "utf8", + }).trim(); + } catch { + return ""; + } +} + +const english = parse(await readFile(resolve(repo, map.source), "utf8")); +const claimed = new Map(); +for (const page of map.pages) { + for (const section of page.sections) { + if (!english.some((h) => h.text === section)) + failures.push(`docs-map.json: "${section}" is not a heading in ${map.source}`); + if (claimed.has(section)) failures.push(`docs-map.json: "${section}" is mapped twice`); + claimed.set(section, page); + } +} +for (const heading of english) { + if (!claimed.has(heading.text)) { + failures.push( + `${map.source}:${heading.line + 1}: heading "${heading.text}" is not mapped in site/docs-map.json` + ); + } +} + +function alignTranslation(lang, translated) { + const expected = english.filter((h) => !(map.untranslated[h.text] ?? []).includes(lang)); + if (expected.length !== translated.length) { + failures.push( + `${map.translations[lang]}: ${translated.length} headings, expected ${expected.length} (README has ${english.length}; list untranslated sections in docs-map.json "untranslated")` + ); + return null; + } + const byEnglish = new Map(); + expected.forEach((heading, i) => { + if (heading.level !== translated[i].level) { + failures.push( + `${map.translations[lang]}:${translated[i].line + 1}: "${translated[i].text}" is h${translated[i].level}, README "${heading.text}" is h${heading.level}` + ); + } + byEnglish.set(heading.text, translated[i]); + }); + return byEnglish; +} + +const languages = [ + { lang: "", file: map.source, sections: new Map(english.map((h) => [h.text, h])) }, +]; +for (const [lang, file] of Object.entries(map.translations)) { + const aligned = alignTranslation(lang, parse(await readFile(resolve(repo, file), "utf8"))); + if (aligned) languages.push({ lang, file, sections: aligned }); +} + +function route(lang, slug) { + return `/${[lang, "docs", slug].filter(Boolean).join("/")}/`; +} + +function anchorTargets(sections, lang) { + const targets = new Map(); + for (const page of map.pages) { + const pageSlugger = new GithubSlugger(); + page.sections.forEach((name, i) => { + const heading = sections.get(name); + if (!heading) return; + const href = route(lang, page.slug); + targets.set(heading.anchor, i === 0 ? href : `${href}#${pageSlugger.slug(heading.text)}`); + }); + } + return targets; +} + +const englishTargets = anchorTargets(languages[0].sections, ""); +const dropLines = map.dropLines.map((pattern) => new RegExp(pattern)); + +function rewriteLinks(text, file, targets, lang, slug) { + return text.replace(/(!?)\[([^\]]*)\]\(([^)\s]+)\)/g, (whole, bang, label, href) => { + if (/^[a-z]+:/i.test(href) || href.startsWith("//")) return whole; + if (href.startsWith("#")) { + const target = + targets.get(href.slice(1)) ?? (lang ? englishTargets.get(href.slice(1)) : undefined); + if (!target) { + failures.push( + `${file}: link "${href}" (docs page ${route(lang, slug)}) has no matching heading` + ); + return whole; + } + return `${bang}[${label}](${target})`; + } + const path = posix.normalize(posix.join(posix.dirname(file), href.split("#")[0])); + const kind = bang ? "raw" : "blob"; + const hash = href.includes("#") ? href.slice(href.indexOf("#")) : ""; + return `${bang}[${label}](${map.repository}/${kind}/main/${path}${hash})`; + }); +} + +function demote(lines, shift) { + let fence = null; + return lines.map((line) => { + const marker = line.match(/^\s*(`{3,}|~{3,})/); + if (marker) { + if (!fence) fence = marker[1]; + else if (marker[1][0] === fence[0] && marker[1].length >= fence.length) fence = null; + return line; + } + if (fence) return line; + return line.replace( + /^(#{1,6})(\s)/, + (_, hashes, space) => `${"#".repeat(Math.max(2, Math.min(6, hashes.length - shift)))}${space}` + ); + }); +} + +function yaml(value) { + return JSON.stringify(value); +} + +function configKeys(body) { + const keys = []; + for (const line of body.split("\n")) { + const cell = line.match(/^\|\s*([^|]+?)\s*\|/); + if (!cell || /^[-:\s]+$/.test(cell[1])) continue; + for (const [, key] of cell[1].matchAll(/`([A-Za-z][A-Za-z0-9]*(?:\.[A-Za-z][A-Za-z0-9]*)*)`/g)) + keys.push(key); + } + return keys; +} + +const configSource = ( + await Promise.all(map.configSources.map((f) => readFile(resolve(repo, f), "utf8"))) +).join("\n"); + +await rm(outRoot, { recursive: true, force: true }); +let written = 0; +for (const { lang, file, sections } of languages) { + const targets = anchorTargets(sections, lang); + const updated = lastChange(file); + for (const page of map.pages) { + const present = page.sections.map((name) => sections.get(name)).filter(Boolean); + if (present.length === 0) continue; + if (lang && present.length !== page.sections.length) continue; + const [first, ...rest] = present; + const title = lang || !page.title ? first.text.replace(/`/g, "") : page.title; + const firstBody = first.body.filter((line) => !dropLines.some((re) => re.test(line))); + const parts = [firstBody.join("\n")]; + for (const heading of rest) { + const level = Math.max(2, heading.level - first.level + 1); + parts.push( + demote( + [`${"#".repeat(level)} ${heading.text}`, ...heading.body], + heading.level - level + ).join("\n") + ); + } + let body = parts + .join("\n\n") + .replace(/\n{3,}/g, "\n\n") + .trim(); + body = rewriteLinks(body, file, targets, lang, page.slug); + if (!lang && map.configPages.some((prefix) => `${page.slug}/`.startsWith(prefix))) { + for (const key of configKeys(body)) { + const leaf = key.split(".").at(-1); + if (!new RegExp(`\\b${leaf}\\b`).test(configSource)) { + failures.push( + `docs page ${route("", page.slug)}: option \`${key}\` is not in ${map.configSources.join(" or ")}` + ); + } + } + } + const description = body + .split("\n\n") + .find((p) => p && !/^[#|`<>\-*!\d]/.test(p.trim())) + ?.replace(/\s+/g, " ") + .replace(/`|\*\*/g, "") + .slice(0, 180); + const frontmatter = [ + "---", + `title: ${yaml(title)}`, + description ? `description: ${yaml(description)}` : null, + `editUrl: ${yaml(`${map.repository}/edit/main/${file}`)}`, + updated ? `lastUpdated: ${updated}` : null, + "sidebar:", + ` order: ${map.pages.indexOf(page)}`, + "---", + ].filter(Boolean); + const isIndex = page.slug === "" || map.pages.some((p) => p.slug.startsWith(`${page.slug}/`)); + const path = isIndex + ? resolve(outRoot, lang, "docs", page.slug, "index.md") + : resolve(outRoot, lang, "docs", `${page.slug}.md`); + await mkdir(dirname(path), { recursive: true }); + await writeFile(path, `${frontmatter.join("\n")}\n\n${body}\n`); + written++; + } +} + +if (failures.length > 0) { + console.error(`docs: ${failures.length} problem(s)\n- ${failures.join("\n- ")}`); + process.exit(1); +} +console.log(`docs: ${written} pages from ${languages.length} README files`); diff --git a/site/scripts/build-tokens.mjs b/site/scripts/build-tokens.mjs new file mode 100644 index 00000000..35b9ff6e --- /dev/null +++ b/site/scripts/build-tokens.mjs @@ -0,0 +1,33 @@ +import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const site = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +const repo = resolve(site, ".."); +const source = resolve(repo, "web/src/app.css"); + +function block(css, selector) { + const start = css.indexOf(`${selector} {`); + if (start === -1) throw new Error(`web/src/app.css: missing "${selector}" token block`); + const end = css.indexOf("}", start); + const declarations = [...css.slice(start, end).matchAll(/--([a-z0-9-]+):\s*([^;]+);/g)]; + if (declarations.length === 0) throw new Error(`web/src/app.css: "${selector}" has no tokens`); + return declarations.map(([, name, value]) => ` --om-${name}: ${value.trim()};`).join("\n"); +} + +const css = await readFile(source, "utf8"); +const light = block(css, ":root"); +const dark = block(css, ".dark"); +const out = [ + "/* generated by site/scripts/build-tokens.mjs from web/src/app.css */", + `:root,\n:root[data-theme="light"] {\n${light}\n color-scheme: light;\n}`, + `:root[data-theme="dark"] {\n${dark}\n color-scheme: dark;\n}`, + "", +].join("\n"); + +await mkdir(resolve(site, "src/generated"), { recursive: true }); +await writeFile(resolve(site, "src/generated/tokens.css"), out); +await mkdir(resolve(site, "public"), { recursive: true }); +await copyFile(resolve(repo, "web/public/favicon.svg"), resolve(site, "public/favicon.svg")); +await copyFile(resolve(repo, "web/public/favicon.ico"), resolve(site, "public/favicon.ico")); +console.log("tokens: web/src/app.css -> src/generated/tokens.css"); diff --git a/site/scripts/check-dist.mjs b/site/scripts/check-dist.mjs new file mode 100644 index 00000000..d2bb5468 --- /dev/null +++ b/site/scripts/check-dist.mjs @@ -0,0 +1,73 @@ +import { readFile, readdir, stat } from "node:fs/promises"; +import { dirname, join, posix, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const site = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +const dist = join(site, "dist"); +const map = JSON.parse(await readFile(join(site, "docs-map.json"), "utf8")); +const failures = []; + +async function exists(path) { + try { + await stat(path); + return true; + } catch { + return false; + } +} + +if ((await readFile(join(dist, "CNAME"), "utf8")).trim() !== "opencode-mem.zhafron.my.id") { + failures.push("dist/CNAME must contain opencode-mem.zhafron.my.id"); +} +for (const page of map.pages) { + const file = join(dist, "docs", page.slug, "index.html"); + if (!(await exists(file))) failures.push(`missing docs page ${file}`); +} +for (const required of [ + "index.html", + "404.html", + "pagefind/pagefind.js", + "sitemap-index.xml", + "og.png", +]) { + if (!(await exists(join(dist, required)))) failures.push(`missing dist/${required}`); +} + +const landing = await readFile(join(dist, "index.html"), "utf8"); +const staticImport = /\b(?:import|export)\s*(?:[\w$*{}\s,]*?from\s*)?["']([^"']+\.js)["']/g; +const scripts = [...landing.matchAll(/]*src="([^"]+)"/g)].map((m) => m[1]); +const inlineBodies = [...landing.matchAll(/]*src=)[^>]*>([\s\S]*?)<\/script>/g)].map( + (m) => m[1] +); +const eager = new Set(); +const pending = [ + ...scripts, + ...inlineBodies.flatMap((body) => + [...body.matchAll(staticImport)].map((m) => posix.resolve("/", m[1])) + ), +]; +while (pending.length > 0) { + const src = pending.pop(); + if (eager.has(src)) continue; + eager.add(src); + const code = await readFile(join(dist, src), "utf8"); + for (const m of code.matchAll(staticImport)) + pending.push(posix.resolve(posix.dirname(src), m[1])); +} +let eagerJs = 0; +for (const src of eager) eagerJs += (await stat(join(dist, src))).size; +const inline = inlineBodies.reduce((n, body) => n + body.length, 0); +const lazy = (await readdir(join(dist, "_astro"))).filter((f) => f.startsWith("memory-field")); +console.log( + `landing: ${scripts.length} external script(s), ${eager.size} eager file(s) ${eagerJs} B, inline ${inline} B, lazy chunk(s): ${lazy.join(", ")}` +); +if (eagerJs + inline > 12000) + failures.push(`landing eager JS ${eagerJs + inline} B exceeds 12000 B budget`); + +if (failures.length > 0) { + console.error(failures.join("\n")); + process.exit(1); +} +console.log( + `site: ${map.pages.length} English docs pages, CNAME, 404, search index, sitemap, og image present` +); diff --git a/site/scripts/fetch-numbers.mjs b/site/scripts/fetch-numbers.mjs new file mode 100644 index 00000000..a12b5422 --- /dev/null +++ b/site/scripts/fetch-numbers.mjs @@ -0,0 +1,47 @@ +import { readFile, writeFile } from "node:fs/promises"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const target = resolve(dirname(fileURLToPath(import.meta.url)), "../src/data/numbers.json"); +const repo = "tickernelz/opencode-mem"; +const pkg = "opencode-mem"; + +async function json(url, headers = {}) { + const response = await fetch(url, { headers, signal: AbortSignal.timeout(15000) }); + if (!response.ok) throw new Error(`${url} -> HTTP ${response.status}`); + return response.json(); +} + +const github = { accept: "application/vnd.github+json", "user-agent": "opencode-mem-site" }; +if (process.env.GITHUB_TOKEN) github.authorization = `Bearer ${process.env.GITHUB_TOKEN}`; + +try { + const [repository, year, month, registry] = await Promise.all([ + json(`https://api.github.com/repos/${repo}`, github), + json(`https://api.npmjs.org/downloads/point/last-year/${pkg}`), + json(`https://api.npmjs.org/downloads/point/last-month/${pkg}`), + json(`https://registry.npmjs.org/${pkg}`, { accept: "application/vnd.npm.install-v1+json" }), + ]); + const numbers = { + fetchedAt: new Date().toISOString().slice(0, 10), + stars: repository.stargazers_count, + forks: repository.forks_count, + license: repository.license?.spdx_id ?? "MIT", + version: registry["dist-tags"].latest, + releases: Object.keys(registry.versions).length, + downloadsYear: year.downloads, + downloadsYearRange: `${year.start}..${year.end}`, + downloadsMonth: month.downloads, + downloadsMonthRange: `${month.start}..${month.end}`, + }; + for (const [key, value] of Object.entries(numbers)) { + if (value === undefined || value === null || Number.isNaN(value)) { + throw new Error(`numbers: ${key} missing from API response`); + } + } + await writeFile(target, `${JSON.stringify(numbers, null, 2)}\n`); + console.log(`numbers: refreshed (${numbers.fetchedAt})`); +} catch (error) { + const kept = JSON.parse(await readFile(target, "utf8")); + console.warn(`numbers: fetch failed (${error.message}); keeping snapshot from ${kept.fetchedAt}`); +} diff --git a/site/src/assets/brain.svg b/site/src/assets/brain.svg new file mode 100644 index 00000000..6f50e127 --- /dev/null +++ b/site/src/assets/brain.svg @@ -0,0 +1 @@ + diff --git a/site/src/assets/ui/ui-profile-dark.png b/site/src/assets/ui/ui-profile-dark.png new file mode 100644 index 00000000..9501b522 Binary files /dev/null and b/site/src/assets/ui/ui-profile-dark.png differ diff --git a/site/src/assets/ui/ui-profile-light.png b/site/src/assets/ui/ui-profile-light.png new file mode 100644 index 00000000..9d8f1679 Binary files /dev/null and b/site/src/assets/ui/ui-profile-light.png differ diff --git a/site/src/assets/ui/ui-project-dark.png b/site/src/assets/ui/ui-project-dark.png new file mode 100644 index 00000000..efeae68b Binary files /dev/null and b/site/src/assets/ui/ui-project-dark.png differ diff --git a/site/src/assets/ui/ui-project-light.png b/site/src/assets/ui/ui-project-light.png new file mode 100644 index 00000000..d1113d59 Binary files /dev/null and b/site/src/assets/ui/ui-project-light.png differ diff --git a/site/src/assets/ui/ui-skills-dark.png b/site/src/assets/ui/ui-skills-dark.png new file mode 100644 index 00000000..095ebfe0 Binary files /dev/null and b/site/src/assets/ui/ui-skills-dark.png differ diff --git a/site/src/assets/ui/ui-skills-light.png b/site/src/assets/ui/ui-skills-light.png new file mode 100644 index 00000000..4e969fb1 Binary files /dev/null and b/site/src/assets/ui/ui-skills-light.png differ diff --git a/site/src/assets/ui/ui-stats-dark.png b/site/src/assets/ui/ui-stats-dark.png new file mode 100644 index 00000000..ee6859ee Binary files /dev/null and b/site/src/assets/ui/ui-stats-dark.png differ diff --git a/site/src/assets/ui/ui-stats-light.png b/site/src/assets/ui/ui-stats-light.png new file mode 100644 index 00000000..abc848ae Binary files /dev/null and b/site/src/assets/ui/ui-stats-light.png differ diff --git a/site/src/components/docs/Head.astro b/site/src/components/docs/Head.astro new file mode 100644 index 00000000..afae1791 --- /dev/null +++ b/site/src/components/docs/Head.astro @@ -0,0 +1,7 @@ +--- +import Default from "@astrojs/starlight/components/Head.astro"; +import displayFont from "@fontsource-variable/bricolage-grotesque/files/bricolage-grotesque-latin-wght-normal.woff2?url"; +--- + + + diff --git a/site/src/components/docs/SiteTitle.astro b/site/src/components/docs/SiteTitle.astro new file mode 100644 index 00000000..89214107 --- /dev/null +++ b/site/src/components/docs/SiteTitle.astro @@ -0,0 +1,31 @@ +--- +import Default from "@astrojs/starlight/components/SiteTitle.astro"; +--- + +
+ + Home +
+ + diff --git a/site/src/components/landing/Closing.astro b/site/src/components/landing/Closing.astro new file mode 100644 index 00000000..df8d255d --- /dev/null +++ b/site/src/components/landing/Closing.astro @@ -0,0 +1,36 @@ +--- +import type { Copy } from "../../i18n/en"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +const year = new Date().getFullYear(); +--- + +
+
+

{copy.closing.title}

+ +
+
+ diff --git a/site/src/components/landing/CodeBlock.astro b/site/src/components/landing/CodeBlock.astro new file mode 100644 index 00000000..6671ee88 --- /dev/null +++ b/site/src/components/landing/CodeBlock.astro @@ -0,0 +1,20 @@ +--- +interface Props { + file: string; + code: string; + copyLabel: string; + copiedLabel: string; +} + +const { file, code, copyLabel, copiedLabel } = Astro.props; +--- + +
+
+ {file} + +
+
{code}
+
diff --git a/site/src/components/landing/Contrast.astro b/site/src/components/landing/Contrast.astro new file mode 100644 index 00000000..d0089367 --- /dev/null +++ b/site/src/components/landing/Contrast.astro @@ -0,0 +1,48 @@ +--- +import type { Copy } from "../../i18n/en"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +--- + +
+
+
+

{copy.contrast.title}

+

{copy.contrast.lede}

+
+
+
+

{copy.contrast.withoutLabel}

+
    + { + copy.contrast.without.map((line, i) => ( +
  1. + you + {line} +
  2. + )) + } +
+

{copy.contrast.withoutFoot}

+
+
+

{copy.contrast.withLabel}

+
    + { + copy.contrast.with.map((line, i) => ( +
  1. + agent + {line} +
  2. + )) + } +
+

{copy.contrast.withFoot}

+
+
+
+
diff --git a/site/src/components/landing/Dream.astro b/site/src/components/landing/Dream.astro new file mode 100644 index 00000000..9a2eed97 --- /dev/null +++ b/site/src/components/landing/Dream.astro @@ -0,0 +1,34 @@ +--- +import type { Copy } from "../../i18n/en"; +import { dreamGraph } from "../../lib/constellation"; +import GraphSvg from "./GraphSvg.astro"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +--- + +
+
+
+ + +
+ { + copy.dream.legend.map((item, i) => ( + + {item} + + )) + } +
+
+
+

{copy.dream.title}

+

{copy.dream.body}

+ "dreaming": {"{"} "enabled": true {"}"} +
+
+
diff --git a/site/src/components/landing/Faq.astro b/site/src/components/landing/Faq.astro new file mode 100644 index 00000000..5239de41 --- /dev/null +++ b/site/src/components/landing/Faq.astro @@ -0,0 +1,25 @@ +--- +import type { Copy } from "../../i18n/en"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +--- + +
+
+

{copy.faq.title}

+
+ { + copy.faq.items.map(([question, answer]) => ( +
+ {question} +

{answer}

+
+ )) + } +
+
+
diff --git a/site/src/components/landing/Features.astro b/site/src/components/landing/Features.astro new file mode 100644 index 00000000..2d61ff3d --- /dev/null +++ b/site/src/components/landing/Features.astro @@ -0,0 +1,35 @@ +--- +import type { Copy } from "../../i18n/en"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +--- + +
+
+
+

{copy.features.title}

+

{copy.features.lede}

+
+
+ { + copy.features.items.map(([name, line]) => ( +
+
{name}
+
{line}
+
+ )) + } +
+
+
+

{copy.hood.title}

+
    + {copy.hood.items.map((item) =>
  • {item}
  • )} +
+ {copy.hood.link} +
+
diff --git a/site/src/components/landing/GraphSvg.astro b/site/src/components/landing/GraphSvg.astro new file mode 100644 index 00000000..f519811c --- /dev/null +++ b/site/src/components/landing/GraphSvg.astro @@ -0,0 +1,42 @@ +--- +import type { MemoryGraph } from "../../lib/constellation"; + +interface Props { + graph: MemoryGraph; + focus?: string; + class?: string; + fit?: "slice" | "meet"; +} + +const { graph, focus, class: className, fit = "slice" } = Astro.props; +const focusIndex = focus ? graph.nodes.findIndex((node) => node.label === focus) : -1; +--- + + diff --git a/site/src/components/landing/Hero.astro b/site/src/components/landing/Hero.astro new file mode 100644 index 00000000..2dcdc361 --- /dev/null +++ b/site/src/components/landing/Hero.astro @@ -0,0 +1,61 @@ +--- +import type { Copy } from "../../i18n/en"; +import { heroGraph } from "../../lib/constellation"; +import numbers from "../../data/numbers.json"; +import GraphSvg from "./GraphSvg.astro"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +const labels = [ + "never use browser confirm()", + "shared types: packages/shared", + "uses pnpm, not npm", + "tests run with bun test", + "prefers small PRs", + "queue stays on SQLite", + "retry fix broke the build", + "CI pinned to Node 24", + "dark theme is the default", +]; +const graph = heroGraph(labels); +const stars = new Intl.NumberFormat("en").format(numbers.stars); +--- + +
+
+
+

{copy.hero.title}

+

{copy.hero.lede}

+ +

{copy.hero.small}

+
+
+
+ + +
+
+

{copy.hero.you}{copy.hero.ask}

+

+ {copy.hero.agent}{copy.hero.answer} +

+

+ {copy.hero.recalled} + {copy.hero.memory} +

+
+
{copy.hero.caption}
+
+
+
diff --git a/site/src/components/landing/HowItWorks.astro b/site/src/components/landing/HowItWorks.astro new file mode 100644 index 00000000..b7f65015 --- /dev/null +++ b/site/src/components/landing/HowItWorks.astro @@ -0,0 +1,106 @@ +--- +import type { Copy } from "../../i18n/en"; +import { captureGraph } from "../../lib/constellation"; +import GraphSvg from "./GraphSvg.astro"; +import CodeBlock from "./CodeBlock.astro"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +const first = copy.how.sessions[0]!; +--- + +
+
+
+

{copy.how.title}

+
    + { + copy.how.steps.map((step, i) => ( +
  1. + +
    +

    {step.title}

    +

    {step.body}

    +
    +
  2. + )) + } +
+
+
+
+ { + first.lines.map(([who, text]) => ( +

+ + {who} + + + {text} + +

+ )) + } +

{copy.how.idle}

+
+
+ {first.tag} + {first.memory} +
+
+ + +
+
+
+
+
+

{copy.install.title}

+

{copy.install.lede}

+
+
+
+ + +
+
+ +
+ +

{copy.install.providerLead}

+ + {copy.install.more} +
+
+
diff --git a/site/src/components/landing/Nav.astro b/site/src/components/landing/Nav.astro new file mode 100644 index 00000000..d228a863 --- /dev/null +++ b/site/src/components/landing/Nav.astro @@ -0,0 +1,50 @@ +--- +import type { Copy } from "../../i18n/en"; +import numbers from "../../data/numbers.json"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +const stars = new Intl.NumberFormat("en").format(numbers.stars); +--- + + + + + diff --git a/site/src/components/landing/Nested.astro b/site/src/components/landing/Nested.astro new file mode 100644 index 00000000..b505ffd8 --- /dev/null +++ b/site/src/components/landing/Nested.astro @@ -0,0 +1,36 @@ +--- +import type { Copy } from "../../i18n/en"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +const rows = [70, 180, 290]; +--- + +
+
+
+

{copy.nested.title}

+

{copy.nested.body}

+
+ + {copy.nested.root} + .opencode-mem-project + { + rows.map((y, i) => ( + + + {copy.nested.repos[i]} + + + + )) + } + + + {copy.nested.shared} + +
+
diff --git a/site/src/components/landing/Privacy.astro b/site/src/components/landing/Privacy.astro new file mode 100644 index 00000000..b5959fb8 --- /dev/null +++ b/site/src/components/landing/Privacy.astro @@ -0,0 +1,25 @@ +--- +import type { Copy } from "../../i18n/en"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +--- + +
+
+

{copy.privacy.title}

+
    + { + copy.privacy.points.map(([lead, text]) => ( +
  • + {lead} {text} +
  • + )) + } +
+

{copy.privacy.note}

+
+
diff --git a/site/src/components/landing/Proof.astro b/site/src/components/landing/Proof.astro new file mode 100644 index 00000000..800924d7 --- /dev/null +++ b/site/src/components/landing/Proof.astro @@ -0,0 +1,36 @@ +--- +import type { Copy } from "../../i18n/en"; +import numbers from "../../data/numbers.json"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +const format = new Intl.NumberFormat("en"); +const items = [ + [format.format(numbers.stars), copy.proof.stars], + [format.format(numbers.forks), copy.proof.forks], + [format.format(numbers.downloadsYear), copy.proof.downloads], + [format.format(numbers.releases), `${copy.proof.releases} v${numbers.version}`], +]; +--- + +
+
+

{copy.proof.title}

+
    + { + items.map(([value, label]) => ( +
  • + {value} + {label} +
  • + )) + } +
+

+ {copy.proof.source.replace("{date}", numbers.fetchedAt)} +

+
+
diff --git a/site/src/components/landing/Showcase.astro b/site/src/components/landing/Showcase.astro new file mode 100644 index 00000000..65b9cf9c --- /dev/null +++ b/site/src/components/landing/Showcase.astro @@ -0,0 +1,81 @@ +--- +import { Picture } from "astro:assets"; +import type { Copy } from "../../i18n/en"; +import numbers from "../../data/numbers.json"; +import memoriesDark from "../../assets/ui/ui-project-dark.png"; +import memoriesLight from "../../assets/ui/ui-project-light.png"; +import profileDark from "../../assets/ui/ui-profile-dark.png"; +import profileLight from "../../assets/ui/ui-profile-light.png"; +import skillsDark from "../../assets/ui/ui-skills-dark.png"; +import skillsLight from "../../assets/ui/ui-skills-light.png"; +import statsDark from "../../assets/ui/ui-stats-dark.png"; +import statsLight from "../../assets/ui/ui-stats-light.png"; + +interface Props { + copy: Copy; +} + +const { copy } = Astro.props; +const shots: Record = { + memories: { dark: memoriesDark, light: memoriesLight }, + profile: { dark: profileDark, light: profileLight }, + skills: { dark: skillsDark, light: skillsLight }, + stats: { dark: statsDark, light: statsLight }, +}; +const widths = [640, 960, 1440]; +const sizes = "(min-width: 80rem) 72rem, 94vw"; +--- + +
+
+
+

{copy.showcase.title}

+

{copy.showcase.lede}

+
+
+ { + copy.showcase.tabs.map(([id, label], i) => ( + + )) + } +
+
+ { + copy.showcase.tabs.map(([id, label], i) => ( + + )) + } +
{copy.showcase.caption.replace("{version}", numbers.version)}
+
+
+
diff --git a/site/src/content.config.ts b/site/src/content.config.ts new file mode 100644 index 00000000..7fbcf2c3 --- /dev/null +++ b/site/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from "astro:content"; +import { docsLoader } from "@astrojs/starlight/loaders"; +import { docsSchema } from "@astrojs/starlight/schema"; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/site/src/data/numbers.json b/site/src/data/numbers.json new file mode 100644 index 00000000..fad824e4 --- /dev/null +++ b/site/src/data/numbers.json @@ -0,0 +1,12 @@ +{ + "fetchedAt": "2026-11-04", + "stars": 1818, + "forks": 183, + "license": "MIT", + "version": "2.40.1", + "releases": 111, + "downloadsYear": 112646, + "downloadsYearRange": "2025-11-03..2026-11-02", + "downloadsMonth": 23518, + "downloadsMonthRange": "2026-10-04..2026-11-02" +} diff --git a/site/src/i18n/en.ts b/site/src/i18n/en.ts new file mode 100644 index 00000000..dcd30413 --- /dev/null +++ b/site/src/i18n/en.ts @@ -0,0 +1,252 @@ +export const en = { + meta: { + title: "opencode-mem: your OpenCode agent finally remembers", + description: + "opencode-mem gives OpenCode a long-term memory. It writes down decisions, fixes, and preferences while you work, and brings them back next session. Free, open source, and stored on your machine.", + }, + nav: { + how: "How it works", + features: "Features", + faq: "FAQ", + docs: "Docs", + github: "GitHub", + theme: "Switch color theme", + skip: "Skip to content", + }, + hero: { + title: "Your agent finally remembers.", + lede: "opencode-mem gives OpenCode a long-term memory. It writes down what matters while you work and hands it back the moment it is useful again. Stop re‑explaining your codebase every Monday.", + primary: "Install in under a minute", + secondary: "Star on GitHub", + small: "Free and open source. MIT licensed. Stored on your machine.", + figureLabel: "Illustration: an agent recalls a rule you set two weeks earlier", + caption: "Illustration. A session two weeks after you set the rule.", + you: "you", + agent: "agent", + ask: "Add a delete button to the invoices page.", + answer: + "Done. It opens the in-app confirmation modal, not the browser confirm(). You asked for that two weeks ago.", + recalled: "recalled from memory", + memory: "rule · never use the browser confirm() for destructive actions", + }, + contrast: { + title: "Every new session starts from zero. Until now.", + lede: "Your agent is brilliant for an hour, then forgets everything. So you repeat yourself. Again.", + withoutLabel: "Without opencode-mem", + withLabel: "With opencode-mem", + without: [ + "We use pnpm here, not npm.", + "No, the shared types live in packages/shared.", + "We tried that retry fix last week. It broke the build.", + "Please never use the browser confirm() dialog.", + ], + with: [ + "Running pnpm test.", + "Importing the types from packages/shared.", + "Skipping the retry fix: it broke the build last time.", + "Using the in-app modal for the delete flow.", + ], + withoutFoot: "You, explaining it all again.", + withFoot: "You, shipping.", + }, + how: { + title: "Three steps. Two of them you already do.", + steps: [ + { + title: "Add one line", + body: "Put opencode-mem in your OpenCode config and restart. OpenCode installs it from npm for you.", + }, + { + title: "Work like you always do", + body: "When a session goes quiet, Auto-capture writes down the decisions, fixes, and preferences worth keeping. You never have to say “remember this”.", + }, + { + title: "Pick up where you left off", + body: "Next session, the right memories are already in your agent's context. Nothing pasted into your prompt, nothing cluttering the chat.", + }, + ], + captureLabel: "Illustration: a session is summarized into a memory that joins the memory graph", + sessions: [ + { + lines: [ + ["you", "the build fails on CI but passes locally"], + ["agent", "CI runs Node 20; the lockfile was made with Node 24. Pinned engines to 24."], + ["you", "nice, that was it"], + ], + memory: "CI must use Node 24, same as the lockfile", + tag: "bug-fix", + }, + { + lines: [ + ["you", "keep PRs small, one concern each"], + ["agent", "Split it into three PRs: schema, API, UI."], + ["you", "perfect"], + ], + memory: "Prefers small PRs, one concern each", + tag: "preference", + }, + { + lines: [ + ["you", "why did we drop Redis again?"], + ["agent", "Checked the ADR: one less service to run. SQLite queue is enough."], + ["you", "right, keep it that way"], + ], + memory: "Queue stays on SQLite; Redis was removed on purpose", + tag: "decision", + }, + ], + idle: "session idle · auto-capture", + }, + install: { + title: "Install in under a minute", + lede: "One line in your OpenCode config, then restart. The plugin writes a commented settings file on first start.", + v2: "OpenCode v2", + v1: "OpenCode v1", + v2File: "opencode.json", + v1File: "~/.config/opencode/opencode.json", + v2Code: '{\n "plugins": ["opencode-mem@latest"]\n}', + v1Code: '{\n "plugin": ["opencode-mem@latest"]\n}', + providerLead: + "Then tell Auto-capture which provider to summarize with. inherit follows the model of your session.", + providerFile: "~/.config/opencode/opencode-mem.jsonc", + providerCode: '{\n "opencodeProvider": "anthropic",\n "opencodeModel": "inherit"\n}', + copy: "Copy", + copied: "Copied", + more: "Full setup guide", + }, + features: { + title: "A memory you can see, edit, and trust.", + lede: "Everything opencode-mem keeps is yours to browse, pin, fix, or throw away.", + items: [ + ["Auto-capture", "Writes memories for you when a session goes idle."], + ["User Profile", "Learns how you like to work, across every project."], + ["Web UI", "Browse, edit, pin, and delete memories at localhost:4747."], + ["Markdown vault", "Keep memories as plain .md files in a folder you already use."], + [ + "Update-on-capture", + "When a fact changes, the old memory is updated instead of duplicated.", + ], + ["Dreaming", "Merges overlapping memories and flags the ones that disagree."], + ["Shared Skills", "Write a procedure once. Your agent loads it when it needs it."], + ["Health stats", "Captures, injections, and errors for the last 14 days at a glance."], + ["Memory Scope", "Search this project, or everything you have ever worked on."], + ], + }, + dream: { + title: "It tidies up while you are away.", + body: "Turn on Dreaming and once a day opencode-mem finds memories that say the same thing, merges them, and flags the ones that contradict each other. Superseded memories go to a trash you can restore. Pinned memories are never touched.", + label: + "Illustration: small related memories merge into brighter ones while a contradiction is flagged", + legend: ["merged", "flagged", "kept in trash"], + }, + nested: { + title: "Many repos. One memory.", + body: "A monorepo, a repo-tool workspace, a folder of services that belong together: drop one empty .opencode-mem-project file at the root and every repository underneath shares the same memory.", + label: "Three nested repositories connected to one shared memory", + root: "my-workspace/", + repos: ["kernel/", "userspace/", "tools/"], + shared: "one shared memory", + }, + showcase: { + title: "Open the drawer. It is all there.", + lede: "A local web UI shows every memory, your profile, your skills, and the health of the whole system.", + caption: "The real opencode-mem web UI (v{version}), running with sample data.", + tabs: [ + ["memories", "Project memories"], + ["profile", "User profile"], + ["skills", "Skills"], + ["stats", "Stats"], + ] as Array<[string, string]>, + }, + privacy: { + title: "Your memories live on your machine.", + points: [ + [ + "No account, no cloud.", + "Memories are stored on your disk, under ~/.opencode-mem by default.", + ], + [ + "Local embeddings.", + "Search runs on your CPU out of the box. No GPU, no embedding API needed.", + ], + [ + "Loopback by default.", + "The web UI listens on 127.0.0.1. Expose it to a network and an API token becomes mandatory.", + ], + [ + "Secrets stay out.", + "Recognizable credentials are redacted before anything is summarized. Wrap anything else in .", + ], + ["Encrypted if you want.", "Turn on AES-256-GCM encryption at rest with one setting."], + ], + note: "Auto-capture summarizes your session with the AI provider you choose, the same kind of request your agent already makes.", + }, + hood: { + title: "Under the hood", + items: [ + "Embedded Turso/libSQL with native vector search, one shard per project", + "Local embeddings via @huggingface/transformers on ONNX, default Xenova/nomic-embed-text-v1", + "12+ local embedding models, or any OpenAI-compatible endpoint", + "On OpenCode v2, memory context goes into the system context, not your prompt or transcript", + ], + link: "How storage and embeddings work", + }, + proof: { + title: "Open source. Check the numbers.", + stars: "GitHub stars", + forks: "forks", + downloads: "npm downloads in the last 12 months", + releases: "versions published, latest", + source: "From the GitHub and npm APIs, fetched {date}.", + }, + faq: { + title: "Questions you might have", + items: [ + [ + "Does my code leave my machine?", + "Memories, embeddings, and the web UI stay local. The one outbound call is Auto-capture: it asks the AI provider you configure to summarize the session, much like your agent already does. Credentials are stripped first.", + ], + [ + "What does it cost?", + "Nothing. opencode-mem is MIT licensed and free. The only cost is the tokens Auto-capture uses on your provider, so pick a small model or inherit the one you already pay for.", + ], + [ + "Will it work with my setup?", + "It runs as an OpenCode plugin on v1 and v2, on Linux, Windows, and Apple Silicon Macs. Intel Macs are not supported because two native dependencies ship no x64 build there.", + ], + [ + "Do I need a GPU?", + "No. Local embeddings run on CPU and use about 0.5 to 2 GB of RAM while loaded. Prefer zero local load? Point it at a remote embeddings API.", + ], + [ + "Do I have to tell it what to remember?", + "No. Auto-capture handles it. When you want something saved right now, ask your agent to use the memory tool.", + ], + [ + "I already have AGENTS.md. Why this?", + "Keep stable, always-on rules in AGENTS.md. Memory is for what grows: decisions, failed attempts, bug patterns, and your preferences. They work best together.", + ], + [ + "Can I see and fix what it stored?", + "Yes. The web UI lists every memory with search, pin, edit, and delete, or switch to the Markdown vault and edit plain files.", + ], + ], + }, + closing: { + title: "Tomorrow's session already knows what today found out.", + primary: "Install opencode-mem", + secondary: "Read the docs", + }, + footer: { + statement: "Memory for coding agents, kept on your machine.", + docs: "Docs", + github: "GitHub", + npm: "npm", + issues: "Issues", + releases: "Releases", + license: "MIT License", + inspired: "Inspired by opencode-supermemory", + }, +}; + +export type Copy = typeof en; diff --git a/site/src/layouts/Landing.astro b/site/src/layouts/Landing.astro new file mode 100644 index 00000000..fd936e5e --- /dev/null +++ b/site/src/layouts/Landing.astro @@ -0,0 +1,61 @@ +--- +import displayFont from "@fontsource-variable/bricolage-grotesque/files/bricolage-grotesque-latin-wght-normal.woff2?url"; +import "../generated/tokens.css"; +import "../styles/fonts.css"; +import "../styles/landing.css"; +import numbers from "../data/numbers.json"; +import type { Copy } from "../i18n/en"; + +interface Props { + copy: Copy; + lang: string; +} + +const { copy, lang } = Astro.props; +const canonical = new URL(Astro.url.pathname, Astro.site); +const jsonLd = { + "@context": "https://schema.org", + "@type": "SoftwareApplication", + name: "opencode-mem", + applicationCategory: "DeveloperApplication", + operatingSystem: "Linux, Windows, macOS (Apple Silicon)", + softwareVersion: numbers.version, + license: "https://opensource.org/licenses/MIT", + url: Astro.site?.href, + downloadUrl: "https://www.npmjs.com/package/opencode-mem", + offers: { "@type": "Offer", price: "0", priceCurrency: "USD" }, +}; +--- + + + + + + + {copy.meta.title} + + + + + + + + + + + + + + + diff --git a/site/src/scripts/landing.ts b/site/src/scripts/landing.ts new file mode 100644 index 00000000..57dc550d --- /dev/null +++ b/site/src/scripts/landing.ts @@ -0,0 +1,63 @@ +function lazyFields(): void { + const fields = document.querySelectorAll("[data-field]"); + if (fields.length === 0 || !("IntersectionObserver" in window)) return; + const observer = new IntersectionObserver( + (entries) => { + for (const entry of entries) { + if (!entry.isIntersecting) continue; + observer.unobserve(entry.target); + import("./memory-field").then(({ mount }) => mount(entry.target as HTMLElement)); + } + }, + { rootMargin: "240px 0px" } + ); + fields.forEach((field) => observer.observe(field)); +} + +function tabs(): void { + document.querySelectorAll("[data-tabs]").forEach((list) => { + const buttons = [...list.querySelectorAll('[role="tab"]')]; + const select = (next: HTMLButtonElement, focus: boolean) => { + for (const button of buttons) { + const active = button === next; + button.setAttribute("aria-selected", String(active)); + button.tabIndex = active ? 0 : -1; + const panel = document.getElementById(button.getAttribute("aria-controls") ?? ""); + if (panel) panel.hidden = !active; + } + if (focus) next.focus(); + }; + buttons.forEach((button, index) => { + button.addEventListener("click", () => select(button, false)); + button.addEventListener("keydown", (event) => { + const step = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0; + if (step === 0) return; + event.preventDefault(); + select(buttons[(index + step + buttons.length) % buttons.length]!, true); + }); + }); + }); +} + +function copyButtons(): void { + document.querySelectorAll("[data-copy]").forEach((button) => { + const label = button.querySelector("[data-copy-label]"); + const original = label?.textContent ?? ""; + button.addEventListener("click", async () => { + try { + await navigator.clipboard.writeText(button.dataset.copy ?? ""); + if (label) label.textContent = button.dataset.copied ?? original; + window.setTimeout(() => label && (label.textContent = original), 1600); + } catch { + if (label) label.textContent = original; + } + }); + }); +} + +tabs(); +copyButtons(); +const idle = + window.requestIdleCallback ?? ((callback: () => void) => window.setTimeout(callback, 200)); +if (document.readyState === "complete") idle(lazyFields); +else window.addEventListener("load", () => idle(lazyFields), { once: true }); diff --git a/site/src/scripts/memory-field.ts b/site/src/scripts/memory-field.ts new file mode 100644 index 00000000..1f7077cf --- /dev/null +++ b/site/src/scripts/memory-field.ts @@ -0,0 +1,528 @@ +import { + captureGraph, + dreamGraph, + heroGraph, + type MemoryGraph, + type MemoryNode, +} from "../lib/constellation"; + +interface Palette { + fg: string; + muted: string; + primary: string; + bright: string; + warning: string; + bg: string; +} + +const motion = window.matchMedia("(prefers-reduced-motion: reduce)"); + +function readPalette(element: Element): Palette { + const style = getComputedStyle(element); + const v = (name: string) => style.getPropertyValue(name).trim(); + return { + fg: v("--om-foreground"), + muted: v("--om-muted-foreground"), + primary: v("--om-primary"), + bright: v("--om-chart-3"), + warning: v("--om-warning"), + bg: v("--om-background"), + }; +} + +const ease = (t: number) => 1 - Math.pow(1 - Math.min(1, Math.max(0, t)), 4); + +class Field { + readonly ctx: CanvasRenderingContext2D; + readonly nodes: MemoryNode[]; + readonly edges: Array<[number, number]>; + energy: Float32Array; + born: number[] = []; + palette: Palette; + width = 0; + height = 0; + scale = 1; + offsetX = 0; + offsetY = 0; + drift = 0; + dim = 1; + pointer: { x: number; y: number } | null = null; + queue: Array<{ i: number; at: number; s: number }> = []; + visible = false; + frameId = 0; + last = 0; + onTick: ((now: number, dt: number) => void) | null = null; + decorate: ((ctx: CanvasRenderingContext2D) => void) | null = null; + nodeAlpha: ((i: number) => number) | null = null; + nodeScale: ((i: number) => number) | null = null; + nodePosition: ((i: number) => [number, number] | null) | null = null; + + constructor( + readonly canvas: HTMLCanvasElement, + readonly graph: MemoryGraph + ) { + const ctx = canvas.getContext("2d"); + if (!ctx) throw new Error("canvas 2d unavailable"); + this.ctx = ctx; + this.palette = readPalette(canvas); + this.nodes = graph.nodes.map((node) => ({ ...node })); + this.edges = graph.edges.map(([a, b]) => [a, b]); + this.energy = new Float32Array(this.nodes.length + 16); + this.resize(); + new ResizeObserver(() => { + this.resize(); + this.draw(); + }).observe(canvas); + new IntersectionObserver(([entry]) => { + this.visible = Boolean(entry?.isIntersecting); + if (this.visible) this.start(); + }).observe(canvas); + new MutationObserver(() => { + this.palette = readPalette(this.canvas); + this.draw(); + }).observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] }); + } + + get still(): boolean { + return motion.matches; + } + + fit: "cover" | "contain" = "cover"; + + resize(): void { + const dpr = Math.min(window.devicePixelRatio || 1, 2); + this.width = this.canvas.clientWidth; + this.height = this.canvas.clientHeight; + this.canvas.width = Math.round(this.width * dpr); + this.canvas.height = Math.round(this.height * dpr); + this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + const pick = this.fit === "cover" ? Math.max : Math.min; + this.scale = pick(this.width / this.graph.width, this.height / this.graph.height); + this.offsetX = (this.width - this.graph.width * this.scale) / 2; + this.offsetY = (this.height - this.graph.height * this.scale) / 2; + } + + point(i: number): [number, number] { + const custom = this.nodePosition?.(i); + const node = this.nodes[i]!; + const [x, y] = custom ?? [node.x, node.y]; + return [this.offsetX + x * this.scale, this.offsetY + y * this.scale - this.drift * node.z]; + } + + toGraph(x: number, y: number): [number, number] { + return [(x - this.offsetX) / this.scale, (y - this.offsetY) / this.scale]; + } + + neighbors(i: number): number[] { + const out: number[] = []; + for (const [a, b] of this.edges) { + if (a === i) out.push(b); + else if (b === i) out.push(a); + } + return out; + } + + pulse(i: number, strength = 1, spread = 2): void { + const now = performance.now(); + const seen = new Set([i]); + let ring = [i]; + for (let depth = 0; depth <= spread; depth++) { + for (const n of ring) + this.queue.push({ i: n, at: now + depth * 180, s: strength * Math.pow(0.55, depth) }); + const next: number[] = []; + for (const n of ring) + for (const m of this.neighbors(n)) { + if (seen.has(m)) continue; + seen.add(m); + next.push(m); + } + ring = next; + } + } + + addNode(node: MemoryNode, links: number, reuse?: number): number { + const index = reuse ?? this.nodes.push(node) - 1; + if (reuse !== undefined) { + this.nodes[index] = node; + this.energy[index] = 0; + for (let e = this.edges.length - 1; e >= 0; e--) { + const [a, b] = this.edges[e]!; + if (a === index || b === index) this.edges.splice(e, 1); + } + } + if (this.energy.length < this.nodes.length) { + const grown = new Float32Array(this.nodes.length + 16); + grown.set(this.energy); + this.energy = grown; + } + this.nodes + .map((other, j) => ({ j, d: Math.hypot(other.x - node.x, other.y - node.y) })) + .filter(({ j }) => j !== index && this.alphaOf(j) > 0.01) + .sort((a, b) => a.d - b.d) + .slice(0, links) + .forEach(({ j }) => this.edges.push([index, j])); + this.born[index] = performance.now(); + return index; + } + + start(): void { + if (this.still) { + this.draw(); + return; + } + if (this.frameId) return; + this.last = performance.now(); + const loop = (now: number) => { + if (!this.visible || document.hidden) { + this.frameId = 0; + return; + } + const dt = Math.min(64, now - this.last); + this.last = now; + this.step(now, dt); + this.draw(); + this.frameId = requestAnimationFrame(loop); + }; + this.frameId = requestAnimationFrame(loop); + } + + step(now: number, dt: number): void { + this.onTick?.(now, dt); + const decay = Math.exp(-dt / 900); + for (let i = 0; i < this.nodes.length; i++) this.energy[i]! *= decay; + this.queue = this.queue.filter((item) => { + if (item.at > now) return true; + this.energy[item.i] = Math.max(this.energy[item.i]!, item.s); + return false; + }); + if (this.pointer) { + for (let i = 0; i < this.nodes.length; i++) { + const [x, y] = this.point(i); + const d = Math.hypot(x - this.pointer.x, y - this.pointer.y); + if (d < 120) this.energy[i] = Math.max(this.energy[i]!, 1 - d / 120); + } + } + } + + draw(): void { + const { ctx, palette } = this; + ctx.clearRect(0, 0, this.width, this.height); + ctx.lineWidth = 1; + ctx.strokeStyle = palette.primary; + for (const [a, b] of this.edges) { + const visibility = Math.min(this.alphaOf(a), this.alphaOf(b)); + if (visibility <= 0.01) continue; + const e = Math.max(this.energy[a]!, this.energy[b]!); + ctx.globalAlpha = (0.2 + 0.55 * e) * visibility * this.dim; + const [ax, ay] = this.point(a); + const [bx, by] = this.point(b); + ctx.beginPath(); + ctx.moveTo(ax, ay); + ctx.lineTo(bx, by); + ctx.stroke(); + } + const now = performance.now(); + ctx.font = `500 12px "JetBrains Mono Variable", ui-monospace, monospace`; + for (let i = 0; i < this.nodes.length; i++) { + const node = this.nodes[i]!; + const alpha = this.alphaOf(i); + if (alpha <= 0.01) continue; + const e = this.energy[i]!; + const birth = this.born[i] ? ease((now - this.born[i]!) / 700) : 1; + const r = node.r * (0.7 + node.z * 0.5) * (1 + e * 0.7) * (this.nodeScale?.(i) ?? 1) * birth; + const [x, y] = this.point(i); + if (e > 0.05) { + ctx.globalAlpha = 0.18 * e * alpha; + ctx.fillStyle = palette.primary; + ctx.beginPath(); + ctx.arc(x, y, r * 4.2, 0, Math.PI * 2); + ctx.fill(); + } + ctx.globalAlpha = (0.45 + 0.55 * Math.max(e, node.z * 0.6)) * alpha * Math.max(this.dim, e); + ctx.fillStyle = e > 0.5 ? palette.bright : palette.primary; + ctx.beginPath(); + ctx.arc(x, y, Math.max(0.8, r), 0, Math.PI * 2); + ctx.fill(); + if (node.label && e > 0.35) { + ctx.globalAlpha = Math.min(1, (e - 0.35) * 2.4) * alpha; + ctx.fillStyle = palette.fg; + const width = ctx.measureText(node.label).width; + const left = x + 12 + width > this.width - 8 ? x - 12 - width : x + 12; + ctx.fillText(node.label, left, y + 4); + } + } + this.decorate?.(ctx); + ctx.globalAlpha = 1; + } + + alphaOf(i: number): number { + return this.nodeAlpha?.(i) ?? 1; + } +} + +function hero(root: HTMLElement): void { + const canvas = root.querySelector("canvas")!; + const labels = JSON.parse(root.dataset.labels ?? "[]") as string[]; + const field = new Field(canvas, heroGraph(labels)); + const focus = field.nodes.findIndex((node) => node.label === labels[0]); + const chat = document.querySelector("[data-recall]"); + const anchor = chat?.querySelector("[data-recall-anchor]"); + let thread = 0; + let threadStart = 0; + + field.decorate = (ctx) => { + if (!anchor || !thread || focus < 0) return; + const box = canvas.getBoundingClientRect(); + const target = anchor.getBoundingClientRect(); + const [fx, fy] = field.point(focus); + const tx = target.left - box.left; + const ty = target.top - box.top + target.height / 2; + const progress = field.still ? 1 : ease((performance.now() - threadStart) / 900); + ctx.globalAlpha = 0.85 * thread; + ctx.strokeStyle = field.palette.bright; + ctx.lineWidth = 1.5; + ctx.setLineDash([4, 5]); + ctx.beginPath(); + ctx.moveTo(fx, fy); + const cx = (fx + tx) / 2; + const steps = 24; + for (let s = 1; s <= Math.round(steps * progress); s++) { + const t = s / steps; + const x = (1 - t) ** 2 * fx + 2 * (1 - t) * t * cx + t * t * tx; + const y = (1 - t) ** 2 * fy + 2 * (1 - t) * t * Math.min(fy, ty) + t * t * ty; + ctx.lineTo(x, y); + } + ctx.stroke(); + ctx.setLineDash([]); + ctx.lineWidth = 1; + }; + + const recall = () => { + if (focus >= 0) { + field.pulse(focus, 1, 3); + field.energy[focus] = 1; + } + thread = 1; + threadStart = performance.now(); + chat?.setAttribute("data-state", "recalled"); + }; + + if (field.still) { + if (focus >= 0) field.energy[focus] = 1; + thread = 1; + field.draw(); + return; + } + + chat?.setAttribute("data-state", "pending"); + window.setTimeout(recall, 700); + + let ambient = 0; + field.onTick = (now) => { + field.drift = Math.min(window.scrollY, 900) * 0.12; + if (focus >= 0 && thread) field.energy[focus] = Math.max(field.energy[focus]!, 0.75); + if (now > ambient) { + ambient = now + 2400; + field.pulse(Math.floor(Math.random() * field.nodes.length), 0.8, 2); + } + }; + + const area = root.closest("[data-pointer-area]") ?? root; + area.addEventListener("pointermove", (event) => { + const box = canvas.getBoundingClientRect(); + field.pointer = { x: event.clientX - box.left, y: event.clientY - box.top }; + }); + area.addEventListener("pointerleave", () => { + field.pointer = null; + }); + document.addEventListener("visibilitychange", () => !document.hidden && field.start()); + field.start(); +} + +function capture(root: HTMLElement): void { + const canvas = root.querySelector("canvas")!; + const field = new Field(canvas, captureGraph()); + field.fit = "contain"; + field.resize(); + const terminal = root.querySelector("[data-terminal]"); + const card = root.querySelector("[data-card]"); + const sessions = JSON.parse(root.dataset.sessions ?? "[]") as Array<{ + lines: Array<[string, string]>; + memory: string; + tag: string; + }>; + if (!terminal || !card || field.still || sessions.length === 0) { + field.draw(); + return; + } + const lineTemplate = terminal.querySelector("[data-line]"); + const idle = terminal.querySelector("[data-idle]"); + const random = Math.random; + let cycle = 0; + const captured: number[] = []; + const keep = 4; + const wait = (ms: number) => new Promise((resolve) => window.setTimeout(resolve, ms)); + + const run = async () => { + if (!field.visible) { + window.setTimeout(run, 600); + return; + } + const session = sessions[cycle % sessions.length]!; + cycle++; + terminal.querySelectorAll("[data-line]").forEach((line) => line.remove()); + idle?.setAttribute("data-on", "false"); + card.setAttribute("data-state", "hidden"); + for (const [who, text] of session.lines) { + const line = + (lineTemplate?.cloneNode(true) as HTMLElement | undefined) ?? document.createElement("p"); + line.querySelector("[data-who]")!.textContent = who; + const target = line.querySelector("[data-text]")!; + target.textContent = ""; + terminal.insertBefore(line, idle ?? null); + for (let c = 1; c <= text.length; c += 2) { + target.textContent = text.slice(0, c + 1); + await wait(28); + } + await wait(320); + } + idle?.setAttribute("data-on", "true"); + await wait(500); + card.querySelector("[data-memory]")!.textContent = session.memory; + card.querySelector("[data-tag]")!.textContent = session.tag; + card.setAttribute("data-state", "shown"); + await wait(1300); + const cluster = Math.floor(random() * 3); + const anchor = field.nodes.find((node) => node.cluster === cluster)!; + const node: MemoryNode = { + x: anchor.x + (random() - 0.5) * 120, + y: anchor.y + (random() - 0.5) * 100, + r: 4.2, + z: 1, + cluster, + }; + const box = canvas.getBoundingClientRect(); + const from = card.getBoundingClientRect(); + const tx = box.left + field.offsetX + node.x * field.scale - (from.left + from.width / 2); + const ty = box.top + field.offsetY + node.y * field.scale - (from.top + from.height / 2); + await card.animate( + [ + { transform: "translate(0, 0) scale(1)", opacity: 1 }, + { transform: `translate(${tx}px, ${ty}px) scale(0.06)`, opacity: 0.2 }, + ], + { duration: 900, easing: "cubic-bezier(0.65, 0, 0.35, 1)" } + ).finished; + card.setAttribute("data-state", "hidden"); + const index = field.addNode(node, 3, captured.length >= keep ? captured.shift() : undefined); + captured.push(index); + field.pulse(index, 1, 2); + await wait(2600); + run(); + }; + + document.addEventListener("visibilitychange", () => !document.hidden && field.start()); + field.start(); + window.setTimeout(run, 400); +} + +function dream(root: HTMLElement): void { + const canvas = root.querySelector("canvas")!; + const field = new Field(canvas, dreamGraph()); + const groups: Array<{ keep: number; merge: number[] }> = []; + const used = new Set(); + field.nodes.forEach((node, i) => { + if (used.has(i) || groups.length >= 6 || i % 3 !== 0) return; + const near = field.nodes + .map((other, j) => ({ + j, + d: + other.cluster === node.cluster + ? Math.hypot(other.x - node.x, other.y - node.y) + : Infinity, + })) + .filter(({ j, d }) => j !== i && !used.has(j) && d < 110) + .sort((a, b) => a.d - b.d) + .slice(0, 2) + .map(({ j }) => j); + if (near.length < 2) return; + used.add(i); + near.forEach((j) => used.add(j)); + groups.push({ keep: i, merge: near }); + }); + const flagged = field.nodes + .map((_, i) => i) + .filter((i) => !used.has(i)) + .slice(0, 2); + const target = new Map(); + groups.forEach((group) => group.merge.forEach((j) => target.set(j, group.keep))); + const legend = root.querySelectorAll("[data-legend]"); + const cycle = 12000; + let phase = 1; + + const apply = (p: number) => { + phase = p; + const night = ease((p - 0.08) / 0.12); + const merge = ease((p - 0.25) / 0.3); + const fade = 1 - ease((p - 0.92) / 0.08); + field.dim = 1 - 0.4 * night * fade; + field.nodePosition = (i) => { + const keep = target.get(i); + if (keep === undefined || merge === 0) return null; + const a = field.nodes[i]!; + const b = field.nodes[keep]!; + const m = merge * fade; + return [a.x + (b.x - a.x) * m, a.y + (b.y - a.y) * m]; + }; + field.nodeAlpha = (i) => (target.has(i) ? 1 - merge * fade * 0.92 : 1); + field.nodeScale = (i) => (groups.some((g) => g.keep === i) ? 1 + 0.9 * merge * fade : 1); + legend.forEach((item, index) => + item.setAttribute("data-on", String(p > [0.55, 0.62, 0.7][index]! && fade > 0.5)) + ); + }; + + field.decorate = (ctx) => { + const glow = ease((phase - 0.55) / 0.1) * (1 - ease((phase - 0.92) / 0.08)); + if (glow <= 0) return; + for (const group of groups) { + const [x, y] = field.point(group.keep); + ctx.globalAlpha = 0.22 * glow; + ctx.fillStyle = field.palette.bright; + ctx.beginPath(); + ctx.arc(x, y, 18, 0, Math.PI * 2); + ctx.fill(); + } + const flag = ease((phase - 0.62) / 0.08) * (1 - ease((phase - 0.92) / 0.08)); + ctx.strokeStyle = field.palette.warning; + ctx.lineWidth = 1.5; + for (const i of flagged) { + const [x, y] = field.point(i); + ctx.globalAlpha = flag * (0.6 + 0.4 * Math.sin(performance.now() / 260)); + ctx.beginPath(); + ctx.arc(x, y, 11, 0, Math.PI * 2); + ctx.stroke(); + } + ctx.lineWidth = 1; + }; + + if (field.still) { + apply(0.8); + field.draw(); + return; + } + let start = performance.now(); + field.onTick = (now) => { + if (now - start > cycle) start = now; + apply((now - start) / cycle); + }; + document.addEventListener("visibilitychange", () => !document.hidden && field.start()); + field.start(); +} + +const scenes: Record void> = { hero, capture, dream }; + +export function mount(root: HTMLElement): void { + const scene = scenes[root.dataset.field ?? ""]; + if (!scene) return; + root.setAttribute("data-live", "true"); + scene(root); +} diff --git a/site/src/styles/docs.css b/site/src/styles/docs.css new file mode 100644 index 00000000..4b690b64 --- /dev/null +++ b/site/src/styles/docs.css @@ -0,0 +1,60 @@ +:root[data-theme="dark"], +:root[data-theme="light"], +:root { + --sl-font: var(--om-font-body); + --sl-font-mono: var(--om-font-mono); + --sl-color-bg: var(--om-background); + --sl-color-bg-nav: var(--om-background); + --sl-color-bg-sidebar: var(--om-sidebar); + --sl-color-bg-inline-code: var(--om-secondary); + --sl-color-hairline: var(--om-border); + --sl-color-hairline-light: var(--om-border); + --sl-color-hairline-shade: var(--om-border); + --sl-color-text: var(--om-foreground); + --sl-color-white: var(--om-foreground-bright); + --sl-color-text-accent: var(--om-accent-foreground); + --sl-color-accent-low: var(--om-accent); + --sl-color-accent: var(--om-primary); + --sl-color-accent-high: var(--om-accent-foreground); + --sl-color-text-invert: var(--om-primary-foreground); +} + +:root[data-theme="dark"] { + --sl-color-gray-1: #ececec; + --sl-color-gray-2: var(--om-foreground); + --sl-color-gray-3: #b4b4b4; + --sl-color-gray-4: var(--om-muted-foreground); + --sl-color-gray-5: var(--om-border); + --sl-color-gray-6: var(--om-card); + --sl-color-black: var(--om-background); +} + +:root[data-theme="light"] { + --sl-color-gray-1: var(--om-foreground); + --sl-color-gray-2: #34323a; + --sl-color-gray-3: #4f4c57; + --sl-color-gray-4: var(--om-muted-foreground); + --sl-color-gray-5: var(--om-border); + --sl-color-gray-6: var(--om-secondary); + --sl-color-gray-7: var(--om-card); + --sl-color-black: var(--om-card); +} + +.sl-markdown-content h1, +.sl-markdown-content h2, +.sl-markdown-content h3, +h1#_top { + font-family: var(--om-font-display); + font-weight: 650; + letter-spacing: -0.015em; + text-wrap: balance; +} + +.sl-markdown-content table { + display: block; + overflow-x: auto; +} + +.sl-markdown-content :not(pre) > code { + overflow-wrap: anywhere; +} diff --git a/site/src/styles/fonts.css b/site/src/styles/fonts.css new file mode 100644 index 00000000..b38328c4 --- /dev/null +++ b/site/src/styles/fonts.css @@ -0,0 +1,29 @@ +@font-face { + font-family: "Bricolage Grotesque Variable"; + font-style: normal; + font-display: swap; + font-weight: 200 800; + src: url("@fontsource-variable/bricolage-grotesque/files/bricolage-grotesque-latin-wght-normal.woff2") + format("woff2-variations"); + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, + U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +@font-face { + font-family: "JetBrains Mono Variable"; + font-style: normal; + font-display: swap; + font-weight: 100 800; + src: url("@fontsource-variable/jetbrains-mono/files/jetbrains-mono-latin-wght-normal.woff2") + format("woff2-variations"); + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, + U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +:root { + --om-font-display: "Bricolage Grotesque Variable", ui-sans-serif, system-ui, sans-serif; + --om-font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + --om-font-mono: "JetBrains Mono Variable", ui-monospace, "SFMono-Regular", Menlo, monospace; +} diff --git a/site/src/styles/landing.css b/site/src/styles/landing.css new file mode 100644 index 00000000..dcdafb39 --- /dev/null +++ b/site/src/styles/landing.css @@ -0,0 +1,1550 @@ +:root { + --bg: var(--om-background); + --fg: var(--om-foreground); + --bright: var(--om-foreground-bright); + --muted: var(--om-muted-foreground); + --surface: var(--om-card); + --surface-2: var(--om-secondary); + --line: var(--om-border); + --primary: var(--om-primary); + --on-primary: var(--om-primary-foreground); + --tint: var(--om-accent); + --on-tint: var(--om-accent-foreground); + --warn: var(--om-warning); + --night: #0b0912; + --night-fg: #e9e6f2; + --night-muted: #a9a3b8; + + --space-2xs: 0.25rem; + --space-xs: 0.5rem; + --space-s: 0.75rem; + --space-m: 1rem; + --space-l: 1.5rem; + --space-xl: 2rem; + --space-2xl: 3rem; + --space-3xl: 4.5rem; + --space-4xl: clamp(4.5rem, 3rem + 6vw, 8rem); + + --step--1: 0.875rem; + --step-0: 1.0625rem; + --step-1: 1.25rem; + --step-2: clamp(1.4rem, 1.2rem + 0.8vw, 1.75rem); + --step-4: clamp(2.1rem, 1.4rem + 2.9vw, 3.6rem); + --step-6: clamp(2.75rem, 1.6rem + 4.6vw, 5.25rem); + + --radius: 0.75rem; + --ease-out: cubic-bezier(0.22, 1, 0.36, 1); +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html, +body { + overflow-x: clip; +} + +html { + -webkit-text-size-adjust: 100%; + scroll-padding-top: 5rem; +} + +@media (prefers-reduced-motion: no-preference) { + html { + scroll-behavior: smooth; + } +} + +body { + margin: 0; + background: var(--bg); + color: var(--fg); + font-family: var(--om-font-body); + font-size: var(--step-0); + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} + +h1, +h2, +h3 { + font-family: var(--om-font-display); + color: var(--bright); + font-style: normal; + font-weight: 700; + line-height: 1.04; + letter-spacing: -0.028em; + text-wrap: balance; + overflow-wrap: anywhere; + min-width: 0; + margin: 0; +} + +h2 { + font-size: var(--step-4); +} + +h3 { + font-size: var(--step-1); + letter-spacing: -0.012em; + line-height: 1.2; +} + +p { + margin: 0; + text-wrap: pretty; +} + +a { + color: inherit; +} + +code, +pre, +kbd { + font-family: var(--om-font-mono); +} + +:focus-visible { + outline: 2px solid var(--primary); + outline-offset: 3px; + border-radius: 4px; +} + +.wrap { + width: min(100% - 2 * clamp(1.25rem, 4vw, 3rem), 74rem); + margin-inline: auto; +} + +.skip { + position: absolute; + left: var(--space-m); + top: -4rem; + z-index: 30; + padding: var(--space-xs) var(--space-m); + background: var(--primary); + color: var(--on-primary); + border-radius: 999px; +} + +.skip:focus-visible { + top: var(--space-m); +} + +.nav { + position: sticky; + top: 0; + z-index: 20; + background: color-mix(in srgb, var(--bg) 82%, transparent); + backdrop-filter: blur(12px); + border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); +} + +.nav__inner { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-m); + min-height: 4rem; +} + +.wordmark { + display: inline-flex; + align-items: center; + gap: var(--space-xs); + font-family: var(--om-font-mono); + font-weight: 600; + font-size: 1rem; + line-height: 1; + color: var(--bright); + text-decoration: none; + white-space: nowrap; +} + +.wordmark svg { + width: 1.6rem; + height: 1.6rem; + fill: none; + stroke: var(--primary); + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; +} + +.nav__links { + display: flex; + align-items: center; + gap: clamp(0.5rem, 2vw, 1.75rem); + font-size: var(--step--1); +} + +.nav__links a { + color: var(--fg); + text-decoration: none; + line-height: 1; + white-space: nowrap; +} + +.nav__links a:hover { + color: var(--bright); +} + +.nav__gh { + display: inline-flex; + align-items: center; + gap: var(--space-xs); +} + +.nav__count, +.button__count { + font-family: var(--om-font-mono); + font-size: 0.8125rem; + padding: 0.2rem 0.45rem; + border-radius: 999px; + background: var(--tint); + color: var(--on-tint); +} + +.theme-toggle { + display: grid; + place-items: center; + width: 2.25rem; + height: 2.25rem; + border: 1px solid var(--line); + border-radius: 999px; + background: transparent; + color: var(--fg); + cursor: pointer; +} + +.theme-toggle svg { + width: 1rem; + height: 1rem; + fill: none; + stroke: currentColor; + stroke-width: 2; +} + +.theme-toggle:hover { + background: var(--surface-2); +} + +.theme-toggle:active { + transform: translateY(1px); +} + +@media (max-width: 52rem) { + .nav__optional { + display: none; + } +} + +@media (max-width: 26rem) { + .nav__count { + display: none; + } +} + +.button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--space-s); + min-height: 3rem; + padding: 0 var(--space-l); + border-radius: 999px; + font-weight: 600; + font-size: 1rem; + line-height: 1; + white-space: nowrap; + text-decoration: none; + border: 1px solid transparent; + transition: + background-color 160ms var(--ease-out), + border-color 160ms var(--ease-out), + transform 160ms var(--ease-out); +} + +.button--primary { + background: var(--primary); + color: var(--on-primary); +} + +.button--primary:hover { + background: color-mix(in srgb, var(--primary) 86%, var(--bright)); +} + +.button--ghost { + border-color: var(--line); + color: var(--bright); +} + +.button--ghost:hover { + border-color: var(--primary); +} + +.button:active { + transform: translateY(1px); +} + +.button[aria-disabled="true"] { + opacity: 0.5; + pointer-events: none; +} + +.link-arrow { + display: inline-flex; + margin-top: var(--space-l); + color: var(--on-tint); + font-weight: 600; + text-decoration: underline; + text-decoration-thickness: 1px; + text-underline-offset: 3px; +} + +.link-arrow::after { + content: " →"; + white-space: pre; +} + +.section-head { + display: grid; + gap: var(--space-m); + max-width: 44rem; + margin-bottom: var(--space-2xl); +} + +.section-head p { + color: var(--muted); + font-size: var(--step-1); + max-width: 60ch; +} + +.field { + position: relative; +} + +.field canvas, +.field .graph-svg { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + display: block; +} + +.field canvas { + opacity: 0; + transition: opacity 600ms var(--ease-out); +} + +.field[data-live="true"] canvas { + opacity: 1; +} + +.field[data-live="true"] .graph-svg { + opacity: 0; + transition: opacity 600ms var(--ease-out); +} + +.graph-svg line { + stroke: var(--primary); + stroke-opacity: 0.16; + stroke-width: 1; + vector-effect: non-scaling-stroke; +} + +.graph-svg circle { + fill: var(--primary); +} + +.graph-svg circle.is-focus { + fill: var(--om-chart-3); +} + +.hero { + position: relative; + padding-block: clamp(2.5rem, 1rem + 6vw, 6rem) var(--space-3xl); +} + +.hero__inner { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-2xl); + align-items: center; +} + +.hero__copy { + display: grid; + gap: var(--space-l); + position: relative; + z-index: 2; +} + +.hero__title { + font-size: var(--step-6); + font-weight: 760; + line-height: 0.98; + max-width: 11ch; + overflow-wrap: normal; +} + +.hero__lede { + font-size: var(--step-1); + color: var(--fg); + max-width: 34rem; +} + +.hero__actions { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-s); +} + +.hero__small { + font-size: var(--step--1); + color: var(--muted); +} + +.hero__visual { + position: relative; + margin: 0; + min-width: 0; +} + +.field--hero { + height: clamp(18rem, 60vw, 38rem); + margin-inline: calc(-1 * clamp(1.25rem, 4vw, 3rem)); + mask-image: radial-gradient(120% 90% at 55% 45%, #000 55%, transparent 100%); +} + +.chat { + position: relative; + z-index: 2; + margin-top: -4.5rem; + margin-left: auto; + width: min(100%, 26rem); + padding: var(--space-m) var(--space-l); + display: grid; + gap: var(--space-s); + background: color-mix(in srgb, var(--surface) 92%, transparent); + border: 1px solid var(--line); + border-radius: var(--radius); + font-size: 0.9375rem; + line-height: 1.5; + backdrop-filter: blur(6px); +} + +.chat__line { + display: grid; + grid-template-columns: 3.75rem minmax(0, 1fr); + gap: var(--space-s); +} + +.chat__who { + font-family: var(--om-font-mono); + font-size: 0.8125rem; + color: var(--muted); + padding-top: 0.1rem; +} + +.chat__line--agent .chat__who { + color: var(--primary); +} + +.chat__line--agent { + color: var(--bright); +} + +.chat__memory { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: var(--space-xs); + padding-top: var(--space-s); + border-top: 1px dashed var(--line); + font-family: var(--om-font-mono); + font-size: 0.75rem; + color: var(--muted); +} + +.chat__chip { + padding: 0.15rem 0.5rem; + border-radius: 999px; + background: var(--tint); + color: var(--on-tint); + white-space: nowrap; +} + +.chat__mem { + min-width: 0; + overflow-wrap: anywhere; +} + +.chat[data-state="pending"] .chat__answer, +.chat[data-state="pending"] .chat__memory { + opacity: 0; +} + +.chat[data-state="recalled"] .chat__answer { + animation: reveal-text 1100ms steps(28) both 500ms; +} + +.chat[data-state="recalled"] .chat__memory { + animation: fade-up 500ms var(--ease-out) both 1500ms; +} + +.hero__caption { + margin-top: var(--space-s); + text-align: right; + font-size: 0.75rem; + color: var(--muted); +} + +@media (min-width: 64rem) { + .hero__inner { + grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); + } + + .field--hero { + height: 36rem; + margin-left: -6rem; + margin-right: calc(-1 * max(3rem, (100vw - 74rem) / 2)); + } + + .chat { + position: absolute; + left: 6%; + bottom: 2.5rem; + margin: 0; + } + + .hero__caption { + position: absolute; + right: 0; + bottom: 0; + } +} + +.contrast { + padding-block: var(--space-4xl); + border-top: 1px solid var(--line); +} + +.section-head--wide { + max-width: 52rem; +} + +.contrast__grid { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-l); +} + +@media (min-width: 52rem) { + .contrast__grid { + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + } +} + +.contrast__side { + padding: var(--space-xl); + border-radius: var(--radius); + display: grid; + gap: var(--space-l); + align-content: start; +} + +.contrast__side h3 { + font-family: var(--om-font-mono); + font-size: 0.875rem; + font-weight: 600; + letter-spacing: 0; +} + +.contrast__side--without { + background: var(--surface-2); +} + +.contrast__side--without h3 { + color: var(--muted); +} + +.contrast__side--with { + background: var(--tint); + border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent); +} + +.contrast__side--with h3 { + color: var(--on-tint); +} + +.contrast__log { + list-style: none; + margin: 0; + padding: 0; + display: grid; + gap: var(--space-s); +} + +.contrast__log li { + display: grid; + grid-template-columns: 3.5rem minmax(0, 1fr); + gap: var(--space-s); + font-size: 1rem; +} + +.contrast__side--without li { + color: var(--fg); +} + +.contrast__side--with li { + color: var(--bright); +} + +.contrast__who { + font-family: var(--om-font-mono); + font-size: 0.8125rem; + color: var(--muted); + padding-top: 0.15rem; +} + +.contrast__side--with .contrast__who { + color: var(--on-tint); +} + +.contrast__foot { + font-family: var(--om-font-display); + font-size: var(--step-2); + font-weight: 650; + letter-spacing: -0.015em; + color: var(--bright); +} + +.contrast__side--without .contrast__foot { + color: var(--muted); +} + +.how { + padding-block: var(--space-4xl); + background: var(--surface); + border-block: 1px solid var(--line); +} + +.how__grid { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-3xl); + align-items: start; +} + +@media (min-width: 64rem) { + .how__grid { + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + } +} + +.how__text { + display: grid; + gap: var(--space-2xl); +} + +.steps { + list-style: none; + margin: 0; + padding: 0; + display: grid; + gap: var(--space-xl); + counter-reset: step; +} + +.step { + display: grid; + grid-template-columns: 3.5rem minmax(0, 1fr); + gap: var(--space-m); +} + +.step__n { + font-family: var(--om-font-display); + font-size: 2.75rem; + font-weight: 760; + line-height: 0.9; + color: var(--primary); +} + +.step h3 { + margin-bottom: var(--space-xs); +} + +.step p { + color: var(--fg); + max-width: 46ch; +} + +.capture { + margin: 0; + position: relative; + display: grid; + gap: var(--space-m); + min-width: 0; +} + +.terminal { + min-height: 11.5rem; + padding: var(--space-l); + background: var(--bg); + border: 1px solid var(--line); + border-radius: var(--radius); + font-family: var(--om-font-mono); + font-size: 0.8125rem; + line-height: 1.6; + display: grid; + align-content: start; + gap: var(--space-xs); +} + +.terminal__line { + display: grid; + grid-template-columns: 3.5rem minmax(0, 1fr); + gap: var(--space-s); +} + +.terminal__who { + color: var(--muted); +} + +.terminal__who--agent { + color: var(--primary); +} + +.terminal__text { + color: var(--bright); + overflow-wrap: anywhere; +} + +.terminal__idle { + margin-top: var(--space-xs); + color: var(--warn); + transition: opacity 300ms var(--ease-out); +} + +:root[data-theme="light"] .terminal__idle { + color: #92400e; +} + +.terminal__idle[data-on="false"] { + opacity: 0; +} + +.memcard { + position: relative; + z-index: 3; + justify-self: start; + display: grid; + gap: var(--space-2xs); + max-width: 22rem; + margin-left: var(--space-xl); + padding: var(--space-s) var(--space-m); + background: var(--tint); + color: var(--on-tint); + border: 1px solid color-mix(in srgb, var(--primary) 45%, transparent); + border-radius: var(--radius); + font-size: 0.9375rem; + transition: + opacity 380ms var(--ease-out), + transform 380ms var(--ease-out); +} + +.memcard__tag { + font-family: var(--om-font-mono); + font-size: 0.75rem; + color: var(--muted); +} + +.memcard__text { + color: var(--bright); +} + +.memcard[data-state="hidden"] { + opacity: 0; + transform: translateY(8px) scale(0.97); +} + +.field--capture { + height: 15rem; + border-radius: var(--radius); + background: var(--bg); + border: 1px solid var(--line); + overflow: hidden; +} + +.install { + margin-top: var(--space-4xl); + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-xl); +} + +@media (min-width: 64rem) { + .install { + grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); + } +} + +.install__head { + display: grid; + gap: var(--space-m); + align-content: start; +} + +.install__head p { + color: var(--muted); + font-size: var(--step-1); + max-width: 40ch; +} + +.install__body { + display: grid; + gap: var(--space-m); + min-width: 0; +} + +.install__provider { + margin-top: var(--space-s); + color: var(--fg); + max-width: 60ch; +} + +.tabs { + display: flex; + flex-wrap: wrap; + gap: var(--space-xs); +} + +.tabs [role="tab"] { + min-height: 2.5rem; + padding: 0 var(--space-m); + border-radius: 999px; + border: 1px solid var(--line); + background: transparent; + color: var(--fg); + font: inherit; + font-size: var(--step--1); + line-height: 1; + white-space: nowrap; + cursor: pointer; +} + +.tabs [role="tab"]:hover { + border-color: var(--primary); +} + +.tabs [role="tab"][aria-selected="true"] { + background: var(--tint); + border-color: color-mix(in srgb, var(--primary) 55%, transparent); + color: var(--on-tint); +} + +.tabs [role="tab"]:active { + transform: translateY(1px); +} + +.code { + border: 1px solid var(--line); + border-radius: var(--radius); + background: var(--bg); + overflow: hidden; +} + +.code__bar { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-s); + padding: var(--space-xs) var(--space-xs) var(--space-xs) var(--space-m); + border-bottom: 1px solid var(--line); +} + +.code__file { + font-family: var(--om-font-mono); + font-size: 0.75rem; + color: var(--muted); + overflow-wrap: anywhere; + min-width: 0; +} + +.code__copy { + min-height: 2rem; + padding: 0 var(--space-s); + border: 1px solid var(--line); + border-radius: 999px; + background: transparent; + color: var(--fg); + font: inherit; + font-size: 0.8125rem; + line-height: 1; + cursor: pointer; +} + +.code__copy:hover { + border-color: var(--primary); + color: var(--bright); +} + +.code__copy:active { + transform: translateY(1px); +} + +.code pre { + margin: 0; + padding: var(--space-m); + font-size: 0.875rem; + line-height: 1.6; + color: var(--bright); + overflow-x: auto; +} + +.features { + padding-block: var(--space-4xl) var(--space-3xl); +} + +.features__grid { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-2xl); +} + +@media (min-width: 64rem) { + .features__grid { + grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); + } + + .features__head { + position: sticky; + top: 7rem; + align-self: start; + } +} + +.features__head { + display: grid; + gap: var(--space-m); +} + +.features__head p { + color: var(--muted); + font-size: var(--step-1); + max-width: 36ch; +} + +.features__list { + margin: 0; + display: grid; +} + +.feature { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-2xs); + padding-block: var(--space-l); + border-top: 1px solid var(--line); +} + +.feature:last-child { + border-bottom: 1px solid var(--line); +} + +@media (min-width: 40rem) { + .feature { + grid-template-columns: 16.5rem minmax(0, 1fr); + gap: var(--space-l); + align-items: baseline; + } +} + +.feature dt { + font-family: var(--om-font-display); + font-size: var(--step-2); + font-weight: 680; + letter-spacing: -0.015em; + color: var(--bright); + line-height: 1.15; +} + +.feature dd { + margin: 0; + color: var(--fg); +} + +.feature:hover dt { + color: var(--primary); +} + +.hood { + margin-top: var(--space-3xl); + padding: var(--space-xl); + border: 1px dashed var(--line); + border-radius: var(--radius); + display: grid; + gap: var(--space-m); +} + +.hood h3 { + font-family: var(--om-font-mono); + font-size: 0.875rem; + letter-spacing: 0; + color: var(--muted); +} + +.hood ul { + margin: 0; + padding-left: 1.1rem; + display: grid; + gap: var(--space-xs); + font-family: var(--om-font-mono); + font-size: 0.875rem; + color: var(--fg); +} + +.hood .link-arrow { + margin-top: 0; +} + +.dream { + --om-primary: #a78bfa; + --om-chart-3: #ddd6fe; + --om-foreground: var(--night-fg); + --om-warning: #f0b429; + color: var(--night-fg); + background: var(--night); + position: relative; +} + +.dream::before { + content: ""; + display: block; + height: clamp(6rem, 14vw, 12rem); + background: linear-gradient(to bottom, var(--bg), var(--night)); +} + +.dream__sky { + position: relative; + padding-bottom: var(--space-4xl); +} + +.field--dream { + margin: 0; + height: clamp(20rem, 48vw, 34rem); +} + +.dream__legend { + position: absolute; + left: 50%; + bottom: var(--space-m); + transform: translateX(-50%); + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: var(--space-xs); + font-family: var(--om-font-mono); + font-size: 0.75rem; +} + +.dream__key { + padding: 0.25rem 0.6rem; + border-radius: 999px; + border: 1px solid #3a3350; + color: var(--night-muted); + transition: + color 300ms var(--ease-out), + border-color 300ms var(--ease-out); + white-space: nowrap; +} + +.dream__key[data-on="true"].dream__key--0 { + color: #ddd6fe; + border-color: #a78bfa; +} + +.dream__key[data-on="true"].dream__key--1 { + color: #f0b429; + border-color: #f0b429; +} + +.dream__key[data-on="true"].dream__key--2 { + color: var(--night-fg); + border-color: var(--night-muted); +} + +.dream__copy { + display: grid; + gap: var(--space-l); + margin-top: var(--space-xl); +} + +.dream__copy > * { + max-width: 46rem; +} + +.dream__copy h2 { + color: #ffffff; +} + +.dream__copy p { + font-size: var(--step-1); + color: var(--night-fg); +} + +.dream__code { + justify-self: start; + padding: var(--space-xs) var(--space-m); + border-radius: 999px; + background: #1a1428; + color: #ddd6fe; + font-size: 0.875rem; +} + +.nested { + padding-block: var(--space-4xl); +} + +.nested__grid { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-2xl); + align-items: center; +} + +@media (min-width: 60rem) { + .nested__grid { + grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); + } +} + +.nested__text { + display: grid; + gap: var(--space-l); +} + +.nested__text p { + font-size: var(--step-1); + max-width: 44ch; +} + +.nested__map { + width: 100%; + height: auto; + font-family: var(--om-font-mono); +} + +.nested__root { + fill: var(--bright); + font-size: 18px; + font-weight: 600; +} + +.nested__marker { + fill: var(--on-tint); + font-size: 15px; +} + +.nested__repo { + fill: var(--fg); + font-size: 16px; +} + +.nested__shared { + fill: var(--muted); + font-size: 14px; +} + +.nested__branch { + fill: none; + stroke: var(--primary); + stroke-width: 2; + stroke-linecap: round; +} + +.nested__node { + fill: var(--primary); +} + +.nested__halo { + fill: var(--primary); + opacity: 0.16; +} + +.showcase { + padding-block: var(--space-4xl); + border-top: 1px solid var(--line); +} + +.showcase .tabs { + margin-bottom: var(--space-l); +} + +.showcase__frame { + margin: 0; + display: grid; + gap: var(--space-s); +} + +.showcase__frame picture, +.showcase__frame img { + display: block; + width: 100%; + height: auto; + border-radius: var(--radius); +} + +.showcase__frame img { + border: 1px solid var(--line); +} + +.showcase__frame figcaption { + font-size: 0.8125rem; + color: var(--muted); +} + +:root[data-theme="dark"] .shot--light, +:root[data-theme="light"] .shot--dark { + display: none; +} + +.privacy { + padding-block: var(--space-4xl); + background: var(--tint); +} + +.privacy__grid { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-xl); +} + +@media (min-width: 60rem) { + .privacy__grid { + grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); + column-gap: var(--space-3xl); + } + + .privacy__note { + grid-column: 2; + } +} + +.privacy h2 { + color: var(--bright); +} + +.privacy__list { + list-style: none; + margin: 0; + padding: 0; + display: grid; + gap: var(--space-l); +} + +.privacy__list li { + font-size: var(--step-0); + color: var(--fg); + max-width: 60ch; +} + +.privacy__list strong { + color: var(--on-tint); +} + +.privacy__note { + font-size: var(--step--1); + color: var(--muted); + max-width: 60ch; + padding-top: var(--space-m); + border-top: 1px solid color-mix(in srgb, var(--primary) 30%, transparent); +} + +.proof { + padding-block: var(--space-4xl) var(--space-3xl); +} + +.proof h2 { + max-width: 18ch; +} + +.proof__row { + list-style: none; + margin: var(--space-2xl) 0 0; + padding: 0; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); + gap: var(--space-xl) var(--space-l); +} + +.proof__row li { + display: grid; + gap: var(--space-2xs); + padding-top: var(--space-m); + border-top: 2px solid var(--primary); +} + +.proof__value { + font-family: var(--om-font-display); + font-size: clamp(2.2rem, 1.6rem + 2.4vw, 3.4rem); + font-weight: 720; + letter-spacing: -0.03em; + line-height: 1; + color: var(--bright); + font-variant-numeric: tabular-nums; +} + +.proof__label { + color: var(--muted); + font-size: var(--step--1); +} + +.proof__source { + margin-top: var(--space-l); + font-family: var(--om-font-mono); + font-size: 0.75rem; + color: var(--muted); +} + +.faq { + padding-block: var(--space-3xl) var(--space-4xl); +} + +.faq__grid { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-xl); +} + +@media (min-width: 60rem) { + .faq__grid { + grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); + } +} + +.faq__list details { + border-top: 1px solid var(--line); +} + +.faq__list details:last-child { + border-bottom: 1px solid var(--line); +} + +.faq__list summary { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-m); + padding-block: var(--space-l); + font-family: var(--om-font-display); + font-size: var(--step-1); + font-weight: 650; + color: var(--bright); + cursor: pointer; + list-style: none; +} + +.faq__list summary::-webkit-details-marker { + display: none; +} + +.faq__list summary::after { + content: "+"; + font-family: var(--om-font-mono); + color: var(--primary); + font-size: 1.25rem; + line-height: 1; +} + +.faq__list details[open] summary::after { + content: "−"; +} + +.faq__list summary:hover { + color: var(--primary); +} + +.faq__list details p { + padding-bottom: var(--space-l); + max-width: 62ch; + color: var(--fg); +} + +.closing { + padding-block: var(--space-4xl); + border-top: 1px solid var(--line); + background: radial-gradient(60% 80% at 15% 100%, var(--tint), transparent 70%); +} + +.closing__inner { + display: grid; + gap: var(--space-2xl); +} + +.closing h2 { + font-size: var(--step-6); + max-width: 16ch; +} + +.closing__actions { + display: flex; + flex-wrap: wrap; + gap: var(--space-s); +} + +.footer { + padding-block: var(--space-2xl); + border-top: 1px solid var(--line); + font-size: var(--step--1); +} + +.footer__inner { + display: grid; + gap: var(--space-m); +} + +@media (min-width: 52rem) { + .footer__inner { + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + } + + .footer__fine { + grid-column: 1 / -1; + } +} + +.footer__statement { + font-family: var(--om-font-display); + font-size: var(--step-1); + color: var(--bright); +} + +.footer__links { + display: flex; + flex-wrap: wrap; + gap: var(--space-l); +} + +.footer__links a { + white-space: nowrap; + text-decoration: none; + line-height: 1; +} + +.footer__links a:hover { + color: var(--primary); +} + +.footer__fine { + color: var(--muted); +} + +@keyframes reveal-text { + from { + clip-path: inset(0 100% 0 0); + } + to { + clip-path: inset(0 0 0 0); + } +} + +@keyframes fade-up { + from { + opacity: 0; + transform: translateY(6px); + } +} + +@keyframes rise { + from { + opacity: 0.001; + transform: translateY(28px); + } +} + +@keyframes draw { + from { + stroke-dashoffset: 600; + } +} + +@keyframes settle { + from { + transform: perspective(1600px) rotateX(10deg) translateY(36px) scale(0.95); + } +} + +@keyframes halo { + from { + transform: scale(0.4); + opacity: 0; + } +} + +@supports (animation-timeline: view()) { + @media (prefers-reduced-motion: no-preference) { + .section-head, + .features__head, + .install__head, + .step, + .feature, + .proof__row li, + .privacy__list li { + animation: rise linear both; + animation-timeline: view(); + animation-range: entry 0% entry 70%; + } + + .contrast__log li { + animation: rise linear both; + animation-timeline: view(); + animation-range: entry calc(10% + var(--i) * 12%) cover 35%; + } + + .nested__branch { + stroke-dasharray: 600; + animation: draw linear both; + animation-timeline: view(); + animation-range: entry calc(20% + var(--i) * 10%) cover 50%; + } + + .nested__halo { + transform-origin: 444px 180px; + animation: halo linear both; + animation-timeline: view(); + animation-range: cover 30% cover 50%; + } + + .showcase__frame { + transform-origin: 50% 100%; + animation: settle linear both; + animation-timeline: view(); + animation-range: entry 0% cover 40%; + } + } +} + +@media (prefers-reduced-motion: reduce) { + .chat[data-state] .chat__answer, + .chat[data-state] .chat__memory { + animation: none; + opacity: 1; + } + + .button, + .memcard, + .field canvas, + .field .graph-svg, + .terminal__idle, + .dream__key { + transition: none; + } +} diff --git a/site/tsconfig.json b/site/tsconfig.json new file mode 100644 index 00000000..738867fe --- /dev/null +++ b/site/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist", "node_modules"], + "compilerOptions": { + "noUncheckedIndexedAccess": true + } +}