diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 00000000..6240da8b
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,21 @@
+# build output
+dist/
+# generated types
+.astro/
+
+# dependencies
+node_modules/
+
+# logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+
+# environment variables
+.env
+.env.production
+
+# macOS-specific files
+.DS_Store
diff --git a/docs/.vscode/extensions.json b/docs/.vscode/extensions.json
new file mode 100644
index 00000000..22a15055
--- /dev/null
+++ b/docs/.vscode/extensions.json
@@ -0,0 +1,4 @@
+{
+ "recommendations": ["astro-build.astro-vscode"],
+ "unwantedRecommendations": []
+}
diff --git a/docs/.vscode/launch.json b/docs/.vscode/launch.json
new file mode 100644
index 00000000..d6422097
--- /dev/null
+++ b/docs/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "command": "./node_modules/.bin/astro dev",
+ "name": "Development server",
+ "request": "launch",
+ "type": "node-terminal"
+ }
+ ]
+}
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000..1b7f5c3d
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,49 @@
+# Starlight Starter Kit: Basics
+
+[](https://starlight.astro.build)
+
+```
+npm create astro@latest -- --template starlight
+```
+
+> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
+
+## 🚀 Project Structure
+
+Inside of your Astro + Starlight project, you'll see the following folders and files:
+
+```
+.
+├── public/
+├── src/
+│ ├── assets/
+│ ├── content/
+│ │ └── docs/
+│ └── content.config.ts
+├── astro.config.mjs
+├── package.json
+└── tsconfig.json
+```
+
+Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
+
+Images can be added to `src/assets/` and embedded in Markdown with a relative link.
+
+Static assets, like favicons, can be placed in the `public/` directory.
+
+## 🧞 Commands
+
+All commands are run from the root of the project, from a terminal:
+
+| Command | Action |
+| :------------------------ | :----------------------------------------------- |
+| `npm install` | Installs dependencies |
+| `npm run dev` | Starts local dev server at `localhost:4321` |
+| `npm run build` | Build your production site to `./dist/` |
+| `npm run preview` | Preview your build locally, before deploying |
+| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
+| `npm run astro -- --help` | Get help using the Astro CLI |
+
+## 👀 Want to learn more?
+
+Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs
new file mode 100644
index 00000000..db6e856b
--- /dev/null
+++ b/docs/astro.config.mjs
@@ -0,0 +1,93 @@
+// @ts-check
+import { defineConfig } from 'astro/config';
+import starlight from '@astrojs/starlight';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [
+ starlight({
+ title: 'Flutter Server Box',
+ description: 'A comprehensive cross-platform server management application built with Flutter',
+ logo: {
+ src: './src/assets/logo.svg',
+ },
+ social: [
+ { icon: 'github', label: 'GitHub', href: 'https://github.com/lollipopkit/flutter_server_box' },
+ ],
+ sidebar: [
+ {
+ label: 'Getting Started',
+ items: [
+ { label: 'Introduction', slug: 'introduction' },
+ { label: 'Installation', slug: 'installation' },
+ { label: 'Quick Start', slug: 'quick-start' },
+ ],
+ },
+ {
+ label: 'Features',
+ items: [
+ { label: 'Server Monitoring', slug: 'features/monitoring' },
+ { label: 'Docker Management', slug: 'features/docker' },
+ { label: 'Process & Services', slug: 'features/process' },
+ { label: 'Command Snippets', slug: 'features/snippets' },
+ { label: 'Network Tools', slug: 'features/network' },
+ { label: 'PVE (Proxmox)', slug: 'features/pve' },
+ ],
+ },
+ {
+ label: 'Configuration',
+ items: [
+ { label: 'Server Setup', slug: 'configuration/server' },
+ { label: 'Terminal & SSH', slug: 'configuration/terminal' },
+ { label: 'SFTP File Browser', slug: 'configuration/sftp' },
+ { label: 'Jump Server', slug: 'configuration/jump-server' },
+ { label: 'Backup & Restore', slug: 'configuration/backup' },
+ { label: 'Appearance', slug: 'configuration/appearance' },
+ { label: 'Localizations', slug: 'configuration/localizations' },
+ ],
+ },
+ {
+ label: 'Platform Features',
+ items: [
+ { label: 'Mobile', slug: 'platforms/mobile' },
+ { label: 'Desktop', slug: 'platforms/desktop' },
+ { label: 'watchOS', slug: 'platforms/watchos' },
+ ],
+ },
+ {
+ label: 'Advanced',
+ items: [
+ { label: 'Bulk Import Servers', slug: 'advanced/bulk-import' },
+ { label: 'Widget Setup', slug: 'advanced/widgets' },
+ { label: 'Custom Commands', slug: 'advanced/custom-commands' },
+ { label: 'Custom Logo', slug: 'advanced/custom-logo' },
+ { label: 'JSON Settings', slug: 'advanced/json-settings' },
+ { label: 'Common Issues', slug: 'advanced/troubleshooting' },
+ ],
+ },
+ {
+ label: 'How It Works',
+ items: [
+ { label: 'Architecture', slug: 'principles/architecture' },
+ { label: 'SSH Connection', slug: 'principles/ssh' },
+ { label: 'Terminal', slug: 'principles/terminal' },
+ { label: 'SFTP', slug: 'principles/sftp' },
+ { label: 'State Management', slug: 'principles/state' },
+ ],
+ },
+ {
+ label: 'Development',
+ items: [
+ { label: 'Project Structure', slug: 'development/structure' },
+ { label: 'Architecture', slug: 'development/architecture' },
+ { label: 'State Management', slug: 'development/state' },
+ { label: 'Code Generation', slug: 'development/codegen' },
+ { label: 'Building', slug: 'development/building' },
+ { label: 'Testing', slug: 'development/testing' },
+ ],
+ },
+ ],
+ customCss: ['./src/styles/custom.css'],
+ }),
+ ],
+});
diff --git a/docs/bun.lock b/docs/bun.lock
new file mode 100644
index 00000000..bb826e27
--- /dev/null
+++ b/docs/bun.lock
@@ -0,0 +1,900 @@
+{
+ "lockfileVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "docs",
+ "dependencies": {
+ "@astrojs/starlight": "^0.37.4",
+ "astro": "^5.6.1",
+ "sharp": "^0.34.2",
+ },
+ },
+ },
+ "packages": {
+ "@astrojs/compiler": ["@astrojs/compiler@2.13.0", "", {}, "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw=="],
+
+ "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.5", "", {}, "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA=="],
+
+ "@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.10", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.5", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.19.0", "smol-toml": "^1.5.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A=="],
+
+ "@astrojs/mdx": ["@astrojs/mdx@4.3.13", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.10", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q=="],
+
+ "@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="],
+
+ "@astrojs/sitemap": ["@astrojs/sitemap@3.7.0", "", { "dependencies": { "sitemap": "^8.0.2", "stream-replace-string": "^2.0.0", "zod": "^3.25.76" } }, "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA=="],
+
+ "@astrojs/starlight": ["@astrojs/starlight@0.37.4", "", { "dependencies": { "@astrojs/markdown-remark": "^6.3.1", "@astrojs/mdx": "^4.2.3", "@astrojs/sitemap": "^3.3.0", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.41.1", "bcp-47": "^2.1.0", "hast-util-from-html": "^2.0.1", "hast-util-select": "^6.0.2", "hast-util-to-string": "^3.0.0", "hastscript": "^9.0.0", "i18next": "^23.11.5", "js-yaml": "^4.1.0", "klona": "^2.0.6", "magic-string": "^0.30.17", "mdast-util-directive": "^3.0.0", "mdast-util-to-markdown": "^2.1.0", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.3.0", "rehype": "^13.0.1", "rehype-format": "^5.0.0", "remark-directive": "^3.0.0", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2" }, "peerDependencies": { "astro": "^5.5.0" } }, "sha512-ygPGDgRd9nCcNgaYMNN7UeAMAkDOR1ibv3ps3xEz+cuvKG3CRLd19UwdB+Gyz1tbkyfjPWPkFKNhLwNybro8Tw=="],
+
+ "@astrojs/telemetry": ["@astrojs/telemetry@3.3.0", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ=="],
+
+ "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
+
+ "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
+
+ "@babel/parser": ["@babel/parser@7.28.6", "", { "dependencies": { "@babel/types": "^7.28.6" }, "bin": "./bin/babel-parser.js" }, "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ=="],
+
+ "@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="],
+
+ "@babel/types": ["@babel/types@7.28.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg=="],
+
+ "@capsizecss/unpack": ["@capsizecss/unpack@4.0.0", "", { "dependencies": { "fontkitten": "^1.0.0" } }, "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA=="],
+
+ "@ctrl/tinycolor": ["@ctrl/tinycolor@4.2.0", "", {}, "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A=="],
+
+ "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
+
+ "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
+
+ "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
+
+ "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
+
+ "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
+
+ "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
+
+ "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
+
+ "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
+
+ "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
+
+ "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
+
+ "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
+
+ "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
+
+ "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
+
+ "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
+
+ "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
+
+ "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
+
+ "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
+
+ "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
+
+ "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
+
+ "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
+
+ "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
+
+ "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
+
+ "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
+
+ "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
+
+ "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
+
+ "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
+
+ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
+
+ "@expressive-code/core": ["@expressive-code/core@0.41.6", "", { "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": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-FvJQP+hG0jWi/FLBSmvHInDqWR7jNANp9PUDjdMqSshHb0y7sxx3vHuoOr6SgXjWw+MGLqorZyPQ0aAlHEok6g=="],
+
+ "@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6" } }, "sha512-d+hkSYXIQot6fmYnOmWAM+7TNWRv/dhfjMsNq+mIZz8Tb4mPHOcgcfZeEM5dV9TDL0ioQNvtcqQNuzA1sRPjxg=="],
+
+ "@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6", "shiki": "^3.2.2" } }, "sha512-Y6zmKBmsIUtWTzdefqlzm/h9Zz0Rc4gNdt2GTIH7fhHH2I9+lDYCa27BDwuBhjqcos6uK81Aca9dLUC4wzN+ng=="],
+
+ "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6" } }, "sha512-PBFa1wGyYzRExMDzBmAWC6/kdfG1oLn4pLpBeTfIRrALPjcGA/59HP3e7q9J0Smk4pC7U+lWkA2LHR8FYV8U7Q=="],
+
+ "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
+
+ "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
+
+ "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
+
+ "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
+
+ "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
+
+ "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
+
+ "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
+
+ "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
+
+ "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
+
+ "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
+
+ "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
+
+ "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
+
+ "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
+
+ "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
+
+ "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
+
+ "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
+
+ "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
+
+ "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
+
+ "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
+
+ "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
+
+ "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
+
+ "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
+
+ "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
+
+ "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
+
+ "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
+
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
+
+ "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="],
+
+ "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
+
+ "@pagefind/darwin-arm64": ["@pagefind/darwin-arm64@1.4.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ=="],
+
+ "@pagefind/darwin-x64": ["@pagefind/darwin-x64@1.4.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A=="],
+
+ "@pagefind/default-ui": ["@pagefind/default-ui@1.4.0", "", {}, "sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ=="],
+
+ "@pagefind/freebsd-x64": ["@pagefind/freebsd-x64@1.4.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q=="],
+
+ "@pagefind/linux-arm64": ["@pagefind/linux-arm64@1.4.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw=="],
+
+ "@pagefind/linux-x64": ["@pagefind/linux-x64@1.4.0", "", { "os": "linux", "cpu": "x64" }, "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg=="],
+
+ "@pagefind/windows-x64": ["@pagefind/windows-x64@1.4.0", "", { "os": "win32", "cpu": "x64" }, "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g=="],
+
+ "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="],
+
+ "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.0", "", { "os": "android", "cpu": "arm" }, "sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA=="],
+
+ "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.0", "", { "os": "android", "cpu": "arm64" }, "sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg=="],
+
+ "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.57.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg=="],
+
+ "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.57.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA=="],
+
+ "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.57.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g=="],
+
+ "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.57.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA=="],
+
+ "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q=="],
+
+ "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA=="],
+
+ "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw=="],
+
+ "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw=="],
+
+ "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q=="],
+
+ "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ=="],
+
+ "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.57.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ=="],
+
+ "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.57.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA=="],
+
+ "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ=="],
+
+ "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ=="],
+
+ "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.57.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg=="],
+
+ "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A=="],
+
+ "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw=="],
+
+ "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.57.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw=="],
+
+ "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.57.0", "", { "os": "none", "cpu": "arm64" }, "sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA=="],
+
+ "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.57.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ=="],
+
+ "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.57.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA=="],
+
+ "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.57.0", "", { "os": "win32", "cpu": "x64" }, "sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA=="],
+
+ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ=="],
+
+ "@shikijs/core": ["@shikijs/core@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA=="],
+
+ "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ=="],
+
+ "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ=="],
+
+ "@shikijs/langs": ["@shikijs/langs@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA=="],
+
+ "@shikijs/themes": ["@shikijs/themes@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw=="],
+
+ "@shikijs/types": ["@shikijs/types@3.21.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA=="],
+
+ "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
+
+ "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
+
+ "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
+
+ "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="],
+
+ "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
+
+ "@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/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="],
+
+ "@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@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="],
+
+ "@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.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
+
+ "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
+
+ "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
+
+ "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
+
+ "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
+
+ "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=="],
+
+ "array-iterate": ["array-iterate@2.0.1", "", {}, "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg=="],
+
+ "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="],
+
+ "astro": ["astro@5.16.16", "", { "dependencies": { "@astrojs/compiler": "^2.13.0", "@astrojs/internal-helpers": "0.7.5", "@astrojs/markdown-remark": "6.3.10", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^4.0.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "acorn": "^8.15.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.3.1", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.1.1", "cssesc": "^3.0.0", "debug": "^4.4.3", "deterministic-object-hash": "^2.0.2", "devalue": "^5.6.2", "diff": "^8.0.3", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.7.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.4.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "magic-string": "^0.30.21", "magicast": "^0.5.1", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.1", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.3", "shiki": "^3.21.0", "smol-toml": "^1.6.0", "svgo": "^4.0.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tsconfck": "^3.1.6", "ultrahtml": "^1.6.0", "unifont": "~0.7.3", "unist-util-visit": "^5.0.0", "unstorage": "^1.17.4", "vfile": "^6.0.3", "vite": "^6.4.1", "vitefu": "^1.1.1", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.3", "zod": "^3.25.76", "zod-to-json-schema": "^3.25.1", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.34.0" }, "bin": { "astro": "astro.js" } }, "sha512-MFlFvQ84ixaHyqB3uGwMhNHdBLZ3vHawyq3PqzQS2TNWiNfQrxp5ag6S3lX+Cvnh0MUcXX+UnJBPMBHjP1/1ZQ=="],
+
+ "astro-expressive-code": ["astro-expressive-code@0.41.6", "", { "dependencies": { "rehype-expressive-code": "^0.41.6" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" } }, "sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw=="],
+
+ "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
+
+ "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
+
+ "base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="],
+
+ "bcp-47": ["bcp-47@2.1.0", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w=="],
+
+ "bcp-47-match": ["bcp-47-match@2.0.3", "", {}, "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ=="],
+
+ "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
+
+ "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="],
+
+ "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
+
+ "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
+
+ "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
+
+ "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.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="],
+
+ "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
+
+ "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
+
+ "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="],
+
+ "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@1.0.1", "", {}, "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="],
+
+ "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
+
+ "cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="],
+
+ "crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="],
+
+ "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
+
+ "css-selector-parser": ["css-selector-parser@3.3.0", "", {}, "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g=="],
+
+ "css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
+
+ "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
+
+ "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
+
+ "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" } }, "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.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
+
+ "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=="],
+
+ "deterministic-object-hash": ["deterministic-object-hash@2.0.2", "", { "dependencies": { "base-64": "^1.0.0" } }, "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ=="],
+
+ "devalue": ["devalue@5.6.2", "", {}, "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg=="],
+
+ "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
+
+ "diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="],
+
+ "direction": ["direction@2.0.1", "", { "bin": { "direction": "cli.js" } }, "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="],
+
+ "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
+
+ "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=="],
+
+ "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
+
+ "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
+
+ "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
+
+ "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="],
+
+ "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="],
+
+ "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
+
+ "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
+
+ "estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="],
+
+ "estree-util-build-jsx": ["estree-util-build-jsx@3.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-walker": "^3.0.0" } }, "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ=="],
+
+ "estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="],
+
+ "estree-util-scope": ["estree-util-scope@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0" } }, "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ=="],
+
+ "estree-util-to-js": ["estree-util-to-js@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", "source-map": "^0.7.0" } }, "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg=="],
+
+ "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="],
+
+ "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
+
+ "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="],
+
+ "expressive-code": ["expressive-code@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6", "@expressive-code/plugin-frames": "^0.41.6", "@expressive-code/plugin-shiki": "^0.41.6", "@expressive-code/plugin-text-markers": "^0.41.6" } }, "sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA=="],
+
+ "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
+
+ "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=="],
+
+ "fontace": ["fontace@0.4.0", "", { "dependencies": { "fontkitten": "^1.0.0" } }, "sha512-moThBCItUe2bjZip5PF/iZClpKHGLwMvR79Kp8XpGRBrvoRSnySN4VcILdv3/MJzbhvUA5WeiUXF5o538m5fvg=="],
+
+ "fontkitten": ["fontkitten@1.0.2", "", { "dependencies": { "tiny-inflate": "^1.0.3" } }, "sha512-piJxbLnkD9Xcyi7dWJRnqszEURixe7CrF/efBfbffe2DPyabmuIuqraruY8cXTs19QoM8VJzx47BDRVNXETM7Q=="],
+
+ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
+
+ "get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
+
+ "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
+
+ "h3": ["h3@1.15.5", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.5", "defu": "^6.1.4", "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-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg=="],
+
+ "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-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", "hast-util-from-parse5": "^8.0.0", "parse5": "^7.0.0", "vfile": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="],
+
+ "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="],
+
+ "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-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="],
+
+ "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-estree": ["hast-util-to-estree@3.1.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-attach-comments": "^3.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="],
+
+ "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
+
+ "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="],
+
+ "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="],
+
+ "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.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "hast-util-is-element": "^3.0.0", "unist-util-find-after": "^5.0.0" } }, "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A=="],
+
+ "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.1", "", { "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-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="],
+
+ "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.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="],
+
+ "i18next": ["i18next@23.16.8", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg=="],
+
+ "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="],
+
+ "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="],
+
+ "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@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
+
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
+
+ "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="],
+
+ "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="],
+
+ "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
+
+ "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="],
+
+ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
+
+ "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
+
+ "klona": ["klona@2.0.6", "", {}, "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA=="],
+
+ "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
+
+ "lru-cache": ["lru-cache@11.2.5", "", {}, "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw=="],
+
+ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
+
+ "magicast": ["magicast@0.5.1", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "source-map-js": "^1.2.1" } }, "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw=="],
+
+ "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="],
+
+ "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
+
+ "mdast-util-definitions": ["mdast-util-definitions@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ=="],
+
+ "mdast-util-directive": ["mdast-util-directive@3.1.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.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q=="],
+
+ "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="],
+
+ "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="],
+
+ "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="],
+
+ "mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="],
+
+ "mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="],
+
+ "mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="],
+
+ "mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "markdown-table": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="],
+
+ "mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="],
+
+ "mdast-util-mdx": ["mdast-util-mdx@3.0.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w=="],
+
+ "mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="],
+
+ "mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="],
+
+ "mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="],
+
+ "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="],
+
+ "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="],
+
+ "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="],
+
+ "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="],
+
+ "mdn-data": ["mdn-data@2.12.2", "", {}, "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA=="],
+
+ "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="],
+
+ "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="],
+
+ "micromark-extension-directive": ["micromark-extension-directive@3.0.2", "", { "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-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA=="],
+
+ "micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="],
+
+ "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="],
+
+ "micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="],
+
+ "micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="],
+
+ "micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="],
+
+ "micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="],
+
+ "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="],
+
+ "micromark-extension-mdx-expression": ["micromark-extension-mdx-expression@3.0.1", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q=="],
+
+ "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.2", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ=="],
+
+ "micromark-extension-mdx-md": ["micromark-extension-mdx-md@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ=="],
+
+ "micromark-extension-mdxjs": ["micromark-extension-mdxjs@3.0.0", "", { "dependencies": { "acorn": "^8.0.0", "acorn-jsx": "^5.0.0", "micromark-extension-mdx-expression": "^3.0.0", "micromark-extension-mdx-jsx": "^3.0.0", "micromark-extension-mdx-md": "^2.0.0", "micromark-extension-mdxjs-esm": "^3.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ=="],
+
+ "micromark-extension-mdxjs-esm": ["micromark-extension-mdxjs-esm@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A=="],
+
+ "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-mdx-expression": ["micromark-factory-mdx-expression@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ=="],
+
+ "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="],
+
+ "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="],
+
+ "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="],
+
+ "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="],
+
+ "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="],
+
+ "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="],
+
+ "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="],
+
+ "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="],
+
+ "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="],
+
+ "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="],
+
+ "micromark-util-events-to-acorn": ["micromark-util-events-to-acorn@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg=="],
+
+ "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="],
+
+ "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="],
+
+ "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="],
+
+ "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="],
+
+ "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="],
+
+ "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="],
+
+ "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="],
+
+ "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
+
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+
+ "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
+
+ "neotraverse": ["neotraverse@0.6.18", "", {}, "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA=="],
+
+ "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.4", "", {}, "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ=="],
+
+ "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=="],
+
+ "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=="],
+
+ "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
+
+ "oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="],
+
+ "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="],
+
+ "p-limit": ["p-limit@6.2.0", "", { "dependencies": { "yocto-queue": "^1.1.1" } }, "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA=="],
+
+ "p-queue": ["p-queue@8.1.1", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^6.1.2" } }, "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ=="],
+
+ "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="],
+
+ "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
+
+ "pagefind": ["pagefind@1.4.0", "", { "optionalDependencies": { "@pagefind/darwin-arm64": "1.4.0", "@pagefind/darwin-x64": "1.4.0", "@pagefind/freebsd-x64": "1.4.0", "@pagefind/linux-arm64": "1.4.0", "@pagefind/linux-x64": "1.4.0", "@pagefind/windows-x64": "1.4.0" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g=="],
+
+ "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=="],
+
+ "parse-latin": ["parse-latin@7.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "@types/unist": "^3.0.0", "nlcst-to-string": "^4.0.0", "unist-util-modify-children": "^4.0.0", "unist-util-visit-children": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ=="],
+
+ "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
+
+ "piccolore": ["piccolore@0.1.3", "", {}, "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw=="],
+
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
+
+ "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
+
+ "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
+
+ "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="],
+
+ "postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
+
+ "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
+
+ "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
+
+ "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
+
+ "radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="],
+
+ "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
+
+ "recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="],
+
+ "recma-jsx": ["recma-jsx@1.0.1", "", { "dependencies": { "acorn-jsx": "^5.0.0", "estree-util-to-js": "^2.0.0", "recma-parse": "^1.0.0", "recma-stringify": "^1.0.0", "unified": "^11.0.0" }, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w=="],
+
+ "recma-parse": ["recma-parse@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "esast-util-from-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ=="],
+
+ "recma-stringify": ["recma-stringify@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-to-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g=="],
+
+ "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": ["rehype@13.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "rehype-parse": "^9.0.0", "rehype-stringify": "^10.0.0", "unified": "^11.0.0" } }, "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A=="],
+
+ "rehype-expressive-code": ["rehype-expressive-code@0.41.6", "", { "dependencies": { "expressive-code": "^0.41.6" } }, "sha512-aBMX8kxPtjmDSFUdZlAWJkMvsQ4ZMASfee90JWIAV8tweltXLzkWC3q++43ToTelI8ac5iC0B3/S/Cl4Ql1y2g=="],
+
+ "rehype-format": ["rehype-format@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-format": "^1.0.0" } }, "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ=="],
+
+ "rehype-parse": ["rehype-parse@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-html": "^2.0.0", "unified": "^11.0.0" } }, "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag=="],
+
+ "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="],
+
+ "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="],
+
+ "rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="],
+
+ "remark-directive": ["remark-directive@3.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", "micromark-extension-directive": "^3.0.0", "unified": "^11.0.0" } }, "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A=="],
+
+ "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="],
+
+ "remark-mdx": ["remark-mdx@3.1.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg=="],
+
+ "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="],
+
+ "remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="],
+
+ "remark-smartypants": ["remark-smartypants@3.0.2", "", { "dependencies": { "retext": "^9.0.0", "retext-smartypants": "^6.0.0", "unified": "^11.0.4", "unist-util-visit": "^5.0.0" } }, "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA=="],
+
+ "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="],
+
+ "retext": ["retext@9.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "retext-latin": "^4.0.0", "retext-stringify": "^4.0.0", "unified": "^11.0.0" } }, "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA=="],
+
+ "retext-latin": ["retext-latin@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "parse-latin": "^7.0.0", "unified": "^11.0.0" } }, "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA=="],
+
+ "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=="],
+
+ "retext-stringify": ["retext-stringify@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "nlcst-to-string": "^4.0.0", "unified": "^11.0.0" } }, "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA=="],
+
+ "rollup": ["rollup@4.57.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.0", "@rollup/rollup-android-arm64": "4.57.0", "@rollup/rollup-darwin-arm64": "4.57.0", "@rollup/rollup-darwin-x64": "4.57.0", "@rollup/rollup-freebsd-arm64": "4.57.0", "@rollup/rollup-freebsd-x64": "4.57.0", "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", "@rollup/rollup-linux-arm-musleabihf": "4.57.0", "@rollup/rollup-linux-arm64-gnu": "4.57.0", "@rollup/rollup-linux-arm64-musl": "4.57.0", "@rollup/rollup-linux-loong64-gnu": "4.57.0", "@rollup/rollup-linux-loong64-musl": "4.57.0", "@rollup/rollup-linux-ppc64-gnu": "4.57.0", "@rollup/rollup-linux-ppc64-musl": "4.57.0", "@rollup/rollup-linux-riscv64-gnu": "4.57.0", "@rollup/rollup-linux-riscv64-musl": "4.57.0", "@rollup/rollup-linux-s390x-gnu": "4.57.0", "@rollup/rollup-linux-x64-gnu": "4.57.0", "@rollup/rollup-linux-x64-musl": "4.57.0", "@rollup/rollup-openbsd-x64": "4.57.0", "@rollup/rollup-openharmony-arm64": "4.57.0", "@rollup/rollup-win32-arm64-msvc": "4.57.0", "@rollup/rollup-win32-ia32-msvc": "4.57.0", "@rollup/rollup-win32-x64-gnu": "4.57.0", "@rollup/rollup-win32-x64-msvc": "4.57.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA=="],
+
+ "sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="],
+
+ "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
+
+ "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
+
+ "shiki": ["shiki@3.21.0", "", { "dependencies": { "@shikijs/core": "3.21.0", "@shikijs/engine-javascript": "3.21.0", "@shikijs/engine-oniguruma": "3.21.0", "@shikijs/langs": "3.21.0", "@shikijs/themes": "3.21.0", "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w=="],
+
+ "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
+
+ "sitemap": ["sitemap@8.0.2", "", { "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.4.1" }, "bin": { "sitemap": "dist/cli.js" } }, "sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ=="],
+
+ "smol-toml": ["smol-toml@1.6.0", "", {}, "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw=="],
+
+ "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
+
+ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
+
+ "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="],
+
+ "stream-replace-string": ["stream-replace-string@2.0.0", "", {}, "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w=="],
+
+ "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=="],
+
+ "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.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
+
+ "style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="],
+
+ "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="],
+
+ "svgo": ["svgo@4.0.0", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.4.1" }, "bin": "./bin/svgo.js" }, "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw=="],
+
+ "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
+
+ "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
+
+ "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
+
+ "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
+
+ "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
+
+ "tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
+
+ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+
+ "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
+
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
+
+ "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="],
+
+ "ultrahtml": ["ultrahtml@1.6.0", "", {}, "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw=="],
+
+ "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
+
+ "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@0.7.3", "", { "dependencies": { "css-tree": "^3.1.0", "ofetch": "^1.5.1", "ohash": "^2.0.11" } }, "sha512-b0GtQzKCyuSHGsfj5vyN8st7muZ6VCI4XD4vFlr7Uy1rlWVYxC3npnfk8MyreHxJYrz1ooLDqDzFe9XqQTlAhA=="],
+
+ "unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
+
+ "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
+
+ "unist-util-modify-children": ["unist-util-modify-children@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "array-iterate": "^2.0.0" } }, "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw=="],
+
+ "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
+
+ "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="],
+
+ "unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="],
+
+ "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.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
+
+ "unist-util-visit-children": ["unist-util-visit-children@3.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA=="],
+
+ "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="],
+
+ "unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "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", "@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-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="],
+
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+
+ "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
+
+ "vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="],
+
+ "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@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
+
+ "vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
+
+ "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
+
+ "which-pm-runs": ["which-pm-runs@1.1.0", "", {}, "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA=="],
+
+ "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
+
+ "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=="],
+
+ "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
+
+ "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="],
+
+ "yocto-spinner": ["yocto-spinner@0.2.3", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ=="],
+
+ "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
+
+ "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
+
+ "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
+
+ "zod-to-ts": ["zod-to-ts@1.2.0", "", { "peerDependencies": { "typescript": "^4.9.4 || ^5.0.2", "zod": "^3" } }, "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA=="],
+
+ "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
+
+ "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
+
+ "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
+
+ "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+
+ "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=="],
+
+ "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
+
+ "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
+
+ "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+
+ "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+
+ "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
+
+ "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+ }
+}
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 00000000..07df67b0
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "docs",
+ "type": "module",
+ "version": "0.0.1",
+ "scripts": {
+ "dev": "astro dev",
+ "start": "astro dev",
+ "build": "astro build",
+ "preview": "astro preview",
+ "astro": "astro"
+ },
+ "dependencies": {
+ "@astrojs/starlight": "^0.37.4",
+ "astro": "^5.6.1",
+ "sharp": "^0.34.2"
+ }
+}
\ No newline at end of file
diff --git a/docs/public/favicon.svg b/docs/public/favicon.svg
new file mode 100644
index 00000000..cba5ac14
--- /dev/null
+++ b/docs/public/favicon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/src/assets/houston.webp b/docs/src/assets/houston.webp
new file mode 100644
index 00000000..930c1649
Binary files /dev/null and b/docs/src/assets/houston.webp differ
diff --git a/docs/src/assets/logo.svg b/docs/src/assets/logo.svg
new file mode 100644
index 00000000..7a4c7c73
--- /dev/null
+++ b/docs/src/assets/logo.svg
@@ -0,0 +1,30 @@
+
diff --git a/docs/src/content.config.ts b/docs/src/content.config.ts
new file mode 100644
index 00000000..d9ee8c9d
--- /dev/null
+++ b/docs/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/docs/src/content/docs/advanced/bulk-import.md b/docs/src/content/docs/advanced/bulk-import.md
new file mode 100644
index 00000000..8ba04647
--- /dev/null
+++ b/docs/src/content/docs/advanced/bulk-import.md
@@ -0,0 +1,83 @@
+---
+title: Bulk Import Servers
+description: Import multiple servers from JSON file
+---
+
+Import multiple server configurations at once using a JSON file.
+
+## JSON Format
+
+:::danger[Security Warning]
+**Never store plaintext passwords in files!** This JSON example shows a password field for demonstration only, but you should:
+
+- **Prefer SSH keys** (`keyId`) instead of `pwd` - they're more secure
+- **Use secret managers** or environment variables if you must use passwords
+- **Delete the file immediately** after import - don't leave credentials lying around
+- **Add to .gitignore** - never commit credential files to version control
+:::
+
+```json
+[
+ {
+ "name": "My Server",
+ "ip": "example.com",
+ "port": 22,
+ "user": "root",
+ "pwd": "password",
+ "keyId": "",
+ "tags": ["production"],
+ "autoConnect": false
+ }
+]
+```
+
+## Fields
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `name` | Yes | Display name |
+| `ip` | Yes | Domain or IP address |
+| `port` | Yes | SSH port (usually 22) |
+| `user` | Yes | SSH username |
+| `pwd` | No | Password (avoid - use SSH keys instead) |
+| `keyId` | No | SSH key name (from Private Keys - recommended) |
+| `tags` | No | Organization tags |
+| `autoConnect` | No | Auto-connect on startup |
+
+## Import Steps
+
+1. Create JSON file with server configurations
+2. Settings → Backup → Bulk Import Servers
+3. Select your JSON file
+4. Confirm import
+
+## Example
+
+```json
+[
+ {
+ "name": "Production",
+ "ip": "prod.example.com",
+ "port": 22,
+ "user": "admin",
+ "keyId": "my-key",
+ "tags": ["production", "web"]
+ },
+ {
+ "name": "Development",
+ "ip": "dev.example.com",
+ "port": 2222,
+ "user": "dev",
+ "keyId": "dev-key",
+ "tags": ["development"]
+ }
+]
+```
+
+## Tips
+
+- **Use SSH keys** instead of passwords when possible
+- **Test connection** after import
+- **Organize with tags** for easier management
+- **Delete JSON file** after import
+- **Never commit** JSON files with credentials to version control
diff --git a/docs/src/content/docs/advanced/custom-commands.md b/docs/src/content/docs/advanced/custom-commands.md
new file mode 100644
index 00000000..b80aa657
--- /dev/null
+++ b/docs/src/content/docs/advanced/custom-commands.md
@@ -0,0 +1,72 @@
+---
+title: Custom Commands
+description: Display custom command output on server page
+---
+
+Add custom shell commands to show their output on the server detail page.
+
+## Setup
+
+1. Server settings → Custom Commands
+2. Enter commands in JSON format
+
+## Basic Format
+
+```json
+{
+ "Display Name": "shell command"
+}
+```
+
+**Example:**
+```json
+{
+ "Memory": "free -h",
+ "Disk": "df -h",
+ "Uptime": "uptime"
+}
+```
+
+## Viewing Results
+
+After setup, custom commands appear on server detail page and refresh automatically.
+
+## Special Command Names
+
+### server_card_top_right
+
+Display on home page server card (top-right corner):
+
+```json
+{
+ "server_card_top_right": "your-command-here"
+}
+```
+
+## Tips
+
+**Use absolute paths:**
+```json
+{"My Script": "/usr/local/bin/my-script.sh"}
+```
+
+**Pipe commands:**
+```json
+{"Top Process": "ps aux | sort -rk 3 | head -5"}
+```
+
+**Format output:**
+```json
+{"CPU Load": "uptime | awk -F'load average:' '{print $2}'"}
+```
+
+**Keep commands fast:** Under 5 seconds for best experience
+
+**Limit output:**
+```json
+{"Logs": "tail -20 /var/log/syslog"}
+```
+
+## Security
+
+Commands run with SSH user permissions. Avoid commands that modify system state.
diff --git a/docs/src/content/docs/advanced/custom-logo.md b/docs/src/content/docs/advanced/custom-logo.md
new file mode 100644
index 00000000..b8d7ae47
--- /dev/null
+++ b/docs/src/content/docs/advanced/custom-logo.md
@@ -0,0 +1,54 @@
+---
+title: Custom Server Logo
+description: Use custom images for server cards
+---
+
+Display custom logos on server cards using image URLs.
+
+## Setup
+
+1. Server settings → Custom Logo
+2. Enter image URL
+
+## URL Placeholders
+
+### {DIST} - Linux Distribution
+
+Auto-replaced with detected distribution:
+
+```
+https://example.com/{DIST}.png
+```
+
+Becomes: `debian.png`, `ubuntu.png`, `arch.png`, etc.
+
+### {BRIGHT} - Theme
+
+Auto-replaced with current theme:
+
+```
+https://example.com/{BRIGHT}.png
+```
+
+Becomes: `light.png` or `dark.png`
+
+### Combine Both
+
+```
+https://example.com/{DIST}-{BRIGHT}.png
+```
+
+Becomes: `debian-light.png`, `ubuntu-dark.png`, etc.
+
+## Tips
+
+- Use PNG or SVG formats
+- Recommended size: 64x64 to 128x128 pixels
+- Use HTTPS URLs
+- Keep file sizes small
+
+## Supported Distributions
+
+debian, ubuntu, centos, fedora, opensuse, kali, alpine, arch, rocky, deepin, armbian, wrt
+
+Full list: [`dist.dart`](https://github.com/lollipopkit/flutter_server_box/blob/main/lib/data/model/server/dist.dart)
diff --git a/docs/src/content/docs/advanced/json-settings.md b/docs/src/content/docs/advanced/json-settings.md
new file mode 100644
index 00000000..18fb531e
--- /dev/null
+++ b/docs/src/content/docs/advanced/json-settings.md
@@ -0,0 +1,75 @@
+---
+title: Hidden Settings (JSON)
+description: Access advanced settings via JSON editor
+---
+
+Some settings are hidden from the UI but accessible via JSON editor.
+
+## Access
+
+Long-press **Settings** in drawer to open JSON editor.
+
+## Common Hidden Settings
+
+### serverTabUseOldUI
+
+Use old server tab UI.
+
+```json
+{"serverTabUseOldUI": true}
+```
+
+**Type:** boolean | **Default:** false
+
+### timeout
+
+Connection timeout in seconds.
+
+```json
+{"timeout": 10}
+```
+
+**Type:** integer | **Default:** 5 | **Range:** 1-60
+
+### recordHistory
+
+Save history (SFTP paths, etc.).
+
+```json
+{"recordHistory": true}
+```
+
+**Type:** boolean | **Default:** true
+
+### textFactor
+
+Text scaling factor.
+
+```json
+{"textFactor": 1.2}
+```
+
+**Type:** double | **Default:** 1.0 | **Range:** 0.8-1.5
+
+## Finding More Settings
+
+All settings defined in [`setting.dart`](https://github.com/lollipopkit/flutter_server_box/blob/main/lib/data/store/setting.dart).
+
+Look for:
+```dart
+late final settingName = StoreProperty(box, 'settingKey', defaultValue);
+```
+
+## ⚠️ Important
+
+**Before editing:**
+- **Create backup** - Wrong settings can cause app to not open
+- **Edit carefully** - JSON must be valid
+- **Change one at a time** - Test each setting
+
+## Recovery
+
+If app won't open after editing:
+1. Clear app data (last resort)
+2. Reinstall app
+3. Restore from backup
diff --git a/docs/src/content/docs/advanced/troubleshooting.md b/docs/src/content/docs/advanced/troubleshooting.md
new file mode 100644
index 00000000..0ea24c8e
--- /dev/null
+++ b/docs/src/content/docs/advanced/troubleshooting.md
@@ -0,0 +1,118 @@
+---
+title: Common Issues
+description: Solutions to common problems
+---
+
+## Connection Issues
+
+### SSH Won't Connect
+
+**Symptoms:** Timeout, connection refused, auth failed
+
+**Solutions:**
+
+1. **Verify server type:** Only Unix-like systems supported (Linux, macOS, Android/Termux)
+2. **Test manually:** `ssh user@server -p port`
+3. **Check firewall:** Port 22 must be open
+4. **Verify credentials:** Username and password/key correct
+
+### Frequent Disconnections
+
+**Symptoms:** Terminal disconnects after inactivity
+
+**Solutions:**
+
+1. **Server keep-alive:**
+ ```bash
+ # /etc/ssh/sshd_config
+ ClientAliveInterval 60
+ ClientAliveCountMax 3
+ ```
+
+2. **Disable battery optimization:**
+ - MIUI: Battery → "No limits"
+ - Android: Settings → Apps → Disable optimization
+ - iOS: Enable background refresh
+
+## Input Issues
+
+### Can't Type Certain Characters
+
+**Solution:** Settings → Keyboard Type → Switch to `visiblePassword`
+
+Note: CJK input may not work after this change.
+
+## App Issues
+
+### App Crashes on Startup
+
+**Symptoms:** App won't open, black screen
+
+**Causes:** Corrupted settings, especially from JSON editor
+
+**Solutions:**
+
+1. **Clear app data:**
+ - Android: Settings → Apps → ServerBox → Clear Data
+ - iOS: Delete and reinstall
+
+2. **Restore backup:** Import backup created before changing settings
+
+### Backup/Restore Issues
+
+**Backup not working:**
+- Check storage space
+- Verify app has storage permissions
+- Try different location
+
+**Restore fails:**
+- Verify backup file integrity
+- Check app version compatibility
+
+## Widget Issues
+
+### Widget Not Updating
+
+**iOS:**
+- Wait up to 30 minutes for automatic refresh
+- Remove and re-add widget
+- Check URL ends with `/status`
+
+**Android:**
+- Tap widget to force refresh
+- Verify widget ID matches configuration in app settings
+
+**watchOS:**
+- Restart watch app
+- Wait a few minutes after config change
+- Verify URL format
+
+### Widget Shows Error
+
+- Verify ServerBox Monitor is running on server
+- Test URL in browser
+- Check authentication credentials
+
+## Performance Issues
+
+### App is Slow
+
+**Solutions:**
+- Reduce refresh rate in settings
+- Check network speed
+- Disable unused servers
+
+### High Battery Usage
+
+**Solutions:**
+- Increase refresh intervals
+- Disable background refresh
+- Close unused SSH sessions
+
+## Getting Help
+
+If issues persist:
+
+1. **Search GitHub Issues:** https://github.com/lollipopkit/flutter_server_box/issues
+2. **Create New Issue:** Include app version, platform, and steps to reproduce
+3. **Check Wiki:** This documentation and GitHub Wiki
diff --git a/docs/src/content/docs/advanced/widgets.md b/docs/src/content/docs/advanced/widgets.md
new file mode 100644
index 00000000..33713e39
--- /dev/null
+++ b/docs/src/content/docs/advanced/widgets.md
@@ -0,0 +1,91 @@
+---
+title: Home Screen Widgets
+description: Add server status widgets to your home screen
+---
+
+Requires [ServerBox Monitor](https://github.com/lollipopkit/server_box_monitor) installed on your servers.
+
+## Prerequisites
+
+Install ServerBox Monitor on your server first. See [ServerBox Monitor Wiki](https://github.com/lollipopkit/server_box_monitor/wiki/Home) for setup instructions.
+
+After installation, your server should have:
+- HTTP/HTTPS endpoint
+- `/status` API endpoint
+- Optional authentication
+
+## URL Format
+
+```
+https://your-server.com/status
+```
+
+Must end with `/status`.
+
+## iOS Widget
+
+### Setup
+
+1. Long press home screen → Tap **+**
+2. Search "ServerBox"
+3. Choose widget size
+4. Long press widget → **Edit Widget**
+5. Enter URL ending with `/status`
+
+### Notes
+
+- Must use HTTPS (except local IPs)
+- Max refresh rate: 30 minutes (iOS limit)
+- Add multiple widgets for multiple servers
+
+## Android Widget
+
+### Setup
+
+1. Long press home screen → **Widgets**
+2. Find "ServerBox" → Add to home screen
+3. Note the widget ID number displayed
+4. Open ServerBox app → Settings
+5. Tap **Config home widget link**
+6. Add entry: `Widget ID` = `Status URL`
+
+Example:
+- Key: `17`
+- Value: `https://my-server.com/status`
+
+7. Tap widget on home screen to refresh
+
+## watchOS Widget
+
+### Setup
+
+1. Open iPhone app → Settings
+2. **iOS Settings** → **Watch app**
+3. Tap **Add URL**
+4. Enter URL ending with `/status`
+5. Wait for watch app to sync
+
+### Notes
+
+- Try restarting watch app if not updating
+- Verify phone and watch are connected
+
+
+## Troubleshooting
+
+### Widget Not Updating
+
+**iOS:** Wait up to 30 minutes, then remove and re-add
+**Android:** Tap widget to force refresh, verify ID in settings
+**watchOS:** Restart watch app, wait a few minutes
+
+### Widget Shows Error
+
+- Verify ServerBox Monitor is running
+- Test URL in browser
+- Check URL ends with `/status`
+
+## Security
+
+- **Always use HTTPS** when possible
+- **Local IPs only** on trusted networks
diff --git a/docs/src/content/docs/configuration/appearance.md b/docs/src/content/docs/configuration/appearance.md
new file mode 100644
index 00000000..847e5748
--- /dev/null
+++ b/docs/src/content/docs/configuration/appearance.md
@@ -0,0 +1,124 @@
+---
+title: Appearance
+description: Customize the look and feel
+---
+
+Flutter Server Box offers extensive appearance customization.
+
+## Themes
+
+### Light Theme
+
+Clean, bright interface for daytime use.
+
+### Dark Theme
+
+Easy on the eyes for low-light environments.
+
+### AMOLED Dark
+
+Pure black background for OLED screens, saves battery.
+
+### System Theme
+
+Automatically switches between light and dark based on system settings.
+
+Set in: **Settings > Appearance > Theme**
+
+## Terminal Appearance
+
+### Customization Options
+
+- **Font Size**: Adjust text size in terminal
+- **Font Family**: Choose from available fonts
+- **Text Color**: Customize text color
+- **Background Color**: Set terminal background
+- **Background Opacity**: Adjust transparency
+- **Blur Effect**: Enable background blur
+
+### Terminal Themes
+
+Create terminal color themes:
+
+1. Go to Settings > Terminal > Themes
+2. Create new theme or edit existing
+3. Customize colors:
+ - Text color
+ - Background color
+ - Cursor color
+ - Selection color
+
+## Server Cards
+
+### Card Style
+
+- **Compact**: Minimal information per card
+- **Detailed**: Extended information per card
+- **Custom**: Choose which metrics to show
+
+### Card Order
+
+1. Go to Settings > Server Card Order
+2. Drag cards to reorder
+3. Changes apply immediately
+
+### Card Metrics
+
+Enable/disable metrics:
+- CPU
+- Memory
+- Disk
+- Network
+- GPU
+- Temperature
+
+## Charts and Graphs
+
+### Chart Style
+
+- **Line**: Continuous line chart
+- **Area**: Filled area chart
+- **Bar**: Bar chart visualization
+
+### Chart Colors
+
+Customize chart colors in:
+**Settings > Charts > Colors**
+
+### Refresh Rate
+
+Adjust how often charts update:
+**Settings > Charts > Refresh Rate**
+
+- **Power Saving**: 5 seconds
+- **Normal**: 2 seconds
+- **High Performance**: 1 second
+
+## Layout
+
+### Navigation Style
+
+- **Bottom Navigation**: Mobile-style bottom tabs
+- **Side Navigation**: Desktop-style sidebar
+- **Tabs**: Classic tab interface
+
+### View Mode
+
+- **List**: Vertical list view
+- **Grid**: Grid layout for servers
+- **Cards**: Card-based layout
+
+## Icons and Symbols
+
+Choose icon style:
+- **Filled**: Solid icons
+- **Outlined**: Line icons
+- **Rounded**: Soft, rounded icons
+
+## Animations
+
+Control animation speed:
+- **Off**: No animations
+- **Reduced**: Minimal animations
+- **Normal**: Standard animations
+- **Enhanced**: Extra animations
diff --git a/docs/src/content/docs/configuration/backup.md b/docs/src/content/docs/configuration/backup.md
new file mode 100644
index 00000000..825a9d15
--- /dev/null
+++ b/docs/src/content/docs/configuration/backup.md
@@ -0,0 +1,80 @@
+---
+title: Backup & Restore
+description: Backup and restore your app data
+---
+
+Protect your server configurations and settings with built-in backup functionality.
+
+## What Gets Backed Up
+
+- **Server Configurations**: All saved servers
+- **SSH Keys**: Imported private keys (encrypted)
+- **Snippets**: Saved command snippets
+- **Settings**: App preferences
+
+**Not included:** Passwords (for security)
+
+## Creating Backups
+
+### Manual Backup
+
+1. Settings → Backup
+2. Tap **Create Backup**
+3. Choose location
+4. Backup saved with timestamp
+
+### Auto Backup
+
+Settings → Backup → Auto Backup:
+- Daily / Weekly / Monthly / Off
+
+### Cloud Sync
+
+- **iOS/macOS**: iCloud automatic backup
+- **Android**: Google Drive integration
+
+## Restoring
+
+### From Local Backup
+
+1. Settings → Backup → Restore Backup
+2. Select backup file
+3. Authenticate (biometric/password)
+4. Confirm restore
+
+### From Cloud
+
+1. Sign in to same cloud account
+2. Settings → Backup → Restore from Cloud
+3. Select backup from list
+4. Authenticate and confirm
+
+## Important Notes
+
+### Passwords Not Backed Up
+
+After restore, you'll need to re-enter passwords for each server.
+
+**Tip:** Use SSH keys instead - they ARE backed up.
+
+### Cross-Platform
+
+Backups work across all platforms (iOS ↔ Android ↔ Desktop).
+
+## Best Practices
+
+1. **Enable auto backup** for peace of mind
+2. **Test restore** periodically to verify backups work
+3. **Backup before** updating app or switching devices
+4. **Use SSH keys** to avoid re-entering passwords
+
+## Troubleshooting
+
+**Restore failed:**
+- Check backup file integrity
+- Ensure sufficient storage
+- Verify app version compatibility
+
+**Missing data after restore:**
+- Passwords are not backed up (re-enter them)
+- Check selective restore settings
diff --git a/docs/src/content/docs/configuration/jump-server.md b/docs/src/content/docs/configuration/jump-server.md
new file mode 100644
index 00000000..655f0a75
--- /dev/null
+++ b/docs/src/content/docs/configuration/jump-server.md
@@ -0,0 +1,88 @@
+---
+title: Jump Server
+description: Route connections through intermediate servers
+---
+
+Connect to servers behind firewalls or in private networks by routing through an intermediate jump server.
+
+## What is Jump Server?
+
+A jump server acts as a gateway to access other servers that:
+- Are behind firewalls
+- Don't have direct SSH access
+- Are in private networks
+- Require multi-hop connections
+
+## Setup
+
+### Step 1: Configure Jump Server
+
+Add the jump server as a normal server first:
+1. Add server with SSH credentials
+2. Test connection to ensure it works
+3. This server will be your jump host
+
+### Step 2: Configure Target Servers
+
+For each server you want to access via jump:
+1. Add target server (credentials for target, not jump)
+2. Server settings → Jump Server
+3. Select your jump server from list
+4. Save
+
+### Step 3: Connect
+
+Connect to target server normally. The app automatically:
+1. Connects to jump server
+2. Tunnels through to target server
+3. Maintains connection
+
+## Use Cases
+
+### Private Network Access
+
+```
+Your Device → Jump Server (public IP) → Private Server (10.0.0.x)
+```
+
+### Behind Firewall
+
+```
+Your Device → Bastion Host → Internal Server
+```
+
+### Multi-Hop
+
+You can chain multiple jump servers for complex networks.
+
+## Requirements
+
+- Jump server must be accessible from your device
+- Jump server must be able to reach target servers
+- SSH keys recommended for jump server (faster authentication)
+
+## Tips
+
+- **Use SSH keys** on jump server for faster connections
+- **Test direct access** to jump server first
+- **Check firewall rules** on both ends
+- **Monitor connection** - issues could be on jump or target
+
+## Troubleshooting
+
+### Connection Times Out
+
+- Verify jump server is accessible
+- Check jump server can reach target
+- Test manually: `ssh -J jump@jump-server user@target-server`
+
+### Authentication Fails
+
+- Verify credentials for target server (not jump)
+- Check SSH keys if using key authentication
+
+### Slow Connection
+
+- Normal for jump connections (extra hop)
+- Consider using SSH keys for faster auth
+- Check network latency to jump server
diff --git a/docs/src/content/docs/configuration/localizations.md b/docs/src/content/docs/configuration/localizations.md
new file mode 100644
index 00000000..80d6f8bb
--- /dev/null
+++ b/docs/src/content/docs/configuration/localizations.md
@@ -0,0 +1,93 @@
+---
+title: Localizations
+description: Language and region settings
+---
+
+Flutter Server Box supports 12+ languages with full localization.
+
+## Supported Languages
+
+| Language | Status |
+|----------|--------|
+| English (en) | ✅ Native |
+| 简体中文 (zh) | ✅ Native |
+| 繁體中文 (zh-Hant) | ✅ Native |
+| Deutsch (de) | ✅ Native |
+| Français (fr) | ✅ Native |
+| Español (es) | ✅ Native |
+| Português (pt) | ✅ Native |
+| Русский (ru) | ✅ Native |
+| Türkçe (tr) | ✅ Native |
+| Українська (uk) | ✅ Native |
+| Bahasa Indonesia (id) | ✅ Native |
+| Nederlands (nl) | ✅ Native |
+| 日本語 (ja) | ✅ AI-translated |
+
+## Changing Language
+
+1. Go to **Settings > Language**
+2. Select preferred language
+3. App restarts to apply changes
+
+## Number Formatting
+
+Numbers are formatted according to locale:
+
+- **Thousands separator**: Comma vs period
+- **Decimal separator**: Period vs comma
+- **Date format**: Locale-specific
+
+## Time Format
+
+Choose between:
+
+- **24-hour**: 13:00, 14:30
+- **12-hour**: 1:00 PM, 2:30 PM
+
+Set in: **Settings > Time Format**
+
+## Contributing Translations
+
+We welcome community translations!
+
+### Translation Files
+
+Located in `lib/l10n/`:
+
+- `app_en.arb` - English (reference)
+- `app_zh.arb` - Simplified Chinese
+- etc.
+
+### How to Contribute
+
+1. Fork the repository
+2. Copy `app_en.arb` to `app_YOUR_LOCALE.arb`
+3. Translate values (keep keys the same)
+4. Test your translations
+5. Submit pull request
+
+### Translation Guidelines
+
+- Keep technical terms consistent
+- Use formal address for professional tone
+- Maintain placeholder format: `{variable}`
+- Test UI with translated strings
+
+## Adding New Language
+
+1. Create new ARB file: `app_xx.arb`
+2. Copy all keys from `app_en.arb`
+3. Translate all values
+4. Add to `l10n.yaml` configuration
+5. Run `flutter gen-l10n`
+6. Test with new locale
+
+## RTL Languages
+
+Right-to-left languages (Arabic, Hebrew) are partially supported. Full RTL layout support is planned for future releases.
+
+## Quality Notes
+
+- Some languages are AI-translated and may contain errors
+- Native speaker reviews are appreciated
+- Report translation issues via GitHub
diff --git a/docs/src/content/docs/configuration/server.md b/docs/src/content/docs/configuration/server.md
new file mode 100644
index 00000000..c3755295
--- /dev/null
+++ b/docs/src/content/docs/configuration/server.md
@@ -0,0 +1,90 @@
+---
+title: Server Setup
+description: Configure and manage server connections
+---
+
+## Adding a Server
+
+1. Tap the **+** button on the main screen
+2. Fill in connection details:
+ - **Name**: Friendly name for identification
+ - **Host**: IP address or domain name
+ - **Port**: SSH port (default: 22)
+ - **Username**: SSH login user
+ - **Authentication**: Password or SSH key
+
+3. Configure optional settings:
+ - **Initial Directory**: Starting directory for terminal/SFTP
+ - **Environment**: Custom environment variables
+ - **Keep-alive Interval**: Connection keep-alive setting
+
+4. Tap **Save**
+
+## Connection Types
+
+### Password Authentication
+
+Simple username/password authentication:
+
+- Enter password in the password field
+- Password is stored securely (encrypted)
+- Requires re-entry on app restart (unless saved)
+
+### SSH Key Authentication
+
+More secure, passwordless authentication:
+
+1. Generate or import SSH key
+2. Add key to server's `~/.ssh/authorized_keys`
+3. Select key in app when adding server
+
+See [SSH Keys](/configuration/ssh-keys/) for detailed setup.
+
+## Server Groups
+
+Organize servers into groups for easier management:
+
+1. Go to Settings > Server Groups
+2. Create a new group
+3. Assign servers to groups
+4. Groups appear as sections in main view
+
+## Server Cards
+
+Customize what information appears on server cards:
+
+1. Go to Settings > Server Card Settings
+2. Enable/disable metrics:
+ - CPU
+ - Memory
+ - Disk
+ - Network
+3. Reorder cards by dragging
+
+## Connection Profiles
+
+Save connection profiles for different use cases:
+
+- **Default Profile**: Standard settings
+- **Low Bandwidth**: Reduced refresh rate
+- **High Performance**: Maximum refresh rate
+
+## Troubleshooting
+
+### Connection Refused
+
+- Check server is running
+- Verify SSH port
+- Check firewall rules
+
+### Authentication Failed
+
+- Verify username/password
+- Check SSH key permissions
+- Ensure SSH service is running
+
+### Timeout
+
+- Check network connectivity
+- Increase timeout in settings
+- Try different network
diff --git a/docs/src/content/docs/configuration/sftp.md b/docs/src/content/docs/configuration/sftp.md
new file mode 100644
index 00000000..5ef7a848
--- /dev/null
+++ b/docs/src/content/docs/configuration/sftp.md
@@ -0,0 +1,118 @@
+---
+title: SFTP File Browser
+description: File transfer and management via SFTP
+---
+
+Browse, edit, and transfer files on your servers with a built-in SFTP client.
+
+## Basic Usage
+
+### Opening SFTP
+
+1. Connect to server
+2. Tap **Files** button on server page
+3. Or from terminal: Tap **SFTP** button
+
+### Navigation
+
+- **Tap folder**: Enter directory
+- **Tap file**: View/Edit/Download options
+- **Back button**: Previous directory
+- **Home button**: User's home directory
+- **Goto button**: Jump to path with autocomplete
+
+## File Operations
+
+### Common Actions
+
+| Action | How |
+|--------|-----|
+| **Download** | Long-press file → Download |
+| **Upload** | Folder icon → Select file |
+| **Rename** | Long-press → Rename |
+| **Delete** | Long-press → Delete |
+| **Copy/Move** | Long-press → Select → Choose destination |
+| **Permissions** | Tap file info → Edit permissions |
+
+### Permission Editor
+
+Unix permissions editor:
+
+- **3x3 Grid**: User/Group/Other × Read/Write/Execute
+- **Numeric**: Direct input (755, 644, etc.)
+- **Symbolic**: rwxr-xr-x format
+
+### Edit Files
+
+1. Tap file → Edit
+2. Edit in built-in editor
+3. Save → Upload back to server
+
+**Size limit:** Files up to 1 MB. For larger files, use the terminal with vim/nano instead.
+
+**Editor settings:** Settings → SFTP Editor
+- Preferred editor (vim, nano, etc.)
+- Close after save
+- Soft wrap
+- Syntax highlighting
+
+## Display Settings
+
+### Sort Order
+
+Settings → Sort By:
+- Name (alphabetical)
+- Size (largest first)
+- Time (newest first)
+
+### Folders First
+
+Show directories before files:
+Settings → Folders First
+
+### Hidden Files
+
+Show dotfiles (`.git`, `.bashrc`, etc.):
+Settings → Show Hidden Files
+
+## Archive Support
+
+Extract common archive formats directly on your server.
+
+| Format | Variants | Command Required |
+|--------|----------|------------------|
+| .tar.gz | .tgz, .tar.Z | tar |
+| .tar.bz2 | .tbz2, .tar.bz2 | tar |
+| .tar.xz | .txz | tar |
+| .zip | .zipx | unzip |
+| .7z | - | 7z |
+| .rar | - | unrar |
+
+**Note:** The corresponding command (`tar`, `unzip`, `7z`, `unrar`) must be installed on your server. These tools handle many sub-formats not listed above.
+
+## Quick Access
+
+### From Terminal
+
+Tap **SFTP** button to open current terminal directory in file browser.
+
+### Remember Last Path
+
+Automatically return to last visited directory:
+Settings → SFTP Open Last Path
+
+## Troubleshooting
+
+### Permission Denied
+
+- Check user has read access to directory
+- Verify directory permissions: `ls -la`
+- Ensure SFTP is enabled in sshd_config
+
+### Slow Listing
+
+Large directories (1000+ items) use pagination for performance.
+
+### Can't Edit File
+
+File larger than 1 MB? Use terminal with vim/nano instead.
diff --git a/docs/src/content/docs/configuration/terminal.md b/docs/src/content/docs/configuration/terminal.md
new file mode 100644
index 00000000..d784f3a1
--- /dev/null
+++ b/docs/src/content/docs/configuration/terminal.md
@@ -0,0 +1,127 @@
+---
+title: Terminal & SSH
+description: SSH terminal setup and configuration
+---
+
+Complete SSH terminal access with full keyboard support and customizable interface.
+
+## Basic Setup
+
+### First Connection
+
+1. Add server with SSH credentials
+2. Tap server card to connect
+3. Accept host key fingerprint (first time only)
+4. Terminal opens automatically
+
+### Virtual Keyboard (Mobile)
+
+Customizable virtual keyboard for terminal access:
+
+| Button | Function |
+|--------|----------|
+| **Ctrl, Alt, Shift** | Modifier keys (tap before other key) |
+| **Esc, Tab** | Special characters |
+| **Arrows** | Navigation |
+| **F1-F12** | Function keys |
+| **SFTP** | Open current directory in file browser |
+| **Clipboard** | Copy selection / Paste clipboard |
+| **Snippets** | Quick command execution |
+
+**Customize keyboard:** Settings → SSH Virtual Keys
+- Enable/disable keys
+- Reorder layout
+- Add/remove buttons
+
+## Terminal Settings
+
+### Appearance
+
+**Font Size:** Settings → Terminal Font Size
+- Affects all new sessions
+- Typical range: 8-24 pixels
+
+**Colors:** Settings → Terminal Color
+- Text color
+- Background color & opacity
+- Blur effect (iOS/macOS)
+- Cursor color
+
+### Keyboard Type
+
+If you can't input certain characters:
+
+1. Settings → Keyboard Type
+2. Switch to `visiblePassword`
+3. Note: CJK input may not work after this change
+
+## Connection Management
+
+### Multi-Tab
+
+- **Desktop**: Ctrl+T (new), Ctrl+W (close)
+- **Mobile**: Tap + button
+- Sessions persist between app launches
+
+### Auto-Connect
+
+Set server to auto-connect on app open:
+1. Server settings → Auto-Connect
+2. Enable toggle
+
+### Jump Server
+
+Route through intermediate server:
+
+1. Add and configure jump server first
+2. Target server settings → Select jump server
+3. Connection routes through jump server automatically
+
+## SSH Keys (Recommended)
+
+More secure than passwords:
+
+1. Generate key: Settings → Private Keys → Add
+2. Upload public key to server: `ssh-copy-id -i pubkey user@server`
+3. Server settings → Use key instead of password
+
+## Common Issues
+
+### Can't Connect
+
+**Timeout/Refused:**
+- Verify server is Unix-like (Linux, macOS, Android/Termux)
+- Check firewall allows SSH port (default 22)
+- Test manually: `ssh user@server -p port`
+
+**Auth Failed:**
+- Verify username and password
+- Check SSH key is uploaded correctly
+- Ensure account is not locked
+
+### Terminal Disconnects
+
+**Frequent disconnections:**
+
+1. Check server keep-alive settings:
+ ```bash
+ # /etc/ssh/sshd_config
+ ClientAliveInterval 60
+ ClientAliveCountMax 3
+ ```
+
+2. Disable battery optimization:
+ - **MIUI**: Battery → "No limits"
+ - **Android**: Settings → Apps → Disable optimization
+ - **iOS**: Enable background refresh
+
+### Can't Input Characters
+
+Change keyboard type to `visiblePassword` in settings.
+
+## Tips
+
+- **Test connection** first with regular SSH client
+- **Use SSH keys** instead of passwords for security
+- **Save snippets** for frequently used commands
+- **Pinch to zoom** for temporary font size change (mobile)
diff --git a/docs/src/content/docs/development/architecture.md b/docs/src/content/docs/development/architecture.md
new file mode 100644
index 00000000..475395a7
--- /dev/null
+++ b/docs/src/content/docs/development/architecture.md
@@ -0,0 +1,86 @@
+---
+title: Architecture
+description: Architecture patterns and design decisions
+---
+
+Flutter Server Box follows clean architecture principles with clear separation between data, domain, and presentation layers.
+
+## Layered Architecture
+
+```
+┌─────────────────────────────────────┐
+│ Presentation Layer │
+│ (lib/view/page/) │
+│ - Pages, Widgets, Controllers │
+└─────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────┐
+│ Business Logic Layer │
+│ (lib/data/provider/) │
+│ - Riverpod Providers │
+│ - State Management │
+└─────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────┐
+│ Data Layer │
+│ (lib/data/model/, store/) │
+│ - Models, Storage, Services │
+└─────────────────────────────────────┘
+```
+
+## Key Patterns
+
+### State Management: Riverpod
+
+- **Code Generation**: Uses `riverpod_generator` for type-safe providers
+- **State Notifiers**: For mutable state with business logic
+- **Async Notifiers**: For loading and error states
+- **Stream Providers**: For real-time data
+
+### Immutable Models: Freezed
+
+- All data models use Freezed for immutability
+- Union types for state representation
+- Built-in JSON serialization
+- CopyWith extensions for updates
+
+### Local Storage: Hive
+
+- **hive_ce**: Community edition of Hive
+- No manual `@HiveField` or `@HiveType` needed
+- Type adapters auto-generated
+- Persistent key-value storage
+
+## Dependency Injection
+
+Services and stores are injected via:
+
+1. **Providers**: Expose dependencies to UI
+2. **GetIt**: Service location (where applicable)
+3. **Constructor Injection**: Explicit dependencies
+
+## Data Flow
+
+```
+User Action → Widget → Provider → Service/Store → Model Update → UI Rebuild
+```
+
+1. User interacts with widget
+2. Widget calls provider method
+3. Provider updates state via service/store
+3. State change triggers UI rebuild
+4. New state reflected in widget
+
+## Custom Dependencies
+
+The project uses several custom forks to extend functionality:
+
+- **dartssh2**: Enhanced SSH features
+- **xterm**: Terminal emulator with mobile support
+- **fl_lib**: Shared UI components and utilities
+
+## Threading
+
+- **Isolates**: Heavy computation off main thread
+- **computer package**: Multi-threading utilities
+- **Async/Await**: Non-blocking I/O operations
diff --git a/docs/src/content/docs/development/building.md b/docs/src/content/docs/development/building.md
new file mode 100644
index 00000000..cf989c38
--- /dev/null
+++ b/docs/src/content/docs/development/building.md
@@ -0,0 +1,116 @@
+---
+title: Building
+description: Build instructions for different platforms
+---
+
+Flutter Server Box uses a custom build system (`fl_build`) for cross-platform builds.
+
+## Prerequisites
+
+- Flutter SDK (stable channel)
+- Platform-specific tools (Xcode for iOS, Android Studio for Android)
+- Rust toolchain (for some native dependencies)
+
+## Development Build
+
+```bash
+# Run in development mode
+flutter run
+
+# Run on specific device
+flutter run -d
+```
+
+## Production Build
+
+The project uses `fl_build` for building:
+
+```bash
+# Build for specific platform
+dart run fl_build -p
+
+# Available platforms:
+# - ios
+# - android
+# - macos
+# - linux
+# - windows
+```
+
+## Platform-Specific Builds
+
+### iOS
+
+```bash
+dart run fl_build -p ios
+```
+
+Requires:
+- macOS with Xcode
+- CocoaPods
+- Apple Developer account for signing
+
+### Android
+
+```bash
+dart run fl_build -p android
+```
+
+Requires:
+- Android SDK
+- Java Development Kit
+- Keystore for signing
+
+### macOS
+
+```bash
+dart run fl_build -p macos
+```
+
+### Linux
+
+```bash
+dart run fl_build -p linux
+```
+
+### Windows
+
+```bash
+dart run fl_build -p windows
+```
+
+Requires Windows with Visual Studio.
+
+## Pre/Post Build
+
+The `make.dart` script handles:
+
+- Metadata generation
+- Version string updates
+- Platform-specific configurations
+
+## Troubleshooting
+
+### Clean Build
+
+```bash
+flutter clean
+dart run build_runner build --delete-conflicting-outputs
+flutter pub get
+```
+
+### Version Mismatch
+
+Ensure all dependencies are compatible:
+```bash
+flutter pub upgrade
+```
+
+## Release Checklist
+
+1. Update version in `pubspec.yaml`
+2. Run code generation
+3. Run tests
+4. Build for all target platforms
+5. Test on physical devices
+6. Create GitHub release
diff --git a/docs/src/content/docs/development/codegen.md b/docs/src/content/docs/development/codegen.md
new file mode 100644
index 00000000..67bce6eb
--- /dev/null
+++ b/docs/src/content/docs/development/codegen.md
@@ -0,0 +1,98 @@
+---
+title: Code Generation
+description: Using build_runner for code generation
+---
+
+Flutter Server Box heavily uses code generation for models, state management, and serialization.
+
+## When to Run Code Generation
+
+Run after modifying:
+
+- Models with `@freezed` annotation
+- Classes with `@JsonSerializable`
+- Hive models
+- Providers with `@riverpod`
+- Localizations (ARB files)
+
+## Running Code Generation
+
+```bash
+# Generate all code
+dart run build_runner build --delete-conflicting-outputs
+
+# Clean and regenerate
+dart run build_runner build --delete-conflicting-outputs --clean
+```
+
+## Generated Files
+
+### Freezed (`*.freezed.dart`)
+
+Immutable data models with union types:
+
+```dart
+@freezed
+class ServerState with _$ServerState {
+ const factory ServerState.connected() = Connected;
+ const factory ServerState.disconnected() = Disconnected;
+ const factory ServerState.error(String message) = Error;
+}
+```
+
+### JSON Serialization (`*.g.dart`)
+
+Generated from `json_serializable`:
+
+```dart
+@JsonSerializable()
+class Server {
+ final String id;
+ final String name;
+ final String host;
+
+ Server({required this.id, required this.name, required this.host});
+
+ factory Server.fromJson(Map json) =>
+ _$ServerFromJson(json);
+ Map toJson() => _$ServerToJson(this);
+}
+```
+
+### Riverpod Providers (`*.g.dart`)
+
+Generated from `@riverpod` annotation:
+
+```dart
+@riverpod
+class MyNotifier extends _$MyNotifier {
+ @override
+ int build() => 0;
+}
+```
+
+### Hive Adapters (`*.g.dart`)
+
+Auto-generated for Hive models (hive_ce):
+
+```dart
+@HiveType(typeId: 0)
+class ServerModel {
+ @HiveField(0)
+ final String id;
+}
+```
+
+## Localization Generation
+
+```bash
+flutter gen-l10n
+```
+
+Generates `lib/generated/l10n/` from `lib/l10n/*.arb` files.
+
+## Tips
+
+- Use `--delete-conflicting-outputs` to avoid conflicts
+- Add generated files to `.gitignore`
+- Never manually edit generated files
diff --git a/docs/src/content/docs/development/state.md b/docs/src/content/docs/development/state.md
new file mode 100644
index 00000000..8d85fbe9
--- /dev/null
+++ b/docs/src/content/docs/development/state.md
@@ -0,0 +1,115 @@
+---
+title: State Management
+description: Riverpod-based state management patterns
+---
+
+Flutter Server Box uses Riverpod with code generation for state management.
+
+## Provider Types
+
+### StateProvider
+
+Simple state that can be read and written:
+
+```dart
+@riverpod
+class Settings extends _$Settings {
+ @override
+ SettingsModel build() {
+ return SettingsModel.defaults();
+ }
+
+ void update(SettingsModel newSettings) {
+ state = newSettings;
+ }
+}
+```
+
+### AsyncNotifierProvider
+
+State that loads asynchronously with loading/error states:
+
+```dart
+@riverpod
+class ServerStatus extends _$ServerStatus {
+ @override
+ Future build(Server server) async {
+ return fetchStatus(server);
+ }
+
+ Future refresh() async {
+ state = const AsyncValue.loading();
+ state = await AsyncValue.guard(() => fetchStatus(server));
+ }
+}
+```
+
+### StreamProvider
+
+Real-time data from streams:
+
+```dart
+@riverpod
+Stream cpuUsage(CpuUsageRef ref, Server server) {
+ return cpuService.monitor(server);
+}
+```
+
+## State Patterns
+
+### Loading States
+
+```dart
+state.when(
+ data: (data) => DataWidget(data),
+ loading: () => LoadingWidget(),
+ error: (error, stack) => ErrorWidget(error),
+)
+```
+
+### Family Providers
+
+Parameterized providers:
+
+```dart
+@riverpod
+List containers(ContainersRef ref, Server server) {
+ return containerService.list(server);
+}
+```
+
+### Auto-Dispose
+
+Providers that dispose when no longer referenced:
+
+```dart
+@Riverpod(keepAlive: false)
+class TempState extends _$TempState {
+ // ...
+}
+```
+
+## Best Practices
+
+1. **Use code generation**: Always use `@riverpod` annotation
+2. **Co-locate providers**: Place near consuming widgets
+3. **Avoid singletons**: Use providers instead
+4. **Layer correctly**: Keep UI logic separate from business logic
+
+## Reading State in Widgets
+
+```dart
+class ServerWidget extends ConsumerWidget {
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ final status = ref.watch(serverStatusProvider(server));
+ return status.when(...);
+ }
+}
+```
+
+## Modifying State
+
+```dart
+ref.read(settingsProvider.notifier).update(newSettings);
+```
diff --git a/docs/src/content/docs/development/structure.md b/docs/src/content/docs/development/structure.md
new file mode 100644
index 00000000..ec31caa9
--- /dev/null
+++ b/docs/src/content/docs/development/structure.md
@@ -0,0 +1,96 @@
+---
+title: Project Structure
+description: Understanding the Flutter Server Box codebase
+---
+
+The Flutter Server Box project follows a modular architecture with clear separation of concerns.
+
+## Directory Structure
+
+```
+lib/
+├── core/ # Core utilities and extensions
+├── data/ # Data layer
+│ ├── model/ # Data models by feature
+│ ├── provider/ # Riverpod providers
+│ └── store/ # Local storage (Hive)
+├── view/ # UI layer
+│ ├── page/ # Main pages
+│ └── widget/ # Reusable widgets
+├── generated/ # Generated localization
+├── l10n/ # Localization ARB files
+└── hive/ # Hive adapters
+```
+
+## Core Layer (`lib/core/`)
+
+Contains utilities, extensions, and routing configuration:
+
+- **Extensions**: Dart extensions for common types
+- **Routes**: App routing configuration
+- **Utils**: Shared utility functions
+
+## Data Layer (`lib/data/`)
+
+### Models (`lib/data/model/`)
+
+Organized by feature:
+
+- `server/` - Server connection and status models
+- `container/` - Docker container models
+- `ssh/` - SSH session models
+- `sftp/` - SFTP file models
+- `app/` - App-specific models
+
+### Providers (`lib/data/provider/`)
+
+Riverpod providers for dependency injection and state management:
+
+- Server providers
+- UI state providers
+- Service providers
+
+### Stores (`lib/data/store/`)
+
+Hive-based local storage:
+
+- Server storage
+- Settings storage
+- Cache storage
+
+## View Layer (`lib/view/`)
+
+### Pages (`lib/view/page/`)
+
+Main application screens:
+
+- `server/` - Server management pages
+- `ssh/` - SSH terminal pages
+- `container/` - Container pages
+- `setting/` - Settings pages
+- `storage/` - SFTP pages
+- `snippet/` - Snippet pages
+
+### Widgets (`lib/view/widget/`)
+
+Reusable UI components:
+
+- Server cards
+- Status charts
+- Input components
+- Dialogs
+
+## Generated Files
+
+- `lib/generated/l10n/` - Auto-generated localization
+- `*.g.dart` - Generated code (json_serializable, freezed, hive, riverpod)
+- `*.freezed.dart` - Freezed immutable classes
+
+## Packages Directory (`/packages/`)
+
+Contains custom forks of dependencies:
+
+- `dartssh2/` - SSH library
+- `xterm/` - Terminal emulator
+- `fl_lib/` - Shared utilities
+- `fl_build/` - Build system
diff --git a/docs/src/content/docs/development/testing.md b/docs/src/content/docs/development/testing.md
new file mode 100644
index 00000000..d19b5345
--- /dev/null
+++ b/docs/src/content/docs/development/testing.md
@@ -0,0 +1,113 @@
+---
+title: Testing
+description: Testing strategies and running tests
+---
+
+## Running Tests
+
+```bash
+# Run all tests
+flutter test
+
+# Run specific test file
+flutter test test/battery_test.dart
+
+# Run with coverage
+flutter test --coverage
+```
+
+## Test Structure
+
+Tests are located in the `test/` directory mirroring the lib structure:
+
+```
+test/
+├── data/
+│ ├── model/
+│ └── provider/
+├── view/
+│ └── widget/
+└── test_helpers.dart
+```
+
+## Unit Tests
+
+Test business logic and data models:
+
+```dart
+test('should calculate CPU percentage', () {
+ final cpu = CpuModel(usage: 75.0);
+ expect(cpu.usagePercentage, '75%');
+});
+```
+
+## Widget Tests
+
+Test UI components:
+
+```dart
+testWidgets('ServerCard displays server name', (tester) async {
+ await tester.pumpWidget(
+ ProviderScope(
+ child: MaterialApp(
+ home: ServerCard(server: testServer),
+ ),
+ ),
+ );
+
+ expect(find.text('Test Server'), findsOneWidget);
+});
+```
+
+## Provider Tests
+
+Test Riverpod providers:
+
+```dart
+test('serverStatusProvider returns status', () async {
+ final container = ProviderContainer();
+ final status = await container.read(serverStatusProvider(testServer).future);
+ expect(status, isA());
+});
+```
+
+## Mocking
+
+Use mocks for external dependencies:
+
+```dart
+class MockSshService extends Mock implements SshService {}
+
+test('connects to server', () async {
+ final mockSsh = MockSshService();
+ when(mockSsh.connect(any)).thenAnswer((_) async => true);
+
+ // Test with mock
+});
+```
+
+## Integration Tests
+
+Test complete user flows (in `integration_test/`):
+
+```dart
+testWidgets('add server flow', (tester) async {
+ await tester.pumpWidget(MyApp());
+
+ // Tap add button
+ await tester.tap(find.byIcon(Icons.add));
+ await tester.pumpAndSettle();
+
+ // Fill form
+ await tester.enterText(find.byKey(Key('name')), 'Test Server');
+ // ...
+});
+```
+
+## Best Practices
+
+1. **Arrange-Act-Assert**: Structure tests clearly
+2. **Descriptive names**: Test names should describe behavior
+3. **One assertion per test**: Keep tests focused
+4. **Mock external deps**: Don't depend on real servers
+5. **Test edge cases**: Empty lists, null values, etc.
diff --git a/docs/src/content/docs/features/docker.md b/docs/src/content/docs/features/docker.md
new file mode 100644
index 00000000..a94c6b3a
--- /dev/null
+++ b/docs/src/content/docs/features/docker.md
@@ -0,0 +1,55 @@
+---
+title: Docker Management
+description: Monitor and manage Docker containers
+---
+
+Flutter Server Box provides an intuitive interface for managing Docker containers on your servers.
+
+## Features
+
+### Container List
+
+- View all containers (running and stopped)
+- Container ID and name display
+- Image information
+- Status indicators
+- Creation time
+
+### Container Actions
+
+- **Start**: Launch stopped containers
+- **Stop**: Gracefully stop running containers
+- **Restart**: Restart containers
+- **Remove**: Delete containers
+- **View Logs**: Check container logs
+- **Inspect**: View container details
+
+### Container Details
+
+- Environment variables
+- Port mappings
+- Volume mounts
+- Network configuration
+- Resource usage
+
+## Requirements
+
+- Docker must be installed on your server
+- SSH user must have Docker permissions
+- For non-root users, add to docker group:
+ ```bash
+ sudo usermod -aG docker your_username
+ ```
+
+## Quick Actions
+
+- Single tap: View container details
+- Long press: Quick action menu
+- Swipe: Quick start/stop
+- Bulk select: Multiple container operations
+
+## Tips
+
+- Use **auto-refresh** to monitor container status changes
+- Filter by running/stopped containers
+- Search containers by name or ID
diff --git a/docs/src/content/docs/features/monitoring.md b/docs/src/content/docs/features/monitoring.md
new file mode 100644
index 00000000..fc60df56
--- /dev/null
+++ b/docs/src/content/docs/features/monitoring.md
@@ -0,0 +1,73 @@
+---
+title: Server Monitoring
+description: Real-time server status monitoring with beautiful charts
+---
+
+Flutter Server Box provides comprehensive real-time monitoring of your server's health and performance.
+
+## Status Cards
+
+The server detail page displays configurable status cards for different system metrics. You can enable/disable cards in settings.
+
+### CPU Monitoring
+
+- Real-time CPU usage percentage
+- Per-core CPU usage breakdown
+- Historical usage charts
+- CPU frequency information
+
+### Memory Monitoring
+
+- **RAM Usage**: Used vs total memory with percentage
+- **Swap Usage**: Swap memory utilization
+- Memory pressure indicators
+- Historical memory trends
+
+### Disk Monitoring
+
+- Mount point usage with percentage
+- Total, used, and free space
+- I/O statistics
+- Multiple disk support
+
+### Network Monitoring
+
+- Real-time upload/download speeds
+- Bandwidth usage charts
+- Network interface statistics
+- Total data transferred
+
+### Advanced Metrics
+
+- **GPU Status**: NVIDIA and AMD GPU monitoring
+- **Temperature**: CPU, GPU, and system temperatures
+- **Sensors**: Fan speeds, voltages, and other sensor data
+- **S.M.A.R.T**: Disk health monitoring
+- **Battery**: UPS or battery status (if available)
+
+## Customizing Display
+
+### Reordering Cards
+
+1. Go to Settings
+2. Select Server Settings
+3. Drag cards to reorder them on the server detail page
+
+### Enabling/Disabling Cards
+
+1. Open a server's detail page
+2. Tap the edit/menu button
+3. Toggle individual cards on or off
+
+## Auto-Refresh
+
+- Status cards automatically refresh
+- Refresh interval is configurable in settings
+- Manual refresh available with pull-to-refresh gesture
+
+## Charts and Visualizations
+
+- **Line Charts**: Historical data trends
+- **Gauge Charts**: Current usage percentage
+- **Color Coding**: Visual indicators for status levels
+- **Zoom**: Pinch to zoom on charts for detailed views
diff --git a/docs/src/content/docs/features/network.md b/docs/src/content/docs/features/network.md
new file mode 100644
index 00000000..ee023f4e
--- /dev/null
+++ b/docs/src/content/docs/features/network.md
@@ -0,0 +1,67 @@
+---
+title: Network Tools
+description: Network testing and diagnostic tools
+---
+
+Flutter Server Box includes several network tools for testing and diagnostics.
+
+## iPerf
+
+Perform network speed tests between your device and server.
+
+### Features
+
+- **Upload/Download Speed**: Test bandwidth
+- **Server Mode**: Use server as iPerf server
+- **Client Mode**: Connect to iPerf servers
+- **Custom Parameters**: Duration, parallel streams, etc.
+
+### Usage
+
+1. Open a server
+2. Tap **iPerf**
+3. Choose server or client mode
+4. Configure parameters
+5. Start test
+
+## Ping
+
+Test network connectivity and latency.
+
+### Features
+
+- **ICMP Ping**: Standard ping tool
+- **Packet Count**: Specify number of packets
+- **Packet Size**: Custom packet size
+- **Interval**: Time between pings
+
+### Usage
+
+1. Open a server
+2. Tap **Ping**
+3. Enter target host
+4. Configure parameters
+5. Start pinging
+
+## Wake on LAN
+
+Wake up remote servers via magic packet.
+
+### Features
+
+- **MAC Address**: Target device MAC
+- **Broadcast**: Send broadcast magic packet
+- **Saved Profiles**: Store WoL configurations
+
+### Requirements
+
+- Target device must support Wake-on-LAN
+- WoL must be enabled in BIOS/UEFI
+- Device must be in sleep/soft-off state
+- Device must be on the same network or reachable via broadcast
+
+## Tips
+
+- Use iPerf to diagnose network bottlenecks
+- Ping multiple hosts to compare latency
+- Save WoL profiles for frequently woken devices
diff --git a/docs/src/content/docs/features/process.md b/docs/src/content/docs/features/process.md
new file mode 100644
index 00000000..99334f59
--- /dev/null
+++ b/docs/src/content/docs/features/process.md
@@ -0,0 +1,56 @@
+---
+title: Process & Services
+description: Monitor processes and manage systemd services
+---
+
+## Process Management
+
+View and manage running processes on your servers.
+
+### Process List
+
+- All running processes with details
+- PID (Process ID)
+- CPU and memory usage
+- User ownership
+- Process command
+
+### Process Actions
+
+- **Kill**: Terminate processes
+- **Filter**: By name or user
+- **Sort**: By CPU, memory, or PID
+- **Search**: Find specific processes
+
+## Systemd Services
+
+Manage systemd services for service control.
+
+### Service List
+
+- All systemd services
+- Active/inactive status
+- Enabled/disabled state
+- Service description
+
+### Service Actions
+
+- **Start**: Launch a stopped service
+- **Stop**: Stop a running service
+- **Restart**: Restart a service
+- **Enable**: Enable auto-start on boot
+- **Disable**: Disable auto-start
+- **View Status**: Check service status and logs
+- **Reload**: Reload service configuration
+
+## Requirements
+
+- SSH user must have appropriate permissions
+- For service management: `sudo` access may be required
+- Process viewing: Standard user permissions usually sufficient
+
+## Tips
+
+- Use process list to identify resource hogs
+- Check service logs for troubleshooting
+- Monitor critical services with auto-refresh
diff --git a/docs/src/content/docs/features/pve.md b/docs/src/content/docs/features/pve.md
new file mode 100644
index 00000000..f3672e71
--- /dev/null
+++ b/docs/src/content/docs/features/pve.md
@@ -0,0 +1,105 @@
+---
+title: Proxmox (PVE)
+description: Proxmox Virtual Environment management
+---
+
+Flutter Server Box includes support for managing Proxmox VE virtualization platform.
+
+## Features
+
+### VM Management
+
+- **List VMs**: View all virtual machines
+- **VM Status**: Check running/stopped states
+- **VM Actions**: Start, stop, restart VMs
+- **VM Details**: View configuration and resources
+
+### Container (LXC) Management
+
+- **List Containers**: View all LXC containers
+- **Container Status**: Monitor container states
+- **Container Actions**: Start, stop, restart containers
+- **Console Access**: Terminal access to containers
+
+### Node Monitoring
+
+- **Resource Usage**: CPU, memory, disk, network
+- **Node Status**: Check node health
+- **Cluster View**: Multi-node cluster overview
+
+## Setup
+
+### Adding PVE Server
+
+1. Add server as normal SSH connection
+2. Ensure user has PVE permissions
+3. Access PVE features from server detail page
+
+### Permissions Required
+
+PVE user needs:
+
+- **VM.Audit**: View VM status
+- **VM.PowerMgmt**: Start/stop VMs
+- **VM.Console**: Console access
+
+Example permissions setup:
+
+```bash
+pveum useradd myuser -password mypass
+pveum aclmod /vms -user myuser@pve -role VMAdmin
+```
+
+## Usage
+
+### VM Management
+
+1. Open server with PVE
+2. Tap **PVE** button
+3. View VM list
+4. Tap VM for details
+5. Use action buttons for management
+
+### Container Management
+
+1. Open server with PVE
+2. Tap **PVE** button
+3. Switch to Containers tab
+4. View and manage LXC containers
+
+### Monitoring
+
+- Real-time resource usage
+- Historical data charts
+- Multiple node support
+
+## Features by Status
+
+### Implemented
+
+- VM listing and status
+- Container listing and status
+- Basic VM operations (start/stop/restart)
+- Resource monitoring
+
+### Planned
+
+- VM creation from templates
+- Snapshot management
+- Console access
+- Storage management
+- Network configuration
+
+## Requirements
+
+- **PVE Version**: 6.x or 7.x
+- **Access**: SSH access to PVE host
+- **Permissions**: Appropriate PVE user roles
+- **Network**: Connectivity to PVE API (via SSH)
+
+## Tips
+
+- Use **dedicated PVE user** with limited permissions
+- Monitor **resource usage** for optimal performance
+- Check **VM status** before maintenance
+- Use **snapshots** before major changes
diff --git a/docs/src/content/docs/features/snippets.md b/docs/src/content/docs/features/snippets.md
new file mode 100644
index 00000000..cd8e2635
--- /dev/null
+++ b/docs/src/content/docs/features/snippets.md
@@ -0,0 +1,60 @@
+---
+title: Snippets
+description: Save and execute custom shell commands
+---
+
+Snippets allow you to save frequently used shell commands for quick execution.
+
+## Creating Snippets
+
+1. Go to the **Snippets** tab
+2. Tap the **+** button
+3. Fill in snippet details:
+ - **Name**: Friendly name for the snippet
+ - **Command**: The shell command to execute
+ - **Description**: Optional notes
+4. Save the snippet
+
+## Using Snippets
+
+1. Open a server
+2. Tap the **Snippet** button
+3. Select a snippet to execute
+4. View output in the terminal
+
+## Snippet Features
+
+- **Quick Execute**: One-tap command execution
+- **Variables**: Use server-specific variables
+- **Organization**: Group related snippets
+- **Import/Export**: Share snippets between devices
+- **Sync**: Optional cloud sync
+
+## Example Snippets
+
+### System Update
+```bash
+sudo apt update && sudo apt upgrade -y
+```
+
+### Disk Cleanup
+```bash
+sudo apt autoremove -y && sudo apt clean
+```
+
+### Docker Cleanup
+```bash
+docker system prune -a
+```
+
+### View System Logs
+```bash
+journalctl -n 50 -f
+```
+
+## Tips
+
+- Use **descriptive names** for easy identification
+- Add **comments** for complex commands
+- Test commands before saving as snippets
+- Organize snippets by category or server type
diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx
new file mode 100644
index 00000000..c0b7cbd7
--- /dev/null
+++ b/docs/src/content/docs/index.mdx
@@ -0,0 +1,46 @@
+---
+title: Flutter Server Box
+description: A comprehensive cross-platform server management application
+hero:
+ tagline: Manage your Linux servers from anywhere
+ actions:
+ - text: Get Started
+ link: /introduction/
+ icon: right-arrow
+ variant: primary
+ - text: View on GitHub
+ link: https://github.com/lollipopkit/flutter_server_box
+ icon: github
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## Features
+
+
+
+ Monitor CPU, memory, disk, network, GPU, and temperature with beautiful real-time charts.
+
+
+ Full-featured SSH terminal with multi-tab support and virtual keyboard for mobile devices.
+
+
+ Manage files on your servers with the built-in SFTP client and local file browser.
+
+
+ Start, stop, and monitor Docker containers with an intuitive interface.
+
+
+ Available on iOS, Android, macOS, Linux, Windows, and watchOS.
+
+
+ Full localization support including English, Chinese, German, French, and more.
+
+
+
+## Quick Links
+
+- **Download**: Available on [App Store](https://apps.apple.com/app/flutter-server-box), [Google Play](https://play.google.com/store/apps/details), [GitHub](https://github.com/lollipopkit/flutter_server_box/releases), and [F-Droid](https://f-droid.org/)
+- **Documentation**: Explore the guides to get started with Flutter Server Box
+- **Support**: Join our community on GitHub for discussions and issues
diff --git a/docs/src/content/docs/installation.mdx b/docs/src/content/docs/installation.mdx
new file mode 100644
index 00000000..5fa6944c
--- /dev/null
+++ b/docs/src/content/docs/installation.mdx
@@ -0,0 +1,52 @@
+---
+title: Installation
+description: Download and install Flutter Server Box on your device
+---
+
+Flutter Server Box is available on multiple platforms. Choose your preferred method of installation.
+
+## Mobile Apps
+
+### iOS
+
+Download from the **[App Store](https://apps.apple.com/app/flutter-server-box)**.
+
+### Android
+
+Choose your preferred source:
+
+- **[Google Play](https://play.google.com/store/apps/details)** - Recommended for most users
+- **[F-Droid](https://f-droid.org/)** - For users who prefer FOSS-only sources
+- **[GitHub Releases](https://github.com/lollipopkit/flutter_server_box/releases)** - For the latest version directly from the source
+
+## Desktop Apps
+
+### macOS
+
+Download from **[GitHub Releases](https://github.com/lollipopkit/flutter_server_box/releases)**.
+
+Features:
+- Native menu bar integration
+- Support for both Intel and Apple Silicon
+
+### Linux
+
+Download from **[GitHub Releases](https://github.com/lollipopkit/flutter_server_box/releases)**.
+
+Available as AppImage, deb, or tar.gz packages.
+
+### Windows
+
+Download from **[GitHub Releases](https://github.com/lollipopkit/flutter_server_box/releases)**.
+
+## watchOS
+
+Available on the **[App Store](https://apps.apple.com/app/flutter-server-box)** as part of the iOS app.
+
+## Building from Source
+
+To build Flutter Server Box from source, see the [Building](/development/building) section in the Development documentation.
+
+## Version Information
+
+Check the [GitHub Releases](https://github.com/lollipopkit/flutter_server_box/releases) page for the latest version and changelog.
diff --git a/docs/src/content/docs/introduction.mdx b/docs/src/content/docs/introduction.mdx
new file mode 100644
index 00000000..44325620
--- /dev/null
+++ b/docs/src/content/docs/introduction.mdx
@@ -0,0 +1,33 @@
+---
+title: Introduction
+description: Learn what Flutter Server Box is and what it can do
+---
+
+Flutter Server Box is a comprehensive cross-platform server management application built with Flutter. It allows you to monitor, manage, and control your Linux, Unix, and Windows servers from anywhere.
+
+## What is Flutter Server Box?
+
+Flutter Server Box provides a unified interface for server administration tasks through SSH connections. Whether you're a system administrator, developer, or hobbyist running home servers, this app puts powerful server management tools in your pocket.
+
+## Key Capabilities
+
+- **Real-time Monitoring**: Track CPU, memory, disk usage, network speed, GPU status, and system temperatures
+- **SSH Terminal**: Full terminal access with multi-tab support and customizable appearance
+- **SFTP Client**: Browse and manage files on your servers
+- **Docker Management**: Control containers with ease
+- **Process Management**: View and manage system processes
+- **Systemd Services**: Start, stop, and monitor systemd services
+- **Network Tools**: iPerf testing, ping, and Wake-on-LAN
+- **Snippets**: Save and execute custom shell commands
+
+## Supported Platforms
+
+Flutter Server Box is truly cross-platform:
+
+- **Mobile**: iOS and Android
+- **Desktop**: macOS, Linux, and Windows
+- **Wearable**: watchOS (Apple Watch)
+
+## License
+
+This project is licensed under AGPL v3. Source code is available on [GitHub](https://github.com/lollipopkit/flutter_server_box).
diff --git a/docs/src/content/docs/platforms/desktop.md b/docs/src/content/docs/platforms/desktop.md
new file mode 100644
index 00000000..baa418d0
--- /dev/null
+++ b/docs/src/content/docs/platforms/desktop.md
@@ -0,0 +1,80 @@
+---
+title: Desktop Features
+description: macOS, Linux, and Windows specific features
+---
+
+Flutter Server Box on desktop platforms provides additional productivity features.
+
+## macOS
+
+### Menu Bar Integration
+
+- Quick server status in menu bar
+- One-click server access
+- Compact mode for minimal distraction
+- Native macOS menu bar styling
+
+### Window State Persistence
+
+- Remembers window position and size
+- Restore previous session on launch
+- Multiple monitor support
+
+### Native Features
+
+- **Title Bar**: Custom or system title bar option
+- **Full Screen Mode**: Dedicated server monitoring
+- **Keyboard Shortcuts**: macOS-native shortcuts
+- **Touch Bar** (supported devices): Quick actions
+
+## Linux
+
+### Native Integration
+
+- System tray support
+- Desktop notification integration
+- File picker integration
+
+### Window Management
+
+- X11 and Wayland support
+- Tiling window manager friendly
+- Custom window decorations option
+
+## Windows
+
+### Features
+
+- System tray integration
+- Jump List quick actions
+- Native window controls
+- Auto-start on boot option
+
+## Cross-Platform Desktop Features
+
+### Keyboard Shortcuts
+
+- **Cmd/Ctrl + N**: New server
+- **Cmd/Ctrl + W**: Close tab
+- **Cmd/Ctrl + T**: New terminal tab
+- **Cmd/Ctrl + ,**: Settings
+
+### Themes
+
+- Light theme
+- Dark theme
+- AMOLED theme (pure black)
+- System theme (follows OS)
+
+### Multiple Windows
+
+- Open multiple servers in separate windows
+- Drag tabs to new window
+- Compare server stats side-by-side
+
+### Advantages Over Mobile
+
+- Larger screen for monitoring
+- Full keyboard for terminal
+- Faster file operations
+- Better multitasking
diff --git a/docs/src/content/docs/platforms/mobile.md b/docs/src/content/docs/platforms/mobile.md
new file mode 100644
index 00000000..8e5a8547
--- /dev/null
+++ b/docs/src/content/docs/platforms/mobile.md
@@ -0,0 +1,77 @@
+---
+title: Mobile Features
+description: iOS and Android specific features
+---
+
+Flutter Server Box provides several mobile-specific features for iOS and Android devices.
+
+## Biometric Authentication
+
+Secure your servers with biometric authentication:
+
+- **iOS**: Face ID or Touch ID
+- **Android**: Fingerprint authentication
+
+Enable in Settings > Security > Biometric Authentication
+
+## Home Screen Widgets
+
+Add server status widgets to your home screen for quick monitoring.
+
+### iOS
+
+- Long press on home screen
+- Tap **+** to add widget
+- Search for "Flutter Server Box"
+- Choose widget size:
+ - Small: Single server status
+ - Medium: Multiple servers
+ - Large: Detailed info
+
+### Android
+
+- Long press on home screen
+- Tap **Widgets**
+- Find "Flutter Server Box"
+- Select widget type
+
+## Background Running
+
+### Android
+
+Keep connections alive in the background:
+
+- Enable in Settings > Advanced > Background Running
+- Requires battery optimization exclusion
+- Persistent notifications for active connections
+
+### iOS
+
+Background limitations apply:
+
+- Connections may pause in background
+- Quick reconnect on return to app
+- Background refresh support
+
+## Push Notifications
+
+Receive notifications for:
+
+- Server offline alerts
+- High resource usage warnings
+- Task completion alerts
+
+Configure in Settings > Notifications
+
+## Mobile UI Features
+
+- **Pull to Refresh**: Update server status
+- **Swipe Actions**: Quick server operations
+- **Landscape Mode**: Better terminal experience
+- **Virtual Keyboard**: Terminal shortcuts
+
+## File Integration
+
+- **Files App (iOS)**: Direct SFTP access from Files
+- **Storage Access Framework (Android)**: Share files with other apps
+- **Document Picker**: Easy file selection
diff --git a/docs/src/content/docs/platforms/watchos.md b/docs/src/content/docs/platforms/watchos.md
new file mode 100644
index 00000000..4513912e
--- /dev/null
+++ b/docs/src/content/docs/platforms/watchos.md
@@ -0,0 +1,55 @@
+---
+title: watchOS App
+description: Apple Watch companion app
+---
+
+Flutter Server Box includes a companion app for Apple Watch, providing quick server monitoring on your wrist.
+
+## Features
+
+### Server Status at a Glance
+
+- View server online/offline status
+- Quick CPU and memory stats
+- One-tap server connectivity check
+
+### Complications
+
+Add server information to your watch face:
+
+- **Modular**: Server status icon
+- **Infograph**: Small complication
+- **Extra Large**: Large complication
+
+### Quick Actions
+
+- Ping servers
+- Wake on LAN
+- Quick terminal command
+
+## Requirements
+
+- Apple Watch Series 3 or later
+- watchOS 8.0 or later
+- Paired iPhone with Flutter Server Box installed
+- iPhone and Watch on same Wi-Fi
+
+## Setup
+
+1. Install Flutter Server Box on iPhone
+2. Open the Watch app on iPhone
+3. Find Flutter Server Box under "Available Apps"
+4. Toggle "Show App on Apple Watch"
+
+## Limitations
+
+- No full terminal access
+- Reduced SFTP functionality
+- Dependent on iPhone connection
+- Simplified server management
+
+## Tips
+
+- Use complications for persistent status
+- Quick actions for emergency checks
+- Sync servers from iPhone app
diff --git a/docs/src/content/docs/principles/architecture.md b/docs/src/content/docs/principles/architecture.md
new file mode 100644
index 00000000..181398b8
--- /dev/null
+++ b/docs/src/content/docs/principles/architecture.md
@@ -0,0 +1,214 @@
+---
+title: Architecture Overview
+description: High-level application architecture
+---
+
+Flutter Server Box follows a layered architecture with clear separation of concerns.
+
+## Architecture Layers
+
+```
+┌─────────────────────────────────────────────────┐
+│ Presentation Layer (UI) │
+│ lib/view/page/, lib/view/widget/ │
+│ - Pages, Widgets, Controllers │
+└─────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────┐
+│ Business Logic Layer │
+│ lib/data/provider/ │
+│ - Riverpod Providers, State Notifiers │
+└─────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────┐
+│ Data Access Layer │
+│ lib/data/store/, lib/data/model/ │
+│ - Hive Stores, Data Models │
+└─────────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────────┐
+│ External Integration Layer │
+│ - SSH (dartssh2), Terminal (xterm), SFTP │
+│ - Platform-specific code (iOS, Android, etc.) │
+└─────────────────────────────────────────────────┘
+```
+
+## Application Foundation
+
+### Main Entry Point
+
+`lib/main.dart` initializes the app:
+
+```dart
+void main() {
+ runApp(
+ ProviderScope(
+ child: MyApp(),
+ ),
+ );
+}
+```
+
+### Root Widget
+
+`MyApp` provides:
+- **Theme Management**: Light/dark theme switching
+- **Routing Configuration**: Navigation structure
+- **Provider Scope**: Dependency injection root
+
+### Home Page
+
+`HomePage` serves as navigation hub:
+- **Tabbed Interface**: Server, Snippet, Container, SSH
+- **State Management**: Per-tab state
+- **Navigation**: Feature access
+
+## Core Systems
+
+### State Management: Riverpod
+
+**Why Riverpod?**
+- Compile-time safety
+- Easy testing
+- No Build context dependency
+- Works across platforms
+
+**Provider Types Used:**
+- `StateProvider`: Simple mutable state
+- `AsyncNotifierProvider`: Loading/error/data states
+- `StreamProvider`: Real-time data streams
+- Future providers: One-time async operations
+
+### Data Persistence: Hive CE
+
+**Why Hive CE?**
+- No native code dependencies
+- Fast key-value storage
+- Type-safe with code generation
+- No manual field annotations needed
+
+**Stores:**
+- `SettingStore`: App preferences
+- `ServerStore`: Server configurations
+- `SnippetStore`: Command snippets
+- `KeyStore`: SSH keys
+
+### Immutable Models: Freezed
+
+**Benefits:**
+- Compile-time immutability
+- Union types for state
+- Built-in JSON serialization
+- CopyWith extensions
+
+## Cross-Platform Strategy
+
+### Plugin System
+
+Flutter plugins provide platform integration:
+
+| Platform | Integration Method |
+|----------|-------------------|
+| iOS | CocoaPods, Swift/Obj-C |
+| Android | Gradle, Kotlin/Java |
+| macOS | CocoaPods, Swift |
+| Linux | CMake, C++ |
+| Windows | CMake, C# |
+
+### Platform-Specific Features
+
+**iOS Only:**
+- Home screen widgets
+- Live Activities
+- Apple Watch companion
+
+**Android Only:**
+- Background service
+- Push notifications
+- File system access
+
+**Desktop Only:**
+- Menu bar integration
+- Multiple windows
+- Custom title bar
+
+## Custom Dependencies
+
+### dartssh2 Fork
+
+Enhanced SSH client with:
+- Better mobile support
+- Enhanced error handling
+- Performance optimizations
+
+### xterm.dart Fork
+
+Terminal emulator with:
+- Mobile-optimized rendering
+- Touch gesture support
+- Virtual keyboard integration
+
+### fl_lib
+
+Shared utilities package with:
+- Common widgets
+- Extensions
+- Helper functions
+
+## Build System
+
+### fl_build Package
+
+Custom build system for:
+- Multi-platform builds
+- Code signing
+- Asset bundling
+- Version management
+
+### Build Process
+
+```
+make.dart (version) → fl_build (build) → Platform output
+```
+
+1. **Pre-build**: Calculate version from Git
+2. **Build**: Compile for target platform
+3. **Post-build**: Package and sign
+
+## Data Flow Example
+
+### Server Status Update
+
+```
+1. Timer triggers →
+2. Provider calls service →
+3. Service executes SSH command →
+4. Response parsed to model →
+5. State updated →
+6. UI rebuilds with new data
+```
+
+### User Action Flow
+
+```
+1. User taps button →
+2. Widget calls provider method →
+3. Provider updates state →
+4. State change triggers rebuild →
+5. New state reflected in UI
+```
+
+## Security Architecture
+
+### Data Protection
+
+- **Passwords**: Encrypted with flutter_secure_storage
+- **SSH Keys**: Encrypted at rest
+- **Host Fingerprints**: Stored securely
+- **Session Data**: Not persisted
+
+### Connection Security
+
+- **Host Key Verification**: MITM detection
+- **Encryption**: Standard SSH encryption
+- **No Plain Text**: Sensitive data never stored plain
diff --git a/docs/src/content/docs/principles/sftp.md b/docs/src/content/docs/principles/sftp.md
new file mode 100644
index 00000000..5e0d82f8
--- /dev/null
+++ b/docs/src/content/docs/principles/sftp.md
@@ -0,0 +1,490 @@
+---
+title: SFTP System
+description: How the SFTP file browser works
+---
+
+The SFTP system provides file management capabilities over SSH.
+
+## Architecture
+
+```
+┌─────────────────────────────────────────────┐
+│ SFTP UI Layer │
+│ - File browser (remote) │
+│ - File browser (local) │
+│ - Transfer queue │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ SFTP State Management │
+│ - sftpProvider │
+│ - Path management │
+│ - Operation queue │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ SFTP Protocol Layer │
+│ - SSH subsystem │
+│ - File operations │
+│ - Directory listing │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ SSH Transport │
+│ - Secure channel │
+│ - Data streaming │
+└─────────────────────────────────────────────┘
+```
+
+## Connection Establishment
+
+### SFTP Client Creation
+
+```dart
+Future createSftpClient(Spi spi) async {
+ // 1. Get SSH client (reuse if available)
+ final sshClient = await genClient(spi);
+
+ // 2. Open SFTP subsystem
+ final sftp = await sshClient.openSftp();
+
+ return sftp;
+}
+```
+
+### Connection Reuse
+
+SFTP reuses existing SSH connections:
+
+```dart
+class ServerProvider {
+ SSHClient? _sshClient;
+ SftpClient? _sftpClient;
+
+ Future getSftpClient(String spiId) async {
+ _sftpClient ??= await _sshClient!.openSftp();
+ return _sftpClient!;
+ }
+}
+```
+
+## File System Operations
+
+### Directory Listing
+
+```dart
+Future> listDirectory(String path) async {
+ final sftp = await getSftpClient(spiId);
+
+ // List directory
+ final files = await sftp.listDir(path);
+
+ // Sort based on settings
+ files.sort((a, b) {
+ switch (sortOption) {
+ case SortOption.name:
+ return a.name.toLowerCase().compareTo(b.name.toLowerCase());
+ case SortOption.size:
+ return a.size.compareTo(b.size);
+ case SortOption.time:
+ return a.modified.compareTo(b.modified);
+ }
+ });
+
+ // Folders first if enabled
+ if (showFoldersFirst) {
+ final dirs = files.where((f) => f.isDirectory);
+ final regular = files.where((f) => !f.isDirectory);
+ return [...dirs, ...regular];
+ }
+
+ return files;
+}
+```
+
+### File Metadata
+
+```dart
+class SftpFile {
+ final String name;
+ final String path;
+ final int size; // Bytes
+ final int modified; // Unix timestamp
+ final String permissions; // e.g., "rwxr-xr-x"
+ final String owner;
+ final String group;
+ final bool isDirectory;
+ final bool isSymlink;
+
+ String get sizeFormatted => formatBytes(size);
+ String get modifiedFormatted => formatDate(modified);
+}
+```
+
+## File Operations
+
+### Upload
+
+```dart
+Future uploadFile(
+ String localPath,
+ String remotePath,
+) async {
+ final sftp = await getSftpClient(spiId);
+
+ // Create request
+ final req = SftpReq(
+ spi: spi,
+ remotePath: remotePath,
+ localPath: localPath,
+ type: SftpReqType.upload,
+ );
+
+ // Add to queue
+ _transferQueue.add(req);
+
+ // Execute transfer with progress
+ final file = File(localPath);
+ final size = await file.length();
+ final stream = file.openRead();
+
+ await sftp.upload(
+ stream: stream,
+ toPath: remotePath,
+ onProgress: (transferred) {
+ _updateProgress(req, transferred, size);
+ },
+ );
+
+ // Complete
+ _transferQueue.remove(req);
+}
+```
+
+### Download
+
+```dart
+Future downloadFile(
+ String remotePath,
+ String localPath,
+) async {
+ final sftp = await getSftpClient(spiId);
+
+ // Create local file
+ final file = File(localPath);
+ final sink = file.openWrite();
+
+ // Download with progress
+ final stat = await sftp.stat(remotePath);
+
+ await sftp.download(
+ fromPath: remotePath,
+ toSink: sink,
+ onProgress: (transferred) {
+ _updateProgress(
+ SftpReq(...),
+ transferred,
+ stat.size,
+ );
+ },
+ );
+
+ await sink.close();
+}
+```
+
+### Permission Editing
+
+```dart
+Future setPermissions(
+ String path,
+ String permissions,
+) async {
+ final sftp = await getSftpClient(spiId);
+
+ // Parse permissions (e.g., "rwxr-xr-x" or "755")
+ final mode = parsePermissions(permissions);
+
+ // Set via SSH command (more reliable than SFTP)
+ final ssh = await getSshClient(spiId);
+ await ssh.exec('chmod $mode "$path"');
+}
+```
+
+## Path Management
+
+### Path Structure
+
+```dart
+class PathWithPrefix {
+ final String prefix; // e.g., "/home/user"
+ final String path; // Relative or absolute
+
+ String get fullPath {
+ if (path.startsWith('/')) {
+ return path; // Absolute path
+ }
+ return '$prefix/$path'; // Relative path
+ }
+
+ PathWithPrefix cd(String subPath) {
+ return PathWithPrefix(
+ prefix: fullPath,
+ path: subPath,
+ );
+ }
+}
+```
+
+### Navigation History
+
+```dart
+class PathHistory {
+ final List _history = [];
+ int _index = -1;
+
+ void push(String path) {
+ // Remove forward history
+ _history.removeRange(_index + 1, _history.length);
+ _history.add(path);
+ _index = _history.length - 1;
+ }
+
+ String? back() {
+ if (_index > 0) {
+ _index--;
+ return _history[_index];
+ }
+ return null;
+ }
+
+ String? forward() {
+ if (_index < _history.length - 1) {
+ _index++;
+ return _history[_index];
+ }
+ return null;
+ }
+}
+```
+
+## Transfer System
+
+### Transfer Request
+
+```dart
+class SftpReq {
+ final Spi spi;
+ final String remotePath;
+ final String localPath;
+ final SftpReqType type;
+ final DateTime createdAt;
+
+ int? totalBytes;
+ int? transferredBytes;
+ String? error;
+}
+```
+
+### Progress Tracking
+
+```dart
+class TransferProgress {
+ final SftpReq request;
+ final int total;
+ final int transferred;
+ final DateTime startTime;
+
+ double get percentage => (transferred / total) * 100;
+ Duration get elapsed => DateTime.now().difference(startTime);
+
+ String get speedFormatted {
+ final bytesPerSecond = transferred / elapsed.inSeconds;
+ return formatSpeed(bytesPerSecond);
+ }
+}
+```
+
+### Queue Management
+
+```dart
+class TransferQueue {
+ final List _queue = [];
+ final Map _progress = {};
+ int _concurrent = 3; // Max concurrent transfers
+
+ Future process() async {
+ final active = _progress.values.where((p) => p.isInProgress);
+ if (active.length >= _concurrent) return;
+
+ final pending = _queue.where((r) => !_progress.containsKey(r.id));
+ for (final req in pending.take(_concurrent - active.length)) {
+ _executeTransfer(req);
+ }
+ }
+
+ Future _executeTransfer(SftpReq req) async {
+ try {
+ _progress[req.id] = TransferProgress.inProgress(req);
+
+ if (req.type == SftpReqType.upload) {
+ await uploadFile(req.localPath, req.remotePath);
+ } else {
+ await downloadFile(req.remotePath, req.localPath);
+ }
+
+ _progress[req.id] = TransferProgress.completed(req);
+ } catch (e) {
+ _progress[req.id] = TransferProgress.failed(req, e);
+ }
+ }
+}
+```
+
+## Local Storage Pattern
+
+### Download Cache
+
+Downloaded files stored at:
+
+```dart
+String getLocalDownloadPath(String spiId, String remotePath) {
+ final normalized = remotePath.replaceAll('/', '_');
+ return 'Paths.file/$spiId/$normalized';
+}
+```
+
+Example:
+- Remote: `/var/log/nginx/access.log`
+- spiId: `server-123`
+- Local: `Paths.file/server-123/_var_log_nginx_access.log`
+
+## File Editing
+
+### Edit Workflow
+
+```dart
+Future editFile(String path) async {
+ final sftp = await getSftpClient(spiId);
+
+ // 1. Check size
+ final stat = await sftp.stat(path);
+ if (stat.size > editorMaxSize) {
+ showWarning('File too large for built-in editor');
+ return;
+ }
+
+ // 2. Download to temp
+ final temp = await downloadToTemp(path);
+
+ // 3. Open in editor
+ final content = await openEditor(temp.path);
+
+ // 4. Upload back
+ await uploadFile(temp.path, path);
+
+ // 5. Cleanup
+ await temp.delete();
+}
+```
+
+### External Editor Integration
+
+```dart
+Future editInExternalEditor(String path) async {
+ final ssh = await getSshClient(spiId);
+
+ // Open terminal with editor
+ final editor = getSetting('sftpEditor', 'vim');
+ await ssh.exec('$editor "$path"');
+
+ // User edits in terminal
+ // After save, refresh SFTP view
+}
+```
+
+## Error Handling
+
+### Permission Errors
+
+```dart
+try {
+ await sftp.upload(...);
+} on SftpPermissionException {
+ showError('Permission denied: ${stat.path}');
+ showHint('Check file permissions and ownership');
+}
+```
+
+### Connection Errors
+
+```dart
+try {
+ await sftp.listDir(path);
+} on SftpConnectionException {
+ showError('Connection lost');
+ await reconnect();
+}
+```
+
+### Space Errors
+
+```dart
+try {
+ await sftp.upload(...);
+} on SftpNoSpaceException {
+ showError('Disk full on remote server');
+}
+```
+
+## Performance Optimizations
+
+### Directory Caching
+
+```dart
+class DirectoryCache {
+ final Map _cache = {};
+ final Duration ttl = Duration(minutes: 5);
+
+ Future> list(String path) async {
+ final cached = _cache[path];
+ if (cached != null && !cached.isExpired) {
+ return cached.files;
+ }
+
+ final files = await sftp.listDir(path);
+ _cache[path] = CachedDirectory(files);
+ return files;
+ }
+}
+```
+
+### Lazy Loading
+
+For large directories (>1000 items):
+
+```dart
+List loadPage(String path, int page, int pageSize) {
+ final all = cache[path] ?? [];
+ final start = page * pageSize;
+ final end = start + pageSize;
+ return all.sublist(start, end.clamp(0, all.length));
+}
+```
+
+### Pagination
+
+```dart
+class PaginatedDirectory {
+ static const pageSize = 100;
+
+ Future> getPage(int page) async {
+ final offset = page * pageSize;
+ return await sftp.listDir(
+ path,
+ offset: offset,
+ limit: pageSize,
+ );
+ }
+}
+```
diff --git a/docs/src/content/docs/principles/ssh.md b/docs/src/content/docs/principles/ssh.md
new file mode 100644
index 00000000..5b759422
--- /dev/null
+++ b/docs/src/content/docs/principles/ssh.md
@@ -0,0 +1,299 @@
+---
+title: SSH Connection
+description: How SSH connections are established and managed
+---
+
+Understanding SSH connections in Flutter Server Box.
+
+## Connection Flow
+
+```
+User Input → Spi Config → genClient() → SSH Client → Session
+```
+
+### Step 1: Configuration
+
+The `Spi` (Server Parameter Info) model contains:
+
+```dart
+class Spi {
+ String name; // Server name
+ String ip; // IP address
+ int port; // SSH port (default 22)
+ String user; // Username
+ String? pwd; // Password (encrypted)
+ String? keyId; // SSH key ID
+ String? jumpId; // Jump server ID
+ String? alterUrl; // Alternative URL
+}
+```
+
+### Step 2: Client Generation
+
+`genClient(spi)` creates SSH client:
+
+```dart
+Future genClient(Spi spi) async {
+ // 1. Establish socket
+ final socket = await connect(spi.ip, spi.port);
+
+ // 2. Try alternative URL if failed
+ if (socket == null && spi.alterUrl != null) {
+ socket = await connect(spi.alterUrl, spi.port);
+ }
+
+ // 3. Authenticate
+ final client = SSHClient(
+ socket: socket,
+ username: spi.user,
+ onPasswordRequest: () => spi.pwd,
+ onIdentityRequest: () => loadKey(spi.keyId),
+ );
+
+ // 4. Verify host key
+ await verifyHostKey(client, spi);
+
+ return client;
+}
+```
+
+### Step 3: Jump Server (if configured)
+
+For jump servers, recursive connection:
+
+```dart
+if (spi.jumpId != null) {
+ final jumpClient = await genClient(getJumpSpi(spi.jumpId));
+ final forwarded = await jumpClient.forwardLocal(
+ spi.ip,
+ spi.port,
+ );
+ // Connect through forwarded socket
+}
+```
+
+## Authentication Methods
+
+### Password Authentication
+
+```dart
+onPasswordRequest: () => spi.pwd
+```
+
+- Password stored encrypted in Hive
+- Decrypted on connection
+- Sent to server for verification
+
+### Private Key Authentication
+
+```dart
+onIdentityRequest: () async {
+ final key = await KeyStore.get(spi.keyId);
+ return decyptPem(key.pem, key.password);
+}
+```
+
+**Key Loading Process:**
+1. Retrieve encrypted key from `KeyStore`
+2. Decrypt password (biometric/prompt)
+3. Parse PEM format
+4. Standardize line endings (LF)
+5. Return for authentication
+
+### Keyboard-Interactive
+
+```dart
+onUserInfoRequest: (instructions) async {
+ // Handle challenge-response
+ return responses;
+}
+```
+
+Supports:
+- Password authentication
+- OTP tokens
+- Two-factor authentication
+
+## Host Key Verification
+
+### Why Verify Host Keys?
+
+Prevents **Man-in-the-Middle (MITM)** attacks by ensuring you're connecting to the same server.
+
+### Storage Format
+
+```
+{spi.id}::{keyType}
+```
+
+Example:
+```
+my-server::ssh-ed25519
+my-server::ecdsa-sha2-nistp256
+```
+
+### Fingerprint Formats
+
+**MD5 Hex:**
+```
+aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
+```
+
+**Base64:**
+```
+SHA256:AbCdEf1234567890...=
+```
+
+### Verification Flow
+
+```dart
+Future verifyHostKey(SSHClient client, Spi spi) async {
+ final key = await client.hostKey;
+ final fingerprint = md5Hex(key); // or base64
+
+ final stored = SettingStore.sshKnownHostsFingerprints
+ ['$keyId::$keyType'];
+
+ if (stored == null) {
+ // New host - prompt user
+ final trust = await promptUser(
+ 'Unknown host',
+ 'Fingerprint: $fingerprint',
+ );
+ if (trust) {
+ SettingStore.sshKnownHostsFingerprints
+ ['$keyId::$keyType'] = fingerprint;
+ }
+ } else if (stored != fingerprint) {
+ // Changed - warn user
+ await warnUser(
+ 'Host key changed!',
+ 'Possible MITM attack',
+ );
+ }
+}
+```
+
+## Session Management
+
+### Connection Pooling
+
+Active clients maintained in `ServerProvider`:
+
+```dart
+class ServerProvider {
+ final Map _clients = {};
+
+ SSHClient getClient(String spiId) {
+ return _clients[spiId] ??= connect(spiId);
+ }
+}
+```
+
+### Keep-Alive
+
+Maintain connection during inactivity:
+
+```dart
+Timer.periodic(
+ Duration(seconds: 30),
+ (_) => client.sendKeepAlive(),
+);
+```
+
+### Auto-Reconnect
+
+On connection loss:
+
+```dart
+client.onError.listen((error) async {
+ await Future.delayed(Duration(seconds: 5));
+ reconnect();
+});
+```
+
+## Connection Lifecycle
+
+```
+┌─────────────┐
+│ Initial │
+└──────┬──────┘
+ │ connect()
+ ↓
+┌─────────────┐
+│ Connecting │ ←──┐
+└──────┬──────┘ │
+ │ success │
+ ↓ │ fail (retry)
+┌─────────────┐ │
+│ Connected │───┘
+└──────┬──────┘
+ │
+ ↓
+┌─────────────┐
+│ Active │ ──→ Send commands
+└──────┬──────┘
+ │
+ ↓ (error/disconnect)
+┌─────────────┐
+│ Disconnected│
+└─────────────┘
+```
+
+## Error Handling
+
+### Connection Timeout
+
+```dart
+try {
+ await client.connect().timeout(
+ Duration(seconds: 30),
+ );
+} on TimeoutException {
+ throw ConnectionException('Connection timeout');
+}
+```
+
+### Authentication Failure
+
+```dart
+onAuthFail: (error) {
+ if (error.contains('password')) {
+ return 'Invalid password';
+ } else if (error.contains('key')) {
+ return 'Invalid SSH key';
+ }
+ return 'Authentication failed';
+}
+```
+
+### Host Key Mismatch
+
+```dart
+onHostKeyMismatch: (stored, current) {
+ showSecurityWarning(
+ 'Host key has changed!',
+ 'Possible MITM attack',
+ );
+}
+```
+
+## Performance Considerations
+
+### Connection Reuse
+
+- Reuse clients across features
+- Don't disconnect/reconnect unnecessarily
+- Pool connections for concurrent operations
+
+### Optimal Settings
+
+- **Timeout**: 30 seconds (adjustable)
+- **Keep-alive**: Every 30 seconds
+- **Retry delay**: 5 seconds
+
+### Network Efficiency
+
+- Single connection for multiple operations
+- Pipeline commands when possible
+- Avoid opening multiple connections
diff --git a/docs/src/content/docs/principles/state.md b/docs/src/content/docs/principles/state.md
new file mode 100644
index 00000000..098a0e25
--- /dev/null
+++ b/docs/src/content/docs/principles/state.md
@@ -0,0 +1,405 @@
+---
+title: State Management
+description: How state is managed with Riverpod
+---
+
+Understanding the state management architecture in Flutter Server Box.
+
+## Why Riverpod?
+
+**Key Benefits:**
+- **Compile-time safety**: Catch errors at compile time
+- **No BuildContext needed**: Access state anywhere
+- **Easy testing**: Simple to test providers in isolation
+- **Code generation**: Less boilerplate, type-safe
+
+## Provider Architecture
+
+```
+┌─────────────────────────────────────────────┐
+│ UI Layer (Widgets) │
+│ - ConsumerWidget / ConsumerStatefulWidget │
+│ - ref.watch() / ref.read() │
+└─────────────────────────────────────────────┘
+ ↓ watches
+┌─────────────────────────────────────────────┐
+│ Provider Layer │
+│ - @riverpod annotations │
+│ - Generated *.g.dart files │
+└─────────────────────────────────────────────┘
+ ↓ uses
+┌─────────────────────────────────────────────┐
+│ Service / Store Layer │
+│ - Business logic │
+│ - Data access │
+└─────────────────────────────────────────────┘
+```
+
+## Provider Types Used
+
+### 1. StateProvider (Simple State)
+
+For simple, observable state:
+
+```dart
+@riverpod
+class ThemeNotifier extends _$ThemeNotifier {
+ @override
+ ThemeMode build() {
+ // Load from settings
+ return SettingStore.themeMode;
+ }
+
+ void setTheme(ThemeMode mode) {
+ state = mode;
+ SettingStore.themeMode = mode; // Persist
+ }
+}
+```
+
+**Usage:**
+```dart
+class MyWidget extends ConsumerWidget {
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ final theme = ref.watch(themeNotifierProvider);
+ return Text('Theme: $theme');
+ }
+}
+```
+
+### 2. AsyncNotifierProvider (Async State)
+
+For data that loads asynchronously:
+
+```dart
+@riverpod
+class ServerStatus extends _$ServerStatus {
+ @override
+ Future build(Server server) async {
+ // Initial load
+ return await fetchStatus(server);
+ }
+
+ Future refresh() async {
+ state = const AsyncValue.loading();
+ state = await AsyncValue.guard(() async {
+ return await fetchStatus(server);
+ });
+ }
+}
+```
+
+**Usage:**
+```dart
+final status = ref.watch(serverStatusProvider(server));
+
+status.when(
+ data: (data) => StatusWidget(data),
+ loading: () => LoadingWidget(),
+ error: (error, stack) => ErrorWidget(error),
+)
+```
+
+### 3. StreamProvider (Real-time Data)
+
+For continuous data streams:
+
+```dart
+@riverpod
+Stream cpuUsage(CpuUsageRef ref, Server server) {
+ final client = ref.watch(sshClientProvider(server));
+ final stream = client.monitorCpu();
+
+ // Auto-dispose when not watched
+ ref.onDispose(() {
+ client.stopMonitoring();
+ });
+
+ return stream;
+}
+```
+
+**Usage:**
+```dart
+final cpu = ref.watch(cpuUsageProvider(server));
+
+cpu.when(
+ data: (usage) => CpuChart(usage),
+ loading: () => CircularProgressIndicator(),
+ error: (error, stack) => ErrorWidget(error),
+)
+```
+
+### 4. Family Providers (Parameterized)
+
+Providers that accept parameters:
+
+```dart
+@riverpod
+Future> containers(ContainersRef ref, Server server) async {
+ final client = await ref.watch(sshClientProvider(server).future);
+ return await client.listContainers();
+}
+```
+
+**Usage:**
+```dart
+final containers = ref.watch(containersProvider(server));
+
+// Different servers = different cached states
+final containers2 = ref.watch(containersProvider(server2));
+```
+
+## State Update Patterns
+
+### Direct State Update
+
+```dart
+ref.read(settingsProvider.notifier).updateTheme(darkMode);
+```
+
+### Computed State
+
+```dart
+@riverpod
+int totalServers(TotalServersRef ref) {
+ final servers = ref.watch(serversProvider);
+ return servers.length;
+}
+```
+
+### Derived State
+
+```dart
+@riverpod
+List onlineServers(OnlineServersRef ref) {
+ final all = ref.watch(serversProvider);
+ return all.where((s) => s.isOnline).toList();
+}
+```
+
+## Server-Specific State
+
+### Per-Server Providers
+
+Each server has isolated state:
+
+```dart
+@riverpod
+class ServerProvider extends _$ServerProvider {
+ @override
+ ServerState build(Server server) {
+ return ServerState.disconnected();
+ }
+
+ Future connect() async {
+ state = ServerState.connecting();
+ try {
+ final client = await genClient(server.spi);
+ state = ServerState.connected(client);
+ } catch (e) {
+ state = ServerState.error(e.toString());
+ }
+ }
+}
+```
+
+### Provider Keys
+
+```dart
+// Unique provider per server
+@riverpod
+ServerStatus serverStatus(ServerStatusRef ref, Server server) {
+ // server.id used as key
+}
+```
+
+## Reactive Patterns
+
+### Auto-Refresh
+
+```dart
+@riverpod
+class AutoRefreshServerStatus extends _$AutoRefreshServerStatus {
+ Timer? _timer;
+
+ @override
+ Future build(Server server) async {
+ // Start timer
+ _timer = Timer.periodic(Duration(seconds: 5), (_) {
+ refresh();
+ });
+
+ ref.onDispose(() {
+ _timer?.cancel();
+ });
+
+ return await fetchStatus(server);
+ }
+
+ Future refresh() async {
+ state = const AsyncValue.loading();
+ state = await AsyncValue.guard(() => fetchStatus(server));
+ }
+}
+```
+
+### Multi-Provider Dependencies
+
+```dart
+@riverpod
+Future systemInfo(SystemInfoRef ref, Server server) async {
+ // Wait for SSH client first
+ final client = await ref.watch(sshClientProvider(server).future);
+
+ // Then fetch system info
+ return await client.getSystemInfo();
+}
+```
+
+## State Persistence
+
+### Hive Integration
+
+```dart
+@riverpod
+class ServerStoreNotifier extends _$ServerStoreNotifier {
+ @override
+ List build() {
+ // Load from Hive
+ return Hive.box('servers').values.toList();
+ }
+
+ void addServer(Server server) {
+ state = [...state, server];
+ // Persist to Hive
+ Hive.box('servers').put(server.id, server);
+ }
+
+ void removeServer(String id) {
+ state = state.where((s) => s.id != id).toList();
+ // Remove from Hive
+ Hive.box('servers').delete(id);
+ }
+}
+```
+
+## Error Handling
+
+### Error States
+
+```dart
+@riverpod
+class ConnectionManager extends _$ConnectionManager {
+ @override
+ ConnectionState build() {
+ return ConnectionState.idle();
+ }
+
+ Future connect(Server server) async {
+ state = ConnectionState.connecting();
+ try {
+ final client = await genClient(server.spi);
+ state = ConnectionState.connected(client);
+ } on SocketException catch (e) {
+ state = ConnectionState.error('Network error: $e');
+ } on AuthenticationException catch (e) {
+ state = ConnectionState.error('Auth failed: $e');
+ } catch (e) {
+ state = ConnectionState.error('Unknown error: $e');
+ }
+ }
+}
+```
+
+### Error Recovery
+
+```dart
+@riverpod
+class ResilientFetcher extends _$ResilientFetcher {
+ int _retryCount = 0;
+
+ @override
+ Future build(Server server) async {
+ return await _fetchWithRetry();
+ }
+
+ Future _fetchWithRetry() async {
+ try {
+ return await fetchData(server);
+ } catch (e) {
+ if (_retryCount < 3) {
+ _retryCount++;
+ await Future.delayed(Duration(seconds: 2));
+ return await _fetchWithRetry();
+ }
+ rethrow;
+ }
+ }
+}
+```
+
+## Performance Optimizations
+
+### Provider Keep-Alive
+
+```dart
+@Riverpod(keepAlive: true) // Don't dispose when no listeners
+class GlobalSettings extends _$GlobalSettings {
+ @override
+ Settings build() {
+ return Settings.defaults();
+ }
+}
+```
+
+### Selective Watching
+
+```dart
+// Watch only specific part of state
+final name = ref.watch(serverProvider.select((s) => s.name));
+```
+
+### Provider Caching
+
+Family providers cache results per parameter:
+
+```dart
+// Cached per server ID
+final status1 = ref.watch(serverStatusProvider(server1));
+final status2 = ref.watch(serverStatusProvider(server2));
+// Different states, both cached
+```
+
+## Testing with Riverpod
+
+### Provider Container
+
+```dart
+test('fetch server status', () async {
+ final container = ProviderContainer();
+ addTearDown(container.dispose);
+
+ // Override provider
+ container.overrideFactory(
+ sshClientProvider,
+ (ref, server) => MockSshClient(),
+ );
+
+ final status = await container.read(
+ serverStatusProvider(testServer).future,
+ );
+
+ expect(status, isA());
+});
+```
+
+## Best Practices
+
+1. **Co-locate providers**: Place near consuming widgets
+2. **Use code generation**: Always use `@riverpod`
+3. **Keep providers focused**: Single responsibility
+4. **Handle loading states**: Always handle AsyncValue states
+5. **Dispose resources**: Use `ref.onDispose()` for cleanup
+6. **Avoid deep provider trees**: Keep provider graph flat
diff --git a/docs/src/content/docs/principles/terminal.md b/docs/src/content/docs/principles/terminal.md
new file mode 100644
index 00000000..0bceeb48
--- /dev/null
+++ b/docs/src/content/docs/principles/terminal.md
@@ -0,0 +1,343 @@
+---
+title: Terminal Implementation
+description: How the SSH terminal works internally
+---
+
+The SSH terminal is one of the most complex features, built on a custom xterm.dart fork.
+
+## Architecture Overview
+
+```
+┌─────────────────────────────────────────────┐
+│ Terminal UI Layer │
+│ - Tab management │
+│ - Virtual keyboard │
+│ - Text selection │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ xterm.dart Emulator │
+│ - PTY (Pseudo Terminal) │
+│ - VT100/ANSI emulation │
+│ - Rendering engine │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ SSH Client Layer │
+│ - SSH session │
+│ - Channel management │
+│ - Data streaming │
+└─────────────────────────────────────────────┘
+ ↓
+┌─────────────────────────────────────────────┐
+│ Remote Server │
+│ - Shell process │
+│ - Command execution │
+└─────────────────────────────────────────────┘
+```
+
+## Terminal Session Lifecycle
+
+### 1. Session Creation
+
+```dart
+Future createSession(Spi spi) async {
+ // 1. Get SSH client
+ final client = await genClient(spi);
+
+ // 2. Create PTY
+ final pty = await client.openPty(
+ term: 'xterm-256color',
+ cols: 80,
+ rows: 24,
+ );
+
+ // 3. Initialize terminal emulator
+ final terminal = Terminal(
+ backend: PtyBackend(pty),
+ );
+
+ // 4. Setup resize handler
+ terminal.onResize.listen((size) {
+ pty.resize(size.cols, size.rows);
+ });
+
+ return TerminalSession(
+ terminal: terminal,
+ pty: pty,
+ client: client,
+ );
+}
+```
+
+### 2. Terminal Emulation
+
+The xterm.dart fork provides:
+
+**VT100/ANSI Emulation:**
+- Cursor movement
+- Colors (256-color support)
+- Text attributes (bold, underline, etc.)
+- Scrolling regions
+- Alternate screen buffer
+
+**Rendering:**
+- Line-based rendering
+- Bidirectional text support
+- Unicode/emoji support
+- Optimized redraws
+
+### 3. Data Flow
+
+```
+User Input
+ ↓
+Virtual Keyboard / Physical Keyboard
+ ↓
+Terminal Emulator (key → escape sequence)
+ ↓
+SSH Channel (send)
+ ↓
+Remote PTY
+ ↓
+Remote Shell
+ ↓
+Command Output
+ ↓
+SSH Channel (receive)
+ ↓
+Terminal Emulator (parse ANSI codes)
+ ↓
+Render to Screen
+```
+
+## Multi-Tab System
+
+### Tab Management
+
+```dart
+class TerminalTabs {
+ final Map _tabs = {};
+ String? _activeTabId;
+
+ void createTab(Server server) {
+ final id = _generateTabId(server);
+ _tabs[id] = TabData(
+ id: id,
+ name: _generateTabName(server),
+ session: createSession(server),
+ );
+ _activeTabId = id;
+ }
+
+ String _generateTabName(Server server) {
+ final count = _tabs.values
+ .where((t) => t.name.startsWith(server.name))
+ .length;
+ return count == 0 ? server.name : '${server.name}($count)';
+ }
+}
+```
+
+### Session Persistence
+
+Tabs maintain state across navigation:
+
+- SSH connection kept alive
+- Terminal state preserved
+- Scroll buffer maintained
+- Input history retained
+
+## Virtual Keyboard
+
+### Platform-Specific Implementation
+
+**iOS:**
+- UIView-based custom keyboard
+- Toggleable with keyboard button
+- Auto-show/hide based on focus
+
+**Android:**
+- Custom input method
+- Integrated with system keyboard
+- Quick action buttons
+
+### Keyboard Buttons
+
+| Button | Action |
+|--------|--------|
+| **Toggle** | Show/hide system keyboard |
+| **Ctrl** | Send Ctrl modifier |
+| **Alt** | Send Alt modifier |
+| **SFTP** | Open current directory |
+| **Clipboard** | Copy/Paste context-aware |
+| **Snippets** | Execute snippet |
+
+### Key Encoding
+
+```dart
+String encodeKey(Key key) {
+ switch (key) {
+ case Key.enter:
+ return '\r';
+ case Key.tab:
+ return '\t';
+ case Key.escape:
+ return '\x1b';
+ case Key.ctrlC:
+ return '\x03';
+ // ... more keys
+ }
+}
+```
+
+## Text Selection
+
+### Selection Mode
+
+1. **Long press**: Enter selection mode
+2. **Drag**: Extend selection
+3. **Release**: Copy to clipboard
+
+### Selection Storage
+
+```dart
+class TextSelection {
+ final BufferRange range;
+ final String text;
+
+ void copyToClipboard() {
+ Clipboard.setData(ClipboardData(text: text));
+ }
+}
+```
+
+## Font and Dimensions
+
+### Size Calculation
+
+```dart
+class TerminalDimensions {
+ static Size calculate(double fontSize, Size screenSize) {
+ final charWidth = fontSize * 0.6; // Monospace aspect ratio
+ final charHeight = fontSize * 1.2;
+
+ final cols = (screenSize.width / charWidth).floor();
+ final rows = (screenSize.height / charHeight).floor();
+
+ return Size(cols.toDouble(), rows.toDouble());
+ }
+}
+```
+
+### Pinch-to-Zoom
+
+```dart
+GestureDetector(
+ onScaleStart: () => _baseFontSize = currentFontSize,
+ onScaleUpdate: (details) {
+ final newFontSize = _baseFontSize * details.scale;
+ resize(newFontSize);
+ },
+)
+```
+
+## Color Scheme
+
+### ANSI Color Mapping
+
+```dart
+const colorMap = {
+ 0: Color(0x000000), // Black
+ 1: Color(0x800000), // Red
+ 2: Color(0x008000), // Green
+ 3: Color(0x808000), // Yellow
+ 4: Color(0x000080), // Blue
+ 5: Color(0x800080), // Magenta
+ 6: Color(0x008080), // Cyan
+ 7: Color(0xC0C0C0), // White
+ // ... 256-color palette
+};
+```
+
+### Theme Support
+
+- **Light**: Light background, dark text
+- **Dark**: Dark background, light text
+- **AMOLED**: Pure black background
+
+## Performance Optimizations
+
+### Rendering Optimizations
+
+- **Dirty rectangle**: Only redraw changed regions
+- **Line caching**: Cache rendered lines
+- **Lazy scrolling**: Virtual scrolling for long buffers
+
+### Data Optimizations
+
+- **Batch updates**: Coalesce multiple writes
+- **Compression**: Compress scroll buffer
+- **Debouncing**: Debounce rapid inputs
+
+## Clipboard Integration
+
+### Copy Selection
+
+```dart
+void copySelection() {
+ final selected = terminal.getSelection();
+ Clipboard.setData(ClipboardData(text: selected));
+}
+```
+
+### Paste Clipboard
+
+```dart
+Future pasteClipboard() async {
+ final data = await Clipboard.getData('text/plain');
+ if (data?.text != null) {
+ terminal.paste(data!.text!);
+ }
+}
+```
+
+### Context-Aware Button
+
+- **Has selection**: Show "Copy"
+- **Has clipboard**: Show "Paste"
+- **Both**: Show primary action
+
+## Special Features
+
+### Snippet Execution
+
+```dart
+void executeSnippet(Snippet snippet) {
+ final formatted = formatSnippet(snippet);
+ terminal.paste(formatted);
+ terminal.paste('\r'); // Execute
+}
+```
+
+### SFTP Quick Access
+
+```dart
+void openSftp() async {
+ final cwd = await terminal.getCurrentWorkingDirectory();
+ Navigator.push(
+ context,
+ SftpPage(initialPath: cwd),
+ );
+}
+```
+
+### Keep-Alive
+
+```dart
+Timer.periodic(Duration(seconds: 30), (_) {
+ if (terminal.isActive) {
+ terminal.send('\x00'); // NUL - no-op keep-alive
+ }
+});
+```
diff --git a/docs/src/content/docs/quick-start.mdx b/docs/src/content/docs/quick-start.mdx
new file mode 100644
index 00000000..948eca68
--- /dev/null
+++ b/docs/src/content/docs/quick-start.mdx
@@ -0,0 +1,51 @@
+---
+title: Quick Start
+description: Get up and running with Flutter Server Box in minutes
+---
+
+Follow this quick start guide to connect to your first server and start monitoring.
+
+## Step 1: Add a Server
+
+1. Open Flutter Server Box
+2. Tap the **+** button to add a new server
+3. Fill in the server information:
+ - **Name**: A friendly name for your server
+ - **Host**: IP address or domain name
+ - **Port**: SSH port (default: 22)
+ - **User**: SSH username
+ - **Password or Key**: Authentication method
+
+4. Tap **Save** to add the server
+
+## Step 2: Connect and Monitor
+
+1. Tap on your server card to connect
+2. The app will establish an SSH connection
+3. You'll see real-time status for:
+ - CPU usage
+ - Memory (RAM) and Swap
+ - Disk usage
+ - Network speed
+
+## Step 3: Explore Features
+
+Once connected, you can:
+
+- **Open Terminal**: Tap the terminal button for full SSH access
+- **Browse Files**: Use SFTP to manage files
+- **Manage Containers**: View and control Docker containers
+- **View Processes**: Check running processes
+- **Run Snippets**: Execute saved commands
+
+## Tips
+
+- **Biometric Authentication**: Enable Face ID / Touch ID / Fingerprint for quick access (mobile)
+- **Home Screen Widgets**: Add server status widgets to your home screen (iOS/Android)
+- **Background Running**: Keep connections alive in the background (Android)
+
+## Next Steps
+
+- Explore the [Features](/features/) section for detailed guides
+- Configure [SSH Keys](/configuration/ssh-keys/) for passwordless authentication
+- Customize your experience in [Settings](/configuration/appearance/)
diff --git a/docs/src/styles/custom.css b/docs/src/styles/custom.css
new file mode 100644
index 00000000..ace1f804
--- /dev/null
+++ b/docs/src/styles/custom.css
@@ -0,0 +1,7 @@
+/* Flutter Server Box Custom Styles */
+
+:root {
+ --sl-color-accent: #02569b;
+ --sl-color-accent-low: #02569b15;
+ --starlight-cards--border: var(--sl-color-accent-low);
+}
diff --git a/docs/tsconfig.json b/docs/tsconfig.json
new file mode 100644
index 00000000..8bf91d3b
--- /dev/null
+++ b/docs/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "astro/tsconfigs/strict",
+ "include": [".astro/types.d.ts", "**/*"],
+ "exclude": ["dist"]
+}
diff --git a/lib/generated/l10n/l10n.dart b/lib/generated/l10n/l10n.dart
index 9747bb72..50125318 100644
--- a/lib/generated/l10n/l10n.dart
+++ b/lib/generated/l10n/l10n.dart
@@ -404,7 +404,7 @@ abstract class AppLocalizations {
/// No description provided for @compactDatabaseContent.
///
/// In en, this message translates to:
- /// **'Database size: {size}\n\nThis will reorganize the database to reduce file size. No data will be deleted.'**
+ /// **'Database size: {size}\n\nThis will rebuild the whole database to reduce file size.'**
String compactDatabaseContent(Object size);
/// No description provided for @confirm.
diff --git a/lib/generated/l10n/l10n_en.dart b/lib/generated/l10n/l10n_en.dart
index 40cf1a52..f80c7b61 100644
--- a/lib/generated/l10n/l10n_en.dart
+++ b/lib/generated/l10n/l10n_en.dart
@@ -166,7 +166,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String compactDatabaseContent(Object size) {
- return 'Database size: $size\n\nThis will reorganize the database to reduce file size. No data will be deleted.';
+ return 'Database size: $size\n\nThis will rebuild the whole database to reduce file size.';
}
@override