diff --git a/README.md b/README.md
index c701304..b871331 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,19 @@
-# Durable workspace
+# Durable
+
+[](https://github.com/wavezync/durable/actions/workflows/ci.yml)
+[](https://hex.pm/packages/durable)
+[](https://hex.pm/packages/durable_dashboard)
+[](https://durable.wavezync.com/docs/)
+[](LICENSE)
+
+Durable, reliable, resumable workflows for Elixir. Write workflows as plain
+steps; every step is saved, so runs resume after crashes, deploys and long
+waits.
+
+- **Docs, guides and interactive examples:** [durable.wavezync.com](https://durable.wavezync.com)
+- **API reference:** [durable](https://hexdocs.pm/durable) and [durable_dashboard](https://hexdocs.pm/durable_dashboard) on HexDocs
+
+## Workspace
This is a path-dep monorepo (pnpm-workspaces style) containing the Durable
workflow engine and its surrounding packages. Each subdirectory is an
@@ -7,11 +22,12 @@ publishing pipeline.
## Packages
-| Path | Package | Description |
-| --- | --- | --- |
-| [`durable/`](durable/) | `:durable` | Core workflow engine — resumable, reliable workflows with PostgreSQL persistence. |
-| [`durable_dashboard/`](durable_dashboard/) | `:durable_dashboard` | LiveView-first web dashboard for monitoring and managing Durable workflows. |
-| [`examples/phoenix_demo/`](examples/phoenix_demo/) | (unpublished) | Reference Phoenix app wiring up `:durable` and `:durable_dashboard`. |
+| Path | Package | Version | Docs | Description |
+| --- | --- | --- | --- | --- |
+| [`durable/`](durable/) | `:durable` | [](https://hex.pm/packages/durable) | [HexDocs](https://hexdocs.pm/durable) | Core workflow engine — resumable, reliable workflows with PostgreSQL persistence. |
+| [`durable_dashboard/`](durable_dashboard/) | `:durable_dashboard` | [](https://hex.pm/packages/durable_dashboard) | [HexDocs](https://hexdocs.pm/durable_dashboard) | LiveView-first web dashboard for monitoring and managing Durable workflows. |
+| [`examples/phoenix_demo/`](examples/phoenix_demo/) | (unpublished) | | | Reference Phoenix app wiring up `:durable` and `:durable_dashboard`. |
+| [`site/`](site/) | (unpublished) | | [durable.wavezync.com](https://durable.wavezync.com) | [durable.wavezync.com](https://durable.wavezync.com): Astro site. Its docs are the packages' own markdown, read in place (`site/src/docs.ts`). `cd site && pnpm install && pnpm dev` |
## Workspace commands
diff --git a/durable/README.md b/durable/README.md
index 41b6e25..719920b 100644
--- a/durable/README.md
+++ b/durable/README.md
@@ -1,10 +1,17 @@
# Durable
-[](https://github.com/wavezync/durable/actions/workflows/ci.yml)
+[](https://github.com/wavezync/durable/actions/workflows/ci.yml)
[](https://hex.pm/packages/durable)
+[](https://hexdocs.pm/durable)
+[](https://hex.pm/packages/durable)
+[](https://github.com/wavezync/durable/blob/main/LICENSE)
A durable, resumable workflow engine for Elixir. Similar to Temporal/Inngest.
+**Docs:** [durable.wavezync.com](https://durable.wavezync.com/docs/) ·
+**Dashboard:** [`durable_dashboard`](https://hex.pm/packages/durable_dashboard) ·
+**API:** [HexDocs](https://hexdocs.pm/durable)
+
## Features
- **Pipeline Model** - Context flows from step to step, simple and explicit
@@ -573,6 +580,9 @@ mix durable.cleanup --older-than 24h --dry-run # preview what would be
## Dashboard
+[](https://hex.pm/packages/durable_dashboard)
+[](https://hexdocs.pm/durable_dashboard)
+
`durable_dashboard` is a LiveView-first console for monitoring and managing
running workflows. Mount it into your Phoenix router with one line:
diff --git a/durable_dashboard/README.md b/durable_dashboard/README.md
index 807365c..1b35d17 100644
--- a/durable_dashboard/README.md
+++ b/durable_dashboard/README.md
@@ -1,5 +1,14 @@
# DurableDashboard
+[](https://github.com/wavezync/durable/actions/workflows/ci.yml)
+[](https://hex.pm/packages/durable_dashboard)
+[](https://hexdocs.pm/durable_dashboard)
+[](https://github.com/wavezync/durable/blob/main/LICENSE)
+
+**Docs:** [durable.wavezync.com](https://durable.wavezync.com/docs/dashboard/) ·
+**Engine:** [`durable`](https://hex.pm/packages/durable) ·
+**API:** [HexDocs](https://hexdocs.pm/durable_dashboard)
+
LiveView-first web console for the [Durable](https://hex.pm/packages/durable)
workflow engine.
diff --git a/site/.gitignore b/site/.gitignore
new file mode 100644
index 0000000..eb1c464
--- /dev/null
+++ b/site/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+dist/
+.astro/
+.wrangler/
diff --git a/site/astro.config.mjs b/site/astro.config.mjs
new file mode 100644
index 0000000..7a451e8
--- /dev/null
+++ b/site/astro.config.mjs
@@ -0,0 +1,58 @@
+import { defineConfig } from 'astro/config';
+import starlight from '@astrojs/starlight';
+import { satteri } from '@astrojs/markdown-satteri';
+import { DOCS, REPO, docLinks } from './src/docs.ts';
+import { changelog } from './src/changelog.ts';
+import { EXAMPLES } from './src/examples.ts';
+import { macroCalls, night } from './src/code-theme.ts';
+
+const doc = (d) => ({ label: d.label, slug: d.id });
+const group = (name) => DOCS.filter((d) => d.group === name).map(doc);
+
+export default defineConfig({
+ site: 'https://durable.wavezync.com',
+ trailingSlash: 'always',
+ markdown: { processor: satteri({ mdastPlugins: [docLinks, changelog] }) },
+ integrations: [
+ starlight({
+ title: 'Durable',
+ description:
+ 'Open-source durable workflow engine for Elixir. Retries, sleeps, events, human approvals and sagas, saved step by step so runs resume after crashes.',
+ logo: { src: './src/assets/logo.svg' },
+ head: [
+ { tag: 'meta', attrs: { property: 'og:image', content: 'https://durable.wavezync.com/og.png' } },
+ { tag: 'meta', attrs: { property: 'og:image:width', content: '1200' } },
+ { tag: 'meta', attrs: { property: 'og:image:height', content: '630' } },
+ { tag: 'meta', attrs: { property: 'og:image:alt', content: 'Resilient, Reliable, Resumable workflows for Elixir' } },
+ { tag: 'meta', attrs: { name: 'twitter:image', content: 'https://durable.wavezync.com/og.png' } },
+ ],
+ favicon: '/favicon.svg',
+ social: [{ icon: 'github', label: 'GitHub', href: REPO }],
+ customCss: ['./src/styles/fonts.css', './src/styles/theme.css'],
+ components: {
+ Head: './src/components/Head.astro',
+ PageTitle: './src/components/PageTitle.astro',
+ SocialIcons: './src/components/HeaderLinks.astro',
+ },
+ expressiveCode: {
+ themes: [night, 'github-light'],
+ shiki: { transformers: [macroCalls] },
+ styleOverrides: { borderRadius: '12px', codeFontFamily: 'var(--sl-font-mono)', uiFontFamily: 'var(--sl-font)' },
+ },
+ sidebar: [
+ { label: 'Start here', items: group('Start here') },
+ { label: 'Guides', items: group('Guides') },
+ { label: 'Examples', items: [{ label: 'All examples', link: '/examples/' }, ...EXAMPLES.map((e) => ({ label: e.heading, link: `/examples/${e.slug}/` }))] },
+ { label: 'Dashboard', items: group('Dashboard') },
+ { label: 'Changelog', items: group('Changelog') },
+ {
+ label: 'API reference',
+ items: [
+ { label: 'durable on HexDocs', link: 'https://hexdocs.pm/durable' },
+ { label: 'durable_dashboard on HexDocs', link: 'https://hexdocs.pm/durable_dashboard' },
+ ],
+ },
+ ],
+ }),
+ ],
+});
diff --git a/site/og/og.html b/site/og/og.html
new file mode 100644
index 0000000..ce7f85a
--- /dev/null
+++ b/site/og/og.html
@@ -0,0 +1,114 @@
+
+
+
+
+
+Durable social card
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
plan
+
+
+
+
+
search
+
read_docs
+
+
+
+
+
draft
+
+
review
+
waiting for you
+
+
send
+
+
+
+ Resilient, Reliable, Resumable
+
+ workflows for Elixir
+
+
+
+
+
diff --git a/site/package.json b/site/package.json
new file mode 100644
index 0000000..203a231
--- /dev/null
+++ b/site/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "durable-site",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "astro dev",
+ "build": "astro build",
+ "preview": "astro preview",
+ "check": "astro check",
+ "deploy": "astro build && wrangler deploy",
+ "preview:cf": "astro build && wrangler dev"
+ },
+ "dependencies": {
+ "@astrojs/markdown-remark": "^7.3.4",
+ "@astrojs/markdown-satteri": "0.4.5",
+ "@astrojs/starlight": "0.42.6",
+ "@fontsource-variable/sora": "5.3.0",
+ "@fontsource/geist-mono": "5.3.0",
+ "@lucide/astro": "1.61.0",
+ "astro": "7.4.2"
+ },
+ "devDependencies": {
+ "@astrojs/check": "^0.9.12",
+ "@types/node": "^24.19.2",
+ "typescript": "^6.0.3",
+ "wrangler": "^4.151.3"
+ }
+}
diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml
new file mode 100644
index 0000000..1736bd2
--- /dev/null
+++ b/site/pnpm-lock.yaml
@@ -0,0 +1,5273 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@astrojs/markdown-remark':
+ specifier: ^7.3.4
+ version: 7.3.4
+ '@astrojs/markdown-satteri':
+ specifier: 0.4.5
+ version: 0.4.5
+ '@astrojs/starlight':
+ specifier: 0.42.6
+ version: 0.42.6(@astrojs/markdown-remark@7.3.4)(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))(typescript@6.0.3)
+ '@fontsource-variable/sora':
+ specifier: 5.3.0
+ version: 5.3.0
+ '@fontsource/geist-mono':
+ specifier: 5.3.0
+ version: 5.3.0
+ '@lucide/astro':
+ specifier: 1.61.0
+ version: 1.61.0(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))
+ astro:
+ specifier: 7.4.2
+ version: 7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)
+ devDependencies:
+ '@astrojs/check':
+ specifier: ^0.9.12
+ version: 0.9.12(@emnapi/runtime@1.11.3)(prettier@3.9.10)(typescript@6.0.3)
+ '@types/node':
+ specifier: ^24.19.2
+ version: 24.19.2
+ typescript:
+ specifier: ^6.0.3
+ version: 6.0.3
+ wrangler:
+ specifier: ^4.151.3
+ version: 4.151.3(@types/node@24.19.2)
+
+packages:
+
+ '@astrojs/astro2tsx@0.1.3':
+ resolution: {integrity: sha512-GMDC7Eo0myBUA/QLBl0u+OcegJ8LiBhccmNZR34KmprQNP8gQUJlWlOOZWUsxNA2rNS6GuPYcGDyLoPnjmn4/Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+
+ '@astrojs/check@0.9.12':
+ resolution: {integrity: sha512-hazpqxIfZWj2VhyPyR0pOEQ/IhFDM/2nIApL96zMXABdD8NrUKYDmhxTy7h+drTDl9MQG/Sd1ET/4amadVJUUA==}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0 || ^6.0.0
+
+ '@astrojs/compiler-binding-android-arm64@0.5.2':
+ resolution: {integrity: sha512-kckIxon6Rm/Bxzh9mGPYpRRqUbToUQoHptCmpMmE+Yt0Xumq8CqrKUidyYhrBsrHVO7bxuRzzWUUqvpf+iYceQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@astrojs/compiler-binding-darwin-arm64@0.5.2':
+ resolution: {integrity: sha512-1ZG5Ar3dD8HtodX9XH1mRmE0qBXZlvjYXSFfpgFwocqfWnvhFuqtGUNseL8wgfImiRMztIjpQqlogQFQQtgiag==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@astrojs/compiler-binding-darwin-x64@0.5.2':
+ resolution: {integrity: sha512-+kl35S7hiHJ2cb7eujwEsPFYYuSgE11uEE2Z20lAJ+undpgulMcW+weQqFPOSSZccEKHOiLIY+kQHkb4e4092w==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@astrojs/compiler-binding-linux-arm64-gnu@0.5.2':
+ resolution: {integrity: sha512-BqlR0EHNQLPLwgL9+xogjsAc7zGf0cHho2CPdhv0P1yqbVMwGVaGAqrANP6VYAXCqSC43AF4Czcxc2n+oqdesg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@astrojs/compiler-binding-linux-arm64-musl@0.5.2':
+ resolution: {integrity: sha512-GRGyby3AZWw5d6JQzidyxPyvGgHWsSusrpgKyFVpDTKctABF7L3Pd5V1cRJbV36/rcu+Eh292/wL7pF7MkmGkQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@astrojs/compiler-binding-linux-x64-gnu@0.5.2':
+ resolution: {integrity: sha512-9XAqGTMQAtIslMsjK3xdyY6OI9d59OZqcLBB6pvD/DcoR0daYswfrKx2azdDERDY4AqAnWPC7odVM1BmxYv3Vw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@astrojs/compiler-binding-linux-x64-musl@0.5.2':
+ resolution: {integrity: sha512-jOViewGeTh9bSfS8vK72ECxoy2yvmA+Pd/ZcEvBI5c7+7IcfHwZ5qA4L9fRYuOhSrAifvQ2dV4vm1XAtloaWBw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@astrojs/compiler-binding-wasm32-wasi@0.5.2':
+ resolution: {integrity: sha512-Z7p64doar1uvR5C9Xs6j1CV9lGlPVQX7OQ2aAtZ/xKC5aGS6GB13nyc2UfQXTQLvZrvVwsyaflTQy6ziY5Bekw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [wasm32]
+
+ '@astrojs/compiler-binding-win32-arm64-msvc@0.5.2':
+ resolution: {integrity: sha512-Tr13bh+ahTWsjXjzctK7pFpWV+dUU4FtBfETlR7gO+ueex0F+RDch7eRr0YfKysaRhk9tWm14lsCJ5uWyFPNHQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@astrojs/compiler-binding-win32-x64-msvc@0.5.2':
+ resolution: {integrity: sha512-SfKkI+jOQYLh6wojPvVPV0lFfQnxisweN9B+qCzRvZp7DHAuGif8Y0WcC5PUgN4jb8VKy57LggQDtggR46Du1g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@astrojs/compiler-binding@0.5.2':
+ resolution: {integrity: sha512-lEn76+0JcMQ5RDXU0wSMWJg2ZppiZvSULpghC29cfv4o9bhvWFDbQjsCtvjjXN9iVLFQ7fL3wTR2L2UU13mP8g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+
+ '@astrojs/compiler-rs@0.5.2':
+ resolution: {integrity: sha512-IvwYLB8t1M86rKO4oPdBi9GP4gzXcgrVlNgocjwos1jeeUuEIV8d9Crn1PvYD/5IKteWOxpIHomf7e8iYlkE+Q==}
+ engines: {node: '>=22.12.0'}
+
+ '@astrojs/internal-helpers@0.13.0':
+ resolution: {integrity: sha512-20jxQqnSmpskcGyad7N5l6Xf1gz0UCa6lNde44bEBdaXGpncEYfAZJ142r2ZgzBaG4dUyzGmhqZWv1INU2eiHQ==}
+
+ '@astrojs/language-server@2.17.3':
+ resolution: {integrity: sha512-QIAFu1e/4quJMTPdmBOm+ZPXc5NDGZE4/YQjgR3EgjhGLl/tdidaWJDr5WmO2lesVc+BW1qN/xNBURmuePDG2A==}
+ hasBin: true
+ peerDependencies:
+ prettier: ^3.0.0
+ prettier-plugin-astro: '>=0.11.0'
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+
+ '@astrojs/markdown-remark@7.3.4':
+ resolution: {integrity: sha512-AB8S4EQKSryzH624iMDtvC+1AD5nSPzYpCXxc7e1H5ydXhv9B5Td2QfCPA0JyEwqsJpsIsPlW0iOqiy1imdqYw==}
+
+ '@astrojs/markdown-satteri@0.4.5':
+ resolution: {integrity: sha512-0IeGdoFbv0f+442KJhYS44Wg8F3MuHmRsxIEYuFyqkjRubc6dPBFZ7azor5t4AeXLQoT5A5h9HyViKpd70Dl9w==}
+
+ '@astrojs/mdx@8.1.1':
+ resolution: {integrity: sha512-jEJUJsO2KqmKfBXaKeDHDCCj+Kerj1Fj+XndHznF9wxahvs+1onYCBeKmieM28N2+uA6mW57DOQQw5YaDLdBnA==}
+ engines: {node: '>=22.23.4'}
+ peerDependencies:
+ '@astrojs/markdown-remark': ^7.3.0
+ '@astrojs/markdown-satteri': ^0.4.0
+ astro: ^7.2.10
+ peerDependenciesMeta:
+ '@astrojs/markdown-remark':
+ optional: true
+
+ '@astrojs/prism@4.1.1':
+ resolution: {integrity: sha512-sXlAXJX6t4QfuLg+CuCDzpg7NoxWcyb4paFprgtFppLeisCBmh935h+tJ5CWXfsXEoW2IDy/ihbRMtiu28Chjw==}
+ engines: {node: '>=22.23.4'}
+
+ '@astrojs/sitemap@3.7.4':
+ resolution: {integrity: sha512-LbKNC24bdUWcQf/pThB6qLlSqHojxGjZDURIzFocY8rlWnAn2t74nnhnK6S5x0NHriHoAduLEpVjRykmeGiVvA==}
+
+ '@astrojs/starlight@0.42.6':
+ resolution: {integrity: sha512-Cfs7GdgzgNRCauDxQVsFUVL1thrGHK/rQdbv/SURv/xhGBXx+j5ypOHW9ENPraQxbIzUC8KAnJV7L9mvEVRuyQ==}
+ peerDependencies:
+ '@astrojs/markdown-remark': ^7.3.0
+ astro: ^7.2.10
+ peerDependenciesMeta:
+ '@astrojs/markdown-remark':
+ optional: true
+
+ '@astrojs/telemetry@3.4.1':
+ resolution: {integrity: sha512-SMkvMsGOpM0FMAoT5pzhgI3LZC0JSPWf7Evwop+fZ3N6UkusPM7lI+sOJjMNI5OJrVoiei1/AGo1cY7sikTc5A==}
+ engines: {node: '>=22.23.4'}
+
+ '@astrojs/yaml2ts@0.2.4':
+ resolution: {integrity: sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==}
+
+ '@babel/helper-string-parser@7.29.7':
+ resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.29.7':
+ resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.9':
+ resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.29.8':
+ resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==}
+ engines: {node: '>=6.9.0'}
+
+ '@bruits/satteri-darwin-arm64@0.10.5':
+ resolution: {integrity: sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@bruits/satteri-darwin-x64@0.10.5':
+ resolution: {integrity: sha512-IjnLe3nKspq6qaeqGgjT7MT8VrTV74yWRlaag7ZdNsI8TDAYZ0iPxMCo+9KQZHUk5EyVB+reBI/PFWL5KuFw9Q==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@bruits/satteri-linux-arm64-gnu@0.10.5':
+ resolution: {integrity: sha512-glkYXZCJywjP13v67eAyAMSJdF+ncvEbYvgi/wOtffL9tQ27lr/zsyzUfgs+ovjJ9d8JNQKiXeiArJcX8PJL9w==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@bruits/satteri-linux-arm64-musl@0.10.5':
+ resolution: {integrity: sha512-yWdgG1g17Nh2QyGVlFUxGRa3FEFwiMcpZEyMNWkbM3deC94cmVc+/i9OuyFpdKuWo3GkgoCtYVOoxk1uCnCZIA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@bruits/satteri-linux-x64-gnu@0.10.5':
+ resolution: {integrity: sha512-FVaLoPT1fBgGl0J+AYebyyXJYBachGl8Oyyrf1lye4RTqCB4S0Gwkj1uM9RJyThUOvx5VUmAT1CnNh1SFHA+kw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@bruits/satteri-linux-x64-musl@0.10.5':
+ resolution: {integrity: sha512-EHpVAx2bqW3GINHTKkljtxVfQmVDGWIuwOYOP5YghTj+0PkBa2o8oKPRtQ9Kbsr1Fye8jtUcDjhwj2jMNugZKg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@bruits/satteri-wasm32-wasi@0.10.5':
+ resolution: {integrity: sha512-ypz8c/Zmipxp4IoeDa228Gstv6TLzVmNs3yC6wKCoNSOjx1iwpgzu87Y3hTkXFdwChVGU85qeUDuOIarGUZQLw==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+
+ '@bruits/satteri-win32-arm64-msvc@0.10.5':
+ resolution: {integrity: sha512-siTV88nb0LRqNpkL2gXboqCwVdq95sLtzMHS1/3eONV2gLbB3NAK46wmSMvCO/yquBvI2lvaFIfd8P12ecsxBw==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@bruits/satteri-win32-x64-msvc@0.10.5':
+ resolution: {integrity: sha512-C3IfPvfvMXmlzBxaMPKFS1XiuV9pu2mC7YqkPk7PSvTgPZ8gbdASIpHpztDLvTTQjqZ0z1Ol8tK5X+V6XXC0wQ==}
+ cpu: [x64]
+ os: [win32]
+
+ '@capsizecss/unpack@4.0.1':
+ resolution: {integrity: sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==}
+ engines: {node: '>=18'}
+
+ '@clack/core@1.5.1':
+ resolution: {integrity: sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==}
+ engines: {node: '>= 20.12.0'}
+
+ '@clack/prompts@1.8.1':
+ resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==}
+ engines: {node: '>= 20.12.0'}
+
+ '@cloudflare/kv-asset-handler@0.5.0':
+ resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==}
+ engines: {node: '>=22.0.0'}
+
+ '@cloudflare/unenv-preset@2.16.2':
+ resolution: {integrity: sha512-JBP1+Z7ZSNG/d4mRP+y8VC5dka3tZVMLEZRvS+rzQ4DGV1EoxRFQckcJTTkXbHSQiTj0DtNI01Zwb/V2fX0mvQ==}
+ peerDependencies:
+ unenv: 2.0.0-rc.24
+ workerd: '>1.20260305.0 <2.0.0-0'
+ peerDependenciesMeta:
+ workerd:
+ optional: true
+
+ '@cloudflare/workerd-darwin-64@1.20261019.1':
+ resolution: {integrity: sha512-5ZILbAta/fBQvhmAYeCE7dKMMYIr7N9wJEX50fEGLKSIwGtvT0HzSfHNIK/O7cBQ4gHQ2WfIiPClvwcye6E0fA==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@cloudflare/workerd-darwin-arm64@1.20261019.1':
+ resolution: {integrity: sha512-cww2Ab6lVMxpTiEEjKmPI58p5EMo0vYTZSH+3WkqXJdQgc3ES66GuL247+U2B2YWajhhu2tqj7jySrXneU749g==}
+ engines: {node: '>=16'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@cloudflare/workerd-linux-64@1.20261019.1':
+ resolution: {integrity: sha512-4++VRi9vkQROYqrpZYOixIJuVDmujkwrT4kszsxNFlvcmsX6Mr2GumvxIN3gIixS3vJUh3Umdtkthqj5X0S3Xw==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [linux]
+
+ '@cloudflare/workerd-linux-arm64@1.20261019.1':
+ resolution: {integrity: sha512-75PVtJOwfjScQ53sbLtQXI7D8yP1c21t+WEUPaYbqkzaz4ZqfR5wAd+zuWs8G5Q7kOj2SQIvEfY5Sn8Y+UVrnA==}
+ engines: {node: '>=16'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@cloudflare/workerd-windows-64@1.20261019.1':
+ resolution: {integrity: sha512-z49fvKTETMCnG6wnMcQwxx9CpryFceiKz04FRjq26EkhCyzRNJ6c3UXhyZz3r5f1CXnnBZc5DcU8ZouPkUJCqw==}
+ engines: {node: '>=16'}
+ cpu: [x64]
+ os: [win32]
+
+ '@cspotcode/source-map-support@0.8.1':
+ resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
+ engines: {node: '>=12'}
+
+ '@ctrl/tinycolor@4.2.1':
+ resolution: {integrity: sha512-Vh5uy9Y1JBMId6J1f68TMXnZrTCvNdo9Fu2k0d1YnJngR+sM5kWTKl441c/3TFs+cG0NWOjRWgQ/iaWhbYx+7A==}
+ engines: {node: '>=14'}
+
+ '@emmetio/abbreviation@2.3.3':
+ resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==}
+
+ '@emmetio/css-abbreviation@2.1.8':
+ resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==}
+
+ '@emmetio/css-parser@0.4.1':
+ resolution: {integrity: sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==}
+
+ '@emmetio/html-matcher@1.3.0':
+ resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==}
+
+ '@emmetio/scanner@1.0.4':
+ resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==}
+
+ '@emmetio/stream-reader-utils@0.1.0':
+ resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==}
+
+ '@emmetio/stream-reader@2.2.0':
+ resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==}
+
+ '@emnapi/core@1.11.1':
+ resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==}
+
+ '@emnapi/core@1.11.3':
+ resolution: {integrity: sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==}
+
+ '@emnapi/runtime@1.11.1':
+ resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==}
+
+ '@emnapi/runtime@1.11.3':
+ resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
+
+ '@emnapi/wasi-threads@1.2.2':
+ resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
+
+ '@emnapi/wasi-threads@1.2.3':
+ resolution: {integrity: sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==}
+
+ '@esbuild/aix-ppc64@0.28.2':
+ resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.28.2':
+ resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.28.2':
+ resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.28.2':
+ resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.28.2':
+ resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.28.2':
+ resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.28.2':
+ resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.28.2':
+ resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.28.2':
+ resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.28.2':
+ resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.28.2':
+ resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.28.2':
+ resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.28.2':
+ resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.28.2':
+ resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.28.2':
+ resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.28.2':
+ resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.28.2':
+ resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.28.2':
+ resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.28.2':
+ resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.28.2':
+ resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.28.2':
+ resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.28.2':
+ resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.28.2':
+ resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.28.2':
+ resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.28.2':
+ resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.28.2':
+ resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@expressive-code/core@0.44.3':
+ resolution: {integrity: sha512-pffktF0TJoxC08dgNcutl/0LcSnTrjF6vXR39qVpwZ0EyxpwO9zjI7dbni6sO7w3yHpRBO0voLFvhzB+EPJRsA==}
+
+ '@expressive-code/plugin-frames@0.44.3':
+ resolution: {integrity: sha512-ysW4VXk9vXEliA99Ur6ApUepVtx74sPolp6o/j45BRjZQoL5O6kXKMhSP4koQLih8HbC5B3ImIvO+HKKhkv/oA==}
+
+ '@expressive-code/plugin-shiki@0.44.3':
+ resolution: {integrity: sha512-jAibAZPG7lDmi61EFJADZjoSZzjHiwZZdbbgR/mTlWXM4ON/Pyo/9tB2vrqQNKylsci6jqtCi6idrwqQXF53xA==}
+
+ '@expressive-code/plugin-text-markers@0.44.3':
+ resolution: {integrity: sha512-4Ae2xRSDV5kdWPsi40xWbOtoihbzM0zLVjQKkDAnD5KzFXl+6/kd+VhuWOlTRVaJ5cqGk++vCbAaf0MR1XbZlw==}
+
+ '@fontsource-variable/sora@5.3.0':
+ resolution: {integrity: sha512-h8kHta4Z8SkfUGeI82TUy1n3rbrKpBRGwuk4t4qCwto5oEHxlbOFD2yGP+Df5fbmTXwKGn+o667vYp0E4K8Whw==}
+
+ '@fontsource/geist-mono@5.3.0':
+ resolution: {integrity: sha512-UtJ1BBBCVpMYdIcW7nEB45UAoAw5M53ZXs2t0ciPW+IokuAAIc56M8+kW5tXbRJCTpDw4XTtU7proT6NdQAHTg==}
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.35.5':
+ resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.35.5':
+ resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-freebsd-wasm32@0.35.5':
+ resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==}
+ engines: {node: '>=20.9.0'}
+ os: [freebsd]
+
+ '@img/sharp-libvips-darwin-arm64@1.3.4':
+ resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.3.4':
+ resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.3.4':
+ resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-arm@1.3.4':
+ resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-ppc64@1.3.4':
+ resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-riscv64@1.3.4':
+ resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-s390x@1.3.4':
+ resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-x64@1.3.4':
+ resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.3.4':
+ resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.3.4':
+ resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linux-arm64@0.35.5':
+ resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linux-arm@0.35.5':
+ resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-linux-ppc64@0.35.5':
+ resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==}
+ engines: {node: '>=20.9.0'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-linux-riscv64@0.35.5':
+ resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==}
+ engines: {node: '>=20.9.0'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-linux-s390x@0.35.5':
+ resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==}
+ engines: {node: '>=20.9.0'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-linux-x64@0.35.5':
+ resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-arm64@0.35.5':
+ resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-x64@0.35.5':
+ resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-wasm32@0.35.5':
+ resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==}
+ engines: {node: '>=20.9.0'}
+
+ '@img/sharp-webcontainers-wasm32@0.35.5':
+ resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==}
+ engines: {node: '>=20.9.0'}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.35.5':
+ resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==}
+ engines: {node: '>=20.9.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.35.5':
+ resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==}
+ engines: {node: ^20.9.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.35.5':
+ resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==}
+ engines: {node: '>=20.9.0'}
+ cpu: [x64]
+ os: [win32]
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.6.0':
+ resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==}
+
+ '@jridgewell/trace-mapping@0.3.9':
+ resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+
+ '@lucide/astro@1.61.0':
+ resolution: {integrity: sha512-XoFZGoHjYtnDTuOQ4b105IO+WUCh8rzitIgBIrkOcdC1PRmsvLx+fwnrCRHiZ1JfbA36r/jAMxQL/HeyRqKJjQ==}
+ peerDependencies:
+ astro: ^4 || ^5 || ^6 || ^7
+
+ '@mdx-js/mdx@3.1.1':
+ resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
+
+ '@napi-rs/wasm-runtime@1.2.4':
+ resolution: {integrity: sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4
+ '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4
+
+ '@napi-rs/wasm-runtime@1.2.5':
+ resolution: {integrity: sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4
+ '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4
+
+ '@oslojs/encoding@1.1.0':
+ resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
+
+ '@oxc-project/types@0.155.0':
+ resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==}
+
+ '@pagefind/darwin-arm64@1.5.2':
+ resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@pagefind/darwin-x64@1.5.2':
+ resolution: {integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@pagefind/default-ui@1.5.2':
+ resolution: {integrity: sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==}
+
+ '@pagefind/freebsd-x64@1.5.2':
+ resolution: {integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@pagefind/linux-arm64@1.5.2':
+ resolution: {integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@pagefind/linux-x64@1.5.2':
+ resolution: {integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@pagefind/windows-arm64@1.5.2':
+ resolution: {integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@pagefind/windows-x64@1.5.2':
+ resolution: {integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==}
+ cpu: [x64]
+ os: [win32]
+
+ '@poppinss/colors@4.1.6':
+ resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==}
+
+ '@poppinss/dumper@0.6.5':
+ resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==}
+
+ '@poppinss/exception@1.2.3':
+ resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==}
+
+ '@rolldown/binding-android-arm-eabi@1.2.15':
+ resolution: {integrity: sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [android]
+
+ '@rolldown/binding-android-arm64@1.2.15':
+ resolution: {integrity: sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@rolldown/binding-darwin-arm64@1.2.15':
+ resolution: {integrity: sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rolldown/binding-darwin-x64@1.2.15':
+ resolution: {integrity: sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rolldown/binding-freebsd-x64@1.2.15':
+ resolution: {integrity: sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.2.15':
+ resolution: {integrity: sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@rolldown/binding-linux-arm64-gnu@1.2.15':
+ resolution: {integrity: sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rolldown/binding-linux-arm64-musl@1.2.15':
+ resolution: {integrity: sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rolldown/binding-linux-ppc64-gnu@1.2.15':
+ resolution: {integrity: sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rolldown/binding-linux-s390x-gnu@1.2.15':
+ resolution: {integrity: sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rolldown/binding-linux-x64-gnu@1.2.15':
+ resolution: {integrity: sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@rolldown/binding-linux-x64-musl@1.2.15':
+ resolution: {integrity: sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@rolldown/binding-openharmony-arm64@1.2.15':
+ resolution: {integrity: sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rolldown/binding-win32-arm64-msvc@1.2.15':
+ resolution: {integrity: sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rolldown/binding-win32-x64-msvc@1.2.15':
+ resolution: {integrity: sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@rolldown/pluginutils@1.0.1':
+ resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
+
+ '@shikijs/core@4.5.0':
+ resolution: {integrity: sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-javascript@4.5.0':
+ resolution: {integrity: sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-oniguruma@4.5.0':
+ resolution: {integrity: sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/langs@4.5.0':
+ resolution: {integrity: sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==}
+ engines: {node: '>=20'}
+
+ '@shikijs/primitive@4.5.0':
+ resolution: {integrity: sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==}
+ engines: {node: '>=20'}
+
+ '@shikijs/themes@4.5.0':
+ resolution: {integrity: sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==}
+ engines: {node: '>=20'}
+
+ '@shikijs/types@4.5.0':
+ resolution: {integrity: sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/vscode-textmate@10.1.0':
+ resolution: {integrity: sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ==}
+
+ '@sindresorhus/is@7.2.0':
+ resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==}
+ engines: {node: '>=18'}
+
+ '@speed-highlight/core@1.2.24':
+ resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==}
+
+ '@tybys/wasm-util@0.10.4':
+ resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==}
+
+ '@types/debug@4.1.13':
+ resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
+
+ '@types/estree-jsx@1.0.5':
+ resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/hast@3.0.5':
+ resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==}
+
+ '@types/js-yaml@4.0.9':
+ resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdx@2.0.14':
+ resolution: {integrity: sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
+ '@types/nlcst@2.0.3':
+ resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
+
+ '@types/node@24.19.2':
+ resolution: {integrity: sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==}
+
+ '@types/sax@1.2.7':
+ resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
+
+ '@types/unist@2.0.11':
+ resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@ungap/structured-clone@1.4.0':
+ resolution: {integrity: sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==}
+
+ '@volar/kit@2.4.28':
+ resolution: {integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==}
+ peerDependencies:
+ typescript: '*'
+
+ '@volar/language-core@2.4.28':
+ resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==}
+
+ '@volar/language-server@2.4.28':
+ resolution: {integrity: sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==}
+
+ '@volar/language-service@2.4.28':
+ resolution: {integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==}
+
+ '@volar/source-map@2.4.28':
+ resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==}
+
+ '@volar/typescript@2.4.28':
+ resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==}
+
+ '@vscode/emmet-helper@2.11.0':
+ resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==}
+
+ '@vscode/l10n@0.0.18':
+ resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==}
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.19.0:
+ resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv-draft-04@1.0.0:
+ resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
+ peerDependencies:
+ ajv: ^8.5.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv-i18n@4.2.0:
+ resolution: {integrity: sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==}
+ peerDependencies:
+ ajv: ^8.0.0-beta.0
+
+ ajv@8.20.0:
+ resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+
+ am-i-vibing@0.5.0:
+ resolution: {integrity: sha512-KLcsDhqf1XRrJmJr+9I/C0EX2K+sGrAGZFgkmd84c8TJO9zJBu+/kFInjazu1KfJWFhWDKdRWkpBzEs7s35DVA==}
+ hasBin: true
+
+ ansi-regex@6.4.0:
+ resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==}
+ engines: {node: '>=12'}
+
+ ansi-styles@6.2.3:
+ resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
+ engines: {node: '>=12'}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-query@5.3.2:
+ resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
+ engines: {node: '>= 0.4'}
+
+ array-iterate@2.0.1:
+ resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
+
+ astring@1.9.0:
+ resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
+ hasBin: true
+
+ astro-expressive-code@0.44.3:
+ resolution: {integrity: sha512-LUpQmmvzr90JXP5QIAopgdjlOKLuT3x0wlPAUpc4OZtPtFS8sbflPcGPpL/lG3pQuUCQV2CXUFgYNBYNu9tphA==}
+ peerDependencies:
+ astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta || ^7.0.0
+
+ astro@7.4.2:
+ resolution: {integrity: sha512-FAH4cdDlFaVnQGjazLTEIC5vJqGlo5XANc1wIbzQHIqAjJTll/RWTUs+SPNW1JdezG4YGxMZllaE5A41T2kzhA==}
+ engines: {node: '>=22.23.4', npm: '>=9.6.5', pnpm: '>=7.1.0'}
+ hasBin: true
+ peerDependencies:
+ '@astrojs/markdown-remark': ^7.3.0
+ peerDependenciesMeta:
+ '@astrojs/markdown-remark':
+ optional: true
+
+ axobject-query@4.1.0:
+ resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
+ engines: {node: '>= 0.4'}
+
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
+ bcp-47-match@2.0.3:
+ resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==}
+
+ bcp-47@2.1.2:
+ resolution: {integrity: sha512-wsv86UuNFuPnVieKLyECTT+CP1WSAHeoIg5P3xu2kA9Z+7fVPoKt7dxzSeEhtJel0AI+NW3fIW3KtTKQKUCngg==}
+
+ blake3-wasm@2.1.5:
+ resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
+
+ boolbase@1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ character-reference-invalid@2.0.1:
+ resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
+
+ chokidar@5.0.0:
+ resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
+ engines: {node: '>= 20.19.0'}
+
+ ci-info@4.4.0:
+ resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==}
+ engines: {node: '>=8'}
+
+ cliui@9.0.1:
+ resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==}
+ engines: {node: '>=20'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ collapse-white-space@2.1.0:
+ resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ commander@11.1.0:
+ resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
+ engines: {node: '>=16'}
+
+ common-ancestor-path@2.0.0:
+ resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==}
+ engines: {node: '>= 18'}
+
+ cookie-es@1.2.3:
+ resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==}
+
+ cookie@1.1.1:
+ resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
+ engines: {node: '>=18'}
+
+ cookie@2.0.1:
+ resolution: {integrity: sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==}
+ engines: {node: '>=22'}
+
+ crossws@0.3.5:
+ resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
+
+ css-select@6.0.0:
+ resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==}
+
+ css-selector-parser@3.3.0:
+ resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==}
+
+ css-tree@2.2.1:
+ resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
+ css-tree@3.2.1:
+ resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
+ css-what@7.0.0:
+ resolution: {integrity: sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==}
+ engines: {node: '>= 6'}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csso@5.0.5:
+ resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decode-named-character-reference@1.3.0:
+ resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
+
+ defu@6.1.7:
+ resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ destr@2.0.5:
+ resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ devalue@6.0.3:
+ resolution: {integrity: sha512-3woMEITftG1wKeO/4d/QXH1DVKctTSZg3jNGPpjp9hNr5Hos8MCFF5McTML5ZtgKDObm2R591B0spRp2IVernA==}
+ engines: {node: '>=18'}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ diff@9.0.0:
+ resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==}
+ engines: {node: '>=0.3.1'}
+
+ direction@2.0.1:
+ resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==}
+ hasBin: true
+
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
+ domelementtype@2.3.0:
+ resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
+ domutils@3.2.2:
+ resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
+
+ dset@3.1.4:
+ resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==}
+ engines: {node: '>=4'}
+
+ emmet@2.4.11:
+ resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==}
+
+ emoji-regex@10.6.0:
+ resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ entities@6.0.1:
+ resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
+ engines: {node: '>=0.12'}
+
+ error-stack-parser-es@1.0.5:
+ resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
+
+ es-module-lexer@3.0.4:
+ resolution: {integrity: sha512-BldNY5mwkVu+cQ5Ymn3e6hB9Sx8XHx4ZevWbiUyZbfKxJxYO27Hf0wfzkxIaD5CAJMaGl3YspKELj0ff/7nCMA==}
+
+ esast-util-from-estree@2.0.0:
+ resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
+
+ esast-util-from-js@2.0.1:
+ resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==}
+
+ esbuild@0.28.2:
+ resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ estree-util-attach-comments@3.0.0:
+ resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
+
+ estree-util-build-jsx@3.0.1:
+ resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==}
+
+ estree-util-is-identifier-name@3.0.0:
+ resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
+
+ estree-util-scope@1.0.1:
+ resolution: {integrity: sha512-B0np3dcdxqILX5e9nEi5/Fr4K7gL4oYFVPV1zRa2e9wRCbQoZZNWOZFYyoInvXUPJXBXjss+QXlWLJChDEHDkA==}
+
+ estree-util-to-js@2.0.0:
+ resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==}
+
+ estree-util-visit@2.0.0:
+ resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ eventemitter3@5.0.4:
+ resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
+
+ expressive-code@0.44.3:
+ resolution: {integrity: sha512-7RGslhJTNt01pdn5I3QmVh5C8ZIiSm0A+ORQ9j9r39oOgJVKjn/7dXl9rMT/SqmFLE6pJkTYI7UjW0BxJnW7OQ==}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-string-truncated-width@3.0.3:
+ resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==}
+
+ fast-string-width@3.0.2:
+ resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==}
+
+ fast-uri@3.1.9:
+ resolution: {integrity: sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==}
+
+ fast-wrap-ansi@0.2.2:
+ resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ flattie@1.1.1:
+ resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
+ engines: {node: '>=8'}
+
+ fnv1a-64@0.1.2:
+ resolution: {integrity: sha512-mJbcILTPybAR1jdOwt/lVv8N2cffeJFFP+gVbSAwLEx1ujXH27RpPd8Rokec/KX9c76UYIB6Co+H4lQzxPnJfA==}
+
+ fontace@0.4.1:
+ resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==}
+
+ fontkitten@1.0.3:
+ resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==}
+ engines: {node: '>=20'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-east-asian-width@1.7.0:
+ resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==}
+ engines: {node: '>=18'}
+
+ get-tsconfig@5.0.0-beta.6:
+ resolution: {integrity: sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==}
+ engines: {node: '>=20.20.0'}
+
+ github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+
+ h3@1.15.11:
+ resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==}
+
+ hast-util-embedded@3.0.0:
+ resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==}
+
+ hast-util-format@1.1.0:
+ resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==}
+
+ hast-util-from-html@2.0.3:
+ resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
+
+ hast-util-from-parse5@8.0.3:
+ resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
+
+ hast-util-has-property@3.0.0:
+ resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==}
+
+ hast-util-is-body-ok-link@3.0.1:
+ resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==}
+
+ hast-util-is-element@3.0.0:
+ resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
+
+ hast-util-minify-whitespace@1.0.1:
+ resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==}
+
+ hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+
+ hast-util-phrasing@3.0.1:
+ resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==}
+
+ hast-util-raw@9.1.0:
+ resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
+
+ hast-util-select@6.0.4:
+ resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==}
+
+ hast-util-to-estree@3.1.3:
+ resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==}
+
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-to-jsx-runtime@2.3.6:
+ resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
+
+ hast-util-to-parse5@8.0.1:
+ resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
+
+ hast-util-to-string@3.0.1:
+ resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==}
+
+ hast-util-to-text@4.0.2:
+ resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hastscript@9.0.1:
+ resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
+
+ html-escaper@3.0.3:
+ resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ html-whitespace-sensitive-tag-names@3.0.1:
+ resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==}
+
+ http-cache-semantics@4.3.0:
+ resolution: {integrity: sha512-M5t5LlJpS1UHMjvwRQVdFHvPISGeLAxNcrWuJkeGh0KxsqCHZ1O3NXZU/8x7cD0BDcGW8kapxMKTvwlqrNkHkA==}
+
+ i18next@26.5.4:
+ resolution: {integrity: sha512-Wg0O1u2xmnsve9gICDwGekLkMe9SIC7+ZiuLYfWUGb/A3TQdRKygQ4OY9ros4raf5D66ZnW9JMrTDtGP2b8a7Q==}
+ peerDependencies:
+ typescript: ^5 || ^6 || ^7
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ inline-style-parser@0.2.7:
+ resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
+
+ iron-webcrypto@1.2.1:
+ resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
+
+ is-alphabetical@2.0.1:
+ resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+
+ is-alphanumerical@2.0.1:
+ resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
+
+ is-decimal@2.0.1:
+ resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+
+ is-docker@4.0.0:
+ resolution: {integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==}
+ engines: {node: '>=20'}
+ hasBin: true
+
+ is-hexadecimal@2.0.1:
+ resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ js-yaml@4.3.2:
+ resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==}
+ hasBin: true
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ jsonc-parser@2.3.1:
+ resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==}
+
+ jsonc-parser@3.3.1:
+ resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
+
+ kleur@4.1.5:
+ resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
+ engines: {node: '>=6'}
+
+ klona@2.0.6:
+ resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==}
+ engines: {node: '>= 8'}
+
+ lightningcss-android-arm64@1.33.0:
+ resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.33.0:
+ resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.33.0:
+ resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.33.0:
+ resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.33.0:
+ resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.33.0:
+ resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
+ engines: {node: '>= 12.0.0'}
+
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
+ lru-cache@11.5.3:
+ resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==}
+ engines: {node: 20 || >=22}
+
+ magic-string@1.4.3:
+ resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==}
+
+ magicast@0.5.5:
+ resolution: {integrity: sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==}
+
+ markdown-extensions@2.0.0:
+ resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
+ engines: {node: '>=16'}
+
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ mdast-util-definitions@6.0.0:
+ resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
+
+ mdast-util-directive@3.1.1:
+ resolution: {integrity: sha512-Gqpa3MHorXYEZ0VfbroyvBlVKUfz371V6mIERqOYMcb0W1D3LwmFq1ZW4O2TDrbn+4ZmGLwMWeFRJgYZ+bc5fQ==}
+
+ mdast-util-find-and-replace@3.0.3:
+ resolution: {integrity: sha512-xPgpDNl0/OXHsI7TlaIs22lWnH3KlpvZdXG1ET/m/YT2Hhdkx8lJV4kLphE6l9simyM4KPDFBwas08BgEob6Jw==}
+
+ mdast-util-from-markdown@2.1.0:
+ resolution: {integrity: sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
+
+ mdast-util-gfm-strikethrough@2.0.1:
+ resolution: {integrity: sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.1.0:
+ resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
+
+ mdast-util-mdx-expression@2.0.1:
+ resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
+
+ mdast-util-mdx-jsx@3.2.0:
+ resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
+
+ mdast-util-mdx@3.0.0:
+ resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==}
+
+ mdast-util-mdxjs-esm@2.0.1:
+ resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdast-util-to-markdown@2.2.0:
+ resolution: {integrity: sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ mdn-data@2.0.28:
+ resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
+
+ mdn-data@2.27.1:
+ resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
+
+ micromark-core-commonmark@2.0.4:
+ resolution: {integrity: sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==}
+
+ micromark-extension-directive@4.0.0:
+ resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==}
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.2:
+ resolution: {integrity: sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-extension-mdx-expression@3.0.1:
+ resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==}
+
+ micromark-extension-mdx-jsx@3.0.2:
+ resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==}
+
+ micromark-extension-mdx-md@2.0.0:
+ resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==}
+
+ micromark-extension-mdxjs-esm@3.0.0:
+ resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==}
+
+ micromark-extension-mdxjs@3.0.0:
+ resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-mdx-expression@2.0.3:
+ resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==}
+
+ micromark-factory-space@2.1.0:
+ resolution: {integrity: sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-edit-map@1.0.0:
+ resolution: {integrity: sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-events-to-acorn@2.0.3:
+ resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.3:
+ resolution: {integrity: sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==}
+
+ micromark@4.0.3:
+ resolution: {integrity: sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==}
+
+ miniflare@5.20261019.1-beta:
+ resolution: {integrity: sha512-1n7MN2UqZnPniyYAqNuV1YEAaja66ozKGVCc5ZTmYQhTubnoAwGLccwb+ZWYLOajuw3pOaJ70u//bZMuURlRew==}
+ engines: {node: '>=22.0.0'}
+
+ mrmime@2.0.1:
+ resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
+ engines: {node: '>=10'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.20:
+ resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ neotraverse@1.0.1:
+ resolution: {integrity: sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w==}
+ engines: {node: '>= 10'}
+
+ nlcst-to-string@4.0.0:
+ resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==}
+
+ node-fetch-native@1.6.7:
+ resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
+
+ node-mock-http@1.0.5:
+ resolution: {integrity: sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ nth-check@2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+
+ obug@3.0.0:
+ resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==}
+ engines: {node: '>=12.20.0'}
+
+ ofetch@1.5.1:
+ resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
+
+ oniguruma-parser@0.12.2:
+ resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==}
+
+ oniguruma-to-es@4.3.6:
+ resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==}
+
+ p-limit@7.3.3:
+ resolution: {integrity: sha512-SKgVvDU5TNIxQ4r30U75BNLC6a+6GOEjngrk/ysM5+Zu3oJuk1SC5ApzIzY/7PjCEjoVPMWJ0zho/4QUiEB7TQ==}
+ engines: {node: '>=20'}
+
+ p-queue@9.3.5:
+ resolution: {integrity: sha512-Lki/zhXFVmDhesBUn/yHRLW9Bte7mE7xoFHzTR8sIomV7a2z+LxYAPkGvdfidNiu4fKSfjtawixxSHcZci5QcQ==}
+ engines: {node: '>=20'}
+
+ p-timeout@7.0.2:
+ resolution: {integrity: sha512-prbX4Z3YszrFNgH+MW5Zoeq3baXrMtP/MQnFeET90UB/GtGcGDQ5Usg9OCy6ETjTTntOw1SL2z9fMPUppN3Guw==}
+ engines: {node: '>=20'}
+
+ package-manager-detector@1.9.0:
+ resolution: {integrity: sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==}
+
+ pagefind@1.5.2:
+ resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==}
+ hasBin: true
+
+ parse-entities@4.0.2:
+ resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
+
+ parse-latin@7.0.0:
+ resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
+
+ parse5@7.3.0:
+ resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ path-to-regexp@6.3.0:
+ resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ piccolore@0.1.3:
+ resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.2:
+ resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.7:
+ resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
+ engines: {node: '>=12'}
+
+ postcss-nested@7.0.2:
+ resolution: {integrity: sha512-5osppouFc0VR9/VYzYxO03VaDa3e8F23Kfd6/9qcZTUI8P58GIYlArOET2Wq0ywSl2o2PjELhYOFI4W7l5QHKw==}
+ engines: {node: '>=18.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@7.1.7:
+ resolution: {integrity: sha512-wWBro/7hJ40ye6TPiXkUQoXKCw23xSsjriUvqd7Uls9Sso3oLiON1flc18cCdnjgCRXw4fBVqUJJeOdDTh3P3g==}
+ engines: {node: '>=4'}
+
+ postcss@8.5.31:
+ resolution: {integrity: sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prettier@3.9.10:
+ resolution: {integrity: sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ prismjs@1.30.0:
+ resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
+ engines: {node: '>=6'}
+
+ process-ancestry@0.1.0:
+ resolution: {integrity: sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg==}
+ engines: {node: '>=18.0.0'}
+
+ property-information@7.2.0:
+ resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
+
+ radix3@1.1.2:
+ resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
+
+ readdirp@5.1.1:
+ resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==}
+ engines: {node: '>= 20.19.0'}
+
+ recma-build-jsx@1.0.0:
+ resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==}
+
+ recma-jsx@1.0.1:
+ resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ recma-parse@1.0.0:
+ resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==}
+
+ recma-stringify@1.0.0:
+ resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==}
+
+ regex-recursion@6.0.2:
+ resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
+
+ regex-utilities@2.3.0:
+ resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
+
+ regex@6.1.0:
+ resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
+
+ rehype-expressive-code@0.44.3:
+ resolution: {integrity: sha512-vaVuQPobFXvmtcHXQ5uqXZlzuuPnLyIuZcX/03sX1U/Qfj9fZrPYI9w66OSr/PUx6alzRYmreEwgYBbsVx8HsA==}
+
+ rehype-raw@7.0.0:
+ resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
+
+ rehype-recma@1.0.0:
+ resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==}
+
+ rehype-stringify@10.0.1:
+ resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==}
+
+ remark-directive@4.0.0:
+ resolution: {integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==}
+
+ remark-gfm@4.0.1:
+ resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
+
+ remark-mdx@3.1.1:
+ resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
+ remark-smartypants@3.0.3:
+ resolution: {integrity: sha512-gCaK+ndZ0hYezlqFegHFCVh2CQemsi0Npdh1qVM9bxlUFknjkbP6VmojWhddOCrbK0PbbacmYLWfTULRiT1eWA==}
+ engines: {node: '>=16.0.0'}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
+ request-light@0.5.8:
+ resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==}
+
+ request-light@0.7.0:
+ resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ retext-latin@4.0.0:
+ resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==}
+
+ retext-smartypants@6.2.0:
+ resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==}
+
+ retext-stringify@4.0.0:
+ resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==}
+
+ retext@9.0.0:
+ resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
+
+ rolldown@1.2.15:
+ resolution: {integrity: sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+
+ satteri@0.10.5:
+ resolution: {integrity: sha512-Ao1LKpAEa9Wdg0otgbVKViZHEq9ebdXe4DMrp3s9vQAU0HNIuHnFEuMuOcm0ZIXyV0Yzxj91NvhLpvXZJO/5ZQ==}
+
+ sax@1.6.1:
+ resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==}
+ engines: {node: '>=11.0.0'}
+
+ semver@7.8.5:
+ resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ sharp@0.35.5:
+ resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==}
+ engines: {node: '>=20.9.0'}
+ peerDependencies:
+ '@types/node': '*'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ shiki@4.5.0:
+ resolution: {integrity: sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==}
+ engines: {node: '>=20'}
+
+ sisteransi@1.0.5:
+ resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
+
+ sitemap@9.0.1:
+ resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==}
+ engines: {node: '>=20.19.5', npm: '>=10.8.2'}
+ hasBin: true
+
+ smol-toml@1.9.1:
+ resolution: {integrity: sha512-j7WyPdf0CJoutMzMoPLF/bVXHtKZIT9Rb4eGeEbWw8X2t5oirjPgpL+OpaENZrILYaXqYwnVH+qgUwVbl+pUJQ==}
+ engines: {node: '>= 18'}
+
+ source-map-js@1.2.2:
+ resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.7.6:
+ resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
+ engines: {node: '>= 12'}
+
+ source-map@0.8.0:
+ resolution: {integrity: sha512-d8EqvL+k/SOXCreS/SUzg2ciyHqBBLcN/yuRjFsbvVhHTE2pgei7oAhmPM7kWFbkX6OSMQfUq4KbkF3au9lhYQ==}
+ engines: {node: '>= 12'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ std-env@4.3.0:
+ resolution: {integrity: sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==}
+
+ string-width@7.2.0:
+ resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
+ engines: {node: '>=18'}
+
+ string-width@8.3.0:
+ resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==}
+ engines: {node: '>=20'}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ strip-ansi@7.2.0:
+ resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
+ engines: {node: '>=12'}
+
+ style-to-js@1.1.21:
+ resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
+
+ style-to-object@1.0.14:
+ resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
+
+ supports-color@10.2.2:
+ resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
+ engines: {node: '>=18'}
+
+ svgo@4.1.0:
+ resolution: {integrity: sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q==}
+ engines: {node: '>=16'}
+ hasBin: true
+
+ tiny-inflate@1.0.3:
+ resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
+
+ tinyclip@1.0.3:
+ resolution: {integrity: sha512-nTv2raKFMzGG6JJp0lpNDsRPdfFE6UHlu2rVEjXo8vkx1ZS3LW2CVXqIaLu8xZlu+6tbFs9V58Qc/Jmk/Ii7wA==}
+ engines: {node: ^16.14.0 || >= 17.3.0}
+
+ tinyexec@1.3.1:
+ resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ tinyps@0.5.1:
+ resolution: {integrity: sha512-B6Ykif5HflC3AdDkS4Zst/2muYVfeXoVMy+KorqH80s/1x4vunIORpNySH681X7fjj+dFM9MDKD6/Hsccjb87Q==}
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ typesafe-path@0.2.2:
+ resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==}
+
+ typescript-auto-import-cache@0.3.6:
+ resolution: {integrity: sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==}
+
+ typescript@6.0.3:
+ resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ ufo@1.6.4:
+ resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
+
+ ultrahtml@1.7.0:
+ resolution: {integrity: sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==}
+
+ uncrypto@0.1.3:
+ resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
+
+ undici-types@7.24.6:
+ resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==}
+
+ undici@7.29.1:
+ resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==}
+ engines: {node: '>=20.18.1'}
+
+ undici@8.12.3:
+ resolution: {integrity: sha512-+fdndUTwBP86cVjihTp21hZHo7d6oj1c/47XPA3lL8mM0XHs+C4EkcjmgRsFnFk2f/UONGDy9ItBItmXsLOQHw==}
+ engines: {node: '>=22.19.0'}
+
+ unenv@2.0.0-rc.24:
+ resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==}
+
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unifont@1.0.3:
+ resolution: {integrity: sha512-XGnEwj5sWdCbiBX01mWLSBncS0yMRjnLygau3IfdOlfjMacNIQvTGW4VH7pWBq+gGWArfSef/CensMLjMmIr/A==}
+
+ unist-util-find-after@5.0.0:
+ resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-modify-children@4.0.0:
+ resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==}
+
+ unist-util-position-from-estree@2.0.0:
+ resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-remove-position@5.0.0:
+ resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-children@3.0.0:
+ resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.1.0:
+ resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+
+ unstorage@1.17.6:
+ resolution: {integrity: sha512-gjKtcmn/KwZuJZO9o2sc0esAQnhmTw0LviDHwevTXbJMYs0dRTp8ZEEWXHU0vTpzbN3cA0yxlTeyXssMp3zDqw==}
+ peerDependencies:
+ '@azure/app-configuration': ^1.8.0
+ '@azure/cosmos': ^4.2.0
+ '@azure/data-tables': ^13.3.0
+ '@azure/identity': ^4.6.0
+ '@azure/keyvault-secrets': ^4.9.0
+ '@azure/storage-blob': ^12.26.0
+ '@capacitor/preferences': ^6 || ^7 || ^8
+ '@deno/kv': '>=0.9.0'
+ '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 || ^11.0.0
+ '@planetscale/database': ^1.19.0
+ '@upstash/redis': ^1.34.3
+ '@vercel/blob': '>=0.27.1'
+ '@vercel/functions': ^2.2.12 || ^3.0.0
+ '@vercel/kv': ^1 || ^2 || ^3
+ aws4fetch: ^1.0.20
+ db0: '>=0.2.1'
+ idb-keyval: ^6.2.1
+ ioredis: ^5.4.2
+ uploadthing: ^7.4.4
+ peerDependenciesMeta:
+ '@azure/app-configuration':
+ optional: true
+ '@azure/cosmos':
+ optional: true
+ '@azure/data-tables':
+ optional: true
+ '@azure/identity':
+ optional: true
+ '@azure/keyvault-secrets':
+ optional: true
+ '@azure/storage-blob':
+ optional: true
+ '@capacitor/preferences':
+ optional: true
+ '@deno/kv':
+ optional: true
+ '@netlify/blobs':
+ optional: true
+ '@planetscale/database':
+ optional: true
+ '@upstash/redis':
+ optional: true
+ '@vercel/blob':
+ optional: true
+ '@vercel/functions':
+ optional: true
+ '@vercel/kv':
+ optional: true
+ aws4fetch:
+ optional: true
+ db0:
+ optional: true
+ idb-keyval:
+ optional: true
+ ioredis:
+ optional: true
+ uploadthing:
+ optional: true
+
+ url-extras@0.1.0:
+ resolution: {integrity: sha512-8tzwTeXFPuX/5PHuCDQE5Dd9Ts4rwoq2t9aIT+HS4iAVpmj5l4Ao7Q+BuuFjvWRqrLswBhQDk8O96ZicgCqQqw==}
+ engines: {node: '>=20'}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ verkit@0.5.0:
+ resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==}
+ engines: {node: '>=18.12.0'}
+
+ vfile-location@5.0.3:
+ resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite@8.3.5:
+ resolution: {integrity: sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ '@vitejs/devtools': ^0.7.1 || ^0.8.0
+ esbuild: ^0.27.0 || ^0.28.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ '@vitejs/devtools':
+ optional: true
+ esbuild:
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitefu@1.1.3:
+ resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==}
+ peerDependencies:
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ vite:
+ optional: true
+
+ volar-service-css@0.0.71:
+ resolution: {integrity: sha512-wRRFt9BpjMKCazcgOh67MSjUjiWUCAh99DyYSDIOTuxaRjEtDC7PpB0k1Y1wbJIW/pVtMUSVbpPo3UGSm0Byxw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-emmet@0.0.71:
+ resolution: {integrity: sha512-zqjzt6bN95e3CUstBm0PBFAJnrfz0ZAARka87fart46/gNCLLuP3Vujy8V/J8HEziTFLnfkgIASLFYPUhonJcA==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-html@0.0.71:
+ resolution: {integrity: sha512-e8tHPhgQ7ooLfudAEIku+kgd9pWkq3SSz8RbnQDI1+Eb8wbenkLGHqoirLqz5ORLV6wIMr2Iv08RWBG5eOcgpw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-prettier@0.0.71:
+ resolution: {integrity: sha512-Rz7JVH3qD108UCdmIEiZvOBNljMt2nLFdbN8AXcDfn7xD9F5I2aCIsDVqBbXw21PsnxG0b7MfwtNF+zPS/NKUg==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ prettier: ^2.2 || ^3.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+ prettier:
+ optional: true
+
+ volar-service-typescript-twoslash-queries@0.0.71:
+ resolution: {integrity: sha512-9K2k72s4n7rV9s4bX0MyjbX9iBribvKZbBJKuEmTCZfeWJXs6Yh7bGpY4eoc7UufAjvpheBqwyZCOIPBvxCv0A==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-typescript@0.0.71:
+ resolution: {integrity: sha512-yTtM/BVT6hoyEYnDtaCyAtNhdNeS/mhTTABlBOdw3NNiRBUin3IznFJpgfjer4c6RYopiPjjQjc9VFhxVl1mLw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-yaml@0.0.71:
+ resolution: {integrity: sha512-qYGWGuVpUTnZGu5P/CR4KLK4aIR8RrcVnmfZ2eRcj9q/I8VZCoC5yy9FtEvfNvnDp4MU17yhdJcvpQPIqhJS2Q==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ vscode-css-languageservice@6.3.10:
+ resolution: {integrity: sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==}
+
+ vscode-html-languageservice@5.6.2:
+ resolution: {integrity: sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==}
+
+ vscode-json-languageservice@4.1.8:
+ resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==}
+ engines: {npm: '>=7.0.0'}
+
+ vscode-jsonrpc@8.2.0:
+ resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
+ engines: {node: '>=14.0.0'}
+
+ vscode-jsonrpc@9.0.3:
+ resolution: {integrity: sha512-qETYf9PCl1lVfwR+oBmMfc4vP2nqLNA35ABxorw3j06+xlKRgDVxbLgKm4Y/xPL0YWdeDjLoI4ImICIT3nB0zQ==}
+ engines: {node: '>=14.0.0'}
+
+ vscode-languageserver-protocol@3.17.5:
+ resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==}
+
+ vscode-languageserver-protocol@3.18.4:
+ resolution: {integrity: sha512-CCXbyr99dafRJzJH/0Ryk7ly5T8XPmSR0//OuF2w4m+9JiOin7zcAT5iET8GRE7Z9taFBejb3GbM0a0mbjdbrg==}
+
+ vscode-languageserver-textdocument@1.0.15:
+ resolution: {integrity: sha512-Gsfr9S8LU3S6885cS+NaleasJ0n3V5y/SOTqHCifQiXWFw3G9w9/YItDfwHrlCz+dSZWWZ8ilYVMcJe7Sz7Sxw==}
+
+ vscode-languageserver-types@3.17.5:
+ resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==}
+
+ vscode-languageserver-types@3.18.4:
+ resolution: {integrity: sha512-nQsacoiijvl0fRf2q28uFDrAVwRhdCa3QveiF7/CX0r18mLR5FU/1WskSsCKOjmEbtteKUnY8x8Yzxop+k0zwg==}
+
+ vscode-languageserver@9.0.1:
+ resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==}
+ hasBin: true
+
+ vscode-nls@5.2.0:
+ resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==}
+
+ vscode-uri@3.2.0:
+ resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==}
+
+ web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+
+ workerd@1.20261019.1:
+ resolution: {integrity: sha512-UUYRUq/7DmeCl11YriNbcVbjUZVLtt8uuCXFu+nz77hGFf8d4DEVXoCYtnA+MlBatE4+wxoj47DVqzK3xGBAiw==}
+ engines: {node: '>=16'}
+ hasBin: true
+
+ wrangler@4.151.3:
+ resolution: {integrity: sha512-mzPQLmkAhZUV7CdiAhE+hiIAJlS9xPL6vZe1B8oQFuWxFu7nmQnvHAVjcAcabwSGkXFXH9uspzXwHOFrfbQmqQ==}
+ engines: {node: '>=22.0.0'}
+ hasBin: true
+ peerDependencies:
+ '@cloudflare/workers-types': ^5.20261019.1
+ peerDependenciesMeta:
+ '@cloudflare/workers-types':
+ optional: true
+
+ wrap-ansi@9.0.2:
+ resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
+ engines: {node: '>=18'}
+
+ ws@8.21.0:
+ resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ xxhash-wasm@1.1.0:
+ resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yaml-language-server@1.23.0:
+ resolution: {integrity: sha512-3qVyCOexLCWw06PQa5kRPwvMWMZ/eZeCRWUvgD6a0OkqL/4iCnxy2WumbWifa937Uo5xhyWJ0uxlU39ljhNh7A==}
+ hasBin: true
+
+ yaml@2.8.3:
+ resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ yaml@2.9.1:
+ resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ yargs-parser@22.0.0:
+ resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=23}
+
+ yargs@18.2.0:
+ resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=23}
+
+ yocto-queue@1.2.2:
+ resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
+ engines: {node: '>=12.20'}
+
+ youch-core@0.3.3:
+ resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==}
+
+ youch@4.1.0-beta.10:
+ resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==}
+
+ zod@4.6.7:
+ resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==}
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@astrojs/astro2tsx@0.1.3(@emnapi/runtime@1.11.3)':
+ dependencies:
+ '@emnapi/core': 1.11.3
+ '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)
+ transitivePeerDependencies:
+ - '@emnapi/runtime'
+
+ '@astrojs/check@0.9.12(@emnapi/runtime@1.11.3)(prettier@3.9.10)(typescript@6.0.3)':
+ dependencies:
+ '@astrojs/language-server': 2.17.3(@emnapi/runtime@1.11.3)(prettier@3.9.10)(typescript@6.0.3)
+ chokidar: 5.0.0
+ kleur: 4.1.5
+ typescript: 6.0.3
+ yargs: 18.2.0
+ transitivePeerDependencies:
+ - '@emnapi/runtime'
+ - prettier
+ - prettier-plugin-astro
+
+ '@astrojs/compiler-binding-android-arm64@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-darwin-arm64@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-darwin-x64@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-linux-arm64-gnu@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-linux-arm64-musl@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-linux-x64-gnu@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-linux-x64-musl@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-wasm32-wasi@0.5.2':
+ dependencies:
+ '@emnapi/core': 1.11.3
+ '@emnapi/runtime': 1.11.3
+ '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)
+ optional: true
+
+ '@astrojs/compiler-binding-win32-arm64-msvc@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding-win32-x64-msvc@0.5.2':
+ optional: true
+
+ '@astrojs/compiler-binding@0.5.2':
+ optionalDependencies:
+ '@astrojs/compiler-binding-android-arm64': 0.5.2
+ '@astrojs/compiler-binding-darwin-arm64': 0.5.2
+ '@astrojs/compiler-binding-darwin-x64': 0.5.2
+ '@astrojs/compiler-binding-linux-arm64-gnu': 0.5.2
+ '@astrojs/compiler-binding-linux-arm64-musl': 0.5.2
+ '@astrojs/compiler-binding-linux-x64-gnu': 0.5.2
+ '@astrojs/compiler-binding-linux-x64-musl': 0.5.2
+ '@astrojs/compiler-binding-wasm32-wasi': 0.5.2
+ '@astrojs/compiler-binding-win32-arm64-msvc': 0.5.2
+ '@astrojs/compiler-binding-win32-x64-msvc': 0.5.2
+
+ '@astrojs/compiler-rs@0.5.2':
+ dependencies:
+ '@astrojs/compiler-binding': 0.5.2
+
+ '@astrojs/internal-helpers@0.13.0':
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ picomatch: 4.0.7
+ retext-smartypants: 6.2.0
+ shiki: 4.5.0
+ smol-toml: 1.9.1
+ unified: 11.0.5
+ yaml: 2.9.1
+
+ '@astrojs/language-server@2.17.3(@emnapi/runtime@1.11.3)(prettier@3.9.10)(typescript@6.0.3)':
+ dependencies:
+ '@astrojs/astro2tsx': 0.1.3(@emnapi/runtime@1.11.3)
+ '@astrojs/yaml2ts': 0.2.4
+ '@volar/kit': 2.4.28(typescript@6.0.3)
+ '@volar/language-core': 2.4.28
+ '@volar/language-server': 2.4.28
+ '@volar/language-service': 2.4.28
+ muggle-string: 0.4.1
+ tinyglobby: 0.2.17
+ volar-service-css: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-emmet: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-html: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-prettier: 0.0.71(@volar/language-service@2.4.28)(prettier@3.9.10)
+ volar-service-typescript: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-typescript-twoslash-queries: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-yaml: 0.0.71(@volar/language-service@2.4.28)
+ vscode-html-languageservice: 5.6.2
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ prettier: 3.9.10
+ transitivePeerDependencies:
+ - '@emnapi/runtime'
+ - typescript
+
+ '@astrojs/markdown-remark@7.3.4':
+ dependencies:
+ '@astrojs/internal-helpers': 0.13.0
+ '@astrojs/prism': 4.1.1
+ '@mdx-js/mdx': 3.1.1
+ acorn: 8.19.0
+ estree-util-visit: 2.0.0
+ github-slugger: 2.0.0
+ hast-util-from-html: 2.0.3
+ hast-util-to-html: 9.0.5
+ hast-util-to-text: 4.0.2
+ 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.3
+ source-map: 0.8.0
+ unified: 11.0.5
+ unist-util-remove-position: 5.0.0
+ unist-util-visit: 5.1.0
+ unist-util-visit-parents: 6.0.2
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@astrojs/markdown-satteri@0.4.5':
+ dependencies:
+ '@astrojs/internal-helpers': 0.13.0
+ '@astrojs/prism': 4.1.1
+ github-slugger: 2.0.0
+ satteri: 0.10.5
+
+ '@astrojs/mdx@8.1.1(@astrojs/markdown-remark@7.3.4)(@astrojs/markdown-satteri@0.4.5)(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))':
+ dependencies:
+ '@astrojs/internal-helpers': 0.13.0
+ '@astrojs/markdown-satteri': 0.4.5
+ astro: 7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)
+ es-module-lexer: 3.0.4
+ optionalDependencies:
+ '@astrojs/markdown-remark': 7.3.4
+
+ '@astrojs/prism@4.1.1':
+ dependencies:
+ prismjs: 1.30.0
+
+ '@astrojs/sitemap@3.7.4':
+ dependencies:
+ sitemap: 9.0.1
+ zod: 4.6.7
+
+ '@astrojs/starlight@0.42.6(@astrojs/markdown-remark@7.3.4)(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))(typescript@6.0.3)':
+ dependencies:
+ '@astrojs/markdown-satteri': 0.4.5
+ '@astrojs/mdx': 8.1.1(@astrojs/markdown-remark@7.3.4)(@astrojs/markdown-satteri@0.4.5)(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))
+ '@astrojs/sitemap': 3.7.4
+ '@pagefind/default-ui': 1.5.2
+ '@types/hast': 3.0.5
+ '@types/js-yaml': 4.0.9
+ '@types/mdast': 4.0.4
+ astro: 7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)
+ astro-expressive-code: 0.44.3(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))
+ bcp-47: 2.1.2
+ hast-util-format: 1.1.0
+ hast-util-select: 6.0.4
+ hast-util-to-html: 9.0.5
+ hast-util-to-string: 3.0.1
+ hastscript: 9.0.1
+ i18next: 26.5.4(typescript@6.0.3)
+ js-yaml: 4.3.2
+ klona: 2.0.6
+ magic-string: 1.4.3
+ mdast-util-directive: 3.1.1
+ mdast-util-to-markdown: 2.2.0
+ mdast-util-to-string: 4.0.0
+ pagefind: 1.5.2
+ remark-directive: 4.0.0
+ satteri: 0.10.5
+ ultrahtml: 1.7.0
+ unified: 11.0.5
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+ optionalDependencies:
+ '@astrojs/markdown-remark': 7.3.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@astrojs/telemetry@3.4.1':
+ dependencies:
+ ci-info: 4.4.0
+ dset: 3.1.4
+ is-docker: 4.0.0
+ package-manager-detector: 1.9.0
+
+ '@astrojs/yaml2ts@0.2.4':
+ dependencies:
+ yaml: 2.9.1
+
+ '@babel/helper-string-parser@7.29.7': {}
+
+ '@babel/helper-validator-identifier@7.29.7': {}
+
+ '@babel/parser@7.29.9':
+ dependencies:
+ '@babel/types': 7.29.8
+
+ '@babel/types@7.29.8':
+ dependencies:
+ '@babel/helper-string-parser': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
+
+ '@bruits/satteri-darwin-arm64@0.10.5':
+ optional: true
+
+ '@bruits/satteri-darwin-x64@0.10.5':
+ optional: true
+
+ '@bruits/satteri-linux-arm64-gnu@0.10.5':
+ optional: true
+
+ '@bruits/satteri-linux-arm64-musl@0.10.5':
+ optional: true
+
+ '@bruits/satteri-linux-x64-gnu@0.10.5':
+ optional: true
+
+ '@bruits/satteri-linux-x64-musl@0.10.5':
+ optional: true
+
+ '@bruits/satteri-wasm32-wasi@0.10.5':
+ dependencies:
+ '@emnapi/core': 1.11.1
+ '@emnapi/runtime': 1.11.1
+ '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)
+ optional: true
+
+ '@bruits/satteri-win32-arm64-msvc@0.10.5':
+ optional: true
+
+ '@bruits/satteri-win32-x64-msvc@0.10.5':
+ optional: true
+
+ '@capsizecss/unpack@4.0.1':
+ dependencies:
+ fontkitten: 1.0.3
+
+ '@clack/core@1.5.1':
+ dependencies:
+ fast-wrap-ansi: 0.2.2
+ sisteransi: 1.0.5
+
+ '@clack/prompts@1.8.1':
+ dependencies:
+ '@clack/core': 1.5.1
+ fast-string-width: 3.0.2
+ fast-wrap-ansi: 0.2.2
+ sisteransi: 1.0.5
+
+ '@cloudflare/kv-asset-handler@0.5.0': {}
+
+ '@cloudflare/unenv-preset@2.16.2(unenv@2.0.0-rc.24)(workerd@1.20261019.1)':
+ dependencies:
+ unenv: 2.0.0-rc.24
+ optionalDependencies:
+ workerd: 1.20261019.1
+
+ '@cloudflare/workerd-darwin-64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-darwin-arm64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-linux-64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-linux-arm64@1.20261019.1':
+ optional: true
+
+ '@cloudflare/workerd-windows-64@1.20261019.1':
+ optional: true
+
+ '@cspotcode/source-map-support@0.8.1':
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.9
+
+ '@ctrl/tinycolor@4.2.1': {}
+
+ '@emmetio/abbreviation@2.3.3':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-abbreviation@2.1.8':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-parser@0.4.1':
+ dependencies:
+ '@emmetio/stream-reader': 2.2.0
+ '@emmetio/stream-reader-utils': 0.1.0
+
+ '@emmetio/html-matcher@1.3.0':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/scanner@1.0.4': {}
+
+ '@emmetio/stream-reader-utils@0.1.0': {}
+
+ '@emmetio/stream-reader@2.2.0': {}
+
+ '@emnapi/core@1.11.1':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.2
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/core@1.11.3':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.3
+ tslib: 2.8.1
+
+ '@emnapi/runtime@1.11.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.11.3':
+ dependencies:
+ tslib: 2.8.1
+
+ '@emnapi/wasi-threads@1.2.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/wasi-threads@1.2.3':
+ dependencies:
+ tslib: 2.8.1
+
+ '@esbuild/aix-ppc64@0.28.2':
+ optional: true
+
+ '@esbuild/android-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/android-arm@0.28.2':
+ optional: true
+
+ '@esbuild/android-x64@0.28.2':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/darwin-x64@0.28.2':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.28.2':
+ optional: true
+
+ '@esbuild/linux-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/linux-arm@0.28.2':
+ optional: true
+
+ '@esbuild/linux-ia32@0.28.2':
+ optional: true
+
+ '@esbuild/linux-loong64@0.28.2':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.28.2':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.28.2':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.28.2':
+ optional: true
+
+ '@esbuild/linux-s390x@0.28.2':
+ optional: true
+
+ '@esbuild/linux-x64@0.28.2':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.28.2':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.28.2':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/sunos-x64@0.28.2':
+ optional: true
+
+ '@esbuild/win32-arm64@0.28.2':
+ optional: true
+
+ '@esbuild/win32-ia32@0.28.2':
+ optional: true
+
+ '@esbuild/win32-x64@0.28.2':
+ optional: true
+
+ '@expressive-code/core@0.44.3':
+ dependencies:
+ '@ctrl/tinycolor': 4.2.1
+ hast-util-select: 6.0.4
+ hast-util-to-html: 9.0.5
+ hast-util-to-text: 4.0.2
+ hastscript: 9.0.1
+ postcss: 8.5.31
+ postcss-nested: 7.0.2(postcss@8.5.31)
+ unist-util-visit: 5.1.0
+ unist-util-visit-parents: 6.0.2
+
+ '@expressive-code/plugin-frames@0.44.3':
+ dependencies:
+ '@expressive-code/core': 0.44.3
+
+ '@expressive-code/plugin-shiki@0.44.3':
+ dependencies:
+ '@expressive-code/core': 0.44.3
+ shiki: 4.5.0
+
+ '@expressive-code/plugin-text-markers@0.44.3':
+ dependencies:
+ '@expressive-code/core': 0.44.3
+
+ '@fontsource-variable/sora@5.3.0': {}
+
+ '@fontsource/geist-mono@5.3.0': {}
+
+ '@img/colour@1.1.0': {}
+
+ '@img/sharp-darwin-arm64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.3.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.3.4
+ optional: true
+
+ '@img/sharp-freebsd-wasm32@0.35.5':
+ dependencies:
+ '@img/sharp-wasm32': 0.35.5
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.3.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.3.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.3.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.3.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.3.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.3.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.3.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.3.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.3.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.35.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.3.4
+ optional: true
+
+ '@img/sharp-wasm32@0.35.5':
+ dependencies:
+ '@emnapi/runtime': 1.11.3
+ optional: true
+
+ '@img/sharp-webcontainers-wasm32@0.35.5':
+ dependencies:
+ '@img/sharp-wasm32': 0.35.5
+ optional: true
+
+ '@img/sharp-win32-arm64@0.35.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.35.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.35.5':
+ optional: true
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.6.0': {}
+
+ '@jridgewell/trace-mapping@0.3.9':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.6.0
+
+ '@lucide/astro@1.61.0(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))':
+ dependencies:
+ astro: 7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)
+
+ '@mdx-js/mdx@3.1.1':
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdx': 2.0.14
+ acorn: 8.19.0
+ collapse-white-space: 2.1.0
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ estree-util-scope: 1.0.1
+ estree-walker: 3.0.3
+ hast-util-to-jsx-runtime: 2.3.6
+ markdown-extensions: 2.0.0
+ recma-build-jsx: 1.0.0
+ recma-jsx: 1.0.1(acorn@8.19.0)
+ recma-stringify: 1.0.0
+ rehype-recma: 1.0.0
+ remark-mdx: 3.1.1
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.2
+ source-map: 0.7.6
+ unified: 11.0.5
+ unist-util-position-from-estree: 2.0.0
+ unist-util-stringify-position: 4.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@napi-rs/wasm-runtime@1.2.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)':
+ dependencies:
+ '@emnapi/core': 1.11.3
+ '@emnapi/runtime': 1.11.3
+ '@tybys/wasm-util': 0.10.4
+
+ '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)':
+ dependencies:
+ '@emnapi/core': 1.11.1
+ '@emnapi/runtime': 1.11.1
+ '@tybys/wasm-util': 0.10.4
+ optional: true
+
+ '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)':
+ dependencies:
+ '@emnapi/core': 1.11.3
+ '@emnapi/runtime': 1.11.3
+ '@tybys/wasm-util': 0.10.4
+ optional: true
+
+ '@oslojs/encoding@1.1.0': {}
+
+ '@oxc-project/types@0.155.0': {}
+
+ '@pagefind/darwin-arm64@1.5.2':
+ optional: true
+
+ '@pagefind/darwin-x64@1.5.2':
+ optional: true
+
+ '@pagefind/default-ui@1.5.2': {}
+
+ '@pagefind/freebsd-x64@1.5.2':
+ optional: true
+
+ '@pagefind/linux-arm64@1.5.2':
+ optional: true
+
+ '@pagefind/linux-x64@1.5.2':
+ optional: true
+
+ '@pagefind/windows-arm64@1.5.2':
+ optional: true
+
+ '@pagefind/windows-x64@1.5.2':
+ optional: true
+
+ '@poppinss/colors@4.1.6':
+ dependencies:
+ kleur: 4.1.5
+
+ '@poppinss/dumper@0.6.5':
+ dependencies:
+ '@poppinss/colors': 4.1.6
+ '@sindresorhus/is': 7.2.0
+ supports-color: 10.2.2
+
+ '@poppinss/exception@1.2.3': {}
+
+ '@rolldown/binding-android-arm-eabi@1.2.15':
+ optional: true
+
+ '@rolldown/binding-android-arm64@1.2.15':
+ optional: true
+
+ '@rolldown/binding-darwin-arm64@1.2.15':
+ optional: true
+
+ '@rolldown/binding-darwin-x64@1.2.15':
+ optional: true
+
+ '@rolldown/binding-freebsd-x64@1.2.15':
+ optional: true
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.2.15':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-gnu@1.2.15':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-musl@1.2.15':
+ optional: true
+
+ '@rolldown/binding-linux-ppc64-gnu@1.2.15':
+ optional: true
+
+ '@rolldown/binding-linux-s390x-gnu@1.2.15':
+ optional: true
+
+ '@rolldown/binding-linux-x64-gnu@1.2.15':
+ optional: true
+
+ '@rolldown/binding-linux-x64-musl@1.2.15':
+ optional: true
+
+ '@rolldown/binding-openharmony-arm64@1.2.15':
+ optional: true
+
+ '@rolldown/binding-win32-arm64-msvc@1.2.15':
+ optional: true
+
+ '@rolldown/binding-win32-x64-msvc@1.2.15':
+ optional: true
+
+ '@rolldown/pluginutils@1.0.1': {}
+
+ '@shikijs/core@4.5.0':
+ dependencies:
+ '@shikijs/primitive': 4.5.0
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
+ hast-util-to-html: 9.0.5
+
+ '@shikijs/engine-javascript@4.5.0':
+ dependencies:
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ oniguruma-to-es: 4.3.6
+
+ '@shikijs/engine-oniguruma@4.5.0':
+ dependencies:
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+
+ '@shikijs/langs@4.5.0':
+ dependencies:
+ '@shikijs/types': 4.5.0
+
+ '@shikijs/primitive@4.5.0':
+ dependencies:
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
+
+ '@shikijs/themes@4.5.0':
+ dependencies:
+ '@shikijs/types': 4.5.0
+
+ '@shikijs/types@4.5.0':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
+
+ '@shikijs/vscode-textmate@10.1.0': {}
+
+ '@sindresorhus/is@7.2.0': {}
+
+ '@speed-highlight/core@1.2.24': {}
+
+ '@tybys/wasm-util@0.10.4':
+ dependencies:
+ tslib: 2.8.1
+
+ '@types/debug@4.1.13':
+ dependencies:
+ '@types/ms': 2.1.0
+
+ '@types/estree-jsx@1.0.5':
+ dependencies:
+ '@types/estree': 1.0.9
+
+ '@types/estree@1.0.9': {}
+
+ '@types/hast@3.0.5':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/js-yaml@4.0.9': {}
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdx@2.0.14': {}
+
+ '@types/ms@2.1.0': {}
+
+ '@types/nlcst@2.0.3':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/node@24.19.2':
+ dependencies:
+ undici-types: 7.24.6
+
+ '@types/sax@1.2.7':
+ dependencies:
+ '@types/node': 24.19.2
+
+ '@types/unist@2.0.11': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@ungap/structured-clone@1.4.0': {}
+
+ '@volar/kit@2.4.28(typescript@6.0.3)':
+ dependencies:
+ '@volar/language-service': 2.4.28
+ '@volar/typescript': 2.4.28
+ typesafe-path: 0.2.2
+ typescript: 6.0.3
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-uri: 3.2.0
+
+ '@volar/language-core@2.4.28':
+ dependencies:
+ '@volar/source-map': 2.4.28
+
+ '@volar/language-server@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ '@volar/language-service': 2.4.28
+ '@volar/typescript': 2.4.28
+ path-browserify: 1.0.1
+ request-light: 0.7.0
+ vscode-languageserver: 9.0.1
+ vscode-languageserver-protocol: 3.18.4
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-uri: 3.2.0
+
+ '@volar/language-service@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ vscode-languageserver-protocol: 3.18.4
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-uri: 3.2.0
+
+ '@volar/source-map@2.4.28': {}
+
+ '@volar/typescript@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ path-browserify: 1.0.1
+ vscode-uri: 3.2.0
+
+ '@vscode/emmet-helper@2.11.0':
+ dependencies:
+ emmet: 2.4.11
+ jsonc-parser: 2.3.1
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-languageserver-types: 3.18.4
+ vscode-uri: 3.2.0
+
+ '@vscode/l10n@0.0.18': {}
+
+ acorn-jsx@5.3.2(acorn@8.19.0):
+ dependencies:
+ acorn: 8.19.0
+
+ acorn@8.19.0: {}
+
+ ajv-draft-04@1.0.0(ajv@8.20.0):
+ optionalDependencies:
+ ajv: 8.20.0
+
+ ajv-i18n@4.2.0(ajv@8.20.0):
+ dependencies:
+ ajv: 8.20.0
+
+ ajv@8.20.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.9
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ am-i-vibing@0.5.0:
+ dependencies:
+ process-ancestry: 0.1.0
+
+ ansi-regex@6.4.0: {}
+
+ ansi-styles@6.2.3: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.2
+
+ arg@5.0.2: {}
+
+ argparse@2.0.1: {}
+
+ aria-query@5.3.2: {}
+
+ array-iterate@2.0.1: {}
+
+ astring@1.9.0: {}
+
+ astro-expressive-code@0.44.3(astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)):
+ dependencies:
+ astro: 7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)
+ rehype-expressive-code: 0.44.3
+ url-extras: 0.1.0
+
+ astro@7.4.2(@astrojs/markdown-remark@7.3.4)(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1):
+ dependencies:
+ '@astrojs/compiler-rs': 0.5.2
+ '@astrojs/internal-helpers': 0.13.0
+ '@astrojs/markdown-satteri': 0.4.5
+ '@astrojs/telemetry': 3.4.1
+ '@capsizecss/unpack': 4.0.1
+ '@clack/prompts': 1.8.1
+ '@oslojs/encoding': 1.1.0
+ am-i-vibing: 0.5.0
+ aria-query: 5.3.2
+ axobject-query: 4.1.0
+ ci-info: 4.4.0
+ clsx: 2.1.1
+ common-ancestor-path: 2.0.0
+ cookie: 2.0.1
+ devalue: 6.0.3
+ diff: 9.0.0
+ dset: 3.1.4
+ es-module-lexer: 3.0.4
+ flattie: 1.1.1
+ fontace: 0.4.1
+ get-tsconfig: 5.0.0-beta.6
+ github-slugger: 2.0.0
+ html-escaper: 3.0.3
+ http-cache-semantics: 4.3.0
+ jsonc-parser: 3.3.1
+ magic-string: 1.4.3
+ magicast: 0.5.5
+ mrmime: 2.0.1
+ neotraverse: 1.0.1
+ obug: 3.0.0
+ p-limit: 7.3.3
+ p-queue: 9.3.5
+ package-manager-detector: 1.9.0
+ piccolore: 0.1.3
+ picomatch: 4.0.7
+ rolldown: 1.2.15
+ shiki: 4.5.0
+ smol-toml: 1.9.1
+ svgo: 4.1.0
+ tinyclip: 1.0.3
+ tinyexec: 1.3.1
+ tinyglobby: 0.2.17
+ tinyps: 0.5.1
+ ultrahtml: 1.7.0
+ unifont: 1.0.3
+ unstorage: 1.17.6
+ verkit: 0.5.0
+ vite: 8.3.5(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)
+ vitefu: 1.1.3(vite@8.3.5(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1))
+ xxhash-wasm: 1.1.0
+ yargs-parser: 22.0.0
+ zod: 4.6.7
+ optionalDependencies:
+ '@astrojs/markdown-remark': 7.3.4
+ sharp: 0.35.5(@types/node@24.19.2)
+ transitivePeerDependencies:
+ - '@azure/app-configuration'
+ - '@azure/cosmos'
+ - '@azure/data-tables'
+ - '@azure/identity'
+ - '@azure/keyvault-secrets'
+ - '@azure/storage-blob'
+ - '@capacitor/preferences'
+ - '@deno/kv'
+ - '@netlify/blobs'
+ - '@planetscale/database'
+ - '@types/node'
+ - '@upstash/redis'
+ - '@vercel/blob'
+ - '@vercel/functions'
+ - '@vercel/kv'
+ - '@vitejs/devtools'
+ - aws4fetch
+ - db0
+ - esbuild
+ - idb-keyval
+ - ioredis
+ - jiti
+ - less
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - terser
+ - tsx
+ - uploadthing
+ - yaml
+
+ axobject-query@4.1.0: {}
+
+ bail@2.0.2: {}
+
+ bcp-47-match@2.0.3: {}
+
+ bcp-47@2.1.2:
+ dependencies:
+ is-alphabetical: 2.0.1
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+
+ blake3-wasm@2.1.5: {}
+
+ boolbase@1.0.0: {}
+
+ ccount@2.0.1: {}
+
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ character-reference-invalid@2.0.1: {}
+
+ chokidar@5.0.0:
+ dependencies:
+ readdirp: 5.1.1
+
+ ci-info@4.4.0: {}
+
+ cliui@9.0.1:
+ dependencies:
+ string-width: 7.2.0
+ strip-ansi: 7.2.0
+ wrap-ansi: 9.0.2
+
+ clsx@2.1.1: {}
+
+ collapse-white-space@2.1.0: {}
+
+ comma-separated-tokens@2.0.3: {}
+
+ commander@11.1.0: {}
+
+ common-ancestor-path@2.0.0: {}
+
+ cookie-es@1.2.3: {}
+
+ cookie@1.1.1: {}
+
+ cookie@2.0.1: {}
+
+ crossws@0.3.5:
+ dependencies:
+ uncrypto: 0.1.3
+
+ css-select@6.0.0:
+ dependencies:
+ boolbase: 1.0.0
+ css-what: 7.0.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ nth-check: 2.1.1
+
+ css-selector-parser@3.3.0: {}
+
+ css-tree@2.2.1:
+ dependencies:
+ mdn-data: 2.0.28
+ source-map-js: 1.2.2
+
+ css-tree@3.2.1:
+ dependencies:
+ mdn-data: 2.27.1
+ source-map-js: 1.2.2
+
+ css-what@7.0.0: {}
+
+ cssesc@3.0.0: {}
+
+ csso@5.0.5:
+ dependencies:
+ css-tree: 2.2.1
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ decode-named-character-reference@1.3.0:
+ dependencies:
+ character-entities: 2.0.2
+
+ defu@6.1.7: {}
+
+ dequal@2.0.3: {}
+
+ destr@2.0.5: {}
+
+ detect-libc@2.1.2: {}
+
+ devalue@6.0.3: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ diff@9.0.0: {}
+
+ direction@2.0.1: {}
+
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
+ domelementtype@2.3.0: {}
+
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
+ domutils@3.2.2:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
+ dset@3.1.4: {}
+
+ emmet@2.4.11:
+ dependencies:
+ '@emmetio/abbreviation': 2.3.3
+ '@emmetio/css-abbreviation': 2.1.8
+
+ emoji-regex@10.6.0: {}
+
+ entities@4.5.0: {}
+
+ entities@6.0.1: {}
+
+ error-stack-parser-es@1.0.5: {}
+
+ es-module-lexer@3.0.4: {}
+
+ esast-util-from-estree@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ devlop: 1.1.0
+ estree-util-visit: 2.0.0
+ unist-util-position-from-estree: 2.0.0
+
+ esast-util-from-js@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ acorn: 8.19.0
+ esast-util-from-estree: 2.0.0
+ vfile-message: 4.0.3
+
+ esbuild@0.28.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.28.2
+ '@esbuild/android-arm': 0.28.2
+ '@esbuild/android-arm64': 0.28.2
+ '@esbuild/android-x64': 0.28.2
+ '@esbuild/darwin-arm64': 0.28.2
+ '@esbuild/darwin-x64': 0.28.2
+ '@esbuild/freebsd-arm64': 0.28.2
+ '@esbuild/freebsd-x64': 0.28.2
+ '@esbuild/linux-arm': 0.28.2
+ '@esbuild/linux-arm64': 0.28.2
+ '@esbuild/linux-ia32': 0.28.2
+ '@esbuild/linux-loong64': 0.28.2
+ '@esbuild/linux-mips64el': 0.28.2
+ '@esbuild/linux-ppc64': 0.28.2
+ '@esbuild/linux-riscv64': 0.28.2
+ '@esbuild/linux-s390x': 0.28.2
+ '@esbuild/linux-x64': 0.28.2
+ '@esbuild/netbsd-arm64': 0.28.2
+ '@esbuild/netbsd-x64': 0.28.2
+ '@esbuild/openbsd-arm64': 0.28.2
+ '@esbuild/openbsd-x64': 0.28.2
+ '@esbuild/openharmony-arm64': 0.28.2
+ '@esbuild/sunos-x64': 0.28.2
+ '@esbuild/win32-arm64': 0.28.2
+ '@esbuild/win32-ia32': 0.28.2
+ '@esbuild/win32-x64': 0.28.2
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@5.0.0: {}
+
+ estree-util-attach-comments@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+
+ estree-util-build-jsx@3.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ estree-walker: 3.0.3
+
+ estree-util-is-identifier-name@3.0.0: {}
+
+ estree-util-scope@1.0.1:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+
+ estree-util-to-js@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ astring: 1.9.0
+ source-map: 0.7.6
+
+ estree-util-visit@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/unist': 3.0.3
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+
+ eventemitter3@5.0.4: {}
+
+ expressive-code@0.44.3:
+ dependencies:
+ '@expressive-code/core': 0.44.3
+ '@expressive-code/plugin-frames': 0.44.3
+ '@expressive-code/plugin-shiki': 0.44.3
+ '@expressive-code/plugin-text-markers': 0.44.3
+
+ extend@3.0.2: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-string-truncated-width@3.0.3: {}
+
+ fast-string-width@3.0.2:
+ dependencies:
+ fast-string-truncated-width: 3.0.3
+
+ fast-uri@3.1.9: {}
+
+ fast-wrap-ansi@0.2.2:
+ dependencies:
+ fast-string-width: 3.0.2
+
+ fdir@6.5.0(picomatch@4.0.7):
+ optionalDependencies:
+ picomatch: 4.0.7
+
+ flattie@1.1.1: {}
+
+ fnv1a-64@0.1.2: {}
+
+ fontace@0.4.1:
+ dependencies:
+ fontkitten: 1.0.3
+
+ fontkitten@1.0.3:
+ dependencies:
+ tiny-inflate: 1.0.3
+
+ fsevents@2.3.3:
+ optional: true
+
+ get-caller-file@2.0.5: {}
+
+ get-east-asian-width@1.7.0: {}
+
+ get-tsconfig@5.0.0-beta.6:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+
+ github-slugger@2.0.0: {}
+
+ h3@1.15.11:
+ dependencies:
+ cookie-es: 1.2.3
+ crossws: 0.3.5
+ defu: 6.1.7
+ destr: 2.0.5
+ iron-webcrypto: 1.2.1
+ node-mock-http: 1.0.5
+ radix3: 1.1.2
+ ufo: 1.6.4
+ uncrypto: 0.1.3
+
+ hast-util-embedded@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+ hast-util-is-element: 3.0.0
+
+ hast-util-format@1.1.0:
+ dependencies:
+ '@types/hast': 3.0.5
+ hast-util-embedded: 3.0.0
+ hast-util-minify-whitespace: 1.0.1
+ hast-util-phrasing: 3.0.1
+ hast-util-whitespace: 3.0.0
+ html-whitespace-sensitive-tag-names: 3.0.1
+ unist-util-visit-parents: 6.0.2
+
+ hast-util-from-html@2.0.3:
+ dependencies:
+ '@types/hast': 3.0.5
+ devlop: 1.1.0
+ hast-util-from-parse5: 8.0.3
+ parse5: 7.3.0
+ vfile: 6.0.3
+ vfile-message: 4.0.3
+
+ hast-util-from-parse5@8.0.3:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ hastscript: 9.0.1
+ property-information: 7.2.0
+ vfile: 6.0.3
+ vfile-location: 5.0.3
+ web-namespaces: 2.0.1
+
+ hast-util-has-property@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hast-util-is-body-ok-link@3.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hast-util-is-element@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hast-util-minify-whitespace@1.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ hast-util-embedded: 3.0.0
+ hast-util-is-element: 3.0.0
+ hast-util-whitespace: 3.0.0
+ unist-util-is: 6.0.1
+
+ hast-util-parse-selector@4.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hast-util-phrasing@3.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ hast-util-embedded: 3.0.0
+ hast-util-has-property: 3.0.0
+ hast-util-is-body-ok-link: 3.0.1
+ hast-util-is-element: 3.0.0
+
+ hast-util-raw@9.1.0:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ '@ungap/structured-clone': 1.4.0
+ hast-util-from-parse5: 8.0.3
+ hast-util-to-parse5: 8.0.1
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ parse5: 7.3.0
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-select@6.0.4:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ bcp-47-match: 2.0.3
+ comma-separated-tokens: 2.0.3
+ css-selector-parser: 3.3.0
+ devlop: 1.1.0
+ direction: 2.0.1
+ hast-util-has-property: 3.0.0
+ hast-util-to-string: 3.0.1
+ hast-util-whitespace: 3.0.0
+ nth-check: 2.1.1
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ unist-util-visit: 5.1.0
+ zwitch: 2.0.4
+
+ hast-util-to-estree@3.1.3:
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.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.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.21
+ unist-util-position: 5.0.0
+ zwitch: 2.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-to-html@9.0.5:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-to-jsx-runtime@2.3.6:
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.21
+ unist-util-position: 5.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-to-parse5@8.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-to-string@3.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hast-util-to-text@4.0.2:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/unist': 3.0.3
+ hast-util-is-element: 3.0.0
+ unist-util-find-after: 5.0.0
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+
+ hastscript@9.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+
+ html-escaper@3.0.3: {}
+
+ html-void-elements@3.0.0: {}
+
+ html-whitespace-sensitive-tag-names@3.0.1: {}
+
+ http-cache-semantics@4.3.0: {}
+
+ i18next@26.5.4(typescript@6.0.3):
+ optionalDependencies:
+ typescript: 6.0.3
+
+ inline-style-parser@0.2.7: {}
+
+ iron-webcrypto@1.2.1: {}
+
+ is-alphabetical@2.0.1: {}
+
+ is-alphanumerical@2.0.1:
+ dependencies:
+ is-alphabetical: 2.0.1
+ is-decimal: 2.0.1
+
+ is-decimal@2.0.1: {}
+
+ is-docker@4.0.0: {}
+
+ is-hexadecimal@2.0.1: {}
+
+ is-plain-obj@4.1.0: {}
+
+ js-yaml@4.3.2:
+ dependencies:
+ argparse: 2.0.1
+
+ json-schema-traverse@1.0.0: {}
+
+ jsonc-parser@2.3.1: {}
+
+ jsonc-parser@3.3.1: {}
+
+ kleur@4.1.5: {}
+
+ klona@2.0.6: {}
+
+ lightningcss-android-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.33.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.33.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ optional: true
+
+ lightningcss@1.33.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.33.0
+ lightningcss-darwin-arm64: 1.33.0
+ lightningcss-darwin-x64: 1.33.0
+ lightningcss-freebsd-x64: 1.33.0
+ lightningcss-linux-arm-gnueabihf: 1.33.0
+ lightningcss-linux-arm64-gnu: 1.33.0
+ lightningcss-linux-arm64-musl: 1.33.0
+ lightningcss-linux-x64-gnu: 1.33.0
+ lightningcss-linux-x64-musl: 1.33.0
+ lightningcss-win32-arm64-msvc: 1.33.0
+ lightningcss-win32-x64-msvc: 1.33.0
+
+ longest-streak@3.1.0: {}
+
+ lru-cache@11.5.3: {}
+
+ magic-string@1.4.3:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.6.0
+
+ magicast@0.5.5:
+ dependencies:
+ '@babel/parser': 7.29.9
+ '@babel/types': 7.29.8
+ source-map-js: 1.2.2
+
+ markdown-extensions@2.0.0: {}
+
+ markdown-table@3.0.4: {}
+
+ mdast-util-definitions@6.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.1.0
+
+ mdast-util-directive@3.1.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ micromark-util-character: 2.1.1
+ parse-entities: 4.0.2
+ stringify-entities: 4.0.4
+ unist-util-visit-parents: 6.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-find-and-replace@3.0.3:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ mdast-util-from-markdown@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.3
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.3
+ micromark-util-character: 2.1.1
+
+ mdast-util-gfm-footnote@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ micromark-util-normalize-identifier: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-strikethrough@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-table@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.4
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm@3.1.0:
+ dependencies:
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.1.0
+ mdast-util-gfm-strikethrough: 2.0.1
+ mdast-util-gfm-table: 2.0.0
+ mdast-util-gfm-task-list-item: 2.0.0
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-expression@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-jsx@3.2.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ parse-entities: 4.0.2
+ stringify-entities: 4.0.4
+ unist-util-stringify-position: 4.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx@3.0.0:
+ dependencies:
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdxjs-esm@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.1.0
+ mdast-util-to-markdown: 2.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.4.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.2.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-character: 2.1.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ unist-util-visit: 5.1.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ mdn-data@2.0.28: {}
+
+ mdn-data@2.27.1: {}
+
+ micromark-core-commonmark@2.0.4:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.1.0
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-edit-map: 1.0.0
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-directive@4.0.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.1.0
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ parse-entities: 4.0.2
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.4
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-table@2.1.2:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.2
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-mdx-expression@3.0.1:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ micromark-factory-mdx-expression: 2.0.3
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-extension-mdx-jsx@3.0.2:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ micromark-factory-mdx-expression: 2.0.3
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ vfile-message: 4.0.3
+
+ micromark-extension-mdx-md@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.3
+
+ micromark-extension-mdxjs-esm@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.4
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.3
+
+ micromark-extension-mdxjs@3.0.0:
+ dependencies:
+ acorn: 8.19.0
+ acorn-jsx: 5.3.2(acorn@8.19.0)
+ micromark-extension-mdx-expression: 3.0.1
+ micromark-extension-mdx-jsx: 3.0.2
+ micromark-extension-mdx-md: 2.0.0
+ micromark-extension-mdxjs-esm: 3.0.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-factory-label@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-factory-mdx-expression@2.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+ devlop: 1.1.0
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.3
+
+ micromark-factory-space@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.3
+
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-factory-whitespace@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-classify-character@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-util-combine-extensions@2.0.1:
+ dependencies:
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-edit-map@1.0.0:
+ dependencies:
+ micromark-util-types: 2.0.3
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-events-to-acorn@2.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ estree-util-visit: 2.0.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ vfile-message: 4.0.3
+
+ micromark-util-html-tag-name@2.0.1: {}
+
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.3
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-subtokenize@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.3: {}
+
+ micromark@4.0.3:
+ dependencies:
+ '@types/debug': 4.1.13
+ debug: 4.4.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.4
+ micromark-factory-space: 2.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-edit-map: 1.0.0
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ miniflare@5.20261019.1-beta(@types/node@24.19.2):
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ sharp: 0.35.5(@types/node@24.19.2)
+ undici: 7.29.1
+ workerd: 1.20261019.1
+ ws: 8.21.0
+ youch: 4.1.0-beta.10
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
+
+ mrmime@2.0.1: {}
+
+ ms@2.1.3: {}
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.20: {}
+
+ neotraverse@1.0.1: {}
+
+ nlcst-to-string@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+
+ node-fetch-native@1.6.7: {}
+
+ node-mock-http@1.0.5: {}
+
+ normalize-path@3.0.0: {}
+
+ nth-check@2.1.1:
+ dependencies:
+ boolbase: 1.0.0
+
+ obug@3.0.0: {}
+
+ ofetch@1.5.1:
+ dependencies:
+ destr: 2.0.5
+ node-fetch-native: 1.6.7
+ ufo: 1.6.4
+
+ oniguruma-parser@0.12.2: {}
+
+ oniguruma-to-es@4.3.6:
+ dependencies:
+ oniguruma-parser: 0.12.2
+ regex: 6.1.0
+ regex-recursion: 6.0.2
+
+ p-limit@7.3.3:
+ dependencies:
+ yocto-queue: 1.2.2
+
+ p-queue@9.3.5:
+ dependencies:
+ eventemitter3: 5.0.4
+ p-timeout: 7.0.2
+
+ p-timeout@7.0.2: {}
+
+ package-manager-detector@1.9.0: {}
+
+ pagefind@1.5.2:
+ optionalDependencies:
+ '@pagefind/darwin-arm64': 1.5.2
+ '@pagefind/darwin-x64': 1.5.2
+ '@pagefind/freebsd-x64': 1.5.2
+ '@pagefind/linux-arm64': 1.5.2
+ '@pagefind/linux-x64': 1.5.2
+ '@pagefind/windows-arm64': 1.5.2
+ '@pagefind/windows-x64': 1.5.2
+
+ parse-entities@4.0.2:
+ dependencies:
+ '@types/unist': 2.0.11
+ character-entities-legacy: 3.0.0
+ character-reference-invalid: 2.0.1
+ decode-named-character-reference: 1.3.0
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+ is-hexadecimal: 2.0.1
+
+ parse-latin@7.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ '@types/unist': 3.0.3
+ nlcst-to-string: 4.0.0
+ unist-util-modify-children: 4.0.0
+ unist-util-visit-children: 3.0.0
+ vfile: 6.0.3
+
+ parse5@7.3.0:
+ dependencies:
+ entities: 6.0.1
+
+ path-browserify@1.0.1: {}
+
+ path-to-regexp@6.3.0: {}
+
+ pathe@2.0.3: {}
+
+ piccolore@0.1.3: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.2: {}
+
+ picomatch@4.0.7: {}
+
+ postcss-nested@7.0.2(postcss@8.5.31):
+ dependencies:
+ postcss: 8.5.31
+ postcss-selector-parser: 7.1.7
+
+ postcss-selector-parser@7.1.7:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss@8.5.31:
+ dependencies:
+ nanoid: 3.3.20
+ picocolors: 1.1.1
+ source-map-js: 1.2.2
+
+ prettier@3.9.10: {}
+
+ prismjs@1.30.0: {}
+
+ process-ancestry@0.1.0: {}
+
+ property-information@7.2.0: {}
+
+ radix3@1.1.2: {}
+
+ readdirp@5.1.1: {}
+
+ recma-build-jsx@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ estree-util-build-jsx: 3.0.1
+ vfile: 6.0.3
+
+ recma-jsx@1.0.1(acorn@8.19.0):
+ dependencies:
+ acorn: 8.19.0
+ acorn-jsx: 5.3.2(acorn@8.19.0)
+ estree-util-to-js: 2.0.0
+ recma-parse: 1.0.0
+ recma-stringify: 1.0.0
+ unified: 11.0.5
+
+ recma-parse@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ esast-util-from-js: 2.0.1
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ recma-stringify@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ estree-util-to-js: 2.0.0
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ regex-recursion@6.0.2:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ regex-utilities@2.3.0: {}
+
+ regex@6.1.0:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ rehype-expressive-code@0.44.3:
+ dependencies:
+ expressive-code: 0.44.3
+
+ rehype-raw@7.0.0:
+ dependencies:
+ '@types/hast': 3.0.5
+ hast-util-raw: 9.1.0
+ vfile: 6.0.3
+
+ rehype-recma@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ '@types/hast': 3.0.5
+ hast-util-to-estree: 3.1.3
+ transitivePeerDependencies:
+ - supports-color
+
+ rehype-stringify@10.0.1:
+ dependencies:
+ '@types/hast': 3.0.5
+ hast-util-to-html: 9.0.5
+ unified: 11.0.5
+
+ remark-directive@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-directive: 3.1.1
+ micromark-extension-directive: 4.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-gfm@4.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.1.0
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-mdx@3.1.1:
+ dependencies:
+ mdast-util-mdx: 3.0.0
+ micromark-extension-mdxjs: 3.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.1.0
+ micromark-util-types: 2.0.3
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.1
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ remark-smartypants@3.0.3:
+ dependencies:
+ retext: 9.0.0
+ retext-smartypants: 6.2.0
+ unified: 11.0.5
+ unist-util-visit: 5.1.0
+
+ remark-stringify@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.2.0
+ unified: 11.0.5
+
+ request-light@0.5.8: {}
+
+ request-light@0.7.0: {}
+
+ require-from-string@2.0.2: {}
+
+ resolve-pkg-maps@1.0.0: {}
+
+ retext-latin@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ parse-latin: 7.0.0
+ unified: 11.0.5
+
+ retext-smartypants@6.2.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ nlcst-to-string: 4.0.0
+ unist-util-visit: 5.1.0
+
+ retext-stringify@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ nlcst-to-string: 4.0.0
+ unified: 11.0.5
+
+ retext@9.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ retext-latin: 4.0.0
+ retext-stringify: 4.0.0
+ unified: 11.0.5
+
+ rolldown@1.2.15:
+ dependencies:
+ '@oxc-project/types': 0.155.0
+ '@rolldown/pluginutils': 1.0.1
+ optionalDependencies:
+ '@rolldown/binding-android-arm-eabi': 1.2.15
+ '@rolldown/binding-android-arm64': 1.2.15
+ '@rolldown/binding-darwin-arm64': 1.2.15
+ '@rolldown/binding-darwin-x64': 1.2.15
+ '@rolldown/binding-freebsd-x64': 1.2.15
+ '@rolldown/binding-linux-arm-gnueabihf': 1.2.15
+ '@rolldown/binding-linux-arm64-gnu': 1.2.15
+ '@rolldown/binding-linux-arm64-musl': 1.2.15
+ '@rolldown/binding-linux-ppc64-gnu': 1.2.15
+ '@rolldown/binding-linux-s390x-gnu': 1.2.15
+ '@rolldown/binding-linux-x64-gnu': 1.2.15
+ '@rolldown/binding-linux-x64-musl': 1.2.15
+ '@rolldown/binding-openharmony-arm64': 1.2.15
+ '@rolldown/binding-win32-arm64-msvc': 1.2.15
+ '@rolldown/binding-win32-x64-msvc': 1.2.15
+
+ satteri@0.10.5:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.5
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ optionalDependencies:
+ '@bruits/satteri-darwin-arm64': 0.10.5
+ '@bruits/satteri-darwin-x64': 0.10.5
+ '@bruits/satteri-linux-arm64-gnu': 0.10.5
+ '@bruits/satteri-linux-arm64-musl': 0.10.5
+ '@bruits/satteri-linux-x64-gnu': 0.10.5
+ '@bruits/satteri-linux-x64-musl': 0.10.5
+ '@bruits/satteri-wasm32-wasi': 0.10.5
+ '@bruits/satteri-win32-arm64-msvc': 0.10.5
+ '@bruits/satteri-win32-x64-msvc': 0.10.5
+
+ sax@1.6.1: {}
+
+ semver@7.8.5: {}
+
+ sharp@0.35.5(@types/node@24.19.2):
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.5
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.35.5
+ '@img/sharp-darwin-x64': 0.35.5
+ '@img/sharp-freebsd-wasm32': 0.35.5
+ '@img/sharp-libvips-darwin-arm64': 1.3.4
+ '@img/sharp-libvips-darwin-x64': 1.3.4
+ '@img/sharp-libvips-linux-arm': 1.3.4
+ '@img/sharp-libvips-linux-arm64': 1.3.4
+ '@img/sharp-libvips-linux-ppc64': 1.3.4
+ '@img/sharp-libvips-linux-riscv64': 1.3.4
+ '@img/sharp-libvips-linux-s390x': 1.3.4
+ '@img/sharp-libvips-linux-x64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.3.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.3.4
+ '@img/sharp-linux-arm': 0.35.5
+ '@img/sharp-linux-arm64': 0.35.5
+ '@img/sharp-linux-ppc64': 0.35.5
+ '@img/sharp-linux-riscv64': 0.35.5
+ '@img/sharp-linux-s390x': 0.35.5
+ '@img/sharp-linux-x64': 0.35.5
+ '@img/sharp-linuxmusl-arm64': 0.35.5
+ '@img/sharp-linuxmusl-x64': 0.35.5
+ '@img/sharp-webcontainers-wasm32': 0.35.5
+ '@img/sharp-win32-arm64': 0.35.5
+ '@img/sharp-win32-ia32': 0.35.5
+ '@img/sharp-win32-x64': 0.35.5
+ '@types/node': 24.19.2
+
+ shiki@4.5.0:
+ dependencies:
+ '@shikijs/core': 4.5.0
+ '@shikijs/engine-javascript': 4.5.0
+ '@shikijs/engine-oniguruma': 4.5.0
+ '@shikijs/langs': 4.5.0
+ '@shikijs/themes': 4.5.0
+ '@shikijs/types': 4.5.0
+ '@shikijs/vscode-textmate': 10.1.0
+ '@types/hast': 3.0.5
+
+ sisteransi@1.0.5: {}
+
+ sitemap@9.0.1:
+ dependencies:
+ '@types/node': 24.19.2
+ '@types/sax': 1.2.7
+ arg: 5.0.2
+ sax: 1.6.1
+
+ smol-toml@1.9.1: {}
+
+ source-map-js@1.2.2: {}
+
+ source-map@0.7.6: {}
+
+ source-map@0.8.0: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ std-env@4.3.0: {}
+
+ string-width@7.2.0:
+ dependencies:
+ emoji-regex: 10.6.0
+ get-east-asian-width: 1.7.0
+ strip-ansi: 7.2.0
+
+ string-width@8.3.0:
+ dependencies:
+ get-east-asian-width: 1.7.0
+ strip-ansi: 7.2.0
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ strip-ansi@7.2.0:
+ dependencies:
+ ansi-regex: 6.4.0
+
+ style-to-js@1.1.21:
+ dependencies:
+ style-to-object: 1.0.14
+
+ style-to-object@1.0.14:
+ dependencies:
+ inline-style-parser: 0.2.7
+
+ supports-color@10.2.2: {}
+
+ svgo@4.1.0:
+ dependencies:
+ commander: 11.1.0
+ css-select: 6.0.0
+ css-tree: 3.2.1
+ css-what: 7.0.0
+ csso: 5.0.5
+ picocolors: 1.1.1
+ sax: 1.6.1
+
+ tiny-inflate@1.0.3: {}
+
+ tinyclip@1.0.3: {}
+
+ tinyexec@1.3.1: {}
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.7)
+ picomatch: 4.0.7
+
+ tinyps@0.5.1: {}
+
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
+ tslib@2.8.1: {}
+
+ typesafe-path@0.2.2: {}
+
+ typescript-auto-import-cache@0.3.6:
+ dependencies:
+ semver: 7.8.5
+
+ typescript@6.0.3: {}
+
+ ufo@1.6.4: {}
+
+ ultrahtml@1.7.0: {}
+
+ uncrypto@0.1.3: {}
+
+ undici-types@7.24.6: {}
+
+ undici@7.29.1: {}
+
+ undici@8.12.3: {}
+
+ unenv@2.0.0-rc.24:
+ dependencies:
+ pathe: 2.0.3
+
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unifont@1.0.3:
+ dependencies:
+ css-tree: 3.2.1
+ fnv1a-64: 0.1.2
+ std-env: 4.3.0
+ undici: 8.12.3
+
+ unist-util-find-after@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-modify-children@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ array-iterate: 2.0.1
+
+ unist-util-position-from-estree@2.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-remove-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.1.0
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-children@3.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ unstorage@1.17.6:
+ dependencies:
+ anymatch: 3.1.3
+ chokidar: 5.0.0
+ destr: 2.0.5
+ h3: 1.15.11
+ lru-cache: 11.5.3
+ node-fetch-native: 1.6.7
+ ofetch: 1.5.1
+ ufo: 1.6.4
+
+ url-extras@0.1.0: {}
+
+ util-deprecate@1.0.2: {}
+
+ verkit@0.5.0: {}
+
+ vfile-location@5.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile: 6.0.3
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ vite@8.3.5(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1):
+ dependencies:
+ lightningcss: 1.33.0
+ picomatch: 4.0.7
+ postcss: 8.5.31
+ rolldown: 1.2.15
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 24.19.2
+ esbuild: 0.28.2
+ fsevents: 2.3.3
+ yaml: 2.9.1
+
+ vitefu@1.1.3(vite@8.3.5(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)):
+ optionalDependencies:
+ vite: 8.3.5(@types/node@24.19.2)(esbuild@0.28.2)(yaml@2.9.1)
+
+ volar-service-css@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-css-languageservice: 6.3.10
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-emmet@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ '@emmetio/css-parser': 0.4.1
+ '@emmetio/html-matcher': 1.3.0
+ '@vscode/emmet-helper': 2.11.0
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-html@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-html-languageservice: 5.6.2
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-prettier@0.0.71(@volar/language-service@2.4.28)(prettier@3.9.10):
+ dependencies:
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+ prettier: 3.9.10
+
+ volar-service-typescript-twoslash-queries@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-typescript@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ path-browserify: 1.0.1
+ semver: 7.8.5
+ typescript-auto-import-cache: 0.3.6
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-nls: 5.2.0
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-yaml@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-uri: 3.2.0
+ yaml-language-server: 1.23.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ vscode-css-languageservice@6.3.10:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.2.0
+
+ vscode-html-languageservice@5.6.2:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-languageserver-types: 3.18.4
+ vscode-uri: 3.2.0
+
+ vscode-json-languageservice@4.1.8:
+ dependencies:
+ jsonc-parser: 3.3.1
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-languageserver-types: 3.18.4
+ vscode-nls: 5.2.0
+ vscode-uri: 3.2.0
+
+ vscode-jsonrpc@8.2.0: {}
+
+ vscode-jsonrpc@9.0.3: {}
+
+ vscode-languageserver-protocol@3.17.5:
+ dependencies:
+ vscode-jsonrpc: 8.2.0
+ vscode-languageserver-types: 3.17.5
+
+ vscode-languageserver-protocol@3.18.4:
+ dependencies:
+ vscode-jsonrpc: 9.0.3
+ vscode-languageserver-types: 3.18.4
+
+ vscode-languageserver-textdocument@1.0.15: {}
+
+ vscode-languageserver-types@3.17.5: {}
+
+ vscode-languageserver-types@3.18.4: {}
+
+ vscode-languageserver@9.0.1:
+ dependencies:
+ vscode-languageserver-protocol: 3.17.5
+
+ vscode-nls@5.2.0: {}
+
+ vscode-uri@3.2.0: {}
+
+ web-namespaces@2.0.1: {}
+
+ workerd@1.20261019.1:
+ optionalDependencies:
+ '@cloudflare/workerd-darwin-64': 1.20261019.1
+ '@cloudflare/workerd-darwin-arm64': 1.20261019.1
+ '@cloudflare/workerd-linux-64': 1.20261019.1
+ '@cloudflare/workerd-linux-arm64': 1.20261019.1
+ '@cloudflare/workerd-windows-64': 1.20261019.1
+
+ wrangler@4.151.3(@types/node@24.19.2):
+ dependencies:
+ '@cloudflare/kv-asset-handler': 0.5.0
+ '@cloudflare/unenv-preset': 2.16.2(unenv@2.0.0-rc.24)(workerd@1.20261019.1)
+ blake3-wasm: 2.1.5
+ esbuild: 0.28.2
+ miniflare: 5.20261019.1-beta(@types/node@24.19.2)
+ path-to-regexp: 6.3.0
+ unenv: 2.0.0-rc.24
+ workerd: 1.20261019.1
+ optionalDependencies:
+ fsevents: 2.3.3
+ transitivePeerDependencies:
+ - '@types/node'
+ - bufferutil
+ - utf-8-validate
+
+ wrap-ansi@9.0.2:
+ dependencies:
+ ansi-styles: 6.2.3
+ string-width: 7.2.0
+ strip-ansi: 7.2.0
+
+ ws@8.21.0: {}
+
+ xxhash-wasm@1.1.0: {}
+
+ y18n@5.0.8: {}
+
+ yaml-language-server@1.23.0:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ ajv: 8.20.0
+ ajv-draft-04: 1.0.0(ajv@8.20.0)
+ ajv-i18n: 4.2.0(ajv@8.20.0)
+ prettier: 3.9.10
+ request-light: 0.5.8
+ vscode-json-languageservice: 4.1.8
+ vscode-languageserver: 9.0.1
+ vscode-languageserver-textdocument: 1.0.15
+ vscode-languageserver-types: 3.18.4
+ vscode-uri: 3.2.0
+ yaml: 2.8.3
+
+ yaml@2.8.3: {}
+
+ yaml@2.9.1: {}
+
+ yargs-parser@22.0.0: {}
+
+ yargs@18.2.0:
+ dependencies:
+ cliui: 9.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ string-width: 8.3.0
+ y18n: 5.0.8
+ yargs-parser: 22.0.0
+
+ yocto-queue@1.2.2: {}
+
+ youch-core@0.3.3:
+ dependencies:
+ '@poppinss/exception': 1.2.3
+ error-stack-parser-es: 1.0.5
+
+ youch@4.1.0-beta.10:
+ dependencies:
+ '@poppinss/colors': 4.1.6
+ '@poppinss/dumper': 0.6.5
+ '@speed-highlight/core': 1.2.24
+ cookie: 1.1.1
+ youch-core: 0.3.3
+
+ zod@4.6.7: {}
+
+ zwitch@2.0.4: {}
diff --git a/site/public/_headers b/site/public/_headers
new file mode 100644
index 0000000..8ea6cad
--- /dev/null
+++ b/site/public/_headers
@@ -0,0 +1,8 @@
+# Cloudflare static asset headers (https://developers.cloudflare.com/workers/static-assets/headers/).
+# Astro fingerprints everything in /_astro/, so it can be cached forever.
+/_astro/*
+ Cache-Control: public, max-age=31536000, immutable
+
+/*
+ X-Content-Type-Options: nosniff
+ Referrer-Policy: strict-origin-when-cross-origin
diff --git a/site/public/favicon.svg b/site/public/favicon.svg
new file mode 100644
index 0000000..668241d
--- /dev/null
+++ b/site/public/favicon.svg
@@ -0,0 +1 @@
+
diff --git a/site/public/og.png b/site/public/og.png
new file mode 100644
index 0000000..f46ac62
Binary files /dev/null and b/site/public/og.png differ
diff --git a/site/public/robots.txt b/site/public/robots.txt
new file mode 100644
index 0000000..e51a616
--- /dev/null
+++ b/site/public/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+
+Sitemap: https://durable.wavezync.com/sitemap-index.xml
diff --git a/site/src/assets/logo.svg b/site/src/assets/logo.svg
new file mode 100644
index 0000000..f2c2673
--- /dev/null
+++ b/site/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/site/src/assets/wavezync-mark.png b/site/src/assets/wavezync-mark.png
new file mode 100644
index 0000000..0cbf0a8
Binary files /dev/null and b/site/src/assets/wavezync-mark.png differ
diff --git a/site/src/assets/wavezync-wordmark.png b/site/src/assets/wavezync-wordmark.png
new file mode 100644
index 0000000..a63780a
Binary files /dev/null and b/site/src/assets/wavezync-wordmark.png differ
diff --git a/site/src/changelog.ts b/site/src/changelog.ts
new file mode 100644
index 0000000..e9b318f
--- /dev/null
+++ b/site/src/changelog.ts
@@ -0,0 +1,88 @@
+// The CHANGELOG.md files are git-cliff output (see cliff.toml): a "## version - date"
+// heading per release, "### Features"-style groups, and a commit link on every
+// entry. This Sätteri plugin keeps the text and reshapes the markup into a release
+// timeline (styled in styles/theme.css): a version heading with its date, a Latest
+// or Pre-release badge and a compare link; colored groups; quiet commit chips.
+
+const GROUPS: Record = {
+ Features: 'feat',
+ 'Bug fixes': 'fix',
+ Performance: 'perf',
+ Refactoring: 'refactor',
+ Documentation: 'docs',
+};
+const COMMIT = /\/commit\/[0-9a-f]{7,40}$/;
+
+type Node = { type: string; url?: string; value?: string; depth?: number; children?: Node[] };
+type Ctx = {
+ fileURL?: URL;
+ data: Record;
+ textContent(node: Node): string;
+ setProperty(node: Node, key: 'data', value: object): void;
+ replaceNode(node: Node, next: object | object[]): void;
+ removeNode(node: Node): void;
+ parent(node: Node): { children: Node[] } | undefined;
+ indexOf(node: Node): number | undefined;
+};
+
+const text = (value: string) => ({ type: 'text', value });
+const el = (tag: string, className: string[], children: object[], props: Record = {}) => ({
+ type: 'changelog',
+ data: { hName: tag, hProperties: { className, ...props } },
+ children,
+});
+const inChangelog = (ctx: Ctx) => !!ctx.fileURL?.pathname.endsWith('/CHANGELOG.md');
+const isCommit = (n?: Node) => n?.type === 'link' && COMMIT.test(n.url ?? '');
+const day = (iso: string) =>
+ new Date(`${iso}T00:00:00Z`).toLocaleDateString('en', { month: 'short', day: 'numeric', year: 'numeric', timeZone: 'UTC' });
+
+// "[1.0.0](…/compare/durable-v0.1.0-rc...durable-v1.0.0) - 2026-10-21", "0.1.0-rc - 2026-06-24" or "Unreleased".
+function release(node: Node, ctx: Ctx) {
+ const [, version, date] = /^(.+?)(?: - (\d{4}-\d{2}-\d{2}))?$/.exec(ctx.textContent(node))!;
+ const compare = node.children?.find((c) => c.type === 'link')?.url;
+ const since = compare && /compare\/(.+?)\.\.\./.exec(compare)?.[1].split('-v').pop();
+ // The first dated release on the page is the newest one.
+ const latest = !!date && !ctx.data.sawRelease;
+ if (date) ctx.data.sawRelease = true;
+
+ const meta = [
+ date ? el('time', ['cl-date'], [text(day(date))], { dateTime: date }) : el('span', ['cl-date'], [text('Not released yet')]),
+ latest && el('span', ['cl-badge', 'cl-latest'], [text('Latest')]),
+ version.includes('-') && el('span', ['cl-badge', 'cl-pre'], [text('Pre-release')]),
+ since && { type: 'link', url: compare, data: { hProperties: { className: ['cl-compare'] } }, children: [text(`Changes since ${since}`)] },
+ ].filter(Boolean) as object[];
+
+ ctx.replaceNode(node, [
+ { type: 'heading', depth: 2, data: { hProperties: { className: ['cl-version'] } }, children: [text(version)] },
+ el('div', ['cl-meta'], meta),
+ ]);
+}
+
+export const changelog = {
+ name: 'changelog',
+ heading(node: Node, ctx: Ctx) {
+ if (!inChangelog(ctx)) return;
+ if (node.depth === 2) return release(node, ctx);
+ const kind = node.depth === 3 && GROUPS[ctx.textContent(node)];
+ if (kind) ctx.setProperty(node, 'data', { hProperties: { className: ['cl-group', `cl-${kind}`] } });
+ },
+ link(node: Node, ctx: Ctx) {
+ if (!inChangelog(ctx) || !isCommit(node)) return;
+ const hash = ctx.textContent(node);
+ ctx.setProperty(node, 'data', { hProperties: { className: ['cl-commit'], ariaLabel: `Commit ${hash} on GitHub` } });
+ },
+ // The chip replaces the parentheses around the commit link.
+ text(node: Node, ctx: Ctx) {
+ if (!inChangelog(ctx)) return;
+ const kids = ctx.parent(node)?.children ?? [];
+ const i = ctx.indexOf(node) ?? -1;
+ const value = node.value ?? '';
+ if (value.endsWith(' (') && isCommit(kids[i + 1])) ctx.replaceNode(node, text(value.slice(0, -1)));
+ else if (value === ')' && isCommit(kids[i - 1])) ctx.removeNode(node);
+ },
+ strong(node: Node, ctx: Ctx) {
+ if (inChangelog(ctx) && ctx.textContent(node) === 'Breaking:') {
+ ctx.replaceNode(node, el('span', ['cl-badge', 'cl-breaking'], [text('Breaking')]));
+ }
+ },
+};
diff --git a/site/src/code-theme.ts b/site/src/code-theme.ts
new file mode 100644
index 0000000..be9be63
--- /dev/null
+++ b/site/src/code-theme.ts
@@ -0,0 +1,50 @@
+// Code colors for the Night look. Used by the run simulator and as the dark
+// Expressive Code theme in the docs.
+import type { ShikiConfig } from '@astrojs/markdown-remark';
+
+type ShikiTransformer = NonNullable[number];
+
+const FG = '#cdd7ed';
+const CALL = '#7cc4ff';
+
+export const night = {
+ name: 'durable-night',
+ type: 'dark' as const,
+ colors: { 'editor.background': '#0d1426', 'editor.foreground': FG },
+ tokenColors: [
+ { scope: ['comment', 'punctuation.definition.comment', 'comment.block.documentation'], settings: { foreground: '#677593', fontStyle: 'italic' } },
+ { scope: ['keyword', 'storage', 'keyword.control', 'keyword.operator', 'punctuation.section.embedded'], settings: { foreground: '#ff86ad' } },
+ { scope: ['punctuation', 'meta.module.elixir punctuation.separator'], settings: { foreground: '#8390ab' } },
+ { scope: ['string', 'punctuation.definition.string'], settings: { foreground: '#b8e38a' } },
+ { scope: ['string meta.embedded source'], settings: { foreground: FG } },
+ { scope: ['constant.other.symbol', 'constant.other.symbol punctuation.definition.constant'], settings: { foreground: '#5fd4c4' } },
+ { scope: ['constant.other.keywords', 'constant.other.keywords punctuation.definition.constant', 'variable.other.readwrite.module'], settings: { foreground: '#a9c1ff' } },
+ { scope: ['constant.numeric', 'constant.language'], settings: { foreground: '#ff9e6b' } },
+ { scope: ['entity.name.type', 'entity.other.inherited-class', 'variable.other.constant', 'support.type'], settings: { foreground: '#ffc27a' } },
+ { scope: ['entity.name.function', 'support.function', 'variable.function'], settings: { foreground: CALL } },
+ { scope: ['comment.wildcard'], settings: { foreground: '#8390ab', fontStyle: '' } },
+ ],
+};
+
+// Elixir's grammar leaves calls without parentheses untagged, so Durable's DSL
+// (`workflow "x" do`, `step :charge, ...`) would read like plain variables.
+// Color a bare call at the start of a line as a call. Only touches Night tokens.
+export const macroCalls: ShikiTransformer = {
+ name: 'elixir-macro-calls',
+ tokens(lines) {
+ if (this.options.lang !== 'elixir') return;
+ return lines.map((line) => {
+ const m = /^(\s*)([a-z_]\w*[?!]?) (?=[:"'%{[@a-z])/.exec(line.map((t) => t.content).join(''));
+ const t = line[0];
+ if (!m || !t || t.color?.toLowerCase() !== FG || t.content.length < m[0].length - 1) return line;
+ const [indent, word] = [m[1], m[2]];
+ const rest = t.content.slice(indent.length + word.length);
+ return [
+ ...(indent ? [{ ...t, content: indent }] : []),
+ { ...t, content: word, offset: t.offset + indent.length, color: CALL },
+ ...(rest ? [{ ...t, content: rest, offset: t.offset + indent.length + word.length }] : []),
+ ...line.slice(1),
+ ];
+ });
+ },
+};
diff --git a/site/src/components/AgentDemo.astro b/site/src/components/AgentDemo.astro
new file mode 100644
index 0000000..f1c3b1b
--- /dev/null
+++ b/site/src/components/AgentDemo.astro
@@ -0,0 +1,428 @@
+---
+// "Ship agents that finish the job": each outcome is a tab that plays a short,
+// scripted run of the agent below, so the claim is shown rather than told.
+import { Code } from 'astro:components';
+import { PiggyBank, UserCheck, RefreshCw, Eye, Lightbulb, FileDiff, FlaskConical, GitMerge, Sparkles, Check, Zap } from '@lucide/astro';
+import { macroCalls, night } from '../code-theme';
+
+// Written for this page; every call in it is real API.
+const code = `workflow "fix_issue", timeout: days(14) do
+ step :plan, [retry: [max_attempts: 3, backoff: :exponential]], fn ctx ->
+ plan = ReqLLM.generate_text!(@model, "Plan a fix for: #{ctx["issue"]}")
+ {:ok, assign(ctx, :plan, plan)}
+ end
+
+ step :write_patch, [retry: [max_attempts: 3]], fn ctx ->
+ patch = ReqLLM.generate_text!(@model, ctx.plan)
+ {:ok, assign(ctx, :patch, patch)}
+ end
+
+ step :run_tests, [retry: [max_attempts: 5]], fn ctx ->
+ {:ok, run} = CI.run(ctx["repo"], ctx.patch)
+ {:ok, assign(ctx, :ci_url, run.url)}
+ end
+
+ step :await_review, fn ctx ->
+ decision = wait_for_approval("maintainer", timeout: days(7))
+ {:ok, assign(ctx, :decision, decision)}
+ end
+
+ step :merge, fn ctx ->
+ GitHub.merge(ctx["repo"], ctx.patch)
+ {:ok, ctx}
+ end
+end`;
+
+const outcomes = [
+ { id: 'crash', icon: PiggyBank, title: 'Crashes cost nothing', text: 'Each LLM and tool call is a step whose result is saved. After a crash or a deploy, the agent resumes at the next step and never pays for a finished call twice.' },
+ { id: 'approval', icon: UserCheck, title: 'Approvals can take a week', text: 'The agent waits on a person with wait_for_approval/2. It holds no process while it waits, then carries on with its full context.' },
+ { id: 'flaky', icon: RefreshCw, title: 'Flaky tools stop being your problem', text: 'Rate limits and timeouts are retried with backoff, step by step, without restarting the whole run.' },
+ { id: 'inspect', icon: Eye, title: 'You can see every move', text: "The dashboard shows each step's input, output and timing, so you know exactly what the agent did and why." },
+];
+// The workflow's graph. `llm` marks the steps that call a model (and cost money).
+const steps = [
+ { id: 'plan', icon: Lightbulb, llm: true },
+ { id: 'write_patch', icon: FileDiff, llm: true },
+ { id: 'run_tests', icon: FlaskConical },
+ { id: 'await_review', icon: UserCheck },
+ { id: 'merge', icon: GitMerge },
+];
+---
+
+
+
+ {outcomes.map((o, i) => (
+
+
+ {o.title} {o.text}
+
+
+ ))}
+
+
Build an AI workflow , step by step, in the guide.
+
+
+
+
+
+ issue_agent.ex
+ LLM cost $0.00
+
+
+
+ {steps.map((s, i) => (
+
+ {i > 0 && }
+
+
+
+ {s.llm && }
+
+
+
+ {/* Narrow cards wrap names at the underscore. */}
+ {s.id.split('_').map((part, j, all) => (j < all.length - 1 ? <>{part}_ > : part))}
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
diff --git a/site/src/components/DashboardShowcase.astro b/site/src/components/DashboardShowcase.astro
new file mode 100644
index 0000000..7a0e31a
--- /dev/null
+++ b/site/src/components/DashboardShowcase.astro
@@ -0,0 +1,264 @@
+---
+// An illustration of durable_dashboard. The sidebar switches views (and they
+// cycle on their own until someone clicks). Example data, real page structure.
+import { LayoutDashboard, ListTree, Workflow, Inbox, Layers, CalendarClock, ChartLine, Search, RotateCcw, Ban, Pause, Play } from '@lucide/astro';
+
+const nav = [
+ { view: null, icon: LayoutDashboard, label: 'Overview' },
+ { view: 'runs', icon: ListTree, label: 'Runs' },
+ { view: null, icon: Workflow, label: 'Workflows' },
+ { view: 'inbox', icon: Inbox, label: 'Inbox', badge: 3 },
+ { view: 'queues', icon: Layers, label: 'Queues' },
+ { view: null, icon: CalendarClock, label: 'Schedules' },
+ { view: null, icon: ChartLine, label: 'Telemetry' },
+];
+const runs = [
+ { s: 'running', wf: 'issue_agent', id: 'a91c3e', d: '12s', at: 'now' },
+ { s: 'failed', wf: 'process_order', id: '8f3c2a', d: '1.4s', at: '2m ago' },
+ { s: 'waiting', wf: 'expense_approval', id: '4b07d1', d: '2d 3h', at: '2d ago' },
+ { s: 'completed', wf: 'process_order', id: '77e0b9', d: '2.1s', at: '5m ago' },
+ { s: 'compensated', wf: 'book_trip', id: 'c2d4a0', d: '3.8s', at: '9m ago' },
+ { s: 'completed', wf: 'daily_sales_report', id: '1fa9e2', d: '41s', at: '9:00' },
+];
+const label: Record = { running: 'Running', failed: 'Failed', waiting: 'Waiting', completed: 'Completed', compensated: 'Compensated' };
+const trace = [
+ { s: 'completed', name: 'validate', at: 0, w: 6, d: '12ms' },
+ { s: 'failed', name: 'charge #1', at: 7, w: 22, d: '1.1s' },
+ { s: 'failed', name: 'charge #2', at: 40, w: 18, d: '0.9s' },
+ { s: 'failed', name: 'charge #3', at: 74, w: 20, d: '1.0s' },
+ { s: 'pending', name: 'send_confirmation', at: 0, w: 0, d: 'not run' },
+];
+const queues = [
+ { name: 'default', conc: 10, busy: 7, backlog: 23, bars: [4, 6, 5, 8, 7, 9, 6, 8, 10, 9, 7, 8] },
+ { name: 'priority', conc: 5, busy: 2, backlog: 0, bars: [1, 2, 1, 3, 2, 1, 2, 2, 1, 2, 3, 2] },
+ { name: 'emails', conc: 20, busy: 0, backlog: 412, paused: true, bars: [3, 5, 8, 11, 14, 18, 21, 25, 30, 34, 38, 42] },
+];
+---
+
+
+
+ localhost:4000/dashboard
+ Search runs and workflows⌘K
+
+
+
+ Durable
+ {nav.map((n) => (
+ n.view ? (
+
+ {n.label}{n.badge && {n.badge} }
+
+ ) : (
+ {n.label}
+ )
+ ))}
+
+
+
+
+ status: any last 1h Filter by workflow, status or run id
+
+ Status Workflow Run Took Started
+
+ {runs.map((r) => (
+
+ {label[r.s]}
+ {r.wf}{r.id}{r.d} {r.at}
+
+ ))}
+
+
+
+
+
+
+
process_order run 8f3c2a Failed
+
Retry from charge Cancel
+
+
+ {trace.map((t) => (
+
+ {t.name}
+ {t.w > 0 && }
+ {t.d}
+
+ ))}
+
+
+ Error on attempt 3
+ {"(MatchError) no match of right hand side value: {:error, :card_declined}"}
+ (my_app 0.1.0) lib/my_app/orders.ex:28: MyApp.OrderWorkflow.charge/1
+
+
+
+
+ {[
+ ['expense_approval', 'Approve the $420 expense from Dana?', 'manager', '2h'],
+ ['issue_agent', 'Review the patch for acme/shop#1042', 'maintainer', '1d'],
+ ['refund_request', 'Refund or store credit?', 'support', '3d'],
+ ].map(([wf, prompt, who, age]) => (
+
+
{wf}{prompt}
waiting for {who}, {age}
+
Approve Reject
+
+ ))}
+
+
+
+ {queues.map((q) => (
+
+
+
{q.name}
+ {q.paused ?
Paused :
{q.busy} of {q.conc} busy}
+
{q.paused ? <> Resume> : <> Pause>}
+
+
{q.bars.map((h) => )}
+
{q.backlog} waiting
+
+ ))}
+
+
+
+
+
+
+
+
diff --git a/site/src/components/Features.astro b/site/src/components/Features.astro
new file mode 100644
index 0000000..3ca5019
--- /dev/null
+++ b/site/src/components/Features.astro
@@ -0,0 +1,102 @@
+---
+// Every workflow primitive, as a bento grid. Two wide tiles carry a small diagram.
+import { RefreshCw, GitBranch, Split, Undo2, Hourglass, Webhook, UserCheck, CalendarClock, Network, Timer } from '@lucide/astro';
+
+const tiles = [
+ { icon: Split, wide: 'parallel', name: 'Parallel steps', text: 'Fan out, run at the same time, and collect each result as {:ok, _} or {:error, _}.', code: 'parallel do ... end', href: '/docs/parallel/' },
+ { icon: RefreshCw, name: 'Retries with backoff', text: 'Exponential, linear or constant, per step.', code: 'retry: [max_attempts: 3]', href: '/docs/#reference' },
+ { icon: GitBranch, name: 'Branching', text: 'Pattern-match on the context to pick one path.', code: 'branch on: fn ctx -> ... end', href: '/docs/branching/' },
+ { icon: Webhook, name: 'Events', text: 'Resume when your app calls Durable.send_event/3.', code: 'wait_for_event("paid")', href: '/docs/waiting/' },
+ { icon: UserCheck, name: 'Human input', text: 'Approvals, choices, text and forms, with timeouts.', code: 'wait_for_approval("lead")', href: '/docs/waiting/' },
+ { icon: Undo2, wide: 'saga', name: 'Compensations', text: 'Sagas built in: when a step fails for good, finished steps are undone in reverse order.', code: 'step :book, [compensate: :cancel]', href: '/docs/compensations/' },
+ { icon: Hourglass, name: 'Sleep', text: 'Pause for minutes or months. Nothing runs while it waits.', code: 'sleep(days(3))', href: '/docs/waiting/' },
+ { icon: CalendarClock, name: 'Cron schedules', text: 'Recurring workflows, in any timezone.', code: '@schedule cron: "0 9 * * *"', href: '/docs/#scheduled-reports' },
+ { icon: Network, name: 'Child workflows', text: 'Call one and wait for it, or start one and move on.', code: 'call_workflow(Child, input)', href: '/docs/orchestration/' },
+ { icon: Timer, name: 'Deadlines', text: 'A run past its timeout fails and runs its compensations.', code: 'timeout: hours(2)', href: '/docs/#workflow-options' },
+];
+---
+
+
+
diff --git a/site/src/components/FontPreload.astro b/site/src/components/FontPreload.astro
new file mode 100644
index 0000000..d622af7
--- /dev/null
+++ b/site/src/components/FontPreload.astro
@@ -0,0 +1,9 @@
+---
+// Preload the fonts every page uses, so text paints in Sora from the first frame
+// instead of flashing a fallback and swapping. Vite gives these the same hashed
+// URLs as the @font-face rules in styles/fonts.css, so nothing downloads twice.
+import sora from '@fontsource-variable/sora/files/sora-latin-wght-normal.woff2?url';
+import mono400 from '@fontsource/geist-mono/files/geist-mono-latin-400-normal.woff2?url';
+import mono500 from '@fontsource/geist-mono/files/geist-mono-latin-500-normal.woff2?url';
+---
+{[sora, mono400, mono500].map((href) => )}
diff --git a/site/src/components/Graph.astro b/site/src/components/Graph.astro
new file mode 100644
index 0000000..3203873
--- /dev/null
+++ b/site/src/components/Graph.astro
@@ -0,0 +1,163 @@
+---
+// The hero graphic: an order workflow unfolding as a graph. Steps light up as
+// they run, fan out into parallel steps, join, wait for an approval, finish.
+const nodes = [
+ { id: 'validate', x: 100, y: 170 },
+ { id: 'charge', x: 285, y: 170 },
+ { id: 'send_receipt', x: 505, y: 70 },
+ { id: 'create_invoice', x: 505, y: 170 },
+ { id: 'reserve_stock', x: 505, y: 270 },
+ { id: 'await_approval', x: 745, y: 170, kind: 'wait' },
+ { id: 'ship', x: 945, y: 170 },
+ { id: 'done', x: 1105, y: 170, kind: 'end' },
+].map((n) => ({ ...n, w: n.id.length * 9 + 46 }));
+const at = Object.fromEntries(nodes.map((n) => [n.id, n]));
+const edges = [
+ ['validate', 'charge'], ['charge', 'send_receipt'], ['charge', 'create_invoice'], ['charge', 'reserve_stock'],
+ ['send_receipt', 'await_approval'], ['create_invoice', 'await_approval'], ['reserve_stock', 'await_approval'],
+ ['await_approval', 'ship'], ['ship', 'done'],
+].map(([from, to]) => {
+ const a = at[from], b = at[to];
+ const sx = a.x + a.w / 2, tx = b.x - b.w / 2, mx = (sx + tx) / 2;
+ return { from, to, d: `M${sx} ${a.y} C${mx} ${a.y} ${mx} ${b.y} ${tx} ${b.y}` };
+});
+---
+
+
+
+ process_order
+ Running Waiting for approval Completed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {edges.map((e) => (
+
+
+
+
+
+ ))}
+ {nodes.map((n) => (
+
+
+
+ {n.id}
+
+ ))}
+
+
+
+
+
+
diff --git a/site/src/components/Head.astro b/site/src/components/Head.astro
new file mode 100644
index 0000000..cbc58bd
--- /dev/null
+++ b/site/src/components/Head.astro
@@ -0,0 +1,7 @@
+---
+// Starlight's head, plus font preloads (see FontPreload.astro).
+import Default from '@astrojs/starlight/components/Head.astro';
+import FontPreload from './FontPreload.astro';
+---
+
+
diff --git a/site/src/components/HeaderLinks.astro b/site/src/components/HeaderLinks.astro
new file mode 100644
index 0000000..dce661b
--- /dev/null
+++ b/site/src/components/HeaderLinks.astro
@@ -0,0 +1,23 @@
+---
+// Starlight has no top navigation; these links sit before the GitHub icon.
+import Default from '@astrojs/starlight/components/SocialIcons.astro';
+
+const path = Astro.url.pathname;
+const links = [
+ ['/docs/', 'Docs'],
+ ['/examples/', 'Examples'],
+ ['/docs/changelog/', 'Changelog'],
+];
+const current = (href: string) =>
+ href === '/docs/' ? path.startsWith('/docs/') && !path.startsWith('/docs/changelog') : path.startsWith(href);
+---
+
+ {links.map(([href, label]) => {label} )}
+
+
+
+
diff --git a/site/src/components/Illus.astro b/site/src/components/Illus.astro
new file mode 100644
index 0000000..aa0d959
--- /dev/null
+++ b/site/src/components/Illus.astro
@@ -0,0 +1,367 @@
+---
+// The stages for the Resilient / Reliable / Resumable panels. Each is a small run
+// drawn in the same language as the agent graph, playing a short scripted
+// sequence while it is on screen, with the code that does it underneath.
+import { Code } from 'astro:components';
+import { ShieldCheck, CreditCard, Truck, Plane, Hotel, Undo2, Mail, Moon, BellRing, Check, X } from '@lucide/astro';
+import { macroCalls, night } from '../code-theme';
+
+interface Props { kind: 'durable' | 'reliable' | 'resumable'; code: string }
+const { kind, code } = Astro.props;
+
+const icons = {
+ validate: ShieldCheck, charge: CreditCard, ship: Truck,
+ book_flight: Plane, book_hotel: Hotel, cancel_flight: Undo2, cancel_hotel: Undo2,
+ send_welcome: Mail, sleep: Moon, send_reminder: BellRing,
+};
+type Name = keyof typeof icons;
+const saved: [Name, string][] = [['validate', '%{valid: true}'], ['charge', '%{charge_id: "ch_9f2"}'], ['ship', '%{tracking: "1Z84…"}']];
+const label = {
+ durable: 'Three steps run; each result is saved as it finishes. A worker restart only re-runs the step that was in flight.',
+ reliable: 'A step fails twice and succeeds on its third attempt after 1s and 2s backoffs. Then a charge fails for good and the bookings are undone in reverse.',
+ resumable: 'A run sends a welcome email, sleeps three days without holding a worker, then wakes with its context and sends a reminder.',
+}[kind];
+---
+
+
+ {kind === 'durable' && (
+ <>
+
+ {(['validate', 'charge', 'ship'] as Name[]).map((n, i) => {
+ const Icon = icons[n];
+ return (
+ <>
+ {i > 0 && }
+
+
+ {n}
+
+ >
+ );
+ })}
+ Worker restarted
+
+
+
Saved with the run
+
+ {saved.map(([n, v]) => (
+ {n}{v} saved
+ ))}
+
+
+ >
+ )}
+
+ {kind === 'reliable' && (
+ <>
+
+
Retry with backoff
+
+ 1
+ 1s
+ 2
+ 2s
+ 3
+
+
+
+
Undo in reverse
+
+ {(['book_flight', 'book_hotel', 'charge', 'cancel_flight', 'cancel_hotel'] as Name[]).map((n) => {
+ const Icon = icons[n];
+ return (
+
+
+ {n}
+
+ );
+ })}
+
+
+
+
+
+ >
+ )}
+
+ {kind === 'resumable' && (
+ <>
+
+ {(['send_welcome', 'sleep', 'send_reminder'] as Name[]).map((n, i) => {
+ const Icon = icons[n];
+ return (
+ <>
+ {i > 0 && }
+
+
+ {n === 'sleep' ? 'sleep(days(3))' : n}
+ {n === 'sleep' && }
+
+ >
+ );
+ })}
+
+
+
+
+
Context
+
user_id: 42plan: "pro"
+
+
+ >
+ )}
+
+
+
+
+
+
+
+
+
diff --git a/site/src/components/Observe.astro b/site/src/components/Observe.astro
new file mode 100644
index 0000000..2e29745
--- /dev/null
+++ b/site/src/components/Observe.astro
@@ -0,0 +1,112 @@
+---
+// Observability: what Durable emits and how you read it. The chart is example
+// data; the events, functions and the metrics hook are the real API.
+import { Activity, Gauge, ChartColumn, ScrollText } from '@lucide/astro';
+
+const points = [
+ { icon: Activity, title: 'Telemetry spans', text: 'Runs, steps, compensations, queues and schedules emit :telemetry spans shaped like Phoenix, Ecto and Oban, so your existing tooling reads them as-is.' },
+ { icon: Gauge, title: 'Metrics for any reporter', text: 'Durable.Telemetry.metrics/0 returns Telemetry.Metrics definitions for Prometheus, StatsD or LiveDashboard.' },
+ { icon: ChartColumn, title: 'Stats you can query', text: 'Durable.Stats gives you overviews, timelines, step performance, queue history and grouped errors.' },
+ { icon: ScrollText, title: 'An activity log', text: 'Recovered runs, fenced workers and queue pauses are recorded, so you can see what the system did on its own.' },
+];
+const events = ['[:durable, :workflow, :stop]', '[:durable, :step, :retry]', '[:durable, :queue, :job_claimed]', '[:durable, :schedule, :trigger]'];
+
+// Example throughput: completed and failed runs per minute.
+const ok = [32, 38, 35, 44, 41, 52, 49, 58, 54, 61, 57, 66, 63, 70, 68, 74];
+const bad = [2, 1, 3, 2, 2, 4, 2, 1, 3, 2, 5, 2, 1, 2, 3, 1];
+const W = 560, H = 150, max = 80;
+const x = (i: number) => (i / (ok.length - 1)) * W;
+const y = (v: number) => H - (v / max) * H;
+const line = (vs: number[]) => vs.map((v, i) => `${i ? 'L' : 'M'}${x(i).toFixed(1)} ${y(v).toFixed(1)}`).join(' ');
+const area = `${line(ok)} L${W} ${H} L0 ${H} Z`;
+---
+
+
+ {points.map((p) => (
+
+ ))}
+
+
+
+
+
Runs per minute 74 +18%
+
Failure rate 1.4% steady
+
p95 step time 320ms -9%
+
+
+
+
+
+
+
+
+
+
+
+ {[0.25, 0.5, 0.75].map((g) => )}
+
+
+
+
+
completed failedExample data
+
# lib/my_app_web/telemetry.ex
+def metrics, do : my_metrics() ++ Durable.Telemetry .metrics()
+
{events.map((e) => {e})}
+
+
+
+
diff --git a/site/src/components/Ops.astro b/site/src/components/Ops.astro
new file mode 100644
index 0000000..deab361
--- /dev/null
+++ b/site/src/components/Ops.astro
@@ -0,0 +1,59 @@
+---
+// Operations: the same controls from code and from the terminal, as two tabs in
+// one window. Both snippets come from the README, so they stay in step with the docs.
+import { Code } from 'astro:components';
+import { Terminal, CodeXml } from '@lucide/astro';
+import { macroCalls, night } from '../code-theme';
+
+interface Props { api: string; mix: string }
+const { api, mix } = Astro.props;
+---
+
+
+
+ From your code
+ From the terminal
+
+
+
+
+
+
+
+
diff --git a/site/src/components/PackageHeader.astro b/site/src/components/PackageHeader.astro
new file mode 100644
index 0000000..46682be
--- /dev/null
+++ b/site/src/components/PackageHeader.astro
@@ -0,0 +1,79 @@
+---
+// Package facts under the page title: what the README's badges say, in the site's
+// own look. Values come from packageMeta() in docs.ts (mix.exs + shared.exs).
+import { Icon } from '@astrojs/starlight/components';
+import { Package, Scale, Droplet, BookOpen, Copy } from '@lucide/astro';
+
+interface Props {
+ name: string;
+ version: string;
+ elixir: string;
+ license: string;
+ dep: string;
+ hex: string;
+ hexdocs: string;
+ github: string;
+}
+const { name, version, elixir, license, dep, hex, hexdocs, github } = Astro.props;
+---
+
+
+ v{version}
+ Elixir {elixir}
+ {license} license
+
+
+
+
+
+
+
diff --git a/site/src/components/PageTitle.astro b/site/src/components/PageTitle.astro
new file mode 100644
index 0000000..764dbe0
--- /dev/null
+++ b/site/src/components/PageTitle.astro
@@ -0,0 +1,10 @@
+---
+// Starlight's title, plus a package header on pages that document a package.
+import Default from '@astrojs/starlight/components/PageTitle.astro';
+import PackageHeader from './PackageHeader.astro';
+import { packageMeta } from '../docs';
+
+const meta = packageMeta(Astro.locals.starlightRoute.entry.id);
+---
+
+{meta && }
diff --git a/site/src/components/Sim.astro b/site/src/components/Sim.astro
new file mode 100644
index 0000000..d8533ff
--- /dev/null
+++ b/site/src/components/Sim.astro
@@ -0,0 +1,101 @@
+---
+// A workflow drawn as a graph (sim/layout.ts) that runs in the browser (sim/engine.ts),
+// with its code and a log of what happened underneath.
+import { Code } from 'astro:components';
+import { macroCalls, night } from '../code-theme';
+import { layout } from '../sim/layout';
+import type { Spec } from '../sim/engine';
+import '../sim/sim.css';
+
+interface Props { code: string; spec: Spec; file: string }
+const { code, spec, file } = Astro.props;
+const g = layout(spec);
+const gid = `sim-${spec.workflow}`;
+---
+
+
+
{spec.workflow}
+
+
Pending
+
+ {spec.toggles?.map((t) => (
+
{t.label}
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+ {g.edges.map((e) => (
+
+
+
+ {e.label && (
+
+
+ {e.label}
+
+ )}
+
+ ))}
+ {g.nodes.map((n) => (
+
+ {n.kind === 'gate' ? (
+
+ ) : n.kind === 'start' || n.kind === 'end' ? (
+
+ ) : (
+
+ )}
+ {n.kind === 'step' || n.kind === 'comp' ? (
+ <>
+
+ {n.label}
+ >
+ ) : (
+ {n.label}
+ )}
+
+
+ ))}
+
+
+
+
+
+
+
diff --git a/site/src/content.config.ts b/site/src/content.config.ts
new file mode 100644
index 0000000..2c6faf9
--- /dev/null
+++ b/site/src/content.config.ts
@@ -0,0 +1,7 @@
+import { defineCollection } from 'astro:content';
+import { docsSchema } from '@astrojs/starlight/schema';
+import { packageDocs } from './docs';
+
+export const collections = {
+ docs: defineCollection({ loader: packageDocs(), schema: docsSchema() }),
+};
diff --git a/site/src/docs.ts b/site/src/docs.ts
new file mode 100644
index 0000000..843809c
--- /dev/null
+++ b/site/src/docs.ts
@@ -0,0 +1,170 @@
+// The docs are the package markdown files themselves (the same ones HexDocs
+// renders), read in place from the repo. This table is the only thing that
+// knows about them: URL, sidebar label and group, in sidebar order.
+import { readFileSync, readdirSync } from 'node:fs';
+import { dirname, join, relative, resolve } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { glob, type Loader } from 'astro/loaders';
+
+export const REPO = 'https://github.com/wavezync/durable';
+// Astro runs from site/; import.meta.url would point into the build output.
+const ROOT = resolve(process.cwd(), '..');
+
+export const DOCS: { file: string; id: string; label: string; group: string; title?: string; description?: string }[] = [
+ { file: 'durable/README.md', id: 'docs', label: 'Introduction', group: 'Start here', title: 'Getting started' },
+ { file: 'durable/guides/waiting.md', id: 'docs/waiting', label: 'Waiting', group: 'Guides' },
+ { file: 'durable/guides/branching.md', id: 'docs/branching', label: 'Branching', group: 'Guides' },
+ { file: 'durable/guides/parallel.md', id: 'docs/parallel', label: 'Parallel', group: 'Guides' },
+ { file: 'durable/guides/compensations.md', id: 'docs/compensations', label: 'Compensations', group: 'Guides' },
+ { file: 'durable/guides/orchestration.md', id: 'docs/orchestration', label: 'Orchestration', group: 'Guides' },
+ { file: 'durable/guides/ai_workflows.md', id: 'docs/ai-workflows', label: 'AI workflows', group: 'Guides' },
+ { file: 'durable_dashboard/README.md', id: 'docs/dashboard', label: 'Dashboard', group: 'Dashboard', title: 'Durable Dashboard' },
+ { file: 'durable/CHANGELOG.md', id: 'docs/changelog', label: 'durable', group: 'Changelog', description: 'Release history of durable, the workflow engine for Elixir: new features, fixes and breaking changes in every version on Hex.' },
+ { file: 'durable_dashboard/CHANGELOG.md', id: 'docs/changelog/dashboard', label: 'durable_dashboard', group: 'Changelog', description: 'Release history of durable_dashboard, the Phoenix LiveView dashboard for Durable: new pages, fixes and changes in every version on Hex.' },
+];
+
+export const docHref = (id: string) => `/${id}/`;
+
+// Pages that document a package get a header with its metadata (PackageHeader.astro),
+// read from the package's own mix.exs and the shared metadata so it matches what's released.
+const PACKAGE_PAGES: Record = { docs: 'durable', 'docs/dashboard': 'durable_dashboard' };
+
+export function packageMeta(id: string) {
+ const name = PACKAGE_PAGES[id];
+ if (!name) return null;
+ const mix = readFileSync(join(ROOT, name, 'mix.exs'), 'utf8');
+ const shared = readFileSync(join(ROOT, 'shared.exs'), 'utf8');
+ const version = /@version "([^"]+)"/.exec(mix)![1];
+ const [major, minor] = version.split('.');
+ return {
+ name,
+ version,
+ elixir: /elixir: "([^"]+)"/.exec(shared)![1],
+ license: /licenses: \["([^"]+)"/.exec(shared)![1],
+ dep: `{:${name}, "~> ${major}.${minor}"}`,
+ hex: `https://hex.pm/packages/${name}`,
+ hexdocs: `https://hexdocs.pm/${name}`,
+ github: `${REPO}/tree/main/${name}`,
+ };
+}
+
+const byFile = new Map(DOCS.map((d) => [d.file, d]));
+
+// The files have no frontmatter. Starlight needs a title, so it comes from
+// the H1; the first prose paragraph after it becomes the meta description.
+function meta(path: string) {
+ const doc = byFile.get(relative(ROOT, path))!;
+ const src = readFileSync(path, 'utf8');
+ const h1 = /^# (.+)$/m.exec(src)?.[1] ?? doc.label;
+ const description = src
+ .slice(src.indexOf(h1) + h1.length)
+ .split('\n\n')
+ .map((p) => p.trim().replace(/\s+/g, ' '))
+ .find((p) => /^[A-Z]/.test(p))
+ // Plain text for : keep link text, drop link targets, code ticks and bold markers.
+ ?.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
+ .replace(/`|\*\*/g, '');
+ return {
+ title: doc.title ?? (doc.group === 'Changelog' ? `${doc.label} changelog` : h1),
+ description: doc.description ?? description,
+ editUrl: `${REPO}/edit/main/${doc.file}`,
+ // Release groups (Features, Bug fixes, …) repeat under every version; the outline lists versions only.
+ ...(doc.group === 'Changelog' && { tableOfContents: { maxHeadingLevel: 2 } }),
+ };
+}
+
+// Starlight's docs collection, fed from the package files instead of src/content/docs.
+export function packageDocs(): Loader {
+ const ids = new Map(DOCS.map((d) => [d.file, d.id]));
+ const inner = glob({ base: ROOT, pattern: [...ids.keys()], generateId: ({ entry }) => ids.get(entry)! });
+ return {
+ name: 'package-docs',
+ load: (ctx) =>
+ inner.load({
+ ...ctx,
+ parseData: (entry) => ctx.parseData({ ...entry, data: { ...meta(resolve(entry.filePath!)), ...entry.data } }),
+ }),
+ };
+}
+
+// Public modules, so `Durable.Wait` in backticks links to HexDocs the way
+// ExDoc autolinks it. Modules with `@moduledoc false` have no page there.
+const MODULES = new Set();
+const lib = join(ROOT, 'durable/lib');
+for (const f of readdirSync(lib, { recursive: true }) as string[]) {
+ if (!f.endsWith('.ex')) continue;
+ const src = readFileSync(join(lib, f), 'utf8');
+ for (const m of src.matchAll(/defmodule ([\w.]+) do\n((?:.*\n){0,2})/g)) {
+ if (!m[2].includes('@moduledoc false')) MODULES.add(m[1]);
+ }
+}
+
+const REF = /^((?:Durable|Mix\.Tasks\.Durable)(?:\.[A-Z]\w*)*)(?:\.([a-z_]\w*[?!]?)\/(\d))?$/;
+
+function hexdocs(code: string) {
+ const m = REF.exec(code);
+ if (!m || !MODULES.has(m[1])) return null;
+ return `https://hexdocs.pm/durable/${m[1]}.html${m[2] ? `#${m[2]}/${m[3]}` : ''}`;
+}
+
+// Relative links point at files in the repo: other docs become site pages,
+// anything else goes to GitHub.
+function rewrite(url: string, from: string) {
+ if (/^([a-z]+:|#|\/)/.test(url)) return url;
+ const [path, hash] = url.split('#');
+ const target = relative(ROOT, resolve(dirname(from), path));
+ const doc = byFile.get(target);
+ if (doc) return docHref(doc.id) + (hash ? `#${hash}` : '');
+ return `${REPO}/blob/main/${target}${hash ? `#${hash}` : ''}`;
+}
+
+type Node = { type: string; url: string; value: string; depth: number; children?: Node[] };
+type Ctx = {
+ fileURL?: URL;
+ setProperty(node: Node, key: 'url', value: string): void;
+ replaceNode(node: Node, next: object): void;
+ removeNode(node: Node): void;
+ parent(node: Node): { type: string } | undefined;
+ textContent(node: Node): string;
+};
+const relink = (node: Node, ctx: Ctx) => ctx.setProperty(node, 'url', rewrite(node.url, fileURLToPath(ctx.fileURL!)));
+
+// A Sätteri mdast plugin (Astro 7's Markdown pipeline).
+export const docLinks = {
+ name: 'doc-links',
+ link: relink,
+ definition: relink,
+ // Starlight renders the title (taken from this H1) itself.
+ heading(node: Node, ctx: Ctx) {
+ if (node.depth === 1) ctx.removeNode(node);
+ },
+ // The README's badge rows and its "Docs: … Dashboard: … API: …" line are for
+ // GitHub and HexDocs readers; on the site, PackageHeader shows the same facts.
+ paragraph(node: Node, ctx: Ctx) {
+ const kids = node.children ?? [];
+ const blank = (c: Node) => c.type === 'text' && !c.value.trim();
+ const badge = (c: Node) => c.type === 'link' && !!c.children?.length && c.children.every((g) => g.type === 'image');
+ const badges = kids.some(badge) && kids.every((c) => badge(c) || blank(c));
+ const links = kids[0]?.type === 'strong' && ctx.textContent(kids[0]) === 'Docs:';
+ if (badges || links) ctx.removeNode(node);
+ },
+ inlineCode(node: Node, ctx: Ctx) {
+ const href = hexdocs(node.value);
+ if (!href || ctx.parent(node)?.type === 'link') return;
+ ctx.replaceNode(node, { type: 'link', url: href, children: [{ type: 'inlineCode', value: node.value }] });
+ },
+};
+
+// First code block in `lang` (and the text before it) under a heading line such
+// as "### Approval Workflow". Throws when the heading is gone, so a README edit
+// can't silently empty a page.
+export function section(body: string, heading: string, lang = 'elixir') {
+ const start = body.indexOf(`\n${heading}\n`);
+ if (start < 0) throw new Error(`README has no "${heading}" section`);
+ const rest = body.slice(start + heading.length + 2);
+ const end = rest.search(/\n##+ /);
+ const text = end < 0 ? rest : rest.slice(0, end);
+ const code = new RegExp('```' + lang + '\\n([\\s\\S]*?)```').exec(text)?.[1] ?? '';
+ const intro = text.slice(0, text.indexOf('```')).trim();
+ return { intro, code: code.trimEnd() };
+}
diff --git a/site/src/examples.ts b/site/src/examples.ts
new file mode 100644
index 0000000..10185cf
--- /dev/null
+++ b/site/src/examples.ts
@@ -0,0 +1,132 @@
+import { section } from './docs';
+import type { Spec } from './sim/engine';
+
+// Code comes from the README section named by `heading`; only the run's
+// behavior (timings, what can fail, what a person can answer) lives here.
+export const EXAMPLES: { slug: string; heading: string; file: string; guide?: string; spec: Spec }[] = [
+ {
+ slug: 'approval',
+ heading: 'Approval Workflow',
+ file: 'expense_approval.ex',
+ guide: 'waiting',
+ spec: {
+ workflow: 'expense_approval',
+ module: 'MyApp.ExpenseApproval',
+ nodes: [
+ {
+ step: 'request_approval',
+ as: 'decision',
+ wait: {
+ says: 'a manager has to approve the expense',
+ actions: [
+ { label: 'Approve', value: ':approved', call: '`Durable.provide_input(id, "manager", :approved)`' },
+ { label: 'Reject', value: ':rejected', call: '`Durable.provide_input(id, "manager", :rejected)`' },
+ { label: 'Let 3 days pass', value: ':auto_rejected', call: 'Nobody answered in 3 days, so `wait_for_approval` returned `:auto_rejected`.' },
+ ],
+ },
+ },
+ { branch: 'decision', clauses: { ':approved': [{ step: 'process', ms: 900 }], _: [{ step: 'notify_rejection', ms: 700 }] } },
+ ],
+ },
+ },
+ {
+ slug: 'parallel-fetch',
+ heading: 'Parallel Data Fetch',
+ file: 'dashboard_builder.ex',
+ guide: 'parallel',
+ spec: {
+ workflow: 'build_dashboard',
+ module: 'MyApp.DashboardBuilder',
+ nodes: [
+ { step: 'init', ms: 400 },
+ { parallel: [{ step: 'user', ms: 900 }, { step: 'orders', ms: 1700 }, { step: 'notifications', ms: 600 }] },
+ { step: 'render', ms: 700 },
+ ],
+ },
+ },
+ {
+ slug: 'trip-booking',
+ heading: 'Trip Booking (Saga)',
+ file: 'trip_booking.ex',
+ guide: 'compensations',
+ spec: {
+ workflow: 'book_trip',
+ module: 'MyApp.TripBooking',
+ toggles: [{ label: 'Decline the card', step: 'charge' }],
+ nodes: [
+ { step: 'book_flight', ms: 1000, compensate: 'cancel_flight' },
+ { step: 'book_hotel', ms: 900, compensate: 'cancel_hotel' },
+ { step: 'charge', ms: 800, error: '`Payments.charge/2` raised: card declined' },
+ ],
+ },
+ },
+ {
+ slug: 'trial-reminder',
+ heading: 'Delayed & Scheduled Execution',
+ file: 'trial_reminder.ex',
+ guide: 'waiting',
+ spec: {
+ workflow: 'trial_reminder',
+ module: 'MyApp.TrialReminder',
+ nodes: [
+ { step: 'welcome', ms: 500 },
+ { step: 'wait_3_days', ms: 300, sleep: 'sleep(days(3))' },
+ { step: 'check_in', ms: 500 },
+ { step: 'wait_until_trial_ends', ms: 300, sleep: 'schedule_at(trial_end)' },
+ { step: 'convert_or_remind', ms: 700 },
+ ],
+ },
+ },
+ {
+ slug: 'payment-events',
+ heading: 'Event-Driven Workflow',
+ file: 'payment_flow.ex',
+ guide: 'waiting',
+ spec: {
+ workflow: 'payment_flow',
+ module: 'MyApp.PaymentFlow',
+ nodes: [
+ { step: 'create_invoice', ms: 700 },
+ {
+ step: 'await_payment',
+ as: 'result',
+ wait: {
+ says: 'the payment provider has to send `payment.success` or `payment.failed`',
+ actions: [
+ { label: 'Send payment.success', value: '"payment.success"', call: 'Your webhook called `Durable.send_event(id, "payment.success", %{transaction_id: "txn_123"})`.' },
+ { label: 'Send payment.failed', value: '"payment.failed"', call: 'Your webhook called `Durable.send_event(id, "payment.failed", %{})`.' },
+ { label: 'Let 7 days pass', value: '"payment.expired"', call: 'No event in 7 days, so `wait_for_any` returned the timeout value.' },
+ ],
+ },
+ },
+ { branch: 'result', clauses: { '"payment.success"': [{ step: 'fulfill', ms: 800 }], _: [{ step: 'cancel', ms: 600 }] } },
+ ],
+ },
+ },
+ {
+ slug: 'batch',
+ heading: 'Batch Processing',
+ file: 'bulk_emailer.ex',
+ spec: {
+ workflow: 'send_campaign',
+ module: 'MyApp.BulkEmailer',
+ nodes: [{ step: 'load', ms: 600 }, { step: 'send_emails', ms: 2600 }],
+ },
+ },
+ {
+ slug: 'daily-report',
+ heading: 'Scheduled Reports',
+ file: 'daily_report.ex',
+ spec: {
+ workflow: 'daily_sales_report',
+ module: 'MyApp.DailyReport',
+ intro: 'The scheduler started a run: cron `0 9 * * *`, America/New_York.',
+ nodes: [{ step: 'generate', ms: 1400 }, { step: 'distribute', ms: 900 }],
+ },
+ },
+];
+
+// `readme` is the durable/README.md body (the docs collection's `docs` entry).
+export function examples(readme: string) {
+ return EXAMPLES.map((e) => ({ ...e, ...section(readme, `### ${e.heading}`) }));
+}
diff --git a/site/src/layouts/Landing.astro b/site/src/layouts/Landing.astro
new file mode 100644
index 0000000..1688307
--- /dev/null
+++ b/site/src/layouts/Landing.astro
@@ -0,0 +1,197 @@
+---
+// The landing page's own shell. The docs use Starlight's; this page stands apart.
+import '../styles/fonts.css';
+import { Image } from 'astro:assets';
+import { Icon } from '@astrojs/starlight/components';
+import FontPreload from '../components/FontPreload.astro';
+import { REPO } from '../docs';
+import mark from '../assets/wavezync-mark.png';
+import wordmark from '../assets/wavezync-wordmark.png';
+
+interface Props { title: string; description: string }
+const { title, description } = Astro.props;
+const canonical = new URL(Astro.url.pathname, Astro.site);
+const WAVEZYNC = 'https://wavezync.com';
+const LINKEDIN = 'https://www.linkedin.com/company/wavezync';
+const ld = {
+ '@context': 'https://schema.org',
+ '@type': 'SoftwareSourceCode',
+ name: 'Durable',
+ description,
+ url: canonical.href,
+ codeRepository: REPO,
+ programmingLanguage: 'Elixir',
+ license: 'https://opensource.org/licenses/MIT',
+ author: {
+ '@type': 'Organization',
+ name: 'WaveZync',
+ url: WAVEZYNC,
+ sameAs: [LINKEDIN, 'https://github.com/wavezync'],
+ },
+};
+---
+
+
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/src/pages/examples/[slug].astro b/site/src/pages/examples/[slug].astro
new file mode 100644
index 0000000..21ad2b0
--- /dev/null
+++ b/site/src/pages/examples/[slug].astro
@@ -0,0 +1,29 @@
+---
+import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
+import { getEntry } from 'astro:content';
+import Sim from '../../components/Sim.astro';
+import { EXAMPLES, examples } from '../../examples';
+import { DOCS, docHref } from '../../docs';
+
+export function getStaticPaths() {
+ return EXAMPLES.map((e) => ({ params: { slug: e.slug } }));
+}
+const all = examples((await getEntry('docs', 'docs'))!.body!);
+const e = all.find((x) => x.slug === Astro.params.slug)!;
+const guide = DOCS.find((d) => d.id === `docs/${e.guide}`);
+const anchor = e.heading.toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s/g, '-');
+---
+
+ {e.intro}
+
+
+ The code is the README example . The run is simulated in your browser,
+ with time sped up.
+ {guide && <> For the details, read the {guide.label.toLowerCase()} guide .>}
+
+
+
+
diff --git a/site/src/pages/examples/index.astro b/site/src/pages/examples/index.astro
new file mode 100644
index 0000000..eb115d6
--- /dev/null
+++ b/site/src/pages/examples/index.astro
@@ -0,0 +1,39 @@
+---
+import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
+import { getEntry } from 'astro:content';
+import { examples } from '../../examples';
+
+const list = examples((await getEntry('docs', 'docs'))!.body!);
+---
+
+ The workflows from the README, each with a simulated run next to the code. Approve things, decline cards, skip ahead through sleeps, and watch each step of the graph run.
+
+
+
+
diff --git a/site/src/pages/index.astro b/site/src/pages/index.astro
new file mode 100644
index 0000000..4c4519a
--- /dev/null
+++ b/site/src/pages/index.astro
@@ -0,0 +1,456 @@
+---
+import { Code } from 'astro:components';
+import { getEntry } from 'astro:content';
+import Landing from '../layouts/Landing.astro';
+import Graph from '../components/Graph.astro';
+import Illus from '../components/Illus.astro';
+import AgentDemo from '../components/AgentDemo.astro';
+import Features from '../components/Features.astro';
+import DashboardShowcase from '../components/DashboardShowcase.astro';
+import Observe from '../components/Observe.astro';
+import Ops from '../components/Ops.astro';
+import {
+ Package, DatabaseZap, PlugZap, Database, Server, Network, Workflow, Check,
+ Scale, Droplet, LayoutDashboard, Bot, Sparkles, ChevronRight,
+} from '@lucide/astro';
+import { macroCalls, night } from '../code-theme';
+import { section } from '../docs';
+
+const readme = (await getEntry('docs', 'docs'))!.body!;
+const dashboard = (await getEntry('docs', 'docs/dashboard'))!.body!;
+const install = section(readme, '## Installation').code;
+const dep = /\{:durable, "[^"]+"\}/.exec(install)![0];
+const version = /~> ([\d.]+)/.exec(dep)![1];
+const steps = [
+ { icon: Package, title: 'Add the dependency', code: install },
+ { icon: DatabaseZap, title: 'Add a migration', code: section(readme, '### 1. Create Migration').code },
+ { icon: PlugZap, title: 'Start it with your Repo', code: section(readme, '### 2. Add to Supervision Tree').code },
+];
+const facts = [
+ { icon: Scale, text: 'MIT licensed' },
+ { icon: Droplet, text: 'Elixir 1.15+' },
+ { icon: Database, text: 'PostgreSQL' },
+ { icon: LayoutDashboard, text: 'LiveView dashboard' },
+ { icon: Bot, text: 'Built for AI agents' },
+];
+const api = section(readme, '### API').code;
+const mix = section(readme, '## Mix Tasks', 'bash').code;
+const mount = /use DurableDashboard\.Router[^\n]*/.exec(dashboard)![0];
+
+const promises = [
+ {
+ word: 'Resilient',
+ art: 'durable',
+ title: 'Every step is saved',
+ text: "Each step's result is saved before the next one starts. A deploy, a crash or a restart can't lose work that's already done.",
+ code: 'step :charge, fn ctx -> ... end',
+ },
+ {
+ word: 'Reliable',
+ art: 'reliable',
+ title: 'Retries, deadlines and rollbacks built in',
+ text: 'Steps retry with exponential, linear or constant backoff. Workflows have timeouts. When a step fails for good, compensations undo what already happened, in reverse.',
+ code: 'retry: [max_attempts: 3, backoff: :exponential]\ncompensate: :cancel_hotel',
+ },
+ {
+ word: 'Resumable',
+ art: 'resumable',
+ title: 'Picks up exactly where it stopped',
+ text: "Sleep for days, wait for a webhook or a person's approval. A waiting run holds no process, and when it wakes up it carries on with everything it already knew.",
+ code: 'sleep(days(3))',
+ },
+];
+
+const faq = [
+ {
+ q: 'What is Durable?',
+ a: "Durable is an open-source workflow engine for Elixir. You write a workflow as a series of steps; Durable saves each step's result in your database, retries failures, and resumes runs after crashes, deploys, sleeps and waits for events or human input.",
+ },
+ {
+ q: 'How is Durable different from Oban?',
+ a: 'Oban runs background jobs. Durable runs multi-step workflows: context flows from step to step, every step is persisted, and a workflow can sleep, wait for events or approvals, branch, run steps in parallel, call child workflows and roll back with compensations. Durable has its own queue, so it does not need Oban.',
+ },
+ {
+ q: 'Is Durable like Temporal or Inngest?',
+ a: "It follows the same durable execution idea, but it's a library: it runs inside your Elixir application, under your supervision tree, and uses your Ecto repo.",
+ },
+ {
+ q: 'What does Durable need to run?',
+ a: 'An Elixir app and an Ecto repo. Out of the box, runs are stored in PostgreSQL and workers claim them with FOR UPDATE SKIP LOCKED. The queue is a pluggable adapter, so other backends can be added.',
+ },
+ {
+ q: 'What happens if a node crashes in the middle of a step?',
+ a: "Workers send heartbeats while a step runs. If a node dies, its lock goes stale and another node recovers the run, re-running only the step that was interrupted. Steps that finished don't run again, so keep each step idempotent.",
+ },
+ {
+ q: 'Can I use Durable for AI agents?',
+ a: "Yes. Put each LLM or tool call in a step: its result is saved, failed calls retry with backoff, and an agent can wait days for a human approval without holding a process. After a crash or deploy it resumes at the next step instead of starting over.",
+ },
+ {
+ q: 'Is there a dashboard?',
+ a: 'Yes. durable_dashboard is a Phoenix LiveView dashboard you mount in your router with one line. It shows runs, step timelines, pending inputs, queues and schedules.',
+ },
+];
+const faqLd = {
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: faq.map(({ q, a }) => ({ '@type': 'Question', name: q, acceptedAnswer: { '@type': 'Answer', text: a } })),
+};
+---
+
+
+
+
+
+
Durable {version} is on Hex
+
+ Resilient, Reliable, Resumable
+ workflows for Elixir
+
+
+ Durable is an open-source workflow engine for Elixir. Write workflows as plain steps. Every step is saved, so
+ runs resume after crashes, deploys and week-long waits.
+
+
+
+ {facts.map(({ icon: Icon, text }) => {text} )}
+
+
+
+
+
+
+ Ship agents that finish the job
+
+ Durable execution for AI agents in Elixir. Every LLM and tool call is saved, so crashes, timeouts and deploys
+ never lose progress or re-bill completed calls.
+
+
+
+
+
+
+ {promises.map((p, i) => {p.word} )}
+
+
+ {promises.map((p) => (
+
+ {p.word}
+ {p.word}: {p.title}
+ {p.text}
+
+
+ ))}
+
+
+
+
+ Every primitive a workflow needs
+ All of it is plain Elixir in one module, and every step it runs is saved, retried and visible in the dashboard.
+
+
+
+
+ See every run
+
+ durable_dashboard is a Phoenix LiveView dashboard: live runs, step traces, an inbox for pending
+ approvals, queues and schedules. Retry, cancel or pause right from the browser.
+
+
+
+
+
+
+ Observability built in
+ Know how your workflows behave in production with the tools you already use.
+
+
+
+
+ Operate it from code or the terminal
+
+ Retry a failed run from the step that failed, rerun a finished one, cancel, pause a queue on every node, or prune
+ old runs.
+
+
+
+
+
+ Runs inside your app
+
+ Durable is a library. Workflows are plain Elixir modules: no YAML, no new language. It starts in your
+ supervision tree on every node and uses your Ecto repo. Runs are stored through a pluggable queue adapter,
+ PostgreSQL by default.
+
+
+
+
Your Elixir app on every node
+
MyApp.Supervisor
+
MyApp.Repo
+
Durablequeues, workers, scheduler
+
+
claims runs withFOR UPDATE SKIP LOCKED
+
+
+ PostgreSQL
+ default queue adapter
+
+
+
+ A library, not a service
+ Uses your Ecto repo
+ Pluggable queue adapter
+
+
+ {steps.map((s, i) => (
+
+ {s.title}
+
+
+ ))}
+
+
+
+
+ Questions
+
+ {faq.map(({ q, a }, i) => (
+
+ {q}
+ {a}
+
+ ))}
+
+
+
+
+
+
Build workflows that finish
+
+
+
+
+
+
+
+
+
+
diff --git a/site/src/pages/llms.txt.ts b/site/src/pages/llms.txt.ts
new file mode 100644
index 0000000..0bc5aa8
--- /dev/null
+++ b/site/src/pages/llms.txt.ts
@@ -0,0 +1,44 @@
+// llms.txt (https://llmstxt.org): the site's pages as a Markdown list for
+// language models, built from the same tables as the sidebar and the examples.
+import type { APIRoute } from 'astro';
+import { getCollection, getEntry } from 'astro:content';
+import { DOCS, REPO, docHref, packageMeta } from '../docs';
+import { examples } from '../examples';
+
+export const GET: APIRoute = async ({ site }) => {
+ const url = (path: string) => new URL(path, site).href;
+ const data = new Map((await getCollection('docs')).map((d) => [d.id, d.data]));
+ const line = (title: string, href: string, about?: string) => `- [${title}](${url(href)})${about ? `: ${about}` : ''}`;
+ const oneLine = (s?: string) => s?.replace(/\s+/g, ' ').trim();
+
+ const groups = new Map();
+ for (const d of DOCS) {
+ const group = d.group === 'Changelog' ? 'Optional' : d.group;
+ const page = data.get(d.id)!;
+ groups.set(group, [...(groups.get(group) ?? []), line(page.title, docHref(d.id), oneLine(page.description))]);
+ }
+ const optional = groups.get('Optional')!;
+ groups.delete('Optional');
+
+ const list = examples((await getEntry('docs', 'docs'))!.body!);
+ groups.set('Examples', list.map((e) => line(e.heading, `/examples/${e.slug}/`, oneLine(e.intro))));
+
+ const { dep } = packageMeta('docs')!;
+ const body = [
+ '# Durable',
+ '> Resilient, reliable, resumable workflows for Elixir. An open-source workflow engine for Elixir apps and AI agents: retries, sleeps, approvals and sagas, saved step by step so runs resume after crashes.',
+ `Durable is an Elixir library: add \`${dep}\` to your deps and start it in your supervision tree with your own Ecto repo. The docs pages are the package's own Markdown, the same files HexDocs renders.`,
+ ...[...groups].map(([group, lines]) => `## ${group}\n\n${lines.join('\n')}`),
+ [
+ '## Optional',
+ '',
+ ...optional,
+ `- [API reference](https://hexdocs.pm/durable): every module and function on HexDocs`,
+ `- [Dashboard API reference](https://hexdocs.pm/durable_dashboard): the dashboard package on HexDocs`,
+ `- [Source code](${REPO}): the durable and durable_dashboard packages on GitHub`,
+ `- [Sitemap](${url('/sitemap-index.xml')}): every page on this site`,
+ ].join('\n'),
+ ].join('\n\n');
+
+ return new Response(body + '\n', { headers: { 'Content-Type': 'text/plain; charset=utf-8' } });
+};
diff --git a/site/src/sim/engine.ts b/site/src/sim/engine.ts
new file mode 100644
index 0000000..5e52d7b
--- /dev/null
+++ b/site/src/sim/engine.ts
@@ -0,0 +1,383 @@
+// A toy Durable run, close enough to the real executor to teach it:
+// - completed steps go in a journal; every resume walks the workflow from the
+// top and skips what the journal already has
+// - a wait or sleep suspends the run; once answered, the run resumes and that
+// step runs again from its top (the wait now returns the answer)
+// - a step that fails after its retries rolls back completed steps' compensations
+// Drawn on the workflow graph from layout.ts: steps light up as they run.
+
+type Action = { label: string; value: string; call: string };
+export type Step = {
+ step: string;
+ ms?: number;
+ retry?: number; // max attempts
+ flaky?: number; // fail the first N attempts
+ error?: string;
+ compensate?: string;
+ wait?: { says: string; actions: Action[]; auto?: number }; // auto: action picked after idling
+ sleep?: string; // the call, e.g. "sleep(days(3))"
+ as?: string; // context key a wait's answer is stored under
+};
+export type Node = Step | { parallel: Step[] } | { branch: string; clauses: Record };
+export type Spec = {
+ workflow: string;
+ module: string;
+ nodes: Node[];
+ toggles?: { label: string; step: string }[];
+ intro?: string;
+};
+
+type Status = 'running' | 'waiting' | 'completed' | 'failed' | 'compensating' | 'compensated';
+type Row = { name: string; attempt: number; status: Status; t0: number; t1?: number; comp?: boolean; waited?: boolean };
+
+const STOPPED = Symbol('stopped');
+const PARKED = Symbol('parked');
+class StepFailed extends Error {}
+
+const LABEL: Record = {
+ pending: 'Pending', running: 'Running', waiting: 'Waiting', completed: 'Completed', failed: 'Failed',
+ compensating: 'Compensating', compensated: 'Compensated',
+};
+const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
+const fmt = (ms: number) => (ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(1)}s`);
+const ids = (nodes: Node[]): string[] =>
+ nodes.flatMap((n) => ('parallel' in n ? n.parallel.map((s) => s.step) : 'branch' in n ? [`branch:${n.branch}`, ...Object.values(n.clauses).flatMap(ids)] : [n.step]));
+
+function h(tag: K, cls = '', text = '') {
+ const el = document.createElement(tag);
+ if (cls) el.className = cls;
+ if (text) el.append(...rich(text));
+ return el;
+}
+// `backticks` become ; everything else is text, never HTML.
+function rich(text: string) {
+ return text.split('`').map((part, i) => (i % 2 ? Object.assign(document.createElement('code'), { textContent: part }) : document.createTextNode(part)));
+}
+
+export class Sim {
+ private steps = new Map();
+ private lines = new Map();
+ private failing = new Set();
+ private ui: Record;
+ private gnodes = new Map();
+ private gedges: SVGGElement[] = [];
+
+ private gen = 0; // bumps on "Run again"; stale timers check it
+ private epoch = 0;
+ private t0 = 0;
+ private tEnd = 0;
+ private status: Status | 'pending' = 'pending';
+ private rows: Row[] = [];
+ private done = new Set();
+ private order: string[] = [];
+ private answers = new Map();
+ private ctx: Record = {};
+ private parked: { step: Step; row: Row } | null = null;
+ private failed = false;
+ private seen = new Set();
+ private taken = new Map(); // branch -> clause key
+ private skipped = new Set(); // node ids on branches not taken
+ private runId = '';
+
+ constructor(private root: HTMLElement, private spec: Spec) {
+ const index = (nodes: Node[]) =>
+ nodes.forEach((n) => ('parallel' in n ? n.parallel.forEach((s) => this.steps.set(s.step, s)) : 'branch' in n ? Object.values(n.clauses).forEach(index) : this.steps.set(n.step, n)));
+ index(spec.nodes);
+ this.ui = Object.fromEntries([...root.querySelectorAll('[data-ui]')].map((el) => [el.dataset.ui!, el]));
+ root.querySelectorAll('[data-node]').forEach((g) => this.gnodes.set(g.dataset.node!, g));
+ this.gedges = [...root.querySelectorAll('[data-from]')];
+ this.mapLines();
+ this.changed();
+ this.frame();
+ }
+
+ // Each step's block in the code panel: from `step :name` to its `end`.
+ private mapLines() {
+ const lines = [...this.root.querySelectorAll('.code .line')];
+ lines.forEach((line, i) => {
+ const m = /^(\s*)(?:step|compensate) :(\w+)/.exec(line.textContent ?? '');
+ if (!m) return;
+ let j = i;
+ if (!/\bend\s*$/.test(line.textContent!)) {
+ while (j < lines.length - 1 && !(lines[++j].textContent!.startsWith(`${m[1]}end`)));
+ }
+ this.lines.set(m[2], lines.slice(i, j + 1));
+ });
+ }
+
+ start() {
+ this.gen++;
+ this.epoch++;
+ Object.assign(this, {
+ t0: performance.now(), tEnd: 0, status: 'pending', rows: [], order: [], ctx: {}, parked: null, failed: false,
+ runId: Math.random().toString(16).slice(2, 8),
+ });
+ this.done = new Set();
+ this.answers = new Map();
+ this.seen = new Set();
+ this.taken = new Map();
+ this.skipped = new Set();
+ this.ui.log.replaceChildren();
+ this.say(this.spec.intro ?? `\`Durable.start(${this.spec.module}, input)\` queued a run.`);
+ this.later(400, () => this.resume(true));
+ }
+
+ private now() { return performance.now() - this.t0; }
+ private later(ms: number, fn: () => void) {
+ const g = this.gen;
+ setTimeout(() => g === this.gen && fn(), ms);
+ }
+
+ private resume(first: boolean) {
+ this.status = this.failed ? 'compensating' : 'running';
+ this.say(first ? 'A worker picked up the run.' : 'The run resumed. Finished steps are skipped, not run again.');
+ this.exec(this.epoch);
+ }
+
+ private async exec(e: number) {
+ try {
+ if (!this.failed) {
+ await this.walk(this.spec.nodes, e);
+ this.finish('completed', 'Run completed.');
+ return;
+ }
+ } catch (x) {
+ if (x === STOPPED || x === PARKED) return;
+ if (!(x instanceof StepFailed)) throw x;
+ this.failed = true;
+ }
+ try {
+ await this.compensate(e);
+ } catch (x) {
+ if (x !== STOPPED) throw x;
+ }
+ }
+
+ private async walk(nodes: Node[], e: number): Promise {
+ for (const n of nodes) {
+ if ('parallel' in n) {
+ const results = await Promise.allSettled(n.parallel.map((s) => this.run(s, e)));
+ const err = results.find((r) => r.status === 'rejected') as PromiseRejectedResult | undefined;
+ if (err) throw err.reason;
+ } else if ('branch' in n) {
+ const value = this.ctx[n.branch];
+ const key = value in n.clauses ? value : '_';
+ if (!this.taken.has(n.branch)) {
+ this.taken.set(n.branch, key);
+ for (const [k, clause] of Object.entries(n.clauses)) if (k !== key) ids(clause).forEach((id) => this.skipped.add(id));
+ this.say(`Branch on \`${n.branch}\` matched \`${key === '_' ? `_ (${value})` : value}\`.`);
+ }
+ await this.walk(n.clauses[key], e);
+ } else {
+ await this.run(n, e);
+ }
+ }
+ }
+
+ private async run(s: Step, e: number) {
+ if (this.done.has(s.step)) return;
+ // Resuming after a wait: the wait is over, and the step body runs again.
+ const waited = this.parked?.step === s ? this.parked.row : null;
+ this.parked = null;
+ let attempt = waited?.attempt ?? (this.rows.findLast((r) => r.name === s.step)?.attempt ?? 0) + 1;
+ let row = waited ? Object.assign(waited, { status: 'running' as Status }) : this.row(s.step, attempt);
+ if (waited) this.changed();
+
+ for (;;) {
+ await this.tick(waited ? 300 : (s.ms ?? 600) * (0.8 + Math.random() * 0.4), e);
+ if ((s.wait || s.sleep) && !this.answers.has(s.step)) this.park(s, row);
+ if (s.as) this.ctx[s.as] = this.answers.get(s.step)!;
+
+ if (!this.failing.has(s.step) && attempt > (s.flaky ?? 0)) {
+ Object.assign(row, { status: 'completed', t1: this.now() });
+ this.done.add(s.step);
+ this.order.push(s.step);
+ this.changed();
+ return;
+ }
+
+ Object.assign(row, { status: 'failed', t1: this.now() });
+ const err = s.error ?? 'raised an error';
+ if (attempt >= (s.retry ?? 1)) {
+ this.say(`\`${s.step}\` failed: ${err}.${s.retry ? ` Out of retries (${s.retry} attempts).` : ''}`);
+ throw new StepFailed();
+ }
+ const backoff = 1000 * 2 ** (attempt - 1);
+ this.say(`\`${s.step}\` failed: ${err}. Retrying in ${backoff / 1000}s (attempt ${attempt + 1} of ${s.retry}).`);
+ this.changed();
+ await this.tick(backoff, e);
+ row = this.row(s.step, ++attempt);
+ }
+ }
+
+ // Suspend: the run waits as a row in the database until it's answered.
+ private park(s: Step, row: Row): never {
+ Object.assign(row, { status: 'waiting', waited: true, t0: this.now() });
+ this.parked = { step: s, row };
+ this.status = 'waiting';
+ if (s.sleep) {
+ this.say(`\`${s.step}\` called \`${s.sleep}\`. The run is suspended; no process holds it while it sleeps.`);
+ this.later(2600, () => this.answer(s.step, 'woke', 'The wake-up time came (sped up here).'));
+ } else {
+ this.say(`\`${s.step}\` is waiting: ${s.wait!.says}. No process holds the run while it waits.`);
+ const auto = s.wait!.auto;
+ if (auto !== undefined) {
+ const a = s.wait!.actions[auto];
+ this.later(5000, () => this.answer(s.step, a.value, a.call));
+ }
+ }
+ this.changed();
+ throw PARKED;
+ }
+
+ private answer(step: string, value: string, said: string) {
+ if (this.parked?.step.step !== step || this.answers.has(step)) return;
+ this.answers.set(step, value);
+ this.say(said);
+ this.later(300, () => this.resume(false));
+ }
+
+ private async compensate(e: number) {
+ const stack = this.order.map((n) => this.steps.get(n)!).filter((s) => s.compensate).reverse();
+ if (!stack.length) return this.finish('failed', 'Run failed. No compensations to run.');
+ if (!this.seen.has('comp')) {
+ this.seen.add('comp');
+ this.status = 'compensating';
+ this.say(`Rolling back: ${stack.map((s) => `\`${s.compensate}\``).join(', then ')}.`);
+ }
+ for (const s of stack) {
+ const name = s.compensate!;
+ if (this.done.has(`comp:${name}`)) continue;
+ const row = this.row(name, 1, true);
+ await this.tick(700, e);
+ Object.assign(row, { status: 'compensated', t1: this.now() });
+ this.done.add(`comp:${name}`);
+ this.changed();
+ }
+ this.finish('compensated', 'Run compensated. Everything it booked was undone.');
+ }
+
+ private finish(status: Status, said: string) {
+ this.status = status;
+ this.tEnd = this.now();
+ this.say(said);
+ }
+
+ // Flipping a toggle starts a fresh run, so its effect shows right away.
+ toggle(step: string, on: boolean) {
+ if (on) this.failing.add(step);
+ else this.failing.delete(step);
+ this.start();
+ }
+
+ private async tick(ms: number, e: number) {
+ await sleep(ms);
+ if (e !== this.epoch) throw STOPPED;
+ }
+
+ private row(name: string, attempt: number, comp = false) {
+ const r: Row = { name, attempt, status: comp ? 'compensating' : 'running', t0: this.now(), comp };
+ this.rows.push(r);
+ this.changed();
+ return r;
+ }
+
+ private say(text: string) {
+ const li = h('li');
+ li.append(h('span', 'at', `+${(this.now() / 1000).toFixed(1)}s`), h('span', '', text));
+ this.ui.log.append(li);
+ this.ui.log.scrollTop = this.ui.log.scrollHeight;
+ this.changed();
+ }
+
+ // The latest attempt of a graph node (a step, or a compensation as comp:name).
+ private latest(id: string) {
+ const comp = id.startsWith('comp:');
+ const name = comp ? id.slice(5) : id;
+ return this.rows.findLast((r) => r.name === name && !!r.comp === comp);
+ }
+
+ private stateOf(id: string): string {
+ if (id === 'start') return this.status === 'pending' ? 'pending' : 'completed';
+ if (id === 'end') return ['completed', 'failed', 'compensated'].includes(this.status) ? this.status : 'pending';
+ if (id.startsWith('branch:')) return this.taken.has(id.slice(7)) ? 'completed' : 'pending';
+ if (this.skipped.has(id)) return 'skipped';
+ return this.latest(id)?.status ?? 'pending';
+ }
+
+ // Repaints header, graph, code gutter and controls. Timers are updated every frame.
+ private changed() {
+ const { ui } = this;
+ ui.status.className = `pill st-${this.status}`;
+ ui.status.replaceChildren(h('i', 'st'), document.createTextNode(LABEL[this.status]));
+ ui.run.textContent = this.runId ? `run ${this.runId}` : '';
+
+ for (const [id, g] of this.gnodes) g.setAttribute('class', `gn ${g.dataset.kind} st-${this.stateOf(id)}`);
+ // An edge lights up when its source finished (or was undone) and its target ran.
+ const ran = (st: string) => st !== 'pending' && st !== 'skipped';
+ const finished = (st: string) => st === 'completed' || st === 'compensated';
+ for (const g of this.gedges) {
+ const from = this.stateOf(g.dataset.from!), to = this.stateOf(g.dataset.to!);
+ g.classList.toggle('drawn', finished(from) && ran(to));
+ g.classList.toggle('dim', from === 'skipped' || to === 'skipped');
+ }
+ // On a narrow screen the graph scrolls sideways; keep the active step in view.
+ const active = [...this.gnodes].find(([id]) => ['running', 'waiting', 'compensating'].includes(this.stateOf(id)))?.[1];
+ const wrap = active?.closest('.graph-wrap');
+ if (active && wrap && wrap.scrollWidth > wrap.clientWidth) {
+ const a = active.getBoundingClientRect(), w = wrap.getBoundingClientRect();
+ if (a.left < w.left || a.right > w.right) wrap.scrollBy({ left: a.left + a.width / 2 - (w.left + w.width / 2) });
+ }
+
+ for (const [name, els] of this.lines) {
+ const r = this.rows.findLast((x) => x.name === name);
+ for (const el of els) el.className = `line${r ? ` on st-${r.status}` : ''}`;
+ }
+
+ const parked = this.parked?.step;
+ const actions: HTMLElement[] = [];
+ if (parked?.wait && !this.answers.has(parked.step)) {
+ for (const a of parked.wait.actions) {
+ const b = h('button', 'act', a.label);
+ b.onclick = () => this.answer(parked.step, a.value, a.call);
+ actions.push(b);
+ }
+ }
+ if (parked?.sleep && !this.answers.has(parked.step)) {
+ const b = h('button', 'act', 'Skip ahead');
+ b.onclick = () => this.answer(parked.step, 'woke', 'Skipped ahead to the wake-up time.');
+ actions.push(b);
+ }
+ if (['completed', 'failed', 'compensated'].includes(this.status)) {
+ const b = h('button', 'act primary', 'Run again');
+ b.onclick = () => this.start();
+ actions.push(b);
+ }
+ ui.actions.replaceChildren(...actions);
+ }
+
+ // Live durations and notes under each node.
+ private frame() {
+ const now = this.tEnd || this.now();
+ for (const [id, g] of this.gnodes) {
+ const meta = g.querySelector('.meta');
+ if (!meta) continue;
+ const st = this.stateOf(id);
+ const r = this.latest(id);
+ let text = '';
+ if (st === 'skipped') text = 'not run';
+ else if (r) {
+ const d = fmt((r.t1 ?? now) - r.t0);
+ const attempt = r.attempt > 1 ? `attempt ${r.attempt}, ` : '';
+ text =
+ r.status === 'waiting' ? (this.steps.get(r.name)?.sleep ? `sleeping ${d}` : `waiting ${d}`)
+ : r.status === 'failed' ? `${attempt}failed`
+ : r.status === 'compensated' ? 'undone'
+ : r.status === 'compensating' ? 'undoing'
+ : `${attempt}${d}`;
+ }
+ if (meta.textContent !== text) meta.textContent = text;
+ }
+ requestAnimationFrame(() => this.frame());
+ }
+}
diff --git a/site/src/sim/layout.ts b/site/src/sim/layout.ts
new file mode 100644
index 0000000..7265491
--- /dev/null
+++ b/site/src/sim/layout.ts
@@ -0,0 +1,120 @@
+// Lays a workflow spec out as a left-to-right graph: sequential steps become
+// columns, parallel steps stack in one column, a branch is a gate followed by
+// one row per clause, and compensations sit in a lane underneath. Computed at
+// build time; the engine only toggles classes on what this produces.
+import type { Node, Spec, Step } from './engine';
+
+export type GNode = { id: string; label: string; kind: 'start' | 'step' | 'gate' | 'end' | 'comp'; x: number; y: number; w: number };
+export type GEdge = { from: string; to: string; d: string; label?: string; lx?: number; ly?: number; comp?: boolean };
+export type Graph = { width: number; height: number; nodes: GNode[]; edges: GEdge[] };
+
+type Cell = { id: string; label: string; kind: GNode['kind']; col: number; row: number; room?: number };
+type Link = { from: string; to: string; label?: string };
+type Block = { cols: number; rows: number; entry: string[]; exit: string[]; cells: Cell[]; links: Link[] };
+
+const ROW = 96;
+const PAD = 26;
+const GAP = 48;
+// A gate's column is as wide as its longest branch label, so the label chips fit
+// between the gate and its clauses.
+const pill = (c: Cell) => (c.kind === 'start' || c.kind === 'end' ? 64 : c.kind === 'gate' ? (c.room ?? 96) : Math.round(c.label.length * 7.5 + 40));
+
+const single = (id: string, label: string, kind: Cell['kind']): Block => ({
+ cols: 1, rows: 1, entry: [id], exit: [id], cells: [{ id, label, kind, col: 0, row: 0 }], links: [],
+});
+const shift = (b: Block, dc: number, dr: number): Block => ({ ...b, cells: b.cells.map((c) => ({ ...c, col: c.col + dc, row: c.row + dr })) });
+
+// Blocks one after another, vertically centred on each other.
+function seq(blocks: Block[]): Block {
+ const rows = Math.max(1, ...blocks.map((b) => b.rows));
+ const cells: Cell[] = [];
+ const links: Link[] = [];
+ let col = 0;
+ blocks.forEach((b, i) => {
+ cells.push(...shift(b, col, (rows - b.rows) / 2).cells);
+ links.push(...b.links);
+ if (i > 0) for (const from of blocks[i - 1].exit) for (const to of b.entry) links.push({ from, to });
+ col += b.cols;
+ });
+ return { cols: col, rows, entry: blocks[0].entry, exit: blocks.at(-1)!.exit, cells, links };
+}
+
+// Blocks on top of each other (parallel steps, branch clauses).
+function stack(blocks: Block[]): Block {
+ const cells: Cell[] = [];
+ const links: Link[] = [];
+ let row = 0;
+ for (const b of blocks) {
+ cells.push(...shift(b, 0, row).cells);
+ links.push(...b.links);
+ row += b.rows;
+ }
+ return { cols: Math.max(...blocks.map((b) => b.cols)), rows: row, entry: blocks.flatMap((b) => b.entry), exit: blocks.flatMap((b) => b.exit), cells, links };
+}
+
+function block(n: Node): Block {
+ if ('parallel' in n) return stack(n.parallel.map((s) => single(s.step, s.step, 'step')));
+ if ('branch' in n) {
+ const gate = `branch:${n.branch}`;
+ const clauses = Object.entries(n.clauses).map(([key, nodes]) => ({ key, b: seq(nodes.map(block)) }));
+ const body = stack(clauses.map((c) => c.b));
+ const rows = Math.max(1, body.rows);
+ const labeled: Link[] = clauses.flatMap((c) => c.b.entry.map((to) => ({ from: gate, to, label: c.key === '_' ? 'otherwise' : c.key })));
+ return {
+ cols: 1 + body.cols, rows, entry: [gate], exit: body.exit,
+ cells: [{ id: gate, label: n.branch, kind: 'gate', col: 0, row: (rows - 1) / 2, room: Math.max(96, ...labeled.map((l) => l.label!.length * 7.2 + 64)) }, ...shift(body, 1, 0).cells],
+ links: [...labeled, ...body.links],
+ };
+ }
+ return single(n.step, n.step, 'step');
+}
+
+// Steps that declare a compensation, in the order they run.
+function compensated(nodes: Node[]): Step[] {
+ return nodes.flatMap((n) => ('parallel' in n ? n.parallel : 'branch' in n ? Object.values(n.clauses).flatMap(compensated) : [n])).filter((s) => s.compensate);
+}
+
+export function layout(spec: Spec): Graph {
+ const main = seq([single('start', 'start', 'start'), ...spec.nodes.map(block), single('end', 'done', 'end')]);
+ const comps = compensated(spec.nodes);
+ const cells = [...main.cells];
+ const links: Link[] = [...main.links];
+ const compRow = main.rows;
+ for (const s of comps) {
+ const owner = cells.find((c) => c.id === s.step)!;
+ cells.push({ id: `comp:${s.compensate}`, label: s.compensate!, kind: 'comp', col: owner.col, row: compRow });
+ }
+
+ // Column widths fit their widest node.
+ const widths: number[] = [];
+ for (const c of cells) widths[c.col] = Math.max(widths[c.col] ?? 0, pill(c));
+ const xs: number[] = [];
+ widths.reduce((x, w, i) => ((xs[i] = x + w / 2), x + w + GAP), PAD);
+ // A gate sits at the left of its wide column; the space to its right holds the branch labels.
+ const nodes: GNode[] = cells.map((c) => ({
+ id: c.id, label: c.label, kind: c.kind, w: c.kind === 'gate' ? 40 : pill(c),
+ x: c.kind === 'gate' ? xs[c.col] - widths[c.col] / 2 + 28 : xs[c.col], y: PAD + c.row * ROW + ROW / 2,
+ }));
+ const at = new Map(nodes.map((n) => [n.id, n]));
+
+ const edges: GEdge[] = links.map(({ from, to, label }) => {
+ const a = at.get(from)!, b = at.get(to)!;
+ const sx = a.x + a.w / 2, tx = b.x - b.w / 2, mx = (sx + tx) / 2;
+ // Branch labels ride on the middle of their edge.
+ return { from, to, label, d: `M${sx} ${a.y} C${mx} ${a.y} ${mx} ${b.y} ${tx} ${b.y}`, lx: mx, ly: (a.y + b.y) / 2 };
+ });
+ // Compensation lane: each step points down to its undo, and the undos chain right to left.
+ comps.forEach((s, i) => {
+ const step = at.get(s.step)!, comp = at.get(`comp:${s.compensate}`)!;
+ edges.push({ from: s.step, to: comp.id, comp: true, d: `M${step.x} ${step.y + 17} V${comp.y - 17}` });
+ const prev = comps[i - 1];
+ if (prev) {
+ const left = at.get(`comp:${prev.compensate}`)!;
+ edges.push({ from: comp.id, to: left.id, comp: true, d: `M${comp.x - comp.w / 2} ${comp.y} H${left.x + left.w / 2}` });
+ }
+ });
+
+ const width = Math.round(xs.at(-1)! + widths.at(-1)! / 2 + PAD);
+ const height = Math.round(PAD * 2 + (compRow + (comps.length ? 1 : 0)) * ROW);
+ return { width, height, nodes, edges };
+}
diff --git a/site/src/sim/sim.css b/site/src/sim/sim.css
new file mode 100644
index 0000000..fc86263
--- /dev/null
+++ b/site/src/sim/sim.css
@@ -0,0 +1,140 @@
+/* The run is always the Night palette, in both site themes.
+ Status shapes follow durable_dashboard DESIGN.md §4. */
+.sim {
+ --s-bg: #111a2e;
+ --s-deep: #0c1322;
+ --s-rule: #22304a;
+ --s-ink: #eaeff9;
+ --s-ink-2: #9ca8c2;
+ --s-ink-3: #8390ab;
+ --s-accent: #a9c1ff;
+ --s-run: #a9c1ff;
+ --s-ok: #2bb3a3;
+ --s-fail: #f0718a;
+ --s-wait: #ffc27a;
+ --s-comp: #9ebcfd;
+ --s-off: #6b7380;
+ background: var(--s-bg);
+ color: var(--s-ink);
+ border: 1px solid var(--s-rule);
+ border-radius: 20px;
+ overflow: hidden;
+ font: 14px/1.55 var(--sl-font, 'Sora Variable', system-ui, sans-serif);
+}
+.sim .head {
+ display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; min-height: 58px; padding: 10px 22px;
+ border-bottom: 1px solid var(--s-rule); font: 13px var(--sl-font-mono, monospace); box-sizing: border-box;
+}
+.sim .wf { font-weight: 500; }
+.sim .runid { color: var(--s-ink-3); }
+
+.st-pending, .st-skipped { --c: var(--s-off); }
+.st-running { --c: var(--s-run); }
+.st-waiting { --c: var(--s-wait); }
+.st-completed { --c: var(--s-ok); }
+.st-failed { --c: var(--s-fail); }
+.st-compensating, .st-compensated { --c: var(--s-comp); }
+
+.sim .pill {
+ display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px; border-radius: 999px;
+ font: 13px var(--sl-font, sans-serif); background: color-mix(in srgb, var(--c) 16%, transparent);
+ color: color-mix(in srgb, var(--c) 60%, var(--s-ink));
+}
+.sim .pill .st { width: 8px; height: 8px; border-radius: 50%; background: var(--c); }
+.sim .pill.st-pending .st { background: none; border: 1.5px dashed var(--c); box-sizing: border-box; }
+.sim .pill.st-waiting .st { background: none; border: 2px solid var(--c); box-sizing: border-box; }
+.sim .pill.st-failed .st { border-radius: 1px; transform: rotate(45deg) scale(0.85); }
+
+/* Controls sit in the head, right-aligned. */
+.sim .controls { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; font-family: var(--sl-font, sans-serif); }
+.sim .actions { display: flex; flex-wrap: wrap; gap: 8px; }
+.sim .act {
+ height: 36px; padding: 0 16px; border-radius: 999px; cursor: pointer; font: 500 13.5px var(--sl-font, sans-serif);
+ color: var(--s-ink); background: transparent; border: 1px solid var(--s-rule); transition: border-color 0.2s;
+}
+.sim .act:hover { border-color: var(--s-ink-3); }
+.sim .act.primary { background: var(--s-accent); border-color: var(--s-accent); color: #0c172e; font-weight: 600; }
+.sim .act:focus-visible, .sim .toggle input:focus-visible { outline: 2px solid var(--s-accent); outline-offset: 2px; }
+.sim .toggle { display: inline-flex; align-items: center; gap: 8px; color: var(--s-ink-2); cursor: pointer; font-size: 13.5px; }
+.sim .toggle input { accent-color: var(--s-fail); margin: 0; }
+
+/* The graph: scales down to fit, but never below a readable size (then it scrolls). */
+.sim .graph-wrap {
+ overflow-x: auto; scroll-behavior: smooth; padding: 18px 16px; scrollbar-width: thin; scrollbar-color: var(--s-rule) transparent;
+ background:
+ radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.05) 1px, transparent 0) 0 0 / 22px 22px,
+ var(--s-deep);
+ border-bottom: 1px solid var(--s-rule);
+}
+.sim .graph { display: block; width: 100%; max-width: calc(var(--w) * 1.3); min-width: calc(var(--w) * 0.8); height: auto; margin: 0 auto; overflow: visible; }
+
+.sim .ge .rail { fill: none; stroke: rgba(255, 255, 255, 0.1); stroke-width: 1.5; }
+.sim .ge .ink { fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 0.55s cubic-bezier(0.4, 0, 0.2, 1); }
+.sim .ge.drawn .ink { stroke-dashoffset: 0; }
+.sim .ge.dim .rail { stroke-dasharray: 3 4; opacity: 0.5; }
+.sim .ge.comp .rail { stroke-dasharray: 3 4; }
+.sim .ge.comp .ink { stroke: var(--s-comp); stroke-dasharray: 1; }
+.sim .elabel rect { fill: var(--s-deep); stroke: rgba(255, 255, 255, 0.12); }
+.sim .elabel text { font: 11.5px var(--sl-font-mono, monospace); fill: var(--s-ink-2); }
+.sim .ge.drawn .elabel rect { stroke: color-mix(in srgb, var(--s-accent) 50%, transparent); }
+.sim .ge.drawn .elabel text { fill: var(--s-ink); }
+.sim .ge.dim .elabel { opacity: 0.45; }
+
+.sim .gn .shape { fill: #141f36; stroke: color-mix(in srgb, var(--c) 55%, transparent); stroke-width: 1.5; transition: stroke 0.3s, fill 0.3s; }
+.sim .gn .dot { fill: var(--c); transition: fill 0.3s; }
+.sim .gn .label { font: 12.5px var(--sl-font-mono, monospace); fill: var(--s-ink); transition: fill 0.3s; }
+.sim .gn .label.small { font-size: 11.5px; fill: var(--s-ink-2); }
+.sim .gn .meta { font: 11px var(--sl-font, sans-serif); fill: var(--s-ink-3); }
+.sim .gn.st-pending .label, .sim .gn.st-skipped .label { fill: var(--s-ink-3); }
+.sim .gn.st-pending .dot { fill: none; stroke: var(--c); stroke-width: 1.5; stroke-dasharray: 2 2; }
+.sim .gn.st-skipped { opacity: 0.45; }
+.sim .gn.st-skipped .label { text-decoration: line-through; }
+.sim .gn.st-running .shape, .sim .gn.st-compensating .shape { fill: color-mix(in srgb, var(--c) 14%, #141f36); stroke: var(--c); }
+.sim .gn.st-running .dot, .sim .gn.st-compensating .dot { animation: sim-beat 1.1s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
+.sim .gn.st-waiting .shape { fill: color-mix(in srgb, var(--c) 10%, #141f36); stroke: var(--c); stroke-dasharray: 5 4; animation: sim-march 1s linear infinite; }
+.sim .gn.st-waiting .dot { fill: none; stroke: var(--c); stroke-width: 2; }
+.sim .gn.st-completed .shape { stroke: color-mix(in srgb, var(--c) 70%, transparent); }
+.sim .gn.st-failed .shape { fill: color-mix(in srgb, var(--c) 14%, #141f36); stroke: var(--c); }
+.sim .gn.st-failed .meta { fill: var(--s-fail); }
+.sim .gn.comp.st-pending { opacity: 0.4; }
+.sim .gn.comp.st-pending .shape { stroke-dasharray: 4 4; }
+.sim .gn.comp.st-compensated .shape { fill: color-mix(in srgb, var(--c) 12%, #141f36); }
+/* Start, gate and end are small markers. */
+.sim .gn.start .shape, .sim .gn.end .shape { stroke-width: 2; }
+.sim .gn.start.st-completed .shape { fill: var(--s-ok); }
+.sim .gn.end.st-completed .shape { fill: var(--s-wait); stroke: var(--s-wait); filter: drop-shadow(0 0 10px rgba(255, 194, 122, 0.6)); }
+.sim .gn.end.st-compensated .shape { fill: var(--s-comp); }
+.sim .gn.end.st-failed .shape { fill: var(--s-fail); }
+.sim .gn.gate.st-completed .shape { fill: color-mix(in srgb, var(--s-accent) 22%, #141f36); stroke: var(--s-accent); }
+@keyframes sim-beat { 50% { transform: scale(1.5); opacity: 0.6; } }
+@keyframes sim-march { to { stroke-dashoffset: -18; } }
+
+/* Code + log */
+.sim .foot { display: flex; flex-wrap: wrap; }
+.sim .code { flex: 1.5 1 440px; min-width: 0; border-right: 1px solid var(--s-rule); background: var(--s-deep); }
+.sim .file { padding: 12px 22px 0; font: 12px var(--sl-font-mono, monospace); color: var(--s-ink-3); }
+.sim .code pre.astro-code {
+ margin: 0; padding: 10px 0 16px; background: transparent !important; font: 12.5px/1.7 var(--sl-font-mono, monospace);
+ overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--s-rule) transparent; border: 0;
+}
+.sim .code .line { display: inline-block; min-width: 100%; padding: 0 22px; box-sizing: border-box; transition: background-color 0.2s; }
+.sim .code .line.on { box-shadow: inset 3px 0 var(--c); }
+.sim .code .line.on.st-running, .sim .code .line.on.st-waiting, .sim .code .line.on.st-compensating { background: color-mix(in srgb, var(--c) 10%, transparent); }
+.sim .log {
+ flex: 1 1 280px; min-width: 0; list-style: none; margin: 0; padding: 14px 22px; max-height: 460px; overflow-y: auto;
+ color: var(--s-ink-2); font-size: 13px; scrollbar-width: thin; scrollbar-color: var(--s-rule) transparent;
+}
+.sim .log li { display: grid; grid-template-columns: 48px 1fr; gap: 8px; padding: 2px 0; margin: 0; }
+.sim .log li:last-child { color: var(--s-ink); }
+.sim .log .at { font: 11.5px var(--sl-font-mono, monospace); padding-top: 2px; color: var(--s-ink-3); }
+.sim .log code { font: 12px var(--sl-font-mono, monospace); color: var(--s-ink); background: none; padding: 0; }
+
+@media (max-width: 640px) {
+ .sim .head, .sim .log { padding-left: 14px; padding-right: 14px; }
+ .sim .controls { margin-left: 0; width: 100%; min-height: 36px; }
+ .sim .code { border-right: 0; border-bottom: 1px solid var(--s-rule); max-height: 320px; overflow: auto; }
+}
+@media (prefers-reduced-motion: reduce) {
+ .sim * { animation: none !important; transition: none !important; }
+ .sim .graph-wrap { scroll-behavior: auto; }
+}
diff --git a/site/src/styles/fonts.css b/site/src/styles/fonts.css
new file mode 100644
index 0000000..071eb2d
--- /dev/null
+++ b/site/src/styles/fonts.css
@@ -0,0 +1,37 @@
+/* Self-hosted fonts (files from Fontsource), declared here rather than through
+ Fontsource's CSS so we can use font-display: optional. Together with the
+ preloads in FontPreload.astro, text paints in Sora from the first frame and
+ never swaps (no reflow on page load); if a font isn't ready in time, that one
+ page view keeps the fallback instead of shifting under the reader. */
+@font-face {
+ font-family: 'Sora Variable';
+ font-style: normal;
+ font-display: optional;
+ font-weight: 100 800;
+ src: url('../../node_modules/@fontsource-variable/sora/files/sora-latin-wght-normal.woff2') format('woff2-variations');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+@font-face {
+ font-family: 'Sora Variable';
+ font-style: normal;
+ font-display: optional;
+ font-weight: 100 800;
+ src: url('../../node_modules/@fontsource-variable/sora/files/sora-latin-ext-wght-normal.woff2') format('woff2-variations');
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+@font-face {
+ font-family: 'Geist Mono';
+ font-style: normal;
+ font-display: optional;
+ font-weight: 400;
+ src: url('../../node_modules/@fontsource/geist-mono/files/geist-mono-latin-400-normal.woff2') format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+@font-face {
+ font-family: 'Geist Mono';
+ font-style: normal;
+ font-display: optional;
+ font-weight: 500;
+ src: url('../../node_modules/@fontsource/geist-mono/files/geist-mono-latin-500-normal.woff2') format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
diff --git a/site/src/styles/theme.css b/site/src/styles/theme.css
new file mode 100644
index 0000000..20539e6
--- /dev/null
+++ b/site/src/styles/theme.css
@@ -0,0 +1,165 @@
+/* Blue hour: Starlight's tokens set to the landing page's palette.
+ Dark is the main look; light mirrors it for people who choose it. */
+:root {
+ --sl-font: 'Sora Variable', system-ui, sans-serif;
+ --sl-font-mono: 'Geist Mono', ui-monospace, monospace;
+
+ --sl-color-accent-low: #1d2f55;
+ --sl-color-accent: #6997fc;
+ --sl-color-accent-high: #a9c1ff;
+ --sl-color-white: #eaeff9;
+ --sl-color-gray-1: #d6def0;
+ --sl-color-gray-2: #b2bdd6;
+ --sl-color-gray-3: #9ca8c2;
+ --sl-color-gray-4: #637294;
+ --sl-color-gray-5: #22304a;
+ --sl-color-gray-6: #111a2e;
+ --sl-color-black: #0a0f1e;
+}
+
+:root[data-theme='light'] {
+ --sl-color-accent-low: #e0eaff;
+ --sl-color-accent: #3a6ad8;
+ --sl-color-accent-high: #21438e;
+ --sl-color-white: #0e182d;
+ --sl-color-gray-1: #1d2840;
+ --sl-color-gray-2: #323f5a;
+ --sl-color-gray-3: #4e5d7e;
+ --sl-color-gray-4: #8793ae;
+ --sl-color-gray-5: #d1d8e8;
+ --sl-color-gray-6: #eaeef8;
+ --sl-color-gray-7: #f4f7fd;
+ --sl-color-black: #ffffff;
+}
+
+/* Headings: tight, like the concept. */
+.sl-markdown-content :is(h1, h2, h3) { letter-spacing: -0.02em; }
+h1#_top { letter-spacing: -0.035em; }
+
+/* Starlight's pill-shaped primary links match the concept's buttons. */
+.sl-link-button { border-radius: 999px; }
+
+/* Wordmark in ink, not the accent. */
+.site-title { color: var(--sl-color-white); font-weight: 600; letter-spacing: -0.02em; }
+
+/* Page-to-page navigation without the blink: the browser cross-fades the
+ content and keeps the header and sidebar where they are. Browsers without
+ cross-document view transitions just navigate as before. */
+@view-transition { navigation: auto; }
+/* Always reserve the scrollbar's space, so nothing slides sideways when a long
+ page grows a scrollbar mid-load or when moving between short and long pages. */
+html { scrollbar-gutter: stable; }
+header.header { view-transition-name: sl-header; }
+/* The visible sidebar is the fixed pane; nav.sidebar itself is 0px tall, so naming it captured nothing. */
+.sidebar-pane { view-transition-name: sl-sidebar; }
+::view-transition-old(root), ::view-transition-new(root) { animation-duration: 180ms; }
+@media (prefers-reduced-motion: reduce) {
+ @view-transition { navigation: none; }
+}
+
+/* README badges sit on one line, with their height reserved before they load. */
+.sl-markdown-content p:has(> a > img[src*='shields.io'], > a > img[src*='badge.svg']) { display: flex; flex-wrap: wrap; gap: 6px; }
+.sl-markdown-content a > img[src*='shields.io'], .sl-markdown-content a > img[src*='badge.svg'] { display: block; height: 20px; width: auto; margin: 0; }
+
+/* Changelog: a release timeline (the markup comes from src/changelog.ts).
+ Each version heading carries a dot on the rail and draws the rail down from it;
+ the next dot paints over the line, and the content box clips the last one. */
+.sl-markdown-content:has(.cl-meta) {
+ --cl-x: 2rem;
+ --cl-dot: 0.8rem;
+ --cl-feat: var(--sl-color-accent-high);
+ --cl-fix: #ff8fa6;
+ --cl-perf: #ffc27a;
+ --cl-refactor: #7cc4ff;
+ --cl-docs: #5fd4c4;
+ padding-left: var(--cl-x);
+ overflow-y: clip;
+}
+:root[data-theme='light'] .sl-markdown-content:has(.cl-meta) {
+ --cl-fix: #c2264b;
+ --cl-perf: #9a5200;
+ --cl-refactor: #1d6aae;
+ --cl-docs: #0b7468;
+}
+.sl-markdown-content:has(.cl-meta) > p:first-child { color: var(--sl-color-gray-3); font-size: var(--sl-text-sm); }
+.sl-markdown-content .cl-version {
+ position: relative; margin-top: 3.5rem;
+ font: 600 1.9rem/1.2 var(--sl-font); letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
+}
+.sl-markdown-content p + .cl-version { margin-top: 2.25rem; }
+.cl-version::before, .cl-version::after { content: ''; position: absolute; left: calc(-1 * var(--cl-x) + 0.1rem); }
+.cl-version::before {
+ z-index: 1; top: 0.32em; width: var(--cl-dot); height: var(--cl-dot); box-sizing: border-box; border-radius: 50%;
+ background: var(--sl-color-black); border: 2px solid var(--sl-color-gray-4);
+}
+.cl-version::after {
+ top: calc(0.32em + var(--cl-dot)); height: 100000px; width: 2px;
+ margin-left: calc(var(--cl-dot) / 2 - 1px); background: var(--sl-color-gray-5);
+}
+.cl-version:has(+ .cl-meta .cl-latest)::before {
+ background: var(--sl-color-accent); border-color: var(--sl-color-accent-high);
+ box-shadow: 0 0 0 4px var(--sl-color-accent-low);
+}
+.sl-markdown-content .cl-meta {
+ display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem; margin-top: 0.5rem;
+ font-size: var(--sl-text-sm); color: var(--sl-color-gray-3);
+}
+.cl-badge {
+ display: inline-flex; align-items: center; height: 1.35rem; padding: 0 0.55rem; border-radius: 999px;
+ font-size: 0.75rem; font-weight: 600; line-height: 1;
+}
+.cl-latest { background: var(--sl-color-accent-low); color: var(--sl-color-accent-high); }
+.cl-pre { border: 1px solid var(--sl-color-gray-5); color: var(--sl-color-gray-3); }
+.cl-breaking { margin-right: 0.35rem; vertical-align: 0.1em; color: var(--cl-fix); background: color-mix(in srgb, var(--cl-fix) 15%, transparent); }
+.sl-markdown-content a.cl-compare { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--sl-color-accent-high); text-decoration: none; }
+.sl-markdown-content a.cl-compare:hover { text-decoration: underline; }
+.cl-compare::before, .cl-group::before {
+ content: ''; flex: none; width: 1rem; height: 1rem; background: currentColor;
+ mask: var(--cl-icon) center / contain no-repeat;
+}
+.cl-compare { --cl-icon: url("data:image/svg+xml;utf8, "); }
+
+/* Groups: a colored label with its icon, entries aligned under the label text. */
+.sl-markdown-content .cl-group {
+ display: flex; align-items: center; gap: 0.55rem; margin-top: 1.75rem;
+ font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; color: var(--cl-c);
+}
+.sl-markdown-content .cl-group + ul { list-style: none; padding-left: 1.55rem; margin-top: 0.55rem; }
+.sl-markdown-content .cl-group + ul > li { position: relative; margin-top: 0.4rem; }
+.cl-group + ul > li::before {
+ content: ''; position: absolute; left: -1.1rem; top: 0.68em; width: 5px; height: 5px; border-radius: 50%;
+ background: var(--cl-c); opacity: 0.7;
+}
+.cl-feat, .cl-feat + ul {
+ --cl-c: var(--cl-feat);
+ --cl-icon: url("data:image/svg+xml;utf8, ");
+}
+.cl-fix, .cl-fix + ul {
+ --cl-c: var(--cl-fix);
+ --cl-icon: url("data:image/svg+xml;utf8, ");
+}
+.cl-perf, .cl-perf + ul {
+ --cl-c: var(--cl-perf);
+ --cl-icon: url("data:image/svg+xml;utf8, ");
+}
+.cl-refactor, .cl-refactor + ul {
+ --cl-c: var(--cl-refactor);
+ --cl-icon: url("data:image/svg+xml;utf8, ");
+}
+.cl-docs, .cl-docs + ul {
+ --cl-c: var(--cl-docs);
+ --cl-icon: url("data:image/svg+xml;utf8, ");
+}
+
+/* Commit hashes: a quiet chip at the end of each entry. */
+.sl-markdown-content a.cl-commit {
+ display: inline-block; margin-left: 0.15rem; padding: 0 0.4rem; border-radius: 0.35rem;
+ border: 1px solid var(--sl-color-gray-5); vertical-align: 0.08em;
+ font: 500 0.72rem/1.55 var(--sl-font-mono); color: var(--sl-color-gray-3); text-decoration: none; white-space: nowrap;
+}
+.sl-markdown-content a.cl-commit:hover { color: var(--sl-color-accent-high); border-color: var(--sl-color-accent); }
+
+@media (max-width: 50rem) {
+ .sl-markdown-content:has(.cl-meta) { --cl-x: 1.5rem; }
+ .sl-markdown-content .cl-version { font-size: 1.45rem; }
+}
diff --git a/site/tsconfig.json b/site/tsconfig.json
new file mode 100644
index 0000000..8bf91d3
--- /dev/null
+++ b/site/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "astro/tsconfigs/strict",
+ "include": [".astro/types.d.ts", "**/*"],
+ "exclude": ["dist"]
+}
diff --git a/site/wrangler.jsonc b/site/wrangler.jsonc
new file mode 100644
index 0000000..b68dee0
--- /dev/null
+++ b/site/wrangler.jsonc
@@ -0,0 +1,17 @@
+// durable.wavezync.com: the built Astro site (dist/), served as Workers static assets.
+// The site is fully static, so there is no Worker script (`main`) and no ASSETS binding.
+// `pnpm run deploy` builds the site and deploys it.
+{
+ "$schema": "node_modules/wrangler/config-schema.json",
+ "name": "durable-site",
+ "compatibility_date": "2026-10-01",
+ "assets": {
+ "directory": "./dist",
+ // Astro writes docs/index.html; /docs redirects to /docs/ (trailingSlash: 'always').
+ "html_handling": "auto-trailing-slash",
+ // Unknown paths get Astro's 404.html with a 404 status.
+ "not_found_handling": "404-page"
+ },
+ "routes": [{ "pattern": "durable.wavezync.com", "custom_domain": true }],
+ "observability": { "enabled": true }
+}