blume 1.7.2 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cli/chunk-0qymqwzz.js +164 -0
  3. package/dist/cli/chunk-0qymqwzz.js.map +15 -0
  4. package/dist/cli/{chunk-9bkjd11x.js → chunk-0xjyb285.js} +1 -1
  5. package/dist/cli/{chunk-hdm2dkd2.js → chunk-1jefwnfs.js} +13 -7
  6. package/dist/cli/{chunk-hdm2dkd2.js.map → chunk-1jefwnfs.js.map} +3 -3
  7. package/dist/cli/{chunk-n9sra6sy.js → chunk-3r45185y.js} +5 -7
  8. package/dist/cli/{chunk-n9sra6sy.js.map → chunk-3r45185y.js.map} +2 -2
  9. package/dist/cli/{chunk-cvky9gb2.js → chunk-4x36ddpw.js} +3 -3
  10. package/dist/cli/{chunk-mqb2ka8m.js → chunk-5093q3n7.js} +12 -12
  11. package/dist/cli/{chunk-9he6crym.js → chunk-5g0w1e2c.js} +4 -4
  12. package/dist/cli/{chunk-mt76t7dj.js → chunk-5qk08vmp.js} +11 -11
  13. package/dist/cli/{chunk-61j18dwk.js → chunk-7s8hm3b6.js} +7 -2
  14. package/dist/cli/{chunk-61j18dwk.js.map → chunk-7s8hm3b6.js.map} +3 -3
  15. package/dist/cli/{chunk-196vjxp9.js → chunk-8cjtbafj.js} +11 -9
  16. package/dist/cli/{chunk-196vjxp9.js.map → chunk-8cjtbafj.js.map} +2 -2
  17. package/dist/cli/{chunk-aztttvb3.js → chunk-97r59kpr.js} +4 -4
  18. package/dist/cli/{chunk-t3tj0dgr.js → chunk-ahnw3kxw.js} +8 -8
  19. package/dist/cli/{chunk-hs3gbh8p.js → chunk-b27xqwn9.js} +3 -3
  20. package/dist/cli/{chunk-450a7rcr.js → chunk-bf6bt1xt.js} +2 -2
  21. package/dist/cli/{chunk-eevwt1sc.js → chunk-bvwwhd84.js} +13 -13
  22. package/dist/cli/{chunk-12dxjqk7.js → chunk-cjtn640a.js} +17 -17
  23. package/dist/cli/{chunk-12dxjqk7.js.map → chunk-cjtn640a.js.map} +1 -1
  24. package/dist/cli/{chunk-ra1v2nc2.js → chunk-ct47dqpx.js} +14 -3
  25. package/dist/cli/{chunk-ra1v2nc2.js.map → chunk-ct47dqpx.js.map} +4 -3
  26. package/dist/cli/{chunk-ppfvdcd4.js → chunk-dwgcp5sm.js} +1 -1
  27. package/dist/cli/{chunk-3w7b2vcx.js → chunk-e7f42gdj.js} +2 -2
  28. package/dist/cli/{chunk-vkrsvbr5.js → chunk-esphfr8p.js} +8 -8
  29. package/dist/cli/{chunk-vkrsvbr5.js.map → chunk-esphfr8p.js.map} +1 -1
  30. package/dist/cli/{chunk-fmceyezb.js → chunk-ex56aa81.js} +27 -18
  31. package/dist/cli/chunk-ex56aa81.js.map +13 -0
  32. package/dist/cli/{chunk-jbj4qhfw.js → chunk-garjf5z9.js} +2 -2
  33. package/dist/cli/{chunk-wjt80jps.js → chunk-js7saxwm.js} +14 -18
  34. package/dist/cli/{chunk-wjt80jps.js.map → chunk-js7saxwm.js.map} +4 -6
  35. package/dist/cli/{chunk-5n7t497w.js → chunk-k79xp7av.js} +53 -91
  36. package/dist/cli/chunk-k79xp7av.js.map +39 -0
  37. package/dist/cli/{chunk-688e0dde.js → chunk-nn13znc2.js} +1 -1
  38. package/dist/cli/{chunk-ejjx8znq.js → chunk-ps4m1xh4.js} +15 -9
  39. package/dist/cli/{chunk-ejjx8znq.js.map → chunk-ps4m1xh4.js.map} +3 -3
  40. package/dist/cli/{chunk-xhtpx3ff.js → chunk-rqy0s5wh.js} +13 -13
  41. package/dist/cli/{chunk-30e87n55.js → chunk-rz9jmfhz.js} +4 -4
  42. package/dist/cli/{chunk-exeeb35e.js → chunk-vacwm2hv.js} +2 -2
  43. package/dist/cli/{chunk-8cd8tj54.js → chunk-yg63d42r.js} +7 -7
  44. package/dist/cli/index.js +15 -15
  45. package/dist/types/core/config-input.d.ts +33 -0
  46. package/dist/types/core/data.d.ts +2 -0
  47. package/dist/types/core/schema.d.ts +20 -0
  48. package/dist/types/core/types.d.ts +5 -0
  49. package/docs/configuration/ask-ai.mdx +14 -0
  50. package/docs/configuration/index.mdx +3 -1
  51. package/docs/content/navigation.mdx +3 -0
  52. package/docs/content/syntax.mdx +10 -0
  53. package/docs/discoverability/agent-discovery.mdx +82 -1
  54. package/docs/discoverability/index.mdx +1 -1
  55. package/docs/discoverability/llms-txt.mdx +1 -1
  56. package/docs/reference/frontmatter.mdx +2 -0
  57. package/package.json +1 -1
  58. package/src/ai/agent-readability.ts +5 -0
  59. package/src/ai/ai-catalog.ts +241 -0
  60. package/src/ai/link-headers.ts +12 -0
  61. package/src/ai/llms.ts +6 -0
  62. package/src/ai/mcp/discovery.ts +1 -1
  63. package/src/astro/generate.ts +2 -0
  64. package/src/cli/commands/build.ts +3 -1
  65. package/src/components/islands/hooks.ts +50 -1
  66. package/src/components/layout/RootLayout.astro +24 -1
  67. package/src/components/layout/analytics-client.ts +36 -7
  68. package/src/core/config-input.ts +34 -0
  69. package/src/core/data.ts +2 -0
  70. package/src/core/navigation.ts +22 -3
  71. package/src/core/schema.ts +32 -0
  72. package/src/core/types.ts +5 -0
  73. package/src/deploy/artifacts.ts +12 -1
  74. package/src/deploy/headers.ts +6 -0
  75. package/src/deploy/vercel-negotiation.ts +25 -2
  76. package/src/search/build.ts +25 -3
  77. package/src/theme/entry.ts +23 -0
  78. package/dist/cli/chunk-5n7t497w.js.map +0 -40
  79. package/dist/cli/chunk-88by27n5.js +0 -17
  80. package/dist/cli/chunk-88by27n5.js.map +0 -10
  81. package/dist/cli/chunk-fmceyezb.js.map +0 -13
  82. package/dist/cli/chunk-tqa1s0k8.js +0 -69
  83. package/dist/cli/chunk-tqa1s0k8.js.map +0 -11
  84. /package/dist/cli/{chunk-9bkjd11x.js.map → chunk-0xjyb285.js.map} +0 -0
  85. /package/dist/cli/{chunk-cvky9gb2.js.map → chunk-4x36ddpw.js.map} +0 -0
  86. /package/dist/cli/{chunk-mqb2ka8m.js.map → chunk-5093q3n7.js.map} +0 -0
  87. /package/dist/cli/{chunk-9he6crym.js.map → chunk-5g0w1e2c.js.map} +0 -0
  88. /package/dist/cli/{chunk-mt76t7dj.js.map → chunk-5qk08vmp.js.map} +0 -0
  89. /package/dist/cli/{chunk-aztttvb3.js.map → chunk-97r59kpr.js.map} +0 -0
  90. /package/dist/cli/{chunk-t3tj0dgr.js.map → chunk-ahnw3kxw.js.map} +0 -0
  91. /package/dist/cli/{chunk-hs3gbh8p.js.map → chunk-b27xqwn9.js.map} +0 -0
  92. /package/dist/cli/{chunk-450a7rcr.js.map → chunk-bf6bt1xt.js.map} +0 -0
  93. /package/dist/cli/{chunk-eevwt1sc.js.map → chunk-bvwwhd84.js.map} +0 -0
  94. /package/dist/cli/{chunk-ppfvdcd4.js.map → chunk-dwgcp5sm.js.map} +0 -0
  95. /package/dist/cli/{chunk-3w7b2vcx.js.map → chunk-e7f42gdj.js.map} +0 -0
  96. /package/dist/cli/{chunk-jbj4qhfw.js.map → chunk-garjf5z9.js.map} +0 -0
  97. /package/dist/cli/{chunk-688e0dde.js.map → chunk-nn13znc2.js.map} +0 -0
  98. /package/dist/cli/{chunk-xhtpx3ff.js.map → chunk-rqy0s5wh.js.map} +0 -0
  99. /package/dist/cli/{chunk-30e87n55.js.map → chunk-rz9jmfhz.js.map} +0 -0
  100. /package/dist/cli/{chunk-exeeb35e.js.map → chunk-vacwm2hv.js.map} +0 -0
  101. /package/dist/cli/{chunk-8cd8tj54.js.map → chunk-yg63d42r.js.map} +0 -0
@@ -3,13 +3,13 @@
3
3
  "sources": ["../src/deploy/adapter-output.ts", "../src/ai/link-headers.ts", "../src/deploy/redirects.ts", "../src/ai/ask.ts", "../src/astro/runtime-modules.ts", "../src/astro/templates.ts"],
4
4
  "sourcesContent": [
5
5
  "import { existsSync } from \"node:fs\";\nimport { cp, mkdir, rm } from \"node:fs/promises\";\n\nimport { dirname, join } from \"pathe\";\n\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport type { ProjectContext } from \"../core/types.ts\";\n\ntype Adapter = NonNullable<ResolvedConfig[\"deployment\"][\"adapter\"]>;\n\n/** An optional per-adapter path, keyed by the closed adapter union. */\ntype AdapterPathMap = { [A in Adapter]?: string };\n\n/**\n * Top-level directory each server adapter writes its deploy bundle into, for\n * `.gitignore` — the bundle is a build artifact, and the platform's own state\n * lives alongside it (`.vercel/project.json`, `.netlify/state.json`), so the\n * whole directory is ignored. `node` and `cloudflare` emit into `dist/`, which\n * `blume init` already ignores.\n */\nexport const ADAPTER_IGNORE_DIRS: AdapterPathMap = {\n netlify: \".netlify/\",\n vercel: \".vercel/\",\n};\n\n/**\n * Server adapters whose deploy bundle lands *outside* Astro's `outDir`, at a\n * path relative to the Astro project root. Blume points the Astro root at the\n * hidden `<root>/.blume` runtime, so these adapters write their bundle to\n * `<root>/.blume/<path>` — where the deploy platform never looks. Each value is\n * the sub-path to surface up to the real project root.\n *\n * `netlify` writes a Frameworks API tree at `.netlify/v1` (its `.netlify/build`\n * sibling is only the intermediate SSR bundle, already traced into\n * `v1/functions`); only `v1` is moved, so the `.netlify/state.json` written by\n * `netlify link` survives too. `node` and `cloudflare` emit into `dist/`\n * (already at the project root), so they are absent here and need no\n * relocation.\n *\n * `vercel` is absent for a different reason: it is shown the real project root\n * up front (see `withAdapterRoot`), because its `@vercel/nft` dependency trace\n * is rooted there too and tracing from `.blume` silently drops the function's\n * chunks and `node_modules`. Given the right root it writes its Build Output\n * tree straight to `<root>/.vercel/output`, so there is nothing left to move.\n */\nexport const ADAPTER_OUTPUT_PATHS: AdapterPathMap = {\n netlify: \".netlify/v1\",\n};\n\n/**\n * Whether this build keeps Astro's `dist/client` + `dist/server` split and\n * serves only the `client/` half. True for Node and Cloudflare server builds:\n * the Node standalone server's static handler reads only `build.client`, and\n * `@astrojs/cloudflare` declares `preserveBuildClientDir: true` and points the\n * ASSETS binding in the `dist/server/wrangler.json` it generates at\n * `../client` — the Worker serves that directory and nothing above it. A\n * Cloudflare *static* build has no server dir to split against, so its\n * `outDir` root is what ships.\n */\nexport const servesClientSubdir = (\n deployment: ResolvedConfig[\"deployment\"]\n): boolean =>\n deployment.output === \"server\" &&\n (deployment.adapter === \"node\" || deployment.adapter === \"cloudflare\");\n\n/**\n * Whether the platform applies a `_headers` file to the static assets it\n * serves. True for every static build (Netlify and Cloudflare Pages/Workers\n * both read it) and, additionally, for a **Cloudflare server** build: the\n * Worker serves `dist/client` through its ASSETS binding, and Workers static\n * assets honor `_headers` from that directory exactly as Pages does.\n *\n * Deliberately not true for a Node server build. Node's standalone server has\n * its own static handler with no `_headers` support, so writing the file there\n * would be inert — and reporting a header that is not applied is worse than\n * omitting it.\n *\n * A Vercel **server** build is excluded because its headers arrive through the\n * routing config instead (see `deploy/vercel-negotiation.ts`), which\n * `_headers` would duplicate rather than complement. A *static* build on the\n * Vercel adapter still returns true: Vercel ignores the file, so it is inert\n * there, matching what the old `output === \"static\"` gate emitted.\n */\nexport const readsHeaderFiles = (\n deployment: ResolvedConfig[\"deployment\"]\n): boolean =>\n deployment.output === \"static\" ||\n (deployment.output === \"server\" && deployment.adapter === \"cloudflare\");\n\n/**\n * Directory whose contents the deploy platform serves as static files. Build\n * artifacts (robots.txt, sitemap.xml, llms.txt, …) must be written here to be\n * served. For a Vercel server build that is the adapter's\n * `.vercel/output/static`; for a Node or Cloudflare server build it is Astro's\n * `build.client` dir (`dist/client/` — see {@link servesClientSubdir}). Every\n * other build serves `dist/` itself, Netlify included.\n */\nexport const deployStaticDir = (\n config: ResolvedConfig,\n context: ProjectContext\n): string => {\n const { adapter, output } = config.deployment;\n if (output === \"server\" && adapter === \"vercel\") {\n return join(context.root, \".vercel\", \"output\", \"static\");\n }\n const dist = context.distDir ?? join(context.root, \"dist\");\n if (servesClientSubdir(config.deployment)) {\n return join(dist, \"client\");\n }\n return dist;\n};\n\n/** Outcome of {@link surfaceAdapterOutput}, for logging. */\nexport type SurfaceResult =\n | { moved: false }\n | { from: string; moved: true; to: string };\n\n/**\n * Move a server adapter's deploy bundle out of the hidden `.blume` runtime and\n * up to the project root, where the deploy platform (and `vercel deploy\n * --prebuilt`) expects it. A no-op for static builds, for adapters that emit\n * into `dist/`, and when the expected output is absent.\n */\nexport const surfaceAdapterOutput = async (\n config: ResolvedConfig,\n context: ProjectContext\n): Promise<SurfaceResult> => {\n const { adapter, output } = config.deployment;\n if (output !== \"server\" || !adapter) {\n return { moved: false };\n }\n const rel = ADAPTER_OUTPUT_PATHS[adapter];\n if (!rel) {\n return { moved: false };\n }\n const from = join(context.outDir, rel);\n const to = join(context.root, rel);\n if (!existsSync(from)) {\n return { moved: false };\n }\n await mkdir(dirname(to), { recursive: true });\n await rm(to, { force: true, recursive: true });\n // `verbatimSymlinks` keeps each symlink's target text as written. Without it,\n // `cp` resolves every relative target against the *source*, rewriting it to an\n // absolute path under `.blume` — which this function then deletes. Adapters\n // that trace dependencies into their function bundle link one package to\n // another that way (under an isolated linker — Bun's `isolated` mode, pnpm —\n // that is every external dependency the function imports), so the resolved\n // links leave the deployed function dying on its first external import with\n // ERR_MODULE_NOT_FOUND. Verbatim, the links stay relative and internal to the\n // bundle, surviving both this move and the platform's own (Vercel mounts the\n // bundle at `/var/task`).\n await cp(from, to, { recursive: true, verbatimSymlinks: true });\n await rm(from, { force: true, recursive: true });\n return { from, moved: true, to };\n};\n",
6
- "import { normalizeBasePath } from \"../core/base-path.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport { API_CATALOG_PATH, hasApiCatalog } from \"./api-catalog.ts\";\nimport { OPENAPI_PATH } from \"./api/paths.ts\";\n\n/**\n * The homepage `Link` response header (RFC 8288) — agent discovery for the\n * machine-readable surface Blume already publishes. Agents probing a site read\n * this header off `GET /` to find the resources without scraping HTML:\n * `agent-readability.json` and `llms.txt` as `rel=\"describedby\"`, the OpenAPI\n * description of the JSON docs API as `rel=\"service-desc\"`, and the\n * homepage's raw-Markdown mirror as `rel=\"alternate\"` (only when the home\n * route is a content page — a user landing page has no mirror). Every rel\n * value is IANA-registered, which agent-readiness checkers require.\n *\n * The header is homepage-only by design: the root response is what agents\n * probe, and `agent-readability.json` indexes the rest of the surface (the\n * per-route Markdown pattern, MCP, feeds) far better than per-page headers\n * could. An agent that enters on a deep page (a search result, a shared link)\n * never sees this header at all — that path is covered in the HTML instead:\n * every page's `<head>` carries the same `describedby` links plus its own\n * Markdown mirror as an `alternate` (see `RootLayout.astro`), which also\n * reaches hosts where Blume can't set response headers. Targets are\n * root-relative under `deployment.base` — RFC 8288 resolves them against the\n * request URL. Returns null when nothing is advertisable.\n */\nexport const buildHomeLinkHeader = (\n config: ResolvedConfig,\n routePaths: readonly string[]\n): string | null => {\n const deployBase = normalizeBasePath(config.deployment.base);\n const links: string[] = [];\n // RFC 9727 §3: the api-catalog relation is how a homepage advertises the\n // well-known catalog.\n if (hasApiCatalog(config)) {\n links.push(\n `<${deployBase}${API_CATALOG_PATH}>; rel=\"api-catalog\"; type=\"application/linkset+json\"`\n );\n }\n // RFC 8631: `service-desc` is the relation for a machine-readable\n // description of the service — the JSON docs API's OpenAPI document.\n if (config.ai.api) {\n links.push(\n `<${deployBase}${OPENAPI_PATH}>; rel=\"service-desc\"; type=\"application/json\"`\n );\n }\n if (config.seo.agentReadability) {\n links.push(\n `<${deployBase}/agent-readability.json>; rel=\"describedby\"; type=\"application/json\"`\n );\n }\n if (config.ai.llmsTxt.enabled) {\n links.push(\n `<${deployBase}/llms.txt>; rel=\"describedby\"; type=\"text/plain\"`\n );\n }\n // Same route list as the negotiation surfaces (`markdownRoutePaths`): \"/\"\n // always has a mirror — the page's own source when the home route is a\n // content page, the synthesized llms.txt fallback otherwise — so callers\n // passing that list always advertise `/index.md` here.\n if (routePaths.includes(\"/\")) {\n links.push(\n `<${deployBase}/index.md>; rel=\"alternate\"; type=\"text/markdown\"`\n );\n }\n return links.length > 0 ? links.join(\", \") : null;\n};\n",
6
+ "import { normalizeBasePath } from \"../core/base-path.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport {\n AI_CATALOG_PATH,\n AI_CATALOG_TYPE,\n hasAiCatalog,\n} from \"./ai-catalog.ts\";\nimport { API_CATALOG_PATH, hasApiCatalog } from \"./api-catalog.ts\";\nimport { OPENAPI_PATH } from \"./api/paths.ts\";\n\n/**\n * The homepage `Link` response header (RFC 8288) — agent discovery for the\n * machine-readable surface Blume already publishes. Agents probing a site read\n * this header off `GET /` to find the resources without scraping HTML:\n * `agent-readability.json` and `llms.txt` as `rel=\"describedby\"`, the OpenAPI\n * description of the JSON docs API as `rel=\"service-desc\"`, and the\n * homepage's raw-Markdown mirror as `rel=\"alternate\"` (only when the home\n * route is a content page — a user landing page has no mirror). Every rel\n * value is IANA-registered, which agent-readiness checkers require.\n *\n * The header is homepage-only by design: the root response is what agents\n * probe, and `agent-readability.json` indexes the rest of the surface (the\n * per-route Markdown pattern, MCP, feeds) far better than per-page headers\n * could. An agent that enters on a deep page (a search result, a shared link)\n * never sees this header at all — that path is covered in the HTML instead:\n * every page's `<head>` carries the same `describedby` links plus its own\n * Markdown mirror as an `alternate` (see `RootLayout.astro`), which also\n * reaches hosts where Blume can't set response headers. Targets are\n * root-relative under `deployment.base` — RFC 8288 resolves them against the\n * request URL. Returns null when nothing is advertisable.\n */\nexport const buildHomeLinkHeader = (\n config: ResolvedConfig,\n routePaths: readonly string[]\n): string | null => {\n const deployBase = normalizeBasePath(config.deployment.base);\n const links: string[] = [];\n // RFC 9727 §3: the api-catalog relation is how a homepage advertises the\n // well-known catalog.\n if (hasApiCatalog(config)) {\n links.push(\n `<${deployBase}${API_CATALOG_PATH}>; rel=\"api-catalog\"; type=\"application/linkset+json\"`\n );\n }\n // The ai-catalog spec's own relation for its well-known document, the\n // header form of the `<link rel=\"ai-catalog\">` every page carries.\n if (hasAiCatalog(config)) {\n links.push(\n `<${deployBase}${AI_CATALOG_PATH}>; rel=\"ai-catalog\"; type=\"${AI_CATALOG_TYPE}\"`\n );\n }\n // RFC 8631: `service-desc` is the relation for a machine-readable\n // description of the service — the JSON docs API's OpenAPI document.\n if (config.ai.api) {\n links.push(\n `<${deployBase}${OPENAPI_PATH}>; rel=\"service-desc\"; type=\"application/json\"`\n );\n }\n if (config.seo.agentReadability) {\n links.push(\n `<${deployBase}/agent-readability.json>; rel=\"describedby\"; type=\"application/json\"`\n );\n }\n if (config.ai.llmsTxt.enabled) {\n links.push(\n `<${deployBase}/llms.txt>; rel=\"describedby\"; type=\"text/plain\"`\n );\n }\n // Same route list as the negotiation surfaces (`markdownRoutePaths`): \"/\"\n // always has a mirror — the page's own source when the home route is a\n // content page, the synthesized llms.txt fallback otherwise — so callers\n // passing that list always advertise `/index.md` here.\n if (routePaths.includes(\"/\")) {\n links.push(\n `<${deployBase}/index.md>; rel=\"alternate\"; type=\"text/markdown\"`\n );\n }\n return links.length > 0 ? links.join(\", \") : null;\n};\n",
7
7
  "import {\n normalizeBasePath,\n withBasePath,\n withComposedBasePath,\n} from \"../core/base-path.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\n\n/**\n * Platform redirect files for a static build. Astro already emits redirect HTML\n * (meta-refresh) pages for `deployment.output: \"static\"`, but that's a soft\n * client redirect. These give the host a real HTTP 3xx: Netlify/Cloudflare read\n * `_redirects`, Vercel reads `vercel.json`, and `blume-redirects.json` is a\n * structured manifest for anything else (Apache/nginx rules, an edge worker).\n */\n\ntype Redirect = ResolvedConfig[\"redirects\"][number];\n\n/**\n * Base a redirect for Astro's `redirects` config, where the two sides are not\n * symmetric:\n *\n * - `from` gains only `basePath`. Astro builds the match pattern with\n * `deployment.base` already applied (`getPattern(segments, config.base)`), so\n * adding it here would serve the redirect at `{base}{base}/from`.\n * - `to` gains the full `{deployment.base}{basePath}` stack. Astro resolves a\n * destination that matches a known route by regenerating it from that route's\n * segments, which carry no base — and passes an unmatched destination through\n * verbatim. Neither path prepends `base`, so a root-relative `to` escapes the\n * base entirely (withastro/astro#7774, still the behavior in Astro 7).\n *\n * Both sides are authored as if mounted at root; external `to` URLs pass\n * through. Idempotent, so a hand-written base isn't doubled.\n */\nexport const applyBaseToAstroRedirects = (\n redirects: Redirect[],\n basePath: string,\n deployBase: string\n): Redirect[] => {\n // `deployment.base` arrives as the user wrote it (Astro accepts `/base/`,\n // even `base`); normalizing here keeps the composed paths well-formed.\n const base = normalizeBasePath(deployBase);\n return basePath || base\n ? redirects.map((redirect) => ({\n ...redirect,\n from: withBasePath(basePath, redirect.from),\n to: withComposedBasePath(base, basePath, redirect.to),\n }))\n : redirects;\n};\n\n/**\n * Base a redirect for the host platform files below. Unlike Astro's config,\n * these are matched against the real served URL, so both sides carry the full\n * `{deployment.base}{basePath}` stack.\n */\nexport const applyBaseToPlatformRedirects = (\n redirects: Redirect[],\n basePath: string,\n deployBase: string\n): Redirect[] => {\n const base = normalizeBasePath(deployBase);\n return basePath || base\n ? redirects.map((redirect) => ({\n ...redirect,\n from: withComposedBasePath(base, basePath, redirect.from),\n to: withComposedBasePath(base, basePath, redirect.to),\n }))\n : redirects;\n};\n\n/**\n * The configured redirects as the host platform matches them, via\n * {@link applyBaseToPlatformRedirects}. The one basing every consumer must\n * share: the emitted redirect files and the Cloudflare worker-first redirect\n * exemptions both compare these paths against real served URLs.\n */\nexport const platformRedirects = (config: ResolvedConfig): Redirect[] =>\n applyBaseToPlatformRedirects(\n config.redirects,\n config.basePath,\n config.deployment.base ?? \"\"\n );\n\n/** `_redirects` text (Netlify + Cloudflare Pages): `from to status` per line. */\nexport const buildNetlifyRedirects = (redirects: Redirect[]): string =>\n `${redirects\n .map((redirect) => `${redirect.from} ${redirect.to} ${redirect.status}`)\n .join(\"\\n\")}\\n`;\n\n/**\n * `vercel.json` contents with a `redirects` array. Uses `statusCode` (Vercel's\n * alternative to the boolean `permanent`) so the configured code ships exactly:\n * `permanent` would silently coerce a 301 to 308 and a 302 to 307, diverging\n * from the `_redirects` file, which preserves exact codes.\n */\nexport const buildVercelConfig = (redirects: Redirect[]): string =>\n `${JSON.stringify(\n {\n redirects: redirects.map((redirect) => ({\n destination: redirect.to,\n source: redirect.from,\n statusCode: redirect.status,\n })),\n },\n null,\n 2\n )}\\n`;\n\n/** Structured manifest for hosts that need manual wiring. */\nexport const buildRedirectManifest = (redirects: Redirect[]): string =>\n `${JSON.stringify(\n redirects.map((redirect) => ({\n from: redirect.from,\n status: redirect.status,\n to: redirect.to,\n })),\n null,\n 2\n )}\\n`;\n",
8
8
  "import type { AskAiConfig } from \"../core/schema.ts\";\n\n/**\n * The concrete backend the Ask AI endpoint is generated against. `gateway` uses\n * the AI SDK core (`streamText({ model })`) and the Vercel AI Gateway;\n * `openrouter` uses its dedicated provider; everything else streams through the\n * AI SDK's OpenAI-compatible provider.\n */\nexport type AskBackend =\n | { headers?: AskHeaders; kind: \"gateway\"; model: string }\n | {\n apiKeyEnv: string;\n headers?: AskHeaders;\n kind: \"openrouter\";\n model: string;\n }\n | {\n apiKeyEnv: string;\n baseUrl: string;\n headers?: AskHeaders;\n kind: \"openai-compatible\";\n model: string;\n name: string;\n };\n\n/**\n * Static request headers (`ai.ask.headers`) every backend forwards to its\n * provider factory. Every provider Blume generates against accepts the same\n * `headers` option, so the map travels unchanged; the OpenAI-compatible\n * provider applies them after the `Authorization` header it derives from the\n * API key, so a custom header can't displace auth.\n */\nexport type AskHeaders = Record<string, string>;\n\ninterface AskPreset {\n apiKeyEnv: string;\n baseUrl?: string;\n kind: \"openai-compatible\" | \"openrouter\";\n name: string;\n runtimeDep: string;\n}\n\n/**\n * Connection presets for the named, non-gateway providers. OpenRouter has a\n * dedicated AI SDK provider; LLMGateway and Inkeep are OpenAI-compatible\n * endpoints with no dedicated provider, so they reuse `@ai-sdk/openai-compatible`.\n */\n/** The discriminant/name shared by the OpenAI-compatible providers. */\nconst OPENAI_COMPATIBLE = \"openai-compatible\";\n/** The AI SDK provider package the OpenAI-compatible providers install. */\nconst OPENAI_COMPATIBLE_DEP = \"@ai-sdk/openai-compatible\";\n\n/**\n * Connection presets keyed by provider name. Open-keyed on purpose: lookups\n * use the configured `ai.ask.provider`, which includes values with no preset\n * (the generic `openai-compatible`).\n */\ninterface AskPresetRegistry {\n [provider: string]: AskPreset;\n}\n\nconst ASK_PRESETS: AskPresetRegistry = {\n inkeep: {\n apiKeyEnv: \"INKEEP_API_KEY\",\n baseUrl: \"https://api.inkeep.com/v1\",\n kind: OPENAI_COMPATIBLE,\n name: \"inkeep\",\n runtimeDep: OPENAI_COMPATIBLE_DEP,\n },\n llmgateway: {\n apiKeyEnv: \"LLMGATEWAY_API_KEY\",\n baseUrl: \"https://api.llmgateway.io/v1\",\n kind: OPENAI_COMPATIBLE,\n name: \"llmgateway\",\n runtimeDep: OPENAI_COMPATIBLE_DEP,\n },\n openrouter: {\n apiKeyEnv: \"OPENROUTER_API_KEY\",\n kind: \"openrouter\",\n name: \"openrouter\",\n runtimeDep: \"@openrouter/ai-sdk-provider\",\n },\n};\n\nconst DEFAULT_MODEL = \"openai/gpt-5.5\";\n\n/**\n * The `headers` field every backend variant shares. An empty map is dropped so\n * the generated route only carries a `headers` option when there is something\n * to send.\n */\nconst askHeadersField = (ask?: AskAiConfig): { headers?: AskHeaders } =>\n ask?.headers && Object.keys(ask.headers).length > 0\n ? { headers: ask.headers }\n : {};\n\n/** Resolve the `ai.ask` config into the backend the endpoint is built against. */\nexport const resolveAskBackend = (ask?: AskAiConfig): AskBackend => {\n const provider = ask?.provider ?? \"gateway\";\n const model = ask?.model ?? DEFAULT_MODEL;\n const headers = askHeadersField(ask);\n if (provider === \"gateway\") {\n return { ...headers, kind: \"gateway\", model };\n }\n const preset = ASK_PRESETS[provider];\n const apiKeyEnv = ask?.apiKeyEnv ?? preset?.apiKeyEnv ?? \"API_KEY\";\n if (provider === \"openrouter\") {\n return { apiKeyEnv, ...headers, kind: \"openrouter\", model };\n }\n // `llmgateway`, `inkeep`, and the generic `openai-compatible` provider all\n // stream through the AI SDK's OpenAI-compatible provider. The schema requires\n // `baseUrl` for the generic case; the named providers fall back to a preset.\n return {\n apiKeyEnv,\n baseUrl: ask?.baseUrl ?? preset?.baseUrl ?? \"\",\n ...headers,\n kind: OPENAI_COMPATIBLE,\n model,\n name: preset?.name ?? OPENAI_COMPATIBLE,\n };\n};\n\n/**\n * The provider SDK a project must install for the configured backend, or\n * `undefined` for `gateway` (which only needs the core `ai` package). Declared\n * in the generated runtime so a project pulls in exactly the backend it uses.\n */\nexport const askBackendRuntimeDep = (ask?: AskAiConfig): string | undefined => {\n const provider = ask?.provider ?? \"gateway\";\n if (provider === \"gateway\") {\n return undefined;\n }\n return ASK_PRESETS[provider]?.runtimeDep ?? OPENAI_COMPATIBLE_DEP;\n};\n",
9
9
  "/**\n * In-memory runtime data modules.\n *\n * The generated runtime's data snapshots — the page data behind `blume:data`,\n * the parsed API specs, the static search index, the raw-Markdown and\n * content-asset maps, the MCP and Ask corpora, and the rendered RSS feeds —\n * used to be written under `.blume/src/generated/*.json` and imported by the\n * generated pages through aliases or relative paths. `generateRuntime` now\n * publishes them here and `runtimeModulesPlugin` serves them to Vite as\n * virtual modules, so a regeneration never round-trips the disk or waits on a\n * file watcher: publishing invalidates the changed modules in every live dev\n * server (Vite walks the importers, so the pages that render them re-evaluate\n * on the next request) and asks the browser to reload — the same effect a JSON\n * file change used to reach through the watcher, minus the write and the\n * watch debounce.\n *\n * The registry hangs off `globalThis`, not module state. On a published\n * install the CLI bundle (`dist/cli`) carries its own copy of this module,\n * separate from the one Vite loads from `blume/astro` for the generated\n * config, and both must see the same map. `blume dev`, `blume build`, and\n * `blume check` all run Astro in-process, so the map the CLI fills is the map\n * the plugin reads.\n *\n * `blume eject` keeps the file form: the ejected project has no CLI to\n * publish, so its `astro.config.mjs` aliases each id to the JSON file eject\n * writes under `src/generated/` — the names in {@link RUNTIME_MODULE_FILES}.\n */\n\nexport type RuntimeModuleId =\n | \"blume:ask-data\"\n | \"blume:content-assets\"\n | \"blume:data\"\n | \"blume:mcp-data\"\n | \"blume:openapi\"\n | \"blume:raw-markdown\"\n | \"blume:rss\"\n | \"blume:search-index\";\n\n/** Virtual module id → the `src/generated` JSON file eject writes for it. */\nexport const RUNTIME_MODULE_FILES: ReadonlyMap<RuntimeModuleId, string> =\n new Map([\n [\"blume:ask-data\", \"ask-data.json\"],\n [\"blume:content-assets\", \"content-assets.json\"],\n [\"blume:data\", \"data.json\"],\n [\"blume:mcp-data\", \"mcp-data.json\"],\n [\"blume:openapi\", \"openapi.json\"],\n [\"blume:raw-markdown\", \"raw-markdown.json\"],\n [\"blume:rss\", \"rss.json\"],\n [\"blume:search-index\", \"search.json\"],\n ]);\n\nconst RUNTIME_MODULE_IDS: ReadonlySet<string> = new Set(\n RUNTIME_MODULE_FILES.keys()\n);\n\n/** Rollup's virtual-module convention: `\\0` keeps other plugins off the id. */\nconst RESOLVED_PREFIX = \"\\0\";\n\n/** A node in Vite's module graph; only its identity matters here. */\ninterface RuntimeModuleNode {\n id: string | null;\n}\n\n/**\n * The Vite dev-server slice the registry touches (structurally typed, like\n * every Blume-authored Vite plugin — see `includeHmrPlugin`).\n */\nexport interface RuntimeModuleServer {\n httpServer?: {\n once: (event: \"close\", listener: () => void) => void;\n } | null;\n moduleGraph: {\n getModuleById: (id: string) => RuntimeModuleNode | undefined;\n invalidateModule: (mod: RuntimeModuleNode) => void;\n };\n ws: { send: (payload: { type: \"full-reload\" }) => void };\n}\n\ninterface RuntimeModuleRegistry {\n /** Published JSON text by module id. */\n modules: Map<string, string>;\n /** Live dev servers to invalidate on publish. */\n servers: Set<RuntimeModuleServer>;\n}\n\nconst REGISTRY_KEY = Symbol.for(\"blume.runtime-modules\");\n\ntype RegistryHost = typeof globalThis & {\n [REGISTRY_KEY]?: RuntimeModuleRegistry;\n};\n\nconst registry = (): RuntimeModuleRegistry => {\n // SAFETY: the registry is stashed on globalThis under a well-known symbol so\n // every copy of this module in the process shares it; the intersection only\n // names that slot.\n const host = globalThis as RegistryHost;\n host[REGISTRY_KEY] ??= { modules: new Map(), servers: new Set() };\n return host[REGISTRY_KEY];\n};\n\n/** The published JSON text for a module, if any (tests and diagnostics). */\nexport const readRuntimeModule = (id: RuntimeModuleId): string | undefined =>\n registry().modules.get(id);\n\n/**\n * Replace the published snapshot set with `modules` (an id absent from the map\n * is unpublished — its feature was switched off). Returns the ids whose text\n * changed; each is invalidated in every live dev server, followed by one\n * full-reload per server. Nothing is sent when nothing changed, so a\n * regeneration triggered by an unrelated edit stays quiet — the same contract\n * `writeIfChanged` gave the file form.\n */\nexport const publishRuntimeModules = (\n modules: ReadonlyMap<RuntimeModuleId, string>\n): RuntimeModuleId[] => {\n const { modules: current, servers } = registry();\n const changed: RuntimeModuleId[] = [];\n for (const id of RUNTIME_MODULE_FILES.keys()) {\n const next = modules.get(id);\n if (current.get(id) === next) {\n continue;\n }\n if (next === undefined) {\n current.delete(id);\n } else {\n current.set(id, next);\n }\n changed.push(id);\n }\n if (changed.length === 0) {\n return changed;\n }\n for (const server of servers) {\n for (const id of changed) {\n const mod = server.moduleGraph.getModuleById(`${RESOLVED_PREFIX}${id}`);\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n }\n }\n server.ws.send({ type: \"full-reload\" });\n }\n return changed;\n};\n\nexport interface RuntimeModulesPlugin {\n configureServer: (server: RuntimeModuleServer) => void;\n enforce: \"pre\";\n load: (id: string) => string | undefined;\n name: string;\n resolveId: (id: string) => string | undefined;\n}\n\n/**\n * Serve the published runtime modules to Vite. `enforce: \"pre\"` claims the\n * `blume:*` ids before Vite's resolver would try (and fail) to find them as\n * packages. Loading an unpublished id is a hard error rather than an empty\n * module: the generated pages only import a module when its data exists, so a\n * miss means the config was run outside the CLI that publishes.\n */\nexport const runtimeModulesPlugin = (): RuntimeModulesPlugin => ({\n configureServer(server) {\n const { servers } = registry();\n servers.add(server);\n // Astro restarts the dev container in place on a config change (and the\n // CLI restarts it on a route-set change): the old Vite server closes and\n // a new one registers, so drop the stale handle rather than invalidating\n // into a dead graph.\n server.httpServer?.once(\"close\", () => {\n servers.delete(server);\n });\n },\n enforce: \"pre\",\n load(id) {\n if (!id.startsWith(RESOLVED_PREFIX)) {\n return;\n }\n const moduleId = id.slice(RESOLVED_PREFIX.length);\n if (!RUNTIME_MODULE_IDS.has(moduleId)) {\n return;\n }\n const text = registry().modules.get(moduleId);\n if (text === undefined) {\n throw new Error(\n `Blume runtime module \"${moduleId}\" was requested before it was published. Run the generated project through the Blume CLI (blume dev / blume build), which publishes the runtime data before starting Astro.`\n );\n }\n // A JSON.parse over a string literal evaluates faster than an equivalent\n // object literal for large snapshots (V8's guidance; Vite's own JSON\n // plugin does the same past a size threshold).\n return `export default JSON.parse(${JSON.stringify(text)});\\n`;\n },\n name: \"blume:runtime-modules\",\n resolveId(id) {\n return RUNTIME_MODULE_IDS.has(id) ? `${RESOLVED_PREFIX}${id}` : undefined;\n },\n});\n",
10
10
  "import { existsSync, readFileSync } from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { dirname, isAbsolute, join, relative } from \"pathe\";\n\nimport type { AskRetrievalOptions } from \"../ai/ask-context.ts\";\nimport { askBackendRuntimeDep } from \"../ai/ask.ts\";\nimport type { AskBackend } from \"../ai/ask.ts\";\nimport { buildHomeLinkHeader } from \"../ai/link-headers.ts\";\nimport { normalizeBasePath } from \"../core/base-path.ts\";\nimport { TOC_HIDDEN_KEY } from \"../core/heading-markers.ts\";\nimport type { AskReasoning, ResolvedConfig } from \"../core/schema.ts\";\nimport { BLUME_IGNORE_DIRS } from \"../core/sources/watch.ts\";\nimport { trimChar } from \"../core/trim.ts\";\nimport type { ProjectContext } from \"../core/types.ts\";\nimport { applyBaseToAstroRedirects } from \"../deploy/redirects.ts\";\nimport type { OgCache } from \"../og/cache.ts\";\nimport type { OgFont, OgFontFamilies } from \"../og/card.ts\";\nimport { hasScalarReferences } from \"../openapi/references.ts\";\nimport { searchProviderMeta } from \"../search/providers.ts\";\nimport { buildFontEntries, fontLocaleCodes } from \"../theme/fonts.ts\";\nimport type { ExampleSpec } from \"./examples.ts\";\nimport type { BlumeIntegrationOptions, BlumePageRoute } from \"./integration.ts\";\nimport type { IslandSpec } from \"./islands.ts\";\nimport type { OgCustomRoute } from \"./pages.ts\";\nimport { RUNTIME_MODULE_FILES } from \"./runtime-modules.ts\";\n\nconst WORKSPACE_MARKERS = [\n \".git\",\n \"bun.lock\",\n \"bun.lockb\",\n \"package-lock.json\",\n \"pnpm-lock.yaml\",\n \"pnpm-workspace.yaml\",\n \"yarn.lock\",\n];\n\n/** True when the package.json at this path declares a `workspaces` field. */\nconst hasWorkspacesField = (pkgPath: string): boolean => {\n if (!existsSync(pkgPath)) {\n return false;\n }\n try {\n // SAFETY: parsed from the user's own package.json; only the presence of a\n // `workspaces` field is read, so this loose shape is all the cast claims.\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n workspaces?: unknown;\n };\n return pkg.workspaces !== undefined;\n } catch {\n return false;\n }\n};\n\n/** True when a directory looks like a workspace/monorepo root. */\nconst hasWorkspaceMarker = (dir: string): boolean =>\n hasWorkspacesField(join(dir, \"package.json\")) ||\n WORKSPACE_MARKERS.some((marker) => existsSync(join(dir, marker)));\n\n/**\n * Walk up from the project root to the workspace/monorepo root so Vite's\n * `fs.allow` can reach hoisted dependencies — e.g. KaTeX fonts that resolve to\n * a monorepo root `node_modules` outside the project directory. Falls back to\n * the project root when no workspace markers are found.\n */\nconst findWorkspaceRoot = (start: string): string => {\n let dir = start;\n for (;;) {\n if (hasWorkspaceMarker(dir)) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return start;\n }\n dir = parent;\n }\n};\n\ntype DeploymentAdapter = NonNullable<ResolvedConfig[\"deployment\"][\"adapter\"]>;\n\nconst ADAPTER_IMPORTS = {\n cloudflare: \"@astrojs/cloudflare\",\n netlify: \"@astrojs/netlify\",\n node: \"@astrojs/node\",\n vercel: \"@astrojs/vercel\",\n} satisfies Record<DeploymentAdapter, string>;\n\n/** Adapter constructor arguments, for the adapters that need any. */\nconst ADAPTER_OPTIONS = new Map<DeploymentAdapter, string>([\n [\"node\", '{ mode: \"standalone\" }'],\n]);\n\nconst WRANGLER_CONFIG_FILES = [\n \"wrangler.jsonc\",\n \"wrangler.json\",\n \"wrangler.toml\",\n];\n\nconst resolveCloudflareAdapterArgs = (context: ProjectContext): string => {\n // Every Blume HTML route prerenders (the only server routes are API\n // endpoints), so images are optimized at build time with sharp. The\n // adapter's default (`cloudflare-binding`) would instead declare a runtime\n // `IMAGES` binding in the generated wrangler config that nothing uses.\n const args: string[] = [\n 'prerenderEnvironment: \"node\"',\n 'imageService: \"compile\"',\n ];\n const wranglerPath = WRANGLER_CONFIG_FILES.map((file) =>\n join(context.root, file)\n ).find((file) => existsSync(file));\n if (wranglerPath) {\n let configPath = relative(context.outDir, wranglerPath);\n // The wrangler config always lives at the project root, above the `.blume`\n // runtime, so `relative` yields a `../…` path; normalize the theoretical\n // sibling case to an explicit `./` so it reads as a relative import.\n if (!configPath.startsWith(\".\") && !configPath.startsWith(\"/\")) {\n configPath = `./${configPath}`;\n }\n args.push(`configPath: ${JSON.stringify(configPath)}`);\n }\n return `{ ${args.join(\", \")} }`;\n};\n\n/**\n * Without a configured driver, `@astrojs/cloudflare` force-enables KV-backed\n * sessions and declares a `SESSION` kv_namespaces entry in the generated\n * wrangler config — which `wrangler deploy` then requires a real KV namespace\n * for, even though Blume never reads `Astro.session`. Astro's `session: false`\n * opts the project out, and the adapter checks for it before adding the\n * binding. (An in-memory driver used to stand in before the opt-out existed.)\n */\nconst resolveSessionOption = (deployment: {\n adapter: string | null;\n output: string;\n}): string =>\n deployment.output === \"server\" && deployment.adapter === \"cloudflare\"\n ? \"\\n session: false,\"\n : \"\";\n\n/**\n * A font weight as Astro's Fonts API spells it: a variable range is\n * `\"100 900\"` there, where Blume's config (and Takumi's Google Fonts helper,\n * which the OG cards use) write `\"100..900\"`. Astro treats the dotted form as\n * an unknown discrete weight and loads nothing for it.\n */\nconst astroFontWeights = (weights: (number | string)[]): string =>\n JSON.stringify(weights).replaceAll(\n /(?<min>\\d+)\\.\\.(?<max>\\d+)/gu,\n \"$<min> $<max>\"\n );\n\n/** The named imports the generated config pulls from `astro/config`. */\nconst astroConfigImportLine = (options: { hasFonts: boolean }): string => {\n const names = [\"defineConfig\"];\n if (options.hasFonts) {\n names.push(\"fontProviders\");\n }\n return `import { ${names.join(\", \")} } from \"astro/config\";`;\n};\n\n/**\n * Integration packages the generated runtime imports. Declaring them in\n * `.blume/package.json` lets Astro's framework-package crawl discover and bundle\n * them — notably the React renderer's server entry, which imports the\n * `astro:react:opts` virtual module and must not be externalized (this applies\n * across the `ssr`, `prerender`, and `client` Vite environments).\n */\nexport const runtimeDependencies = (options: {\n config: ResolvedConfig;\n needsReact: boolean;\n needsVue?: boolean;\n needsSvelte?: boolean;\n}): string[] => {\n const { config, needsReact, needsSvelte, needsVue } = options;\n const deps = [\"@astrojs/mdx\"];\n if (needsReact) {\n deps.push(\"@astrojs/react\");\n }\n if (needsVue) {\n deps.push(\"@astrojs/vue\");\n }\n if (needsSvelte) {\n deps.push(\"@astrojs/svelte\");\n }\n // The Scalar integration is only declared for a Scalar-rendered reference\n // (the `renderer: \"scalar\"` opt-out on either block). Blume-rendered\n // references parse at generate time and need no runtime Scalar dependency.\n if (hasScalarReferences(config)) {\n deps.push(\"@scalar/astro\");\n }\n // Only the configured search provider's SDK is declared, so a project pulls in\n // (and the user installs) exactly the backend it uses — nothing more.\n deps.push(...searchProviderMeta(config.search.provider).runtimeDeps);\n // Ask AI's provider SDK, when its backend needs one (gateway uses core `ai`).\n if (config.ai.ask?.enabled && !config.ai.ask.endpoint) {\n const askDep = askBackendRuntimeDep(config.ai.ask);\n if (askDep) {\n deps.push(askDep);\n }\n }\n const { deployment } = config;\n if (deployment.output === \"server\" && deployment.adapter) {\n const adapter = ADAPTER_IMPORTS[deployment.adapter];\n if (adapter) {\n deps.push(adapter);\n }\n }\n return deps;\n};\n\n/** Generate `.blume/astro.config.mjs`. */\n/**\n * Render project tsconfig path aliases as `vite.resolve.alias` object entries.\n * Longest find first, so a more specific prefix (`@components`) is matched\n * before a broader one (`@`); these follow Blume's `blume:*` aliases, which\n * never overlap with a project's.\n */\n/**\n * Blume's render-time dependencies, forced external on the build's SSR and\n * static-prerender Vite environments.\n *\n * Two reasons a dep lands here:\n * - `takumi-js` (OG image rendering) loads `@takumi-rs/core`, a native NAPI\n * addon that finds its platform-specific `.node` binding via\n * `createRequire(import.meta.url)`. Bundling it relocates `import.meta.url`\n * and breaks the binding lookup (\"Cannot find native binding\") on other\n * platforms (e.g. the Linux CI runner), so it must resolve from\n * `node_modules` at runtime instead. The prerender env matches these by\n * exact specifier, so every entry point Blume imports has to be listed:\n * the bare `takumi-js` (render) plus `takumi-js/helpers` (the `googleFonts`\n * OG-font loader). The `@takumi-rs/*` packages are listed too so the native\n * backend is never pulled into a chunk down any transitive path.\n * - The rest are pure-JS packages kept external so an isolated linker (Bun's\n * `isolated` mode, pnpm) doesn't bundle their symlinked store copies. When\n * Vite bundles such a package but leaves its own `node_modules` child\n * external, that child surfaces as an unresolvable bare import in the\n * prerender chunk (e.g. `batchwork` via `@astrojs/markdown-satteri`). Kept\n * external, each package's transitive imports resolve relative to its real\n * store location — reachable through the `node_modules` junction {@link\n * prerenderDepsPlugin} drops beside the prerender bundle.\n *\n * Astro 7 configures externalization per Vite environment, so this must be\n * applied to both `prerender` (static) and `ssr` (server) — a top-level\n * `ssr.external` only reaches the latter.\n */\nconst RENDER_EXTERNAL_DEPS = [\n \"@astrojs/markdown-satteri\",\n \"@pierre/diffs\",\n \"@shikijs/transformers\",\n \"@takumi-rs/core\",\n \"@takumi-rs/helpers\",\n \"@takumi-rs/wasm\",\n \"github-slugger\",\n \"katex\",\n \"shiki\",\n \"simple-icons\",\n \"takumi-js\",\n \"takumi-js/helpers\",\n \"zod\",\n];\n\nconst renderUserAliases = (\n aliases: Record<string, string> | undefined\n): string =>\n Object.entries(aliases ?? {})\n .toSorted(([a], [b]) => b.length - a.length)\n .map(\n ([find, replacement]) =>\n `\\n ${JSON.stringify(find)}: ${JSON.stringify(replacement)},`\n )\n .join(\"\");\n\n/** Astro's build output dir: the runtime's own `distDir`, else `<root>/dist`. */\nconst astroOutDir = (context: ProjectContext): string =>\n context.distDir ?? `${context.root}/dist`;\n\n/**\n * The root a deploy adapter is shown, in place of the `.blume` runtime Astro\n * actually roots at. Adapters assume `outDir` is `<root>/dist` and resolve their\n * own output (and Vercel's dependency trace) against `root`, so the root implied\n * by Blume's `outDir` is the one that keeps that assumption true. See\n * {@link withAdapterRoot}.\n *\n * For a normal build that is the project root (`<project>/dist` -> `<project>`).\n * For a relocated runtime (`blume build --isolated`) it is the runtime dir\n * itself (`<runtime>/dist` -> `<runtime>`), keeping a verify build's adapter\n * output self-contained instead of overwriting the real `.vercel/output`.\n */\nconst adapterRoot = (context: ProjectContext): string =>\n dirname(astroOutDir(context));\n\n/**\n * Excludes Vite's pre-bundled dep cache from @vitejs/plugin-react. Astro's\n * react() replaces the plugin's default `/node_modules/` exclude with just\n * `/\\.astro$/`, so without this Babel re-parses every optimized dep chunk\n * served from `.vite/deps` — a 500KB+ vendor bundle per chunk, re-done on each\n * re-optimization. A blanket `/node_modules/` exclude would instead switch the\n * React Compiler off for Blume's own components in published installs (they\n * resolve under `node_modules/blume/src`, and exclude beats include in the\n * plugin's filter), so only the pre-bundle cache is excluded. The hidden runtime\n * relocates that cache to `<runtime>/.cache/vite` (see `cacheOptions`), so both\n * the default and the relocated path are excluded.\n */\nconst REACT_EXCLUDE = String.raw`exclude: [/\\/node_modules\\/\\.vite\\//, /\\/\\.cache\\/vite\\//]`;\n\n/**\n * The `cacheDir` entries for the generated config's top level and its `vite`\n * block. The hidden runtime's `node_modules` is a junction into Blume's own\n * package directory, and Astro (`node_modules/.astro`: the content data store,\n * the fonts cache) and Vite (`node_modules/.vite`: pre-bundled deps) both\n * default their caches under the project's `node_modules`. Two Blume projects\n * that resolve the same package (a monorepo building docs and a sandbox in\n * parallel) would therefore share one data store, and each build would serve\n * the other's content — or 404 on entries the other cleared. Keep every cache\n * inside the runtime dir instead. An ejected project (`generatedModulesDir`\n * set) has real `node_modules`, so it keeps the defaults.\n */\nconst runtimeCacheOptions = (\n context: ProjectContext,\n generatedModulesDir: string | undefined\n) => {\n if (generatedModulesDir !== undefined) {\n return { astro: \"\", vite: \"\" };\n }\n return {\n astro: `\n cacheDir: ${JSON.stringify(`${context.outDir}/.cache/astro`)},`,\n vite: `\n cacheDir: ${JSON.stringify(`${context.outDir}/.cache/vite`)},`,\n };\n};\n\n/**\n * The `react()` integration call. When `compilerPath` is set (the resolved\n * absolute path to `babel-plugin-react-compiler`), react() carries the compiler\n * as the first babel plugin — an absolute path, because @vitejs/plugin-react\n * resolves babel plugins from the *project* root, not `.blume/`, so a bare\n * specifier wouldn't resolve in a user project. `target: \"19\"` matches Blume's\n * React pin. `null`/`undefined` (compiler off or unresolvable) omits the babel\n * block. Both variants carry the pre-bundle exclude above.\n */\nconst reactIntegration = (compilerPath: string | null | undefined): string =>\n compilerPath\n ? `react({ babel: { plugins: [[${JSON.stringify(compilerPath)}, { target: \"19\" }]] }, ${REACT_EXCLUDE} })`\n : `react({ ${REACT_EXCLUDE} })`;\n\ninterface IntegrationBridgeOptions {\n /** Config path relative to the generated Astro config. */\n configFile: string;\n /** SHA-256 used to invalidate Astro's generated config. */\n sourceHash?: string;\n}\n\nconst renderIntegrationBridge = (\n bridge: IntegrationBridgeOptions | undefined\n) => {\n if (!bridge) {\n return {\n configSourceMarker: \"\",\n userConfigImports: \"\",\n userConfigSetup: \"\",\n userIntegrationSpread: \"\",\n };\n }\n return {\n configSourceMarker: bridge.sourceHash\n ? `// Blume config source SHA-256: ${bridge.sourceHash}\\n`\n : \"\",\n userConfigImports: `import { dirname, resolve } from \"node:path\";\\nimport { fileURLToPath } from \"node:url\";\\nimport { createModuleLoader } from \"blume/core/load-module.ts\";\\n`,\n userConfigSetup: `const loadBlumeConfig = createModuleLoader();\\nconst blumeConfig = await loadBlumeConfig(resolve(dirname(fileURLToPath(import.meta.url)), ${JSON.stringify(\n bridge.configFile\n )}));\\n\\n`,\n userIntegrationSpread: \", ...(blumeConfig?.integrations ?? [])\",\n };\n};\n\n/**\n * The generated config's `image` block. Remote images are only optimized when\n * their host is authorized; local (relative-path) images need no\n * configuration. Emitted only when set, so the generated config stays minimal.\n */\nconst renderImageOption = (config: ResolvedConfig): string =>\n config.image.domains.length > 0 || config.image.remotePatterns.length > 0\n ? `\\n image: ${JSON.stringify(config.image)},`\n : \"\";\n\n/** What `resolveOptimizeDeps` feeds the generated `optimizeDeps` block. */\ninterface OptimizeDepsConfig {\n optimizeDepsEntries: string[];\n optimizeDepsInclude: string[];\n}\n\n/**\n * Startup-scan entry points and forced includes for the dev dep optimizer:\n * the Vite root is the generated runtime, so user pages, convention islands,\n * and alias-reachable components all live outside it and are otherwise only\n * crawled when first requested. The compiler runtime rides the include list\n * because it is Babel-injected and no source scan can see it. @vitejs/plugin-react\n * would add it itself, but only when the babel plugin is passed by its bare\n * name (`getReactCompilerPlugin` is an exact string match) — Blume passes an\n * absolute path (see `reactIntegration`), which that check never matches. See\n * the optimizeDeps comment in the generated config for the failure this prevents.\n */\n/**\n * The client-side libraries a site needs, decided at generation time. A\n * feature no page uses is left out of the module graph entirely (see\n * {@link featuresTemplate}), so its library never enters the client bundle —\n * Mermaid alone is over 3 MB of chunks (ELK, Cytoscape, KaTeX, every diagram\n * type) and most of the build's client-bundle memory.\n */\nexport interface ClientFeatures {\n /** `export.epub` is on: the EPUB generator's browser bundle is needed. */\n epub: boolean;\n /** Some page has a mermaid fence: the `<blume-mermaid>` element is needed. */\n mermaid: boolean;\n}\n\n/** Every feature on: what a checkout that predates the detection shipped. */\nconst ALL_CLIENT_FEATURES: ClientFeatures = { epub: true, mermaid: true };\n\nconst resolveOptimizeDeps = (options: {\n aliases: Record<string, string> | undefined;\n context: ProjectContext;\n features: ClientFeatures;\n needsReact: boolean;\n reactCompilerPath: string | null | undefined;\n}): OptimizeDepsConfig => {\n const { context, features } = options;\n const optimizeDepsEntries = [\n ...(context.pagesRoot ? [`${context.pagesRoot}/**/*.astro`] : []),\n `${context.root}/islands/**/*.{jsx,svelte,tsx,vue}`,\n ...[...new Set(Object.values(options.aliases ?? {}))]\n .toSorted()\n .map((dir) => `${dir}/**/*.{astro,jsx,svelte,tsx,vue}`),\n ];\n const optimizeDepsInclude = [\n // Only the libraries the site's features actually import: pre-bundling\n // Mermaid costs the dev server seconds at startup for nothing otherwise.\n ...(features.mermaid ? [\"blume > mermaid\"] : []),\n ...(features.epub ? [\"blume > epub-gen-memory/bundle\"] : []),\n // Astro's own client-router/prefetch virtual modules are deliberately NOT\n // forced in here: they read Vite `define`-injected constants\n // (__PREFETCH_PREFETCH_ALL__ and friends) that a pre-bundled copy loses,\n // throwing ReferenceError on every page. Astro manages their optimization\n // itself, without a mid-session reload.\n ...(options.needsReact && options.reactCompilerPath\n ? [\"react/compiler-runtime\"]\n : []),\n ];\n return { optimizeDepsEntries, optimizeDepsInclude };\n};\n\n/**\n * How the generated config reaches the runtime data modules (`blume:data`,\n * the search index, …): served from memory by `runtimeModulesPlugin` in the\n * hidden runtime, or aliased to JSON files under `generatedModulesDir` for an\n * ejected project, which has no CLI to publish them (see `runtime-modules.ts`).\n */\ninterface RuntimeModuleWiring {\n /** `resolve.alias` entries (one per module), empty in the in-memory form. */\n aliasLines: string;\n /** Extra `blume/astro` imports the wiring needs. */\n imports: string[];\n /** Leading `vite.plugins` entry, empty in the file-alias form. */\n pluginEntry: string;\n}\n\nconst renderRuntimeModuleWiring = (\n generatedModulesDir: string | undefined\n): RuntimeModuleWiring => {\n if (generatedModulesDir === undefined) {\n return {\n aliasLines: \"\",\n imports: [\"runtimeModulesPlugin\"],\n pluginEntry: \"runtimeModulesPlugin(), \",\n };\n }\n const aliasLines = [...RUNTIME_MODULE_FILES]\n .map(\n ([id, file]) =>\n `\\n ${JSON.stringify(id)}: ${JSON.stringify(`${generatedModulesDir}/${file}`)},`\n )\n .join(\"\");\n return { aliasLines, imports: [], pluginEntry: \"\" };\n};\n\n/**\n * The options baked into the generated config's `blumeIntegration(...)` call.\n * The hidden runtime gets the content routes and homepage `Link` header from\n * the CLI in memory (`publishDevNegotiation`, republished on every\n * regeneration), so a content-route change never rewrites the config — Astro\n * restarts the dev server in place on a config change — and its scanned\n * project from `blume build` for the deploy artifacts. An ejected project has\n * no CLI, so the negotiation inputs are baked in and `astro:build:done` scans\n * the project root (the Astro root, after eject) for the artifacts.\n */\nconst blumeIntegrationOptions = (options: {\n config: ResolvedConfig;\n contentRoutes: string[];\n ejected: boolean;\n pages: BlumePageRoute[];\n}): BlumeIntegrationOptions =>\n options.ejected\n ? {\n buildArtifactsRoot: \".\",\n contentRoutes: options.contentRoutes,\n homeLinkHeader:\n buildHomeLinkHeader(options.config, options.contentRoutes) ??\n undefined,\n pages: options.pages,\n }\n : { pages: options.pages };\n\nexport const astroConfigTemplate = (options: {\n context: ProjectContext;\n config: ResolvedConfig;\n needsReact: boolean;\n needsVue?: boolean;\n needsSvelte?: boolean;\n pages: BlumePageRoute[];\n contentRoutes: string[];\n /** The generated Ask trigger (`blume:ask`); renders nothing when Ask is off. */\n askPath: string;\n examplesPath: string;\n /** The example-preview Tailwind entry (`blume:examples-theme`). */\n examplesThemePath: string;\n themePath: string;\n searchClientPath: string;\n /** The generated client-feature loaders (`blume:features`). */\n featuresPath: string;\n /** Which client features the site uses; every feature on when omitted. */\n features?: ClientFeatures;\n /**\n * Where the runtime data modules (`blume:data`, the search index, …) live as\n * JSON files, for a project with no CLI to publish them in memory (eject):\n * each id is aliased to its file under this directory. Absent, the modules\n * are served from memory by `runtimeModulesPlugin` — the hidden runtime.\n */\n generatedModulesDir?: string;\n /**\n * Absolute path to `babel-plugin-react-compiler` when the React Compiler is\n * enabled (resolved from Blume's package root by the caller); null/absent\n * disables the compiler and emits a bare `react()`.\n */\n reactCompilerPath?: string | null;\n /** Project tsconfig path aliases (`find` -> absolute dir), e.g. `@` -> src. */\n aliases?: Record<string, string>;\n /**\n * The docs collection's content root; bounds `<include>` resolution in the\n * processors and locates the include graph for dev-server invalidation.\n */\n contentRoot?: string;\n /** Bridge used to load configured integrations without serializing them. */\n integrationBridge?: IntegrationBridgeOptions;\n}): string => {\n const { context, config, needsReact, pages, themePath } = options;\n\n const { astro: cacheOptions, vite: viteCacheOption } = runtimeCacheOptions(\n context,\n options.generatedModulesDir\n );\n const {\n askPath,\n contentRoutes,\n examplesPath,\n examplesThemePath,\n features = ALL_CLIENT_FEATURES,\n featuresPath,\n generatedModulesDir,\n needsSvelte,\n needsVue,\n searchClientPath,\n } = options;\n const {\n aliasLines: runtimeModuleAliasLines,\n imports: runtimeModuleImports,\n pluginEntry: runtimeModulesPluginEntry,\n } = renderRuntimeModuleWiring(generatedModulesDir);\n const { deployment } = config;\n const userAliasLines = renderUserAliases(options.aliases);\n const server = deployment.output === \"server\";\n\n // The project root plus the workspace root, so hoisted dependencies (e.g.\n // KaTeX fonts under a monorepo's root node_modules) stay servable in dev.\n const fsAllow = [...new Set([findWorkspaceRoot(context.root), context.root])];\n\n const { optimizeDepsEntries, optimizeDepsInclude } = resolveOptimizeDeps({\n aliases: options.aliases,\n context,\n features,\n needsReact,\n reactCompilerPath: options.reactCompilerPath,\n });\n\n const adapterImport =\n server && deployment.adapter\n ? `import adapter from \"${ADAPTER_IMPORTS[deployment.adapter]}\";\\n`\n : \"\";\n const adapterArgs = (() => {\n if (!server || !deployment.adapter) {\n return \"\";\n }\n if (deployment.adapter === \"cloudflare\") {\n return resolveCloudflareAdapterArgs(context);\n }\n return ADAPTER_OPTIONS.get(deployment.adapter) ?? \"\";\n })();\n // Vercel resolves its Build Output tree and its `@vercel/nft` dependency\n // trace against the Astro root, which for Blume is the hidden `.blume`\n // runtime — leaving the traced function without its chunks or node_modules.\n // The other adapters emit into `outDir` (cloudflare, node) or are surfaced\n // afterwards (netlify), so none of them read `root` this way.\n const adapterExpr =\n deployment.adapter === \"vercel\"\n ? `withAdapterRoot(adapter(${adapterArgs}), ${JSON.stringify(adapterRoot(context))})`\n : `adapter(${adapterArgs})`;\n const adapterOption =\n server && deployment.adapter ? `\\n adapter: ${adapterExpr},` : \"\";\n\n const sessionOption = resolveSessionOption(deployment);\n\n const siteOption = deployment.site\n ? `\\n site: ${JSON.stringify(deployment.site)},`\n : \"\";\n const baseOption = deployment.base\n ? `\\n base: ${JSON.stringify(deployment.base)},`\n : \"\";\n const imageOption = renderImageOption(config);\n\n // Astro's native i18n resolves `Astro.currentLocale` from the URL, which the\n // document shells fall back to for `<html lang>`/`dir` on pages the content\n // catch-all doesn't drive (custom pages, the 404, the reference shell).\n // Blume owns getStaticPaths and materializes fallback routes in the manifest,\n // so we deliberately omit Astro's `fallback` to keep one source of routing.\n const i18nOption = config.i18n\n ? `\\n i18n: ${JSON.stringify({\n defaultLocale: config.i18n.defaultLocale,\n locales: config.i18n.locales.map((locale) => locale.code),\n routing: {\n prefixDefaultLocale: !config.i18n.hideDefaultLocalePrefix,\n },\n })},`\n : \"\";\n\n // Base the redirect paths the same way routes are based, so a redirect lands\n // under `basePath` too. Astro layers its own `base` (deployment.base) onto\n // `from` when matching, but never onto `to` — see applyBaseToAstroRedirects.\n const basedRedirects = applyBaseToAstroRedirects(\n config.redirects,\n config.basePath,\n deployment.base ?? \"\"\n );\n const redirectsOption =\n basedRedirects.length > 0\n ? `\\n redirects: ${JSON.stringify(\n Object.fromEntries(\n basedRedirects.map((redirect) => [\n redirect.from,\n { destination: redirect.to, status: redirect.status },\n ])\n )\n )},`\n : \"\";\n\n // Self-hosted fonts via Astro's Fonts API, derived from theme.fonts.\n // `fontProviders` is only imported when at least one font is configured.\n // Local variant sources are emitted as absolute paths (the Astro root is\n // `.blume/`, not the user's project, so root-relative paths would miss).\n // Subsets follow the configured locales (a Vietnamese site loads the\n // `vietnamese` faces) unless a family pins its own.\n const fontEntries = buildFontEntries(\n config.theme.fonts,\n fontLocaleCodes(config.i18n)\n );\n const fontsOption = fontEntries.length\n ? `\\n fonts: [${fontEntries\n .map((font) =>\n font.kind === \"local\"\n ? `{ provider: fontProviders.local(), name: ${JSON.stringify(\n font.name\n )}, cssVariable: ${JSON.stringify(\n font.cssVariable\n )}, fallbacks: ${JSON.stringify(\n font.fallbacks\n )}, options: { variants: ${JSON.stringify(\n font.variants.map((variant) => {\n const face: Pick<typeof variant, \"style\" | \"weight\"> = {};\n if (variant.weight !== undefined) {\n face.weight = variant.weight;\n }\n if (variant.style !== undefined) {\n face.style = variant.style;\n }\n return {\n ...face,\n src: [\n isAbsolute(variant.src)\n ? variant.src\n : join(context.root, variant.src),\n ],\n };\n })\n )} } }`\n : `{ provider: fontProviders.${font.provider}(), name: ${JSON.stringify(\n font.name\n )}, cssVariable: ${JSON.stringify(\n font.cssVariable\n )}, weights: ${astroFontWeights(font.weights)}, subsets: ${JSON.stringify(\n font.subsets\n )}, fallbacks: ${JSON.stringify(font.fallbacks)} }`\n )\n .join(\", \")}],`\n : \"\";\n const defineConfigImport = astroConfigImportLine({\n hasFonts: fontEntries.length > 0,\n });\n\n // Framework renderers are only wired in when an island (or Ask AI, for React)\n // needs them. The core theme is Astro-first and ships no client JS.\n const reactImport = needsReact ? `import react from \"@astrojs/react\";\\n` : \"\";\n const vueImport = needsVue ? `import vue from \"@astrojs/vue\";\\n` : \"\";\n const svelteImport = needsSvelte\n ? `import svelte from \"@astrojs/svelte\";\\n`\n : \"\";\n const blumeImports = [\n \"blumeIntegration\",\n \"includeHmrPlugin\",\n \"prerenderDepsPlugin\",\n ...runtimeModuleImports,\n ...(adapterOption.includes(\"withAdapterRoot\") ? [\"withAdapterRoot\"] : []),\n ];\n const blumeImport = `import { ${blumeImports.join(\", \")} } from \"blume/astro\";\\n`;\n\n // Twoslash runs first, before the always-on transformers, but only on fences\n // with the `twoslash` meta (explicitTrigger) — so it's opt-in per block with\n // no config flag; the TypeScript compiler only spins up when a block uses it.\n // Blume's preconfigured transformer compiles with the package's own pinned\n // classic TypeScript, so the user's project can be on any version (see\n // markdown/twoslash.ts).\n const twoslashTransformer = \"blumeTwoslashTransformer(), \";\n\n // Content links are rewritten to their real served URL: the `deployment.base`\n // subdirectory (Astro doesn't rewrite `<a href>`) layered over the site-wide\n // `basePath` baked into routes. The layers are passed separately so a\n // hand-written `basePath` link (`/docs/x`) isn't double-prefixed (see\n // `withComposedBasePath`). The link checker validates the base-less authored\n // path against `basePath` routes separately.\n const deployBase = normalizeBasePath(deployment.base);\n\n const integrations = [\n `mdx({ processor: blumeMdxProcessor(${JSON.stringify({\n basePath: config.basePath,\n codeThemes: config.markdown.codeBlocks.theme,\n contentRoot: options.contentRoot,\n deployBase,\n headingAnchors: config.markdown.headingAnchors,\n })}) })`,\n ];\n if (needsReact) {\n integrations.push(reactIntegration(options.reactCompilerPath));\n }\n if (needsVue) {\n integrations.push(\"vue()\");\n }\n if (needsSvelte) {\n integrations.push(\"svelte()\");\n }\n // Always mounted: injects user pages (a no-op when there are none) and wires\n // up dev-server `Accept: text/markdown` negotiation over the content routes,\n // plus the homepage agent-discovery `Link` header.\n integrations.push(\n `blumeIntegration(${JSON.stringify(\n blumeIntegrationOptions({\n config,\n contentRoutes,\n ejected: generatedModulesDir !== undefined,\n pages,\n })\n )})`\n );\n\n const {\n configSourceMarker,\n userConfigImports,\n userConfigSetup,\n userIntegrationSpread,\n } = renderIntegrationBridge(options.integrationBridge);\n\n return `// Generated by Blume. Do not edit; this file is recreated on each run.\n${configSourceMarker}${userConfigImports}import { availableParallelism } from \"node:os\";\n${defineConfigImport}\nimport mdx from \"@astrojs/mdx\";\nimport tailwindcss from \"@tailwindcss/vite\";\nimport { blumeMarkdownProcessor, blumeMdxProcessor, blumeShikiTransformers, blumeTwoslashTransformer } from \"blume/markdown\";\n${reactImport}${vueImport}${svelteImport}${blumeImport}${adapterImport}\n${userConfigSetup}export default defineConfig({\n root: ${JSON.stringify(context.outDir)},\n srcDir: ${JSON.stringify(`${context.outDir}/src`)},\n outDir: ${JSON.stringify(astroOutDir(context))},\n publicDir: ${JSON.stringify(`${context.root}/public`)},${cacheOptions}\n output: ${JSON.stringify(deployment.output)},${adapterOption}${sessionOption}${siteOption}${baseOption}${imageOption}${redirectsOption}${i18nOption}${fontsOption}\n integrations: [${integrations.join(\", \")}${userIntegrationSpread}],\n markdown: {\n processor: blumeMarkdownProcessor(${JSON.stringify({\n basePath: config.basePath,\n codeThemes: config.markdown.codeBlocks.theme,\n contentRoot: options.contentRoot,\n deployBase,\n headingAnchors: config.markdown.headingAnchors,\n })}),\n shikiConfig: {\n themes: {\n light: ${JSON.stringify(config.markdown.codeBlocks.theme.light)},\n dark: ${JSON.stringify(config.markdown.codeBlocks.theme.dark)},\n },\n defaultColor: false,\n transformers: [${twoslashTransformer}...blumeShikiTransformers(${JSON.stringify(\n { icons: config.markdown.code.icons }\n )})],\n },\n },\n devToolbar: { enabled: false },\n // One canonical URL per page: canonicals, the sitemap, and hreflang all use\n // the slashless form, so the slashed spelling is not a second address. Astro\n // applies this itself — its dev server answers a slashed URL with a 404 that\n // names the setting, an on-demand route redirects — and the Vercel adapter\n // turns it into the platform's 308 route, so the Build Output config needs\n // no hand-spliced redirect (see deploy/vercel-negotiation.ts). Static hosts\n // serve the \\`index.html\\` directory layout as they always did.\n trailingSlash: \"never\",\n // The layouts render Astro's <ClientRouter />, and its in-place swaps read\n // from the prefetch cache — fetching every link on hover/viewport hides the\n // request latency behind the user's intent, so most navigations swap\n // instantly.\n prefetch: { prefetchAll: true },\n // Prerender several pages at once. Rendering is single-threaded, but a\n // page's OG card renders on a native thread and its HTML is written\n // asynchronously, so the main thread would otherwise idle behind each\n // page's off-thread work. Capped at 8: the gain flattens there and beyond it\n // the overlap only adds memory.\n build: { concurrency: Math.min(8, availableParallelism()) },\n vite: {${viteCacheOption}\n plugins: [${runtimeModulesPluginEntry}tailwindcss(), includeHmrPlugin(${JSON.stringify(\n `${context.outDir}/src/generated/includes.json`\n )}), prerenderDepsPlugin()],\n // Everything hydration can reach must be part of the dev dep optimizer's\n // FIRST run. The Vite root is the generated runtime, so user pages,\n // islands, and aliased components live outside it and are only crawled\n // when first requested — and \\`react/compiler-runtime\\` is Babel-injected,\n // so no source scan can ever see it. A dependency discovered after\n // hydration begins triggers a mid-session re-optimization whose new\n // generation imports React through new \\`?v=\\` URLs; the browser then\n // evaluates a second React copy and every island tears down with\n // \"Invalid hook call\" (#157). \\`entries\\` points the startup scanner at\n // the user's files (the scanner follows their imports, so their deps land\n // in the initial optimization); the compiler runtime rides the include\n // list because only the transform pipeline knows it exists.\n //\n // The mermaid/epub includes fix CJS interop instead: both lazy client-side\n // imports land on CJS/UMD files (mermaid statically imports dayjs as CJS,\n // epub-gen-memory's browser bundle is a browserified UMD) that break when\n // served as raw ESM — mermaid throws on load and the EPUB export throws\n // \\`epub is not a function\\`. They resolve through the \\`blume\\` package\n // (they aren't direct deps of the generated project), so the nested\n // \\`blume > x\\` form is required, and epub-gen-memory must name the\n // \\`/bundle\\` subpath that is actually imported: optimizing the package\n // root leaves that entry out. Production (Rollup) already handles the\n // interop, so all of this only affects dev.\n optimizeDeps: {\n entries: ${JSON.stringify(optimizeDepsEntries)},\n include: ${JSON.stringify(optimizeDepsInclude)},\n },\n // Blume's render-time deps are forced external on both build environments so\n // native bindings resolve at runtime and isolated linkers don't bundle\n // symlinked store copies (which would surface their children as unresolvable\n // imports). See RENDER_EXTERNAL_DEPS / prerenderDepsPlugin.\n //\n // The SSR externals go through the legacy \\`ssr.external\\` key rather than\n // \\`environments.ssr\\`: defining a user-owned \\`environments.ssr\\` block\n // collides with the internal environment Astro 7 builds the server under and\n // detaches the adapter's server entrypoint from the rolldown input, so the\n // SSR entry is emitted as \\`index.mjs\\` instead of the \\`entry.mjs\\` the\n // Vercel adapter's \\`astro:build:done\\` hook then fails to find. \\`prerender\\`\n // is Astro-only and has no legacy equivalent, so it stays under \\`environments\\`.\n ssr: { external: ${JSON.stringify(RENDER_EXTERNAL_DEPS)} },\n environments: {\n prerender: { resolve: { external: ${JSON.stringify(RENDER_EXTERNAL_DEPS)} } },\n },\n resolve: {\n alias: {\n \"blume:ask\": ${JSON.stringify(askPath)},\n \"blume:examples\": ${JSON.stringify(examplesPath)},\n \"blume:examples-theme\": ${JSON.stringify(examplesThemePath)},\n \"blume:features\": ${JSON.stringify(featuresPath)},\n \"blume:search-client\": ${JSON.stringify(searchClientPath)},\n \"blume:theme\": ${JSON.stringify(themePath)},${runtimeModuleAliasLines}${userAliasLines}\n },\n },\n server: {\n fs: {\n allow: ${JSON.stringify(fsAllow)},\n },\n },\n },\n});\n`;\n};\n\n/** The default staged-content base, relative to the runtime `outDir`. */\nexport const stagedContentDir = (outDir: string): string =>\n join(outDir, \"content\");\n\n/**\n * The runtime dir relative to the docs collection `base` when it sits inside\n * it (a migrated, `content.root: \".\"` project) — null when it lives elsewhere.\n * Drives the collection's negative glob in `contentConfigTemplate`, which both\n * keeps runtime-dir files out of the collection and (Astro's watcher honors\n * negated patterns) keeps the content watcher off Astro's own `.astro` writes.\n */\nconst runtimeDirWithin = (base: string, outDir: string): string | null => {\n const rel = relative(base, outDir);\n return rel && !rel.startsWith(\"..\") && !isAbsolute(rel) ? rel : null;\n};\n\n/**\n * Astro's glob loader resolves `base` with `new URL(base, config.root)`. On\n * Windows an absolute path like `C:\\\\docs\\\\content` makes `new URL` parse the\n * drive letter as a URL scheme, so the result isn't a `file:` URL and Astro's\n * subsequent `fileURLToPath` throws \"The URL must be of scheme file\". Emit an\n * absolute base as a proper `file://` URL so the drive letter can't be mistaken\n * for a scheme; relative bases resolve against `config.root` unchanged.\n */\nconst astroGlobBase = (base: string): string =>\n isAbsolute(base) ? pathToFileURL(base).href : base;\n\n/** Generate `.blume/src/content.config.ts`. */\nexport const contentConfigTemplate = (options: {\n context: ProjectContext;\n config: ResolvedConfig;\n /** Whether any non-filesystem source materialized MDX into the staged dir. */\n staged?: boolean;\n /** Base dir for the staged collection; defaults to `<outDir>/content`. */\n stagedBase?: string;\n /**\n * The `docs` collection's base + include/exclude globs. Defaults to\n * `content.root` and the top-level content globs; a single filesystem source\n * roots the collection at *its* root so entry ids resolve (see\n * `resolveDocsCollection`).\n */\n collection?: { base: string; include: string[]; exclude: string[] };\n /**\n * Whether any filesystem (non-staged) source feeds the `docs` collection.\n * When false (e.g. an all-staged project where every page is materialized by\n * a non-filesystem source), the collection globs nothing — see below.\n */\n filesystem?: boolean;\n}): string => {\n const { context, config } = options;\n const stagedBase = options.stagedBase ?? stagedContentDir(context.outDir);\n const collectionBase = options.collection?.base ?? context.contentRoot;\n const includeGlobs = options.collection?.include ?? config.content.include;\n const excludeGlobs = options.collection?.exclude ?? config.content.exclude;\n\n // Fold the content excludes into the glob as negative patterns so the `docs`\n // collection doesn't ingest ignored trees (`node_modules`, `snippets`, the\n // staged bodies under `.blume/content`, …) as entries. This matters when\n // the collection base is the project root (a migrated `.`-rooted project).\n const outDirRel = runtimeDirWithin(collectionBase, context.outDir);\n const outDirIgnore = outDirRel ? [`!${outDirRel}/**`] : [];\n\n // With no filesystem source, no route renders through `docs`, so glob\n // nothing: an all-staged project roots the collection at the project dir,\n // and a patterned glob would scan (and watch) the whole project for nothing.\n // The collection is still declared below so `getCollection(\"docs\")` /\n // `getEntry` resolve (to empty).\n const filesystem = options.filesystem ?? true;\n const docsPattern = filesystem\n ? [\n ...includeGlobs,\n ...(excludeGlobs ?? []).map((pattern) => `!${pattern}`),\n // Mirror the filesystem scan's baseline ignores (see BLUME_IGNORE_DIRS):\n // Astro's content layer roots at the project dir, so a `.`-wide content\n // root would otherwise re-ingest dependency trees and build output —\n // e.g. a prior `dist/*.mdx` render — and crash the content-module graph.\n // The runtime dir (`.blume`, or a custom distDir) is excluded precisely\n // by `outDirIgnore` instead, so it's left out of this baseline.\n ...BLUME_IGNORE_DIRS.flatMap((dir) =>\n dir === \".blume\" ? [] : [`!**/${dir}/**`]\n ),\n ...outDirIgnore,\n ]\n : [];\n\n // Non-filesystem sources render through a parallel `staged` collection backed\n // by materialized MDX, so the filesystem `docs` collection stays untouched.\n const stagedBlock = options.staged\n ? `\nconst staged = defineCollection({\n loader: glob({\n pattern: [\"**/*.{md,mdx}\"],\n base: ${JSON.stringify(astroGlobBase(stagedBase))},\n generateId: ({ entry }) => entry,\n }),\n schema: pageCollectionSchema,\n});\n`\n : \"\";\n\n return `// Generated by Blume. Do not edit.\nimport { defineCollection } from \"astro:content\";\nimport { glob } from \"astro/loaders\";\nimport { withIncludeRefresh } from \"blume/astro\";\nimport { pageCollectionSchema } from \"blume/core/schema.ts\";\n\n// withIncludeRefresh keeps <include>-bearing pages fresh: plain .md entries\n// are rendered at sync time and digest-cached on the page file alone, so a\n// partial edit (or a warm-cache rebuild after one) would serve stale HTML.\n//\n// pageCollectionSchema is the scan's page front-matter schema, so entry.data\n// is typed and normalized the same way; it passes custom keys through and\n// falls back to defaults for a page the scan already dropped as invalid.\nconst docs = defineCollection({\n loader: withIncludeRefresh(glob({\n pattern: ${JSON.stringify(docsPattern)},\n base: ${JSON.stringify(astroGlobBase(collectionBase))},\n generateId: ({ entry }) => entry,\n }), ${JSON.stringify(`${context.outDir}/src/generated/includes.json`)}),\n schema: pageCollectionSchema,\n});\n${stagedBlock}\nexport const collections = { docs${options.staged ? \", staged\" : \"\"} };\n`;\n};\n\n/** Generate `.blume/src/pages/[...slug].astro`, the docs catch-all route. */\n/** The plain prompt used when there is no grounding context to inject. */\nconst ASK_FALLBACK_PROMPT =\n \"You are a helpful documentation assistant. Answer using the project's documentation.\";\n\n/** The `ai.ask` values the generated endpoint has to carry with it. */\nexport interface AskEndpointOptions {\n /** `ai.ask.cors` — origins allowed to call the route from another site. */\n cors?: string[];\n /** `ai.ask.instructions` — extra system-prompt text. */\n instructions?: string;\n /**\n * `ai.ask.reasoning` — how much the model reasons before answering, sent\n * as the backend's own reasoning-effort control.\n */\n reasoning?: AskReasoning;\n /** `ai.ask.retrieval` — how much documentation each question carries. */\n retrieval?: AskRetrievalOptions;\n}\n\n/** The pieces `askEndpointTemplate` splices in for `ai.ask.cors`. */\ninterface AskCorsTemplate {\n /** The route's closing token: `});` when the POST is wrapped, `};` otherwise. */\n close: string;\n /** The runtime import, when anything is listed. */\n imports: string[];\n /** The opening of `export const POST: APIRoute = `. */\n open: string;\n /** The allow list and the `OPTIONS` handler, spliced after the provider setup. */\n setup: string;\n}\n\n/**\n * `ai.ask.cors`: a browser only lets another origin read the stream when the\n * response names that origin, and a JSON POST preflights first, so the route\n * answers `OPTIONS` and wraps the `POST` in `withCors`, which stamps a listed\n * origin on every response — errors included, so a cross-origin caller can\n * tell a 400 from a 500 — without each `return` having to remember to.\n * Unlisted origins get no allow header and stay subject to the same-origin\n * rule. Left out entirely when nothing is listed, so the default route is\n * unchanged.\n */\nconst askCorsTemplate = (cors: readonly string[] = []): AskCorsTemplate =>\n cors.length > 0\n ? {\n close: \"});\",\n imports: [\n 'import { preflightResponse, withCors } from \"blume/ai/cors.ts\";',\n ],\n open: \"withCors(ALLOWED_ORIGINS, async ({ request }) => {\",\n setup: `\nconst ALLOWED_ORIGINS = ${JSON.stringify(cors)};\n\nexport const OPTIONS: APIRoute = ({ request }) =>\n preflightResponse(request, ALLOWED_ORIGINS);\n`,\n }\n : { close: \"};\", imports: [], open: \"async ({ request }) => {\", setup: \"\" };\n\n/**\n * Generate the Ask AI server endpoint (`.blume/src/pages/api/ask.ts`).\n *\n * `options.instructions` (the `ai.ask.instructions` config) is appended to the\n * built-in prompt on every path: the grounded prompt via `createAskContext`,\n * and the plain fallback here. `options.retrieval` (the `ai.ask.retrieval`\n * config) is forwarded to `createAskContext` on the grounded path, where it\n * sizes retrieval. `options.reasoning` (the `ai.ask.reasoning` config)\n * reaches the model call on both paths. `options.cors` (the `ai.ask.cors`\n * config) adds a preflight handler and wraps the `POST` so every response\n * names a listed origin. All four travel in one options object so a new call\n * site can't silently drop one of them.\n */\nexport const askEndpointTemplate = (\n backend: AskBackend,\n grounded: boolean,\n options?: AskEndpointOptions\n): string => {\n const { instructions, reasoning, retrieval } = options ?? {};\n // `ai.ask.reasoning`. The gateway and OpenAI-compatible providers take it\n // from `streamText`'s top-level `reasoning` (the gateway maps it to the\n // model's own control, the OpenAI-compatible provider sends it as\n // `reasoning_effort`). OpenRouter's provider ignores that call option and\n // only reads its own model setting, so there the level rides on the model\n // as `reasoning.effort`. Omitted keeps the provider default on every path.\n const fallbackPrompt = instructions\n ? `${ASK_FALLBACK_PROMPT}\\n\\n${instructions}`\n : ASK_FALLBACK_PROMPT;\n // Secrets go through Astro's `getSecret` rather than `process.env`, so each\n // adapter supplies them its own way (Cloudflare from the Worker's bindings,\n // Node and Vercel from the environment).\n const imports = [\n 'import type { APIRoute } from \"astro\";',\n 'import { getSecret } from \"astro:env/server\";',\n // The gateway provider reads the key (or Vercel's OIDC token) from the\n // environment itself; passing the key explicitly lets a binding-backed\n // secret store reach it too.\n backend.kind === \"gateway\"\n ? 'import { createGateway, streamText } from \"ai\";'\n : 'import { streamText } from \"ai\";',\n ];\n let setup = \"\";\n let modelExpr = JSON.stringify(backend.model);\n // `ai.ask.headers`, inlined as literals: every provider factory below takes\n // the same `headers` option, so one line serves all three.\n const headersField = backend.headers\n ? `\\n headers: ${JSON.stringify(backend.headers)},`\n : \"\";\n if (backend.kind === \"gateway\") {\n setup = `\\nconst gateway = createGateway({\n apiKey: getSecret(\"AI_GATEWAY_API_KEY\"),${headersField}\n});\\n`;\n modelExpr = `gateway(${JSON.stringify(backend.model)})`;\n } else if (backend.kind === \"openrouter\") {\n imports.push(\n 'import { createOpenRouter } from \"@openrouter/ai-sdk-provider\";'\n );\n setup = `\\nconst openrouter = createOpenRouter({\n apiKey: getSecret(${JSON.stringify(backend.apiKeyEnv)}),${headersField}\n});\\n`;\n const settings = reasoning\n ? `, { reasoning: { effort: ${JSON.stringify(reasoning)} } }`\n : \"\";\n modelExpr = `openrouter(${JSON.stringify(backend.model)}${settings})`;\n } else if (backend.kind === \"openai-compatible\") {\n imports.push(\n 'import { createOpenAICompatible } from \"@ai-sdk/openai-compatible\";'\n );\n setup = `\\nconst provider = createOpenAICompatible({\n apiKey: getSecret(${JSON.stringify(backend.apiKeyEnv)}),\n baseURL: ${JSON.stringify(backend.baseUrl)},${headersField}\n name: ${JSON.stringify(backend.name)},\n});\\n`;\n modelExpr = `provider(${JSON.stringify(backend.model)})`;\n }\n // Ground the answer in retrieved docs, except for RAG-native backends (Inkeep),\n // which run their own retrieval and would conflict with injected context.\n if (grounded) {\n imports.push(\n 'import { createAskContext } from \"blume/ai/ask-context.ts\";',\n 'import askData from \"blume:ask-data\";'\n );\n const groundFields: string[] = [];\n if (instructions) {\n groundFields.push(`instructions: ${JSON.stringify(instructions)}`);\n }\n if (retrieval) {\n groundFields.push(`retrieval: ${JSON.stringify(retrieval)}`);\n }\n const groundOptions =\n groundFields.length > 0 ? `, { ${groundFields.join(\", \")} }` : \"\";\n setup += `\\nconst ground = createAskContext(askData${groundOptions});\\n`;\n }\n const cors = askCorsTemplate(options?.cors);\n imports.push(...cors.imports);\n // Validate the client-supplied body and cap its size. The endpoint is\n // unauthenticated, so bounding message count/length limits how much a caller\n // can spend against the model per request, and restricting roles to\n // user/assistant keeps callers from injecting their own system prompt and\n // repurposing the endpoint as a general LLM proxy; front it with a rate\n // limiter (or your provider's limits) for stronger protection.\n const validate = ` const body = await request.json().catch(() => null);\n const raw = body?.messages;\n const valid =\n Array.isArray(raw) &&\n raw.length > 0 &&\n raw.length <= 40 &&\n raw.every(\n (m: unknown) =>\n typeof m === \"object\" &&\n m !== null &&\n (\"role\" in m && (m.role === \"user\" || m.role === \"assistant\")) &&\n (\"content\" in m && typeof m.content === \"string\")\n ) &&\n JSON.stringify(raw).length <= 24_000;\n if (!valid) {\n return new Response(\n \"Invalid request: send 1-40 user/assistant messages with string content.\",\n { status: 400 }\n );\n }\n // Re-build the array so only role/content ever reach the model.\n const messages = raw.map((m: { role: \"user\" | \"assistant\"; content: string }) => ({\n content: m.content,\n role: m.role,\n }));`;\n // `streamText` returns synchronously and defers provider/auth/network errors\n // to stream consumption, so the handler's try/catch never sees them: without\n // these the client gets a 200 whose stream aborts mid-flight and nothing is\n // logged server-side. A missing credential is rejected up front as a real\n // 500; everything else is at least logged via `onError`.\n const keyCheck =\n backend.kind === \"gateway\"\n ? ` // The AI Gateway authenticates with an API key or Vercel's OIDC token.\n if (!(getSecret(\"AI_GATEWAY_API_KEY\") || getSecret(\"VERCEL_OIDC_TOKEN\"))) {\n return new Response(\n \"Ask AI is not configured: set AI_GATEWAY_API_KEY (or deploy on Vercel with OIDC).\",\n { status: 500 }\n );\n }`\n : ` if (!getSecret(${JSON.stringify(backend.apiKeyEnv)})) {\n return new Response(\n ${JSON.stringify(`Ask AI is not configured: set ${backend.apiKeyEnv}.`)},\n { status: 500 }\n );\n }`;\n // Provider errors surface mid-stream, after the 200 is committed; this is\n // the only place they can be observed server-side.\n const onError = ` onError({ error }) {\n console.error(\"Ask AI provider error:\", error);\n },`;\n // The `streamText` argument list, built once so the grounded and plain\n // paths can't drift: they differ only in where the instructions come from.\n const streamFields = [\n `model: ${modelExpr}`,\n grounded\n ? \"instructions\"\n : `instructions:\\n ${JSON.stringify(fallbackPrompt)}`,\n \"messages\",\n ];\n if (reasoning && backend.kind !== \"openrouter\") {\n streamFields.push(`reasoning: ${JSON.stringify(reasoning)}`);\n }\n const call = ` const result = streamText({\n ${streamFields.join(\",\\n \")},\n${onError}\n });`;\n const stream = grounded\n ? ` const instructions =\n (await ground(messages, body.page)) ??\n ${JSON.stringify(fallbackPrompt)};\n${call}`\n : call;\n const handler = `export const POST: APIRoute = ${cors.open}\n${validate}\n${keyCheck}\n try {\n${stream}\n return result.toTextStreamResponse();\n } catch {\n return new Response(\"Failed to generate a response.\", { status: 500 });\n }\n${cors.close}`;\n return `// Generated by Blume. Do not edit.\n${imports.join(\"\\n\")}\n\nexport const prerender = false;\n${setup}${cors.setup}\n${handler}\n`;\n};\n\n/**\n * Generate `.blume/src/generated/Ask.astro` — the component behind the\n * `blume:ask` alias that the shared header renders in place of a per-page slot.\n *\n * The header can't import the Ask AI island directly: it's a React component, so\n * the import alone would drag the JSX renderer into the module graph of every\n * project — including the ones that never enable Ask AI and therefore have no\n * React integration wired into their generated Astro config (see `needsReact`).\n * Routing the import through a generated component keeps that dependency behind\n * the config switch: enabled projects get the island, disabled ones get a\n * component that renders nothing and imports no React.\n *\n * `strings` comes from the header (the active locale's dictionary); the empty-\n * state suggestions are read straight from the data snapshot, which is why no\n * page has to pass them.\n */\nexport const askComponentTemplate = (askEnabled: boolean): string =>\n askEnabled\n ? `---\n// Generated by Blume. Do not edit.\nimport AskAI from \"blume/components/islands/AskAI.astro\";\nimport data from \"blume:data\";\n\nconst { strings } = Astro.props;\n---\n\n<AskAI\n endpoint={data.config.ask?.endpoint ?? undefined}\n strings={strings ?? data.ui.ask}\n suggestions={data.config.ask?.suggestions ?? []}\n/>\n`\n : `---\n// Generated by Blume. Do not edit.\n// Ask AI is off (\\`ai.ask.enabled\\`), so the header's Ask trigger renders nothing.\n// Deliberately imports no React island, keeping the JSX renderer out of projects\n// that don't need it.\n---\n`;\n\n/** Generate the static search index endpoint (`/blume-search.json`). */\nexport const searchEndpointTemplate = (): string =>\n `// Generated by Blume. Do not edit.\nimport documents from \"blume:search-index\";\n\nexport const prerender = true;\n\nexport function GET() {\n return new Response(JSON.stringify(documents), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n`;\n\nconst SEARCH_CLIENT_HEADER = \"// Generated by Blume. Do not edit.\\n\";\n\n/** Import the chosen provider's `createSearch` from the Blume package. */\nconst searchClientImport = (module: string): string =>\n `import { createSearch as create } from \"blume/components/layout/search/${module}.ts\";\\n`;\n\n// Joins a base-relative path onto BASE_URL, which arrives with or without a\n// trailing slash (Astro normalizes `base` by `trailingSlash`, which the\n// generated config pins to \"never\" but an owned config may set either way —\n// naive concatenation of a bare `/docs` would yield `/docsblume-search.json`).\nconst SEARCH_BASE_IMPORT =\n 'import { joinBase } from \"blume/components/islands/base-path.ts\";\\n';\n\n/**\n * A client that loads a static `blume-search.json` index (Orama, FlexSearch).\n * `locale` (Orama only) is the site's `i18n.defaultLocale`, which selects a\n * word-segmenting tokenizer for every non-Latin script.\n */\nconst staticSearchClient = (module: string, locale?: string): string =>\n `${SEARCH_CLIENT_HEADER}${searchClientImport(module)}${SEARCH_BASE_IMPORT}\nconst indexUrl = joinBase(import.meta.env.BASE_URL, \"blume-search.json\");\n\nexport const createSearch = () => create({ indexUrl${\n locale ? `, locale: ${JSON.stringify(locale)}` : \"\"\n } });\n`;\n\n/**\n * Public credential fields baked into a hosted provider's generated client\n * (Algolia/Orama Cloud/Typesense config values from `search.*`, all plain\n * strings or numbers; `JSON.stringify` drops the absent ones).\n */\ntype HostedSearchCredentials = Record<string, string | number | undefined>;\n\n/** A client that passes public credentials straight to the provider SDK. */\nconst hostedSearchClient = (\n module: string,\n options: HostedSearchCredentials\n): string =>\n `${SEARCH_CLIENT_HEADER}${searchClientImport(module)}\nexport const createSearch = () => create(${JSON.stringify(options)});\n`;\n\n/** Build the per-provider config object the hosted client is created with. */\nconst hostedSearchOptions = (\n search: ResolvedConfig[\"search\"]\n): { module: string; options: HostedSearchCredentials } | null => {\n switch (search.provider) {\n case \"algolia\": {\n return { module: \"algolia\", options: { ...search.algolia } };\n }\n case \"orama-cloud\": {\n return {\n module: \"orama-cloud\",\n options: {\n apiKey: search.oramaCloud?.apiKey,\n endpoint: search.oramaCloud?.endpoint,\n },\n };\n }\n case \"typesense\": {\n return { module: \"typesense\", options: { ...search.typesense } };\n }\n default: {\n return null;\n }\n }\n};\n\n/**\n * Generate `.blume/src/generated/features.ts` — the client-feature loaders\n * behind the `blume:features` alias. Each loader is a dynamic import when the\n * site uses the feature and `null` otherwise, so an unused library is absent\n * from the module graph (never bundled, never pre-bundled in dev) rather than\n * merely lazy. Regenerated on every pass: a page that gains a mermaid fence\n * turns the loader on.\n */\nexport const featuresTemplate = (features: ClientFeatures): string =>\n `// Generated by Blume. Do not edit.\n//\n// The client features this site uses. A feature no page needs stays out of\n// the module graph entirely: its loader is null and its library never enters\n// the client bundle.\n\n/** Registers the <blume-mermaid> element; null when no page has a mermaid fence. */\nexport const loadMermaid: (() => Promise<unknown>) | null = ${\n features.mermaid\n ? '() => import(\"blume/components/content/mermaid-element.ts\")'\n : \"null\"\n };\n\n/** The EPUB generator's browser bundle; null when export.epub is off. */\nexport const loadEpub:\n | (() => Promise<typeof import(\"epub-gen-memory/bundle\")>)\n | null = ${features.epub ? '() => import(\"epub-gen-memory/bundle\")' : \"null\"};\n`;\n\n/**\n * Generate `.blume/src/generated/search-client.ts` — the provider-specific\n * loader the `<Search>` component lazy-imports via the `blume:search-client`\n * alias. Only the configured provider's module (and therefore its SDK) is\n * referenced, so the build bundles exactly one backend. Public credentials are\n * baked in here; secret keys never reach the client.\n */\nexport const searchClientTemplate = (config: ResolvedConfig): string => {\n const { search } = config;\n\n if (search.provider === \"orama\" || search.provider === \"flexsearch\") {\n // Only Orama derives a tokenizer from the locale; FlexSearch has no\n // equivalent hook, so its client keeps the bare index URL.\n const locale =\n search.provider === \"orama\" ? config.i18n?.defaultLocale : undefined;\n return staticSearchClient(search.provider, locale);\n }\n\n const hosted = hostedSearchOptions(search);\n if (hosted) {\n return hostedSearchClient(hosted.module, hosted.options);\n }\n\n if (search.provider === \"mixedbread\") {\n return `${SEARCH_CLIENT_HEADER}${searchClientImport(\"endpoint\")}${SEARCH_BASE_IMPORT}\nconst api = joinBase(import.meta.env.BASE_URL, \"api/search\");\n\nexport const createSearch = () => create({ api });\n`;\n }\n\n if (search.provider === \"pagefind\") {\n return `${SEARCH_CLIENT_HEADER}${searchClientImport(\"pagefind\")}${SEARCH_BASE_IMPORT}\nconst url = joinBase(import.meta.env.BASE_URL, \"pagefind/pagefind.js\");\n\nexport const createSearch = () => create({ url });\n`;\n }\n\n // Search disabled: a no-op client so the alias always resolves.\n return `${SEARCH_CLIENT_HEADER}export const createSearch = () => () =>\n Promise.resolve({ hits: [], sections: [] });\n`;\n};\n\n/**\n * Generate the Mixedbread search endpoint (`/api/search`). It holds the secret\n * key server-side and proxies semantic queries to the configured store. The\n * result mapping is best-effort and may need tuning to how your content was\n * synced (see the Mixedbread sync step / \\`mxbai vs sync\\`).\n */\nexport const mixedbreadSearchEndpointTemplate = (storeId: string): string =>\n `// Generated by Blume. Do not edit.\nimport type { APIRoute } from \"astro\";\nimport { getSecret } from \"astro:env/server\";\nimport Mixedbread from \"@mixedbread/sdk\";\n\nexport const prerender = false;\n\nconst client = new Mixedbread({ apiKey: getSecret(\"MIXEDBREAD_API_KEY\") ?? \"\" });\nconst STORE_ID = ${JSON.stringify(storeId)};\n\nexport const POST: APIRoute = async ({ request }) => {\n // The endpoint is public: a malformed body must 200-empty, not 500.\n const body = await request.json().catch(() => null);\n const query = body?.query;\n if (!query || typeof query !== \"string\") {\n return new Response(\"[]\", {\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n const response = await client.stores.search({\n query,\n store_identifiers: [STORE_ID],\n top_k: 8,\n });\n const hits = (response.data ?? []).map((chunk) => {\n const meta = chunk.generated_metadata ?? {};\n return {\n excerpt: chunk.text ?? meta.excerpt ?? \"\",\n title: meta.title ?? chunk.filename ?? \"\",\n url: meta.url ?? \"\",\n };\n });\n return new Response(JSON.stringify(hits), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n};\n`;\n\n/**\n * Generate the raw-Markdown endpoints (`[...slug].md.ts` and `[...slug].mdx.ts`).\n * Both read `raw-markdown.json`, whose entries hold the verbatim source (`mdx`)\n * plus a component-downleveled variant (`md`) when the page uses components:\n * `/<route>.mdx` serves the source exactly as written, `/<route>.md` serves\n * plain Markdown with `<TypeTable>`-style components converted for consumers\n * that can't interpret JSX.\n */\nexport const rawMarkdownEndpointTemplate = (kind: \"md\" | \"mdx\"): string =>\n `// Generated by Blume. Do not edit.\nimport raw from \"blume:raw-markdown\";\n\nexport const prerender = true;\n\nexport function getStaticPaths() {\n return Object.keys(raw).map((route) => ({\n params: { slug: route === \"/\" ? \"index\" : route.slice(1) },\n props: { route },\n }));\n}\n\nexport function GET({ props }: { props: { route: string } }) {\n const entries = raw as Record<string, { md?: string; mdx?: string }>;\n const entry = entries[props.route];\n const body = entry ? ${\n kind === \"md\" ? '(entry.md ?? entry.mdx ?? \"\")' : '(entry.mdx ?? \"\")'\n } : \"\";\n return new Response(body, {\n headers: {\n \"Content-Type\": \"text/markdown; charset=utf-8\",\n // ~4 characters per token; keep in sync with markdownTokenCount.\n \"x-markdown-tokens\": String(Math.ceil(body.length / 4)),\n },\n });\n}\n`;\n\n/**\n * Generate the `/blume-assets/[...asset]` endpoint. It serves two families of\n * files that exist on disk but outside the public dir:\n * - `content/<project-relative path>` — colocated content images\n * (`![alt](./diagram.png)`), served as originals for the agent-facing\n * Markdown endpoints (the HTML render uses the `astro:assets`-optimized\n * copies instead). The mapping comes from `generated/content-assets.json`.\n * - `<source>/<hash>.<ext>` — remote-source images the scan pipeline\n * materializes under `.blume/public/blume-assets` (see\n * `core/sources/assets.ts`). That directory is NOT Astro's `publicDir`\n * (which points at the user project's `public/`), so without this endpoint\n * those references 404.\n * Prerendered: every asset becomes a static file in the build output; the dev\n * server renders on demand, so new images appear without a restart.\n */\nexport const contentAssetsEndpointTemplate = (\n stagedAssetsDir: string\n): string =>\n `// Generated by Blume. Do not edit.\nimport { existsSync } from \"node:fs\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { isAbsolute, join, relative, resolve } from \"node:path\";\nimport type { APIRoute } from \"astro\";\nimport assets from \"blume:content-assets\";\n\nexport const prerender = true;\n\nconst files = assets as Record<string, string>;\nconst STAGED_DIR = ${JSON.stringify(stagedAssetsDir)};\n\nconst TYPES: Record<string, string> = {\n \".apng\": \"image/apng\",\n \".avif\": \"image/avif\",\n \".bmp\": \"image/bmp\",\n \".gif\": \"image/gif\",\n \".ico\": \"image/x-icon\",\n \".jpeg\": \"image/jpeg\",\n \".jpg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".svg\": \"image/svg+xml\",\n \".tiff\": \"image/tiff\",\n \".webp\": \"image/webp\",\n};\n\nconst contentType = (path: string): string =>\n TYPES[path.slice(path.lastIndexOf(\".\")).toLowerCase()] ??\n \"application/octet-stream\";\n\nconst stagedParams = async (): Promise<string[]> => {\n if (!existsSync(STAGED_DIR)) {\n return [];\n }\n const entries = await readdir(STAGED_DIR, {\n recursive: true,\n withFileTypes: true,\n });\n return entries\n .filter((entry) => entry.isFile())\n .map((entry) =>\n relative(STAGED_DIR, join(entry.parentPath, entry.name)).replaceAll(\n \"\\\\\\\\\",\n \"/\"\n )\n );\n};\n\nexport async function getStaticPaths() {\n const params = [\n ...Object.keys(files).map((key) => \"content/\" + key),\n ...(await stagedParams()),\n ];\n return params.map((asset) => ({ params: { asset } }));\n}\n\nconst resolveAsset = (asset: string): string | null => {\n if (asset.startsWith(\"content/\")) {\n return files[asset.slice(\"content/\".length)] ?? null;\n }\n const abs = resolve(STAGED_DIR, asset);\n // Traversal guard: the dev server renders on demand, so the param is\n // attacker-controlled there — never step outside the staged directory.\n // path.relative rather than a string-prefix test: STAGED_DIR is baked in\n // with forward slashes while resolve() answers in the platform's\n // separators, so on Windows the prefix test 404'd every legitimate staged\n // asset — and a bare prefix also admits a sibling directory that merely\n // shares the name.\n const rel = relative(STAGED_DIR, abs);\n if (rel === \"\" || rel.startsWith(\"..\") || isAbsolute(rel)) {\n return null;\n }\n return existsSync(abs) ? abs : null;\n};\n\nexport const GET: APIRoute = async ({ params }) => {\n const path = resolveAsset(String(params.asset ?? \"\"));\n if (!path) {\n return new Response(null, { status: 404 });\n }\n const body = await readFile(path);\n return new Response(new Uint8Array(body), {\n headers: { \"Content-Type\": contentType(path) },\n });\n};\n`;\n\n/** The `src/pages` file that serves a route, e.g. `/mcp` -> `mcp.ts`. */\nexport const mcpPageFile = (route: string): string =>\n `${trimChar(route, \"/\")}.ts`;\n\n/**\n * Generate the hosted MCP server endpoint (e.g. `.blume/src/pages/mcp.ts`). A\n * thin wrapper around the shipped `createMcpFetchHandler`, served from the\n * generated data snapshot. Runs server-side (no prerender) so agents can query\n * the docs over Streamable HTTP.\n */\nexport const mcpEndpointTemplate = (): string =>\n `// Generated by Blume. Do not edit.\nimport type { APIRoute } from \"astro\";\nimport { createMcpFetchHandler } from \"blume/ai/mcp/server.ts\";\nimport data from \"blume:mcp-data\";\n\nexport const prerender = false;\n\nconst handler = createMcpFetchHandler(data);\n\nexport const ALL: APIRoute = ({ request }) => handler(request);\n`;\n\n/**\n * Generate the playground's CORS proxy endpoint\n * (`.blume/src/blume-openapi/api-proxy.ts`), behind\n * `openapi.playground.proxy: true`. A thin server-rendered wrapper around the\n * shipped `createPlaygroundProxyHandler`; injected at `/_api-proxy` rather\n * than written under `pages/` because Astro treats `_`-prefixed page files as\n * private.\n *\n * `origins` — the origins of the servers the documented specs declare — is\n * baked in as the handler's allowlist. It cannot come from the request or from\n * client-side data: that is the whole trust boundary keeping the endpoint from\n * being an open proxy onto the deployment's own network.\n */\nexport const playgroundProxyTemplate = (origins: string[]): string =>\n `// Generated by Blume. Do not edit.\nimport type { APIRoute } from \"astro\";\nimport { createPlaygroundProxyHandler } from \"blume/openapi/proxy.ts\";\n\nexport const prerender = false;\n\nconst handler = createPlaygroundProxyHandler(${JSON.stringify(origins)});\n\nexport const ALL: APIRoute = ({ request }) => handler(request);\n`;\n\n/** Generate a prerendered endpoint that serves a fixed JSON payload. */\nexport const staticJsonEndpointTemplate = <Payload extends object>(\n payload: Payload\n): string =>\n `// Generated by Blume. Do not edit.\nexport const prerender = true;\n\nconst payload = ${JSON.stringify(payload, null, 2)};\n\nexport function GET() {\n return new Response(JSON.stringify(payload), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n`;\n\n/**\n * Generate the RSS endpoint (`[section]/rss.xml.ts`). One feed per content\n * type is served from the generated `rss.json`, e.g. `/blog/rss.xml`.\n */\nexport const rssEndpointTemplate = (): string =>\n `// Generated by Blume. Do not edit.\nimport feeds from \"blume:rss\";\n\nexport const prerender = true;\n\nexport function getStaticPaths() {\n return Object.keys(feeds).map((section) => ({\n params: { section },\n props: { section },\n }));\n}\n\nexport function GET({ props }: { props: { section: string } }) {\n const bySection = feeds as Record<string, string>;\n return new Response(bySection[props.section] ?? \"\", {\n headers: { \"Content-Type\": \"application/rss+xml; charset=utf-8\" },\n });\n}\n`;\n\n/**\n * Generate the deferred sidebar fragments page\n * (`.blume/src/pages/blume-nav/[version]/[locale]/[id].astro`): one\n * prerendered partial per collapsible or drill-in group, holding just that\n * group's rows, which the sidebar fetches on first open instead of carrying\n * every collapsed section on every page. Ids are `navGroupIds` over the full\n * tree, the same ids the pages' sidebars use; the `version`/`locale`\n * segments pick the navigation variant (`current`/`default` for the\n * unversioned, unlocalized tree, and `default` again for the default locale\n * while its URL prefix is hidden: Astro's i18n routing 404s a page URL that\n * carries the default locale's code as a segment). Rendered with no current\n * route — a section that isn't on the active path has no active row by\n * definition.\n */\nexport const navFragmentTemplate = (): string =>\n `---\n// Generated by Blume. Do not edit.\nimport NavTree from \"blume/components/layout/NavTree.astro\";\nimport { withBase } from \"blume/components/islands/base-path.ts\";\nimport {\n hiddenDefaultLocale,\n navGroupIds,\n navVariants,\n} from \"blume/components/layout/nav-utils.ts\";\nimport type { NavNode } from \"blume/core/types.ts\";\nimport data from \"blume:data\";\n\nexport const prerender = true;\n// A partial: no doctype, head, or script/style injection — the rows only.\nexport const partial = true;\n\n// Only imports are in scope here (Astro hoists getStaticPaths), which is why\n// the variant walk lives in nav-utils.\nexport function getStaticPaths() {\n return navVariants(data, hiddenDefaultLocale(data.config.i18n)).flatMap(\n ({ locale, navigation, version }) =>\n [...navGroupIds(navigation.sidebar)]\n .filter(([node]) => (node.display ?? \"flat\") !== \"flat\")\n .map(([, id]) => ({ params: { id, locale, version } }))\n );\n}\n\nconst { id, locale, version } = Astro.params;\nconst variant = navVariants(data, hiddenDefaultLocale(data.config.i18n)).find(\n (entry) => entry.version === version && entry.locale === locale\n);\nconst ids = variant\n ? navGroupIds(variant.navigation.sidebar)\n : new Map<NavNode, string>();\nconst node = [...ids].find(([, groupId]) => groupId === id)?.[0];\nif (!(variant && node && node.kind === \"group\")) {\n return new Response(null, { status: 404 });\n}\nconst strings =\n locale === \"default\" ? data.ui.nav : (data.uiByLocale[locale] ?? data.ui).nav;\nconst fragmentBase = withBase(\\`/blume-nav/\\${version}/\\${locale}\\`);\n---\n\n<NavTree\n currentRoute=\"\"\n depth={1}\n fragmentBase={fragmentBase}\n idPrefix={id}\n ids={ids}\n items={node.children}\n root={false}\n strings={strings}\n/>\n`;\n\n/** Generate the OG image endpoint (`.blume/src/pages/og/[...slug].png.ts`). */\nexport const ogEndpointTemplate = (\n customRoutes: OgCustomRoute[] = [],\n og: {\n /**\n * The on-disk card cache (directory plus the rendering Blume version).\n * Absent, every card renders on every build.\n */\n cache?: OgCache;\n families?: OgFontFamilies;\n fonts?: OgFont[];\n /**\n * Whether a page's own description may replace the site-wide subtitle.\n * `false` when `seo.og.description` is `false`, which hides the subtitle\n * on every card, page text included. Defaults to `true`.\n */\n pageDescriptions?: boolean;\n } = {},\n includeChangelog = false\n): string =>\n `// Generated by Blume. Do not edit.\nimport { cachedOgImage } from \"blume/og\";\nimport type { OgCache, OgFont, OgFontFamilies } from \"blume/og\";\nimport data from \"blume:data\";\n\nexport const prerender = true;\n\n// Custom (non-content) pages opted into a generated card, baked in at build.\n// The annotation keeps the empty-array case from being an implicit any[]\n// (ts(7034)) under a strict tsconfig.\nconst customRoutes: { slug: string; title: string }[] = ${JSON.stringify(customRoutes)};\n\n// Card fonts, resolved at generation time (explicit seo.og.fonts, or derived\n// from theme.fonts). Local entries carry absolute build-machine paths, which\n// is why they are baked into this build-only endpoint instead of the runtime\n// data that pages serialize into HTML.\nconst fonts: OgFont[] = ${JSON.stringify(og.fonts ?? [])};\nconst families: OgFontFamilies | undefined = ${\n og.families ? JSON.stringify(og.families) : \"undefined\"\n };\n\n// Rendered cards are kept on disk between builds, keyed by everything that\n// decides their pixels, so a rebuild renders only the cards whose title,\n// description, branding, or fonts changed. The directory is a build-machine\n// path, baked in for the same reason as the local font paths above.\nconst cache: OgCache | undefined = ${\n og.cache ? JSON.stringify(og.cache) : \"undefined\"\n };\n\n// A page's own description (its \\`seo.description\\`, else \\`description\\`) is\n// the card subtitle, so the image says what the page's og:description says.\n// Pages without one fall back to the site-wide subtitle at render time.\n// \\`seo.og.description: false\\` hides the subtitle on every card, page text\n// included, which is what switches this off.\nconst pageDescriptions = ${og.pageDescriptions !== false};\n\ninterface CardProps {\n title: string;\n description: string | null;\n}\n\nexport function getStaticPaths() {\n const seen = new Set<string>();\n const paths: { params: { slug: string }; props: CardProps }[] = [];\n const add = (slug: string, title: string, description: string | null) => {\n if (seen.has(slug)) {\n return;\n }\n seen.add(slug);\n paths.push({\n params: { slug },\n props: { title, description: pageDescriptions ? description : null },\n });\n };\n // A custom page wins over a content route sharing its path, so add it first.\n // Its description is unknown at generate time, so it takes the site subtitle.\n for (const route of customRoutes) {\n add(route.slug, route.title, null);\n }\n for (const route of data.routes) {\n add(\n route.path === \"/\" ? \"index\" : route.path.slice(1),\n route.title,\n route.description\n );\n }${\n includeChangelog\n ? `\n // The generated changelog index is not a content route, so it needs its own\n // card. Added last: a custom page or content route owning /changelog wins.\n add(\n \"changelog\",\n data.ui.changelog?.title ?? \"Changelog\",\n data.ui.changelog?.description ?? null\n );`\n : \"\"\n }\n return paths;\n}\n\n// Footer branding shared by every card. The slug comes from the configured\n// repo rather than the URL, so an Enterprise host reads the same as github.com;\n// the site text (host plus deployment base) is resolved at generate time.\nconst repoSlug = data.config.github\n ? \\`\\${data.config.github.owner}/\\${data.config.github.repo}\\`\n : undefined;\n\nexport async function GET({ props }: { props: CardProps }) {\n const png = await cachedOgImage(cache, {\n accent: data.config.og.palette?.accent ?? data.config.theme.accent.light,\n brand: data.config.title,\n description: props.description ?? data.config.og.description,\n families,\n fonts,\n logo: data.config.og.logo,\n palette: data.config.og.palette,\n repo: repoSlug,\n site: data.config.og.site,\n title: props.title,\n });\n return new Response(new Uint8Array(png), {\n headers: {\n \"Cache-Control\": \"public, max-age=31536000, immutable\",\n \"Content-Type\": \"image/png\",\n },\n });\n}\n`;\n\n/**\n * Generate a Scalar API/AsyncAPI reference page (`.blume/src/pages/<route>.astro`).\n * The reference UI is owned by Scalar (its standalone bundle, loaded from a CDN)\n * but mounted inside Blume's {@link ReferenceLayout} so the page keeps Blume's\n * navbar on top. `renderMode: \"client\"` mounts the reference into a container\n * element (rather than emitting a full HTML document), which is what lets it\n * live inside our shell.\n */\nexport const scalarReferenceTemplate = <Configuration extends object>(options: {\n /** Scalar options forwarded verbatim (spec/theme config plus the author's `scalar` escape hatch). */\n configuration: Configuration;\n noindex?: boolean;\n route: string;\n title: string;\n}): string =>\n `---\n// Generated by Blume. Do not edit.\nimport { ScalarComponent } from \"@scalar/astro\";\nimport ReferenceLayout from \"blume/components/layout/ReferenceLayout.astro\";\nimport data from \"blume:data\";\n\nexport const prerender = true;\n\nconst configuration = ${JSON.stringify(options.configuration, null, 2)};\n\n// The reference is an unlocalized route, so its chrome renders in the default\n// locale's language and direction (\\`data.ui\\` is the default locale's resolved\n// dictionary), mirroring the changelog index's locale wiring.\nconst i18n = data.config.i18n;\nconst localeMeta = i18n\n ? i18n.locales.find((l) => l.code === i18n.defaultLocale)\n : null;\nconst dir = localeMeta?.dir ?? \"ltr\";\nconst htmlLang = i18n ? i18n.defaultLocale : \"en\";\n---\n\n<ReferenceLayout\n analytics={data.config.analytics}\n banner={data.config.banner}\n dir={dir}\n fontCssVars={data.fontCssVars}\n locale={htmlLang}\n logo={data.config.logo}\n favicon={data.config.favicon}\n appleIcon={data.config.appleIcon}\n navigation={data.navigation}\n noindex={${options.noindex === true}}\n pageTitle={${JSON.stringify(options.title)}}\n route={${JSON.stringify(options.route)}}\n searchEnabled={data.config.search.enabled}\n site={{ title: data.config.title, description: data.config.description }}\n themeMode={data.config.theme.mode}\n ui={data.ui}\n>\n <ScalarComponent configuration={configuration} renderMode=\"client\" />\n</ReferenceLayout>\n`;\n\n/**\n * The component map every rendered entry body receives via\n * `<Content components={...} />`: Blume's content components, `<Math>` when\n * math is enabled, the island wrappers, and the user's `mdxComponents`\n * overrides. Shared by the catch-all page and the changelog index so a\n * `:::` directive (compiled to `<Callout>`) or an explicit `<Steps>` renders\n * wherever an entry is rendered — an MDX body throws \"Expected component\n * `X` to be defined\" the moment a page renders it without this map.\n */\nconst contentComponentsSource = (mathEnabled: boolean) => {\n const mathImport = mathEnabled\n ? 'import Math from \"blume/components/content/Math.astro\";\\n'\n : \"\";\n const mathEntry = mathEnabled ? \"Math,\\n \" : \"\";\n return {\n imports: `import Accordion from \"blume/components/content/Accordion.astro\";\nimport AccordionItem from \"blume/components/content/AccordionItem.astro\";\nimport AutoTypeTable from \"blume/components/content/AutoTypeTable.astro\";\nimport Badge from \"blume/components/content/Badge.astro\";\nimport Callout from \"blume/components/content/Callout.astro\";\nimport Card from \"blume/components/content/Card.astro\";\nimport CardGroup from \"blume/components/content/CardGroup.astro\";\nimport CodeBlock from \"blume/components/content/CodeBlock.astro\";\nimport CodeGroup from \"blume/components/content/CodeGroup.astro\";\nimport ColorRoot from \"blume/components/content/Color.astro\";\nimport ColorItem from \"blume/components/content/ColorItem.astro\";\nimport ColorRow from \"blume/components/content/ColorRow.astro\";\nimport Column from \"blume/components/content/Column.astro\";\nimport Columns from \"blume/components/content/Columns.astro\";\nimport Component from \"blume/components/content/Component.astro\";\nimport Diff from \"blume/components/content/Diff.astro\";\nimport Expandable from \"blume/components/content/Expandable.astro\";\nimport FileTree from \"blume/components/content/FileTree.astro\";\nimport Frame from \"blume/components/content/Frame.astro\";\nimport GithubInfo from \"blume/components/content/GithubInfo.astro\";\nimport Panel from \"blume/components/content/Panel.astro\";\nimport Prompt from \"blume/components/content/Prompt.astro\";\nimport Step from \"blume/components/content/Step.astro\";\nimport Steps from \"blume/components/content/Steps.astro\";\nimport Tab from \"blume/components/content/Tab.astro\";\nimport Tabs from \"blume/components/content/Tabs.astro\";\nimport Tile from \"blume/components/content/Tile.astro\";\nimport Tooltip from \"blume/components/content/Tooltip.astro\";\nimport TreeRoot from \"blume/components/content/Tree.astro\";\nimport TreeFile from \"blume/components/content/TreeFile.astro\";\nimport TreeFolder from \"blume/components/content/TreeFolder.astro\";\nimport TypeTable from \"blume/components/content/TypeTable.astro\";\nimport Visibility from \"blume/components/content/Visibility.astro\";\nimport YouTube from \"blume/components/content/YouTube.astro\";\nimport Icon from \"blume/components/Icon.astro\";\nimport LocaleLinks from \"blume/components/layout/LocaleLinks.astro\";\nimport ApiOverview from \"blume/components/openapi/ApiOverview.astro\";\nimport ApiTagOperations from \"blume/components/openapi/ApiTagOperations.astro\";\nimport Operation from \"blume/components/openapi/Operation.astro\";\n${mathImport}import { mdxComponents as userMdx, layoutOverrides } from \"../generated/components.ts\";\nimport { islandComponents } from \"../generated/islands.ts\";`,\n map: `{\n Accordion,\n AccordionItem,\n ApiOverview,\n ApiTagOperations,\n AutoTypeTable,\n Badge,\n Callout,\n Card,\n CardGroup,\n CodeBlock,\n CodeGroup,\n Color,\n Column,\n Columns,\n Component,\n Diff,\n Expandable,\n FileTree,\n Frame,\n GithubInfo,\n Icon,\n Operation,\n Panel,\n Prompt,\n Step,\n Steps,\n Tab,\n Tabs,\n Tile,\n Tooltip,\n Tree,\n TypeTable,\n Visibility,\n YouTube,\n ${mathEntry}...islandComponents,\n ...userMdx,\n}`,\n };\n};\n\nexport const catchAllPageTemplate = (options: {\n exportEpub: boolean;\n exportPdf: boolean;\n mathEnabled: boolean;\n /**\n * Whether the sidebar defers collapsed sections to prerendered fragments\n * (see `navFragmentTemplate`); true when some group renders as a\n * disclosure or a drill-in panel.\n */\n navFragments?: boolean;\n /** Serialize the island-hooks snapshot; only needed when React is enabled. */\n needsReact: boolean;\n}): string => {\n const { imports: componentImports, map: componentMap } =\n contentComponentsSource(options.mathEnabled);\n // The island-hooks snapshot (config + navigation + page) for `blume/hooks`.\n const clientData = options.needsReact\n ? \"\\n clientData={{ config: data.config, navigation, page: { route, title: seo.title ?? title } }}\"\n : \"\";\n\n return `---\n// Generated by Blume. Do not edit.\nimport { getEntry, render } from \"astro:content\";\nimport type { CollectionKey } from \"astro:content\";\nimport RootLayout from \"blume/components/layout/RootLayout.astro\";\nimport { withBase } from \"blume/components/islands/base-path.ts\";\nimport { stripBasePath, withBasePath } from \"blume/core/base-path.ts\";\nimport { resolveSlot } from \"blume/components/layout/overrides.ts\";\n${componentImports}\nimport data from \"blume:data\";\n\nconst Color = Object.assign(ColorRoot, { Item: ColorItem, Row: ColorRow });\nconst Tree = Object.assign(TreeRoot, { File: TreeFile, Folder: TreeFolder });\n\n// Docs content is file-based and always prerendered, even in server output\n// (where only endpoints like /api/ask render on demand). Without this, server\n// builds would render this route on demand and ignore getStaticPaths, leaving\n// the entry id undefined.\nexport const prerender = true;\n\nconst components = ${componentMap};\n\nexport function getStaticPaths() {\n return data.routes.map((route) => ({\n params: { slug: route.path === \"/\" ? undefined : route.path.slice(1) },\n props: {\n alternates: route.alternates,\n collection: route.collection,\n editUrl: route.editUrl,\n entryId: route.entryId,\n fallback: route.fallback,\n indexable: route.indexable,\n lastModified: route.lastModified,\n locale: route.locale,\n route: route.path,\n title: route.title,\n version: route.version,\n versionAlternates: route.versionAlternates,\n },\n }));\n}\n\nconst { entryId, collection, route, title, indexable, editUrl, lastModified, locale, alternates, fallback, version, versionAlternates } = Astro.props;\nconst entry = await getEntry(collection as CollectionKey, entryId);\nif (!entry) {\n return new Response(null, { status: 404 });\n}\nconst { Content, headings: allHeadings, remarkPluginFrontmatter } = await render(entry);\n// \\`[!toc]\\`-marked headings render on the page but stay out of the table of\n// contents; the heading plugin reports their slugs through the render's\n// frontmatter (see markdown/heading-anchors.ts). Only the plugin's array\n// counts: \\`frontmatter.extend\\` can declare the same key, and on a page with\n// no headings that user-supplied value would pass straight through.\nconst tocHiddenRaw = remarkPluginFrontmatter?.${TOC_HIDDEN_KEY};\nconst tocHidden = new Set(Array.isArray(tocHiddenRaw) ? tocHiddenRaw : []);\nconst headings =\n tocHidden.size > 0\n ? allHeadings.filter((heading) => !tocHidden.has(heading.slug))\n : allHeadings;\nconst frontmatter = entry.data;\n\nconst seo = frontmatter.seo;\nconst base = data.config.site ? data.config.site.replace(/\\\\/$/, \"\") : null;\n\n// Percent-encode the route-derived path (the sitemap convention): a Unicode\n// slug (\\`/api/größe\\`) is not legal in a raw URI, and crawlers compare\n// canonical against the sitemap's encoded <loc> byte-for-byte.\nconst ogPath = data.config.og.enabled\n ? encodeURI(\\`/og/\\${route === \"/\" ? \"index\" : route.slice(1)}.png\\`)\n : null;\nconst ogRel = seo.image ?? ogPath;\n// Absolute URLs also carry the deployment base (the page is served under it):\n// \\`site + base + path\\`. Only absolutize root-relative paths: \\`seo.image\\` may be\n// an external URL, which passes through verbatim (mirrors PageLayout).\nconst ogImage =\n ogRel && base && ogRel.startsWith(\"/\") ? \\`\\${base}\\${withBase(ogRel)}\\` : ogRel;\n// Blume's generated card has known dimensions the layout can declare; a user's\n// \\`seo.image\\` could be any size or format, so it gets none.\nconst ogGenerated = !seo.image && Boolean(ogPath);\n\n// X attribution: the site's account, plus a creator the page can claim for\n// itself (a guest post crediting its own author) over the configured default.\nconst x = { ...data.config.x, ...(seo.x?.creator ? { creator: seo.x.creator } : {}) };\n\nconst basedRoute = withBase(route);\n\n// Locale resolution. With i18n on, pick the active locale's nav + dictionary,\n// build hreflang alternates, and derive the language-switcher targets.\nconst i18n = data.config.i18n;\nconst localePrefix = (codeArg: string) =>\n i18n && codeArg === i18n.defaultLocale && i18n.hideDefaultLocalePrefix\n ? \"\"\n : \\`/\\${codeArg}\\`;\nconst localizeRoute = (logical: string, codeArg: string) => {\n const prefix = localePrefix(codeArg);\n if (!prefix) {\n return logical;\n }\n return logical === \"/\" ? prefix : \\`\\${prefix}\\${logical}\\`;\n};\nconst stripLocale = (path: string, codeArg: string) => {\n const prefix = localePrefix(codeArg);\n return prefix && path.startsWith(prefix) ? path.slice(prefix.length) || \"/\" : path;\n};\n\n// Version resolution. An archived page renders its snapshot's navigation tree,\n// points its canonical at the latest equivalent (unless configured otherwise),\n// and shows the old-version notice.\nconst versionsConfig = data.config.versions;\nconst archived = versionsConfig && version\n ? (versionsConfig.archived.find((v) => v.id === version) ?? null)\n : null;\nconst latestVersionAlt = (versionAlternates ?? []).find((alt) => alt.version === \"\");\n\nconst navigation = version\n ? (data.navigationByVersion[version]?.[i18n ? locale : \"\"] ?? data.navigation)\n : i18n\n ? (data.navigationByLocale[locale] ?? data.navigation)\n : data.navigation;\nconst ui = i18n ? (data.uiByLocale[locale] ?? data.ui) : data.ui;\nconst localeMeta = i18n ? i18n.locales.find((l) => l.code === locale) : null;\nconst dir = localeMeta?.dir ?? \"ltr\";\nconst htmlLang = i18n ? locale : \"en\";\n// A fallback page renders the fallback locale's content, so its text direction\n// follows that language — not the (mirrored) page locale.\nconst contentLocale =\n fallback && i18n?.fallbackLocale ? i18n.fallbackLocale : locale;\nconst contentDir = i18n\n ? (i18n.locales.find((l) => l.code === contentLocale)?.dir ?? \"ltr\")\n : \"ltr\";\n// The root route keeps its trailing slash (\\`https://site/\\`) so canonical and\n// hreflang URLs byte-match the sitemap's <loc> for the home page.\nconst absolute = (path: string) => base + withBase(path);\n\n// An archived page defaults its canonical to the same page in the latest docs\n// when that page still exists — search engines treat the live page as\n// authoritative without deindexing version-only content. A page's own\n// \\`seo.canonical\\` always wins, and \\`canonical: \"self\"\\` keeps the default.\nconst canonical =\n seo.canonical ??\n (archived && archived.canonical === \"latest\" && latestVersionAlt && base\n ? absolute(latestVersionAlt.path)\n : base\n ? \\`\\${base}\\${basedRoute === \"/\" ? \"/\" : encodeURI(basedRoute)}\\`\n : null);\nconst effectiveNoindex = Boolean(seo.noindex) || (archived?.noindex ?? false);\n\nconst localeAlternates =\n i18n && base\n ? (alternates ?? []).map((alt) => ({ hreflang: alt.locale, href: absolute(alt.path) }))\n : [];\nconst defaultAlt = i18n ? (alternates ?? []).find((alt) => alt.locale === i18n.defaultLocale) : null;\nconst xDefault = defaultAlt && base ? absolute(defaultAlt.path) : null;\n\n// \\`route\\` arrives with \\`basePath\\` already applied, so the locale segment it\n// carries sits *after* the base (\\`/docs/ja/guide\\`), while \\`localePrefix\\` is\n// base-less (\\`/ja\\`). Stripping and re-adding a locale therefore happen in\n// base-less space, with the base re-applied at the end — the same\n// \\`withBasePath(basePath, localizeRoute(...))\\` composition the manifest uses to\n// build every real route. Done in based space, \\`stripLocale\\` matches nothing\n// and \\`localizeRoute\\` prepends a second prefix (\\`/ja/docs/ja/guide\\`). Only a\n// switcher entry for a locale with no real translation reaches this fallback:\n// a partially translated hand-written page for its missing locales, or a\n// generated reference (which has no \\`alternates\\` at all) for every locale\n// but its own.\nconst mountLocalized = (logical: string, codeArg: string) =>\n withBasePath(data.config.basePath, localizeRoute(logical, codeArg));\nconst logicalRoute = i18n\n ? stripLocale(stripBasePath(data.config.basePath, route), locale)\n : route;\nconst localeSwitch = i18n\n ? i18n.locales.map((l) => {\n const alt = (alternates ?? []).find((x) => x.locale === l.code);\n return {\n code: l.code,\n current: l.code === locale,\n dir: l.dir,\n href: alt ? alt.path : mountLocalized(logicalRoute, l.code),\n label: l.label,\n untranslated: !alt,\n };\n })\n : [];\n\n// Version switcher + old-version notice. The switcher auto-populates from the\n// versions config as a \\`kind: \"version\"\\` selector; a user-declared version\n// selector in \\`navigation.selectors\\` suppresses it (theirs renders instead).\n// Fallback version roots compose like real routes — \\`{basePath}/{locale?}/{id}\\`\n// (manifest \\`versionAlternates\\` paths arrive with the base already applied).\nconst versionRootFor = (id: string) => {\n const logical = id ? \\`/\\${id}\\` : \"/\";\n return i18n\n ? mountLocalized(logical, locale)\n : withBasePath(data.config.basePath, logical);\n};\nconst samePageSwitch = versionsConfig\n ? versionsConfig.switcher.redirect === \"same-page\"\n : true;\nconst userHasVersionSelector = navigation.selectors.some(\n (selector) => selector.kind === \"version\"\n);\nconst versionSelector =\n versionsConfig && !userHasVersionSelector\n ? {\n items: [\n {\n id: \"\",\n label: versionsConfig.current.label,\n tag: versionsConfig.current.badge,\n },\n ...versionsConfig.archived.map((v) => ({\n id: v.id,\n label: v.label ?? v.id,\n tag: undefined,\n })),\n ].map((entry) => {\n const alt = (versionAlternates ?? []).find(\n (a) => a.version === entry.id\n );\n return {\n label: entry.label,\n path: samePageSwitch && alt ? alt.path : versionRootFor(entry.id),\n ...(entry.tag ? { tag: entry.tag } : {}),\n };\n }),\n kind: \"version\" as const,\n label: ui.versions.switcher,\n }\n : null;\n\nconst versionNotice =\n archived && archived.banner !== false\n ? {\n latestHref: latestVersionAlt\n ? latestVersionAlt.path\n : versionRootFor(\"\"),\n latestLabel: ui.versions.latest,\n message:\n typeof archived.banner === \"string\"\n ? archived.banner\n : ui.versions.notice.replace(\n \"{version}\",\n archived.label ?? archived.id\n ),\n }\n : null;\n\n// The whole page shell is overridable via \\`layout.Layout\\`; it receives the same\n// props as the built-in RootLayout, plus the \\`layout\\` map for its inner slots.\nconst LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);\n---\n\n<LayoutComponent\n site={{ title: data.config.title, description: data.config.description }}\n layout={layoutOverrides}${clientData}\n logo={data.config.logo}\n mcp={data.config.mcp}\n favicon={data.config.favicon}\n appleIcon={data.config.appleIcon}\n banner={data.config.banner}\n analytics={data.config.analytics}\n imageZoom={data.config.imageZoom}\n codeWrap={data.config.codeWrap}\n navigation={navigation}\n locale={htmlLang}\n dir={dir}\n contentDir={contentDir}\n ui={ui}\n localeAlternates={localeAlternates}\n xDefault={xDefault}\n localeSwitch={localeSwitch}\n versionSelector={versionSelector}\n versionNotice={versionNotice}\n searchVersion={versionsConfig ? version : null}\n page={{ title: seo.title ?? title, description: seo.description ?? frontmatter.description, route }}\n headings={headings}\n toc={data.config.toc}\n dateFormat={data.config.dateFormat}\n themeMode={data.config.theme.mode}\n fontCssVars={data.fontCssVars}\n searchEnabled={data.config.search.enabled}\n indexable={indexable}\n ogImage={ogImage}\n ogGenerated={ogGenerated}\n x={x}\n canonical={canonical}\n editUrl={editUrl}\n feedback={data.config.feedback}\n exportPdf={${options.exportPdf}}\n exportEpub={${options.exportEpub}}${\n options.navFragments\n ? `\n navFragmentBase={withBase(\\`/blume-nav/\\${version || \"current\"}/\\${i18n && localePrefix(locale) ? locale : \"default\"}\\`)}`\n : \"\"\n }\n openInChat={data.config.openInChat}\n feeds={data.feeds}\n discovery={data.config.discovery}\n siteUrl={data.config.site}\n pageType={frontmatter.type}\n published={frontmatter.date ?? frontmatter.changelog?.date ?? null}\n lastModified={lastModified}\n noindex={effectiveNoindex}\n structuredDataEnabled={data.config.structuredData}\n>\n <h1>{title}</h1>\n {frontmatter.description && <p class=\"text-lg text-muted-foreground\">{frontmatter.description}</p>}\n <LocaleLinks locale={locale}>\n <Content components={components} />\n </LocaleLinks>\n</LayoutComponent>\n`;\n};\n\n/**\n * Generate `.blume/src/pages/changelog.astro` — the changelog index. Collects\n * every `type: changelog` entry, sorts newest-first, and renders each through\n * the `Update` timeline layout (date/version rail + entry content). Only written\n * by {@link generateAstroProject} when changelog entries exist.\n */\nexport const changelogIndexTemplate = (options: {\n exportEpub: boolean;\n exportPdf: boolean;\n mathEnabled: boolean;\n /** Serialize the island-hooks snapshot; only needed when React is enabled. */\n needsReact: boolean;\n /** Whether a `staged` collection exists (non-filesystem changelog sources). */\n staged: boolean;\n}): string => {\n const clientData = options.needsReact\n ? '\\n clientData={{ config: data.config, navigation: data.navigation, page: { route: \"/changelog\", title: pageTitle } }}'\n : \"\";\n // Staged sources (e.g. GitHub Releases) render through a parallel collection,\n // so fold them in alongside filesystem entries when one exists.\n const stagedSpread = options.staged\n ? '\\n ...(await getCollection(\"staged\")),'\n : \"\";\n const { imports: componentImports, map: componentMap } =\n contentComponentsSource(options.mathEnabled);\n\n return `---\n// Generated by Blume. Do not edit.\nimport { getCollection, render } from \"astro:content\";\nimport RootLayout from \"blume/components/layout/RootLayout.astro\";\nimport Update from \"blume/components/content/Update.astro\";\nimport { withBase } from \"blume/components/islands/base-path.ts\";\nimport { resolveSlot } from \"blume/components/layout/overrides.ts\";\nimport { resolveDateFormatOptions } from \"blume/core/date-format.ts\";\n${componentImports}\nimport data from \"blume:data\";\n\nconst Color = Object.assign(ColorRoot, { Item: ColorItem, Row: ColorRow });\nconst Tree = Object.assign(TreeRoot, { File: TreeFile, Folder: TreeFolder });\n\nexport const prerender = true;\n\n// Entry bodies are MDX rendered outside the catch-all, so they need the same\n// component map: a \\`:::\\` callout or \\`<Steps>\\` in a release note otherwise\n// throws \"Expected component ... to be defined\" at build time.\nconst components = ${componentMap};\n\nconst entryDate = (entry: {\n data: { date?: string | null; changelog?: { date?: string | null } | null };\n}) => entry.data.date ?? entry.data.changelog?.date ?? null;\n\nconst toTime = (value: string | null | undefined) => {\n if (!value) {\n return 0;\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? 0 : date.getTime();\n};\n\n// The changelog is an unlocalized route, so its chrome renders in the default\n// locale's dictionary and direction (\\`data.ui\\` is the default locale's resolved\n// dictionary), mirroring the catch-all's locale wiring.\nconst i18n = data.config.i18n;\nconst localeMeta = i18n\n ? i18n.locales.find((l) => l.code === i18n.defaultLocale)\n : null;\nconst dir = localeMeta?.dir ?? \"ltr\";\nconst htmlLang = i18n ? i18n.defaultLocale : \"en\";\n\n// Formatted in the same locale as the chrome, and with the configured\n// \\`dateFormat\\` (UTC by default), to match the per-page \"last updated\" stamp.\nconst dateFormatOptions = resolveDateFormatOptions(data.config.dateFormat);\nconst formatDate = (value: string | null | undefined) => {\n if (!value) {\n return;\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime())\n ? undefined\n : new Intl.DateTimeFormat(htmlLang, dateFormatOptions).format(date);\n};\n\nconst slugify = (text: string) =>\n text.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\") ||\n \"update\";\n\n// The major of a version's embedded semver (\\`1.2.3\\` -> 1, \\`pkg@2.0.0\\` -> 2), or\n// null when there is no full major.minor.patch to key on. Drives the changelog's\n// group-by-major pagination, so it tolerates the scoped tags monorepos publish.\nconst majorVersion = (version: string | null | undefined) => {\n const match = /(\\\\d+)\\\\.\\\\d+\\\\.\\\\d+/.exec(String(version ?? \"\"));\n return match ? Number(match[1]) : null;\n};\n\n// Map each entry to its own generated page so the timeline heading can deep-link\n// to it. The collection entry id matches the route manifest's \\`entryId\\`.\nconst routeByEntry = new Map(\n data.routes.map((route) => [route.entryId, route.path])\n);\n\nconst changelogEntries = [\n ...(await getCollection(\"docs\")),${stagedSpread}\n]\n .filter(\n (entry) =>\n entry.data.type === \"changelog\" &&\n !entry.data.draft &&\n !entry.data.sidebar?.hidden\n )\n .toSorted((a, b) => toTime(entryDate(b)) - toTime(entryDate(a)));\n\nconst items = await Promise.all(\n changelogEntries.map(async (entry) => {\n const label =\n entry.data.title ??\n (entry.data.changelog?.version\n ? \"v\" + entry.data.changelog.version\n : \"Update\");\n return {\n Content: (await render(entry)).Content,\n date: formatDate(entryDate(entry)),\n href: routeByEntry.get(entry.id) ?? undefined,\n id: slugify(label),\n label,\n major: majorVersion(entry.data.changelog?.version),\n tags: entry.data.changelog?.category\n ? [entry.data.changelog.category]\n : [],\n };\n })\n);\n\n// Repeated labels slug to the same id (e.g. two entries with neither a title\n// nor a version both falling back to \"update\"); suffix the later ones -2, -3,\n// ... so every heading deep-links to its own entry. The first keeps the plain\n// slug, and the rendered ids stay in lockstep with the \\`headings\\` list below.\nconst seenIds = new Set();\nfor (const item of items) {\n let uniqueId = item.id;\n for (let n = 2; seenIds.has(uniqueId); n += 1) {\n uniqueId = item.id + \"-\" + n;\n }\n seenIds.add(uniqueId);\n item.id = uniqueId;\n}\n\n// A changelog is semver-paginated only when every visible release parses as\n// semver and they span more than one major line. Older majors then collapse\n// into groups the reader reveals one at a time; otherwise the timeline is flat.\nconst majors = items.every((item) => item.major !== null)\n ? [...new Set(items.map((item) => item.major))]\n .filter((major): major is number => major !== null)\n .toSorted((a, b) => b - a)\n : [];\nconst paginate = majors.length > 1;\nconst majorGroups = majors.map((major) => ({\n items: items.filter((item) => item.major === major),\n label: major + \".x\",\n major,\n}));\n\nconst headings = items.map((item) => ({\n depth: 2,\n slug: item.id,\n text: item.label,\n}));\n\nconst base = data.config.site ? data.config.site.replace(/\\\\/$/, \"\") : null;\n// The canonical URL carries the deployment base (the page is served under it),\n// matching how the catch-all canonicalizes via \\`withBase(route)\\`.\nconst basedRoute = withBase(\"/changelog\");\nconst canonical = base ? base + basedRoute : null;\n\n// The generated OG card for this route (the /og endpoint emits it alongside\n// the content-route cards), absolutized like the catch-all's so crawlers get\n// a full URL when the site is known.\nconst ogPath = data.config.og.enabled ? withBase(\"/og/changelog.png\") : null;\nconst ogImage = ogPath && base ? base + ogPath : ogPath;\n\n// The page chrome (h1, title, description) comes from the same translatable\n// \\`changelog\\` group as the reveal button; optional chaining tolerates a\n// not-yet-regenerated data snapshot from before these keys existed.\nconst changelogTitle = data.ui.changelog?.title ?? \"Changelog\";\nconst changelogDescription =\n data.ui.changelog?.description ??\n \"Product updates, new features, and fixes from every release.\";\n// The layout suffixes \"- {site title}\" itself, so the page title is just the\n// changelog's own name — prefixing the site title too would double it\n// (\"Acme Changelog - Acme\").\nconst pageTitle = changelogTitle;\n\nconst LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);\n---\n\n<LayoutComponent\n site={{ title: data.config.title, description: data.config.description }}\n layout={layoutOverrides}${clientData}\n logo={data.config.logo}\n mcp={data.config.mcp}\n favicon={data.config.favicon}\n appleIcon={data.config.appleIcon}\n banner={data.config.banner}\n analytics={data.config.analytics}\n imageZoom={data.config.imageZoom}\n codeWrap={data.config.codeWrap}\n navigation={data.navigation}\n locale={htmlLang}\n dir={dir}\n ui={data.ui}\n page={{\n title: pageTitle,\n description: changelogDescription,\n route: \"/changelog\",\n }}\n headings={headings}\n toc={data.config.toc}\n contentLayout=\"bare\"\n themeMode={data.config.theme.mode}\n fontCssVars={data.fontCssVars}\n searchEnabled={data.config.search.enabled}\n indexable={true}\n ogImage={ogImage}\n ogGenerated={Boolean(ogImage)}\n x={data.config.x}\n canonical={canonical}\n exportPdf={${options.exportPdf}}\n exportEpub={${options.exportEpub}}\n openInChat={data.config.openInChat}\n feeds={data.feeds}\n discovery={data.config.discovery}\n siteUrl={data.config.site}\n noindex={false}\n structuredDataEnabled={data.config.structuredData}\n>\n <h1>{changelogTitle}</h1>\n {\n items.length === 0 ? (\n <p>No changelog entries yet.</p>\n ) : paginate ? (\n <blume-changelog\n class=\"not-prose mt-8 block\"\n data-i18n-more={data.ui.changelog?.showReleases}\n >\n {majorGroups[0].items.map(({ Content, href, id, label, date, tags }) => (\n <Update description={date} href={href} id={id} label={label} tags={tags}>\n <Content components={components} />\n </Update>\n ))}\n {majorGroups.slice(1).map((group) => (\n <section\n aria-label={group.label + \" releases\"}\n data-changelog-label={group.label}\n data-changelog-major={group.major}\n >\n {group.items.map(({ Content, href, id, label, date, tags }) => (\n <Update description={date} href={href} id={id} label={label} tags={tags}>\n <Content components={components} />\n </Update>\n ))}\n </section>\n ))}\n <div class=\"mt-10 flex justify-center\">\n <button\n class=\"inline-flex items-center gap-2 rounded-full border border-border bg-background px-4 py-2 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground\"\n data-changelog-more\n hidden\n type=\"button\"\n >\n Show older releases\n </button>\n </div>\n </blume-changelog>\n ) : (\n <div class=\"not-prose mt-8\">\n {items.map(({ Content, href, id, label, date, tags }) => (\n <Update description={date} href={href} id={id} label={label} tags={tags}>\n <Content components={components} />\n </Update>\n ))}\n </div>\n )\n }\n <script>\n import \"blume/components/content/changelog-element.ts\";\n </script>\n</LayoutComponent>\n`;\n};\n\n/**\n * Generate `.blume/src/pages/404.astro`: the default not-found page. Rendered\n * through `PageLayout` (header + search, no sidebar) so it stays consistent with\n * the rest of the site, with copy pulled from the translatable `notFound` UI\n * strings. Written at Astro's reserved `src/pages/404.astro` path so static\n * builds emit `dist/404.html` and the dev server serves it for unmatched routes.\n * Skipped by the generator when a user `pages/404.astro` already occupies the\n * `/404` route, so projects can fully override it.\n */\nexport const notFoundPageTemplate = (): string => `---\n// Generated by Blume. Do not edit. Override by adding \\`pages/404.astro\\`.\nimport Icon from \"blume/components/Icon.astro\";\nimport PageLayout from \"blume/components/layout/PageLayout.astro\";\nimport { withBase } from \"blume/components/islands/base-path.ts\";\nimport data from \"blume:data\";\n\nexport const prerender = true;\n\nconst nf = data.ui.notFound;\n\n// The 404 page is an unlocalized route, so its chrome renders in the default\n// locale's dictionary and direction (\\`data.ui\\` is the default locale's resolved\n// dictionary), mirroring the catch-all's locale wiring.\nconst i18n = data.config.i18n;\nconst localeMeta = i18n\n ? i18n.locales.find((l) => l.code === i18n.defaultLocale)\n : null;\nconst dir = localeMeta?.dir ?? \"ltr\";\nconst htmlLang = i18n ? i18n.defaultLocale : \"en\";\n\n// Recovery links, so a reader — or an agent that followed a stale URL — can\n// get back on track without guessing: every top-level section, then the\n// machine-readable indexes the build emits (the sitemap only exists with a\n// \\`deployment.site\\`; llms.txt only when \\`ai.llmsTxt\\` is on). Tabs link to\n// their resolved target when the section has no index page of its own.\nconst suggestions = [\n ...data.navigation.tabs.map((tab) => ({\n href: withBase(tab.href ?? tab.path),\n label: tab.label,\n })),\n ...(data.config.discovery.sitemap\n ? [{ href: withBase(\"/sitemap.xml\"), label: nf.sitemap }]\n : []),\n ...(data.config.discovery.llmsTxt\n ? [{ href: withBase(\"/llms.txt\"), label: nf.llms }]\n : []),\n];\n---\n\n<PageLayout\n site={{ title: data.config.title, description: data.config.description }}\n logo={data.config.logo}\n favicon={data.config.favicon}\n appleIcon={data.config.appleIcon}\n banner={data.config.banner}\n analytics={data.config.analytics}\n navigation={data.navigation}\n page={{ title: nf.title, route: \"/404\" }}\n themeMode={data.config.theme.mode}\n fontCssVars={data.fontCssVars}\n searchEnabled={data.config.search.enabled}\n locale={htmlLang}\n dir={dir}\n ui={data.ui}\n noindex={true}\n>\n <div\n class=\"mx-auto grid w-full max-w-5xl gap-12 px-6 py-20 sm:py-28 md:grid-cols-[3fr_2fr] md:gap-16 lg:gap-24 lg:py-36\"\n >\n <div class=\"flex flex-col items-start\">\n <p\n class=\"font-mono text-xs font-medium tracking-widest text-muted-foreground\"\n >\n 404\n </p>\n <h1\n class=\"mt-4 text-balance text-4xl font-semibold tracking-tight text-foreground sm:text-5xl\"\n >\n {nf.title}\n </h1>\n <p class=\"mt-4 max-w-md text-pretty text-lg text-muted-foreground\">\n {nf.description}\n </p>\n <a\n class=\"mt-8 inline-flex items-center gap-1.5 rounded-full bg-accent py-2 pe-4 ps-3.5 text-sm font-medium text-accent-foreground transition-opacity hover:opacity-90\"\n href={withBase(\"/\")}\n >\n <Icon class=\"rtl:-scale-x-100\" name=\"arrow-left\" size={14} />\n {nf.home}\n </a>\n </div>\n {\n suggestions.length > 0 && (\n <nav aria-label={nf.suggestions} class=\"md:border-s md:border-border md:ps-12 lg:ps-16\">\n <h2 class=\"text-xs font-medium uppercase tracking-widest text-muted-foreground\">\n {nf.suggestions}\n </h2>\n <ul class=\"mt-4 divide-y divide-border border-y border-border\">\n {suggestions.map((link) => (\n <li>\n <a\n class=\"group flex items-center justify-between gap-4 py-3 text-sm font-medium text-foreground transition-colors hover:text-accent\"\n href={link.href}\n >\n <span>{link.label}</span>\n <Icon\n class=\"shrink-0 text-muted-foreground transition-transform group-hover:translate-x-0.5 rtl:-scale-x-100 rtl:group-hover:-translate-x-0.5\"\n name=\"arrow-right\"\n size={14}\n />\n </a>\n </li>\n ))}\n </ul>\n </nav>\n )\n }\n </div>\n</PageLayout>\n`;\n\n/**\n * Generate `.blume/src/pages/404.md.ts`: the Markdown twin of the default 404\n * page, prerendered to `dist/404.md`. An agent that asked for a missing page\n * with `Accept: text/markdown` — or fetched a `.md` URL no page backs — gets\n * this body with the 404 status instead of the HTML shell; Vercel server\n * builds wire that into the routing config (`deploy/vercel-negotiation.ts`).\n * Same recovery links as the HTML page, absolute when the site URL is known:\n * the body is read out of context, so a relative link would leave the reader\n * guessing the host. Written alongside `404.astro` and skipped under the same\n * rule, so a project that owns `/404` owns both variants.\n */\nexport const notFoundMarkdownTemplate =\n (): string => `// Generated by Blume. Do not edit. Override by adding \\`pages/404.astro\\`.\nimport { withBase } from \"blume/components/islands/base-path.ts\";\nimport { absoluteUrl } from \"blume/core/site-url.ts\";\nimport data from \"blume:data\";\n\nexport const prerender = true;\n\nconst nf = data.ui.notFound;\n\n// Absolute for internal routes when the site is known; an external tab href\n// passes through untouched.\nconst href = (path: string): string => {\n const based = withBase(path);\n return data.config.site && based.startsWith(\"/\") && !based.startsWith(\"//\")\n ? absoluteUrl(data.config.site, based)\n : based;\n};\n\n// The recovery set of 404.astro: home, every top-level section (a tab links to\n// its resolved target), then the machine-readable indexes that exist.\nconst links = [\n { href: href(\"/\"), label: nf.home },\n ...data.navigation.tabs.map((tab) => ({\n href: href(tab.href ?? tab.path),\n label: tab.label,\n })),\n ...(data.config.discovery.sitemap\n ? [{ href: href(\"/sitemap.xml\"), label: nf.sitemap }]\n : []),\n ...(data.config.discovery.llmsTxt\n ? [{ href: href(\"/llms.txt\"), label: nf.llms }]\n : []),\n ...(data.config.discovery.api\n ? [{ href: href(\"/openapi.json\"), label: nf.api }]\n : []),\n];\n\nconst body = [\n \"# \" + nf.title,\n \"\",\n nf.description,\n \"\",\n \"## \" + nf.suggestions,\n \"\",\n ...links.map((link) => \"- [\" + link.label + \"](\" + link.href + \")\"),\n \"\",\n].join(\"\\\\n\");\n\nexport function GET() {\n return new Response(body, {\n headers: {\n \"Content-Type\": \"text/markdown; charset=utf-8\",\n // ~4 characters per token; keep in sync with markdownTokenCount.\n \"x-markdown-tokens\": String(Math.ceil(body.length / 4)),\n },\n });\n}\n`;\n\n/**\n * Generate `.blume/src/pages/404.json.ts`: the JSON twin of the default 404\n * page, prerendered to `dist/404.json` as RFC 9457 problem details. An agent\n * that asked for a missing page with `Accept: application/json` gets this body\n * with the 404 status instead of the HTML shell (Vercel server builds wire\n * that into the routing config, like the Markdown twin). Same recovery links\n * as the other variants, carried as `links` and spelled out in `resolution`.\n * Written alongside `404.astro` and skipped under the same rule.\n */\nexport const notFoundJsonTemplate =\n (): string => `// Generated by Blume. Do not edit. Override by adding \\`pages/404.astro\\`.\nimport { problem } from \"blume/ai/api/problem.ts\";\nimport { withBase } from \"blume/components/islands/base-path.ts\";\nimport { absoluteUrl } from \"blume/core/site-url.ts\";\nimport data from \"blume:data\";\n\nexport const prerender = true;\n\nconst nf = data.ui.notFound;\n\n// Absolute for internal routes when the site is known; an external tab href\n// passes through untouched.\nconst href = (path: string): string => {\n const based = withBase(path);\n return data.config.site && based.startsWith(\"/\") && !based.startsWith(\"//\")\n ? absoluteUrl(data.config.site, based)\n : based;\n};\n\n// The recovery set of 404.astro: home, every top-level section (a tab links to\n// its resolved target), then the machine-readable indexes that exist.\nconst links = [\n { href: href(\"/\"), label: nf.home },\n ...data.navigation.tabs.map((tab) => ({\n href: href(tab.href ?? tab.path),\n label: tab.label,\n })),\n ...(data.config.discovery.sitemap\n ? [{ href: href(\"/sitemap.xml\"), label: nf.sitemap }]\n : []),\n ...(data.config.discovery.llmsTxt\n ? [{ href: href(\"/llms.txt\"), label: nf.llms }]\n : []),\n ...(data.config.discovery.api\n ? [{ href: href(\"/openapi.json\"), label: nf.api }]\n : []),\n];\n\nconst body = problem({\n code: \"PAGE_NOT_FOUND\",\n detail: nf.description,\n links,\n resolution: nf.suggestions + \": \" + links.map((link) => link.href).join(\", \"),\n status: 404,\n title: nf.title,\n});\n\nexport function GET() {\n return new Response(JSON.stringify(body, null, 2) + \"\\\\n\", {\n headers: { \"Content-Type\": \"application/problem+json; charset=utf-8\" },\n });\n}\n`;\n\n/**\n * Generate the prerendered JSON docs API endpoints under\n * `.blume/src/pages/api/docs/`: the page index (`pages.json`), one JSON\n * document per page (`pages/[...route].json`), and the navigation tree\n * (`navigation.json`). Each is a thin wrapper over `blume/ai/api/handlers.ts`\n * reading the same snapshot the MCP server serves (`blume:mcp-data`), so the\n * REST and MCP answers can never diverge.\n */\nexport const apiPagesIndexTemplate = (): string =>\n `// Generated by Blume. Do not edit.\nimport { pagesIndexResponse } from \"blume/ai/api/handlers.ts\";\nimport data from \"blume:mcp-data\";\n\nexport const prerender = true;\n\nexport function GET() {\n return pagesIndexResponse(data);\n}\n`;\n\nexport const apiPageTemplate = (): string =>\n `// Generated by Blume. Do not edit.\nimport { pageParams, pageResponse } from \"blume/ai/api/handlers.ts\";\nimport data from \"blume:mcp-data\";\n\nexport const prerender = true;\n\nexport function getStaticPaths() {\n return pageParams(data);\n}\n\nexport function GET({ props }: { props: { route: string } }) {\n return pageResponse(data, props.route);\n}\n`;\n\nexport const apiNavigationTemplate = (): string =>\n `// Generated by Blume. Do not edit.\nimport { navigationResponse } from \"blume/ai/api/handlers.ts\";\nimport data from \"blume:mcp-data\";\n\nexport const prerender = true;\n\nexport function GET() {\n return navigationResponse(data);\n}\n`;\n\n/**\n * Generate the live search endpoint (`.blume/src/pages/api/docs/search.ts`),\n * server output only: the REST twin of the MCP `search_docs` tool, over the\n * same snapshot and index.\n */\nexport const apiSearchTemplate = (): string =>\n `// Generated by Blume. Do not edit.\nimport type { APIRoute } from \"astro\";\nimport { createSearchHandler } from \"blume/ai/api/handlers.ts\";\nimport data from \"blume:mcp-data\";\n\nexport const prerender = false;\n\nconst handler = createSearchHandler(data);\n\nexport const GET: APIRoute = ({ request }) => handler(request);\n`;\n\n/**\n * Generate the API namespace's catch-all (`.blume/src/pages/api/[...path].ts`),\n * server output only: any `/api/…` request no endpoint answers gets an RFC\n * 9457 problem document with the 404 status instead of the HTML not-found\n * page. Static segments always beat the rest parameter, so `/api/ask`, the\n * search proxy, and every prerendered docs endpoint keep winning. The site\n * context is baked in so the resolution links are absolute when the site is\n * known.\n */\nexport const apiNotFoundTemplate = (context: {\n base: string;\n site: string | null;\n}): string =>\n `// Generated by Blume. Do not edit.\nimport type { APIRoute } from \"astro\";\nimport { apiNotFoundResponse } from \"blume/ai/api/handlers.ts\";\n\nexport const prerender = false;\n\nconst context = ${JSON.stringify(context)};\n\nexport const ALL: APIRoute = ({ request }) => apiNotFoundResponse(request, context);\n`;\n\n/** The literal Astro hydration directive for an island's client mode. */\nconst islandDirective = (spec: IslandSpec): string =>\n spec.client === \"only\"\n ? `client:only=\"${spec.framework}\"`\n : `client:${spec.client}`;\n\n/**\n * Frontmatter `Props` alias mirroring the wrapped component's own props, so\n * `{...Astro.props}` satisfies required props under `astro check` (the spread\n * of an untyped `Astro.props` contributes nothing to the JSX props type).\n * `infer P extends object` rather than `Record<string, unknown>` because\n * interfaces have no implicit index signature and would miss the narrower\n * constraint. Non-function component types (Vue/Svelte ambient modules) fall\n * back to an open record, keeping the untyped permissiveness they had.\n */\nconst wrapperPropsType = (name: string): string =>\n `type Props = typeof ${name} extends (\n props: infer P extends object,\n ...rest: never[]\n) => unknown\n ? P\n : Record<string, unknown>;`;\n\n/**\n * Generate `.blume/src/generated/islands/<Name>.astro` — a wrapper that renders\n * a convention island with its hydration directive applied. Astro client\n * directives must be written statically, so one wrapper is emitted per island;\n * props and the default slot (MDX children) forward through.\n */\nexport const islandWrapperTemplate = (spec: IslandSpec): string =>\n `---\n// Generated by Blume. Do not edit.\nimport Island from ${JSON.stringify(spec.file)};\n${wrapperPropsType(\"Island\")}\n---\n<Island ${islandDirective(spec)} {...Astro.props}><slot /></Island>\n`;\n\n/**\n * Generate `.blume/src/generated/islands.ts` — the map of island names to their\n * wrappers, spread into the MDX component scope by the catch-all page. Always\n * written (an empty map when there are no islands) so the import resolves.\n */\nexport const islandMapTemplate = (specs: IslandSpec[]): string => {\n if (specs.length === 0) {\n return `// Generated by Blume. Do not edit.\nexport const islandComponents = {};\n`;\n }\n const imports = specs\n .map(\n (spec, index) => `import I${index} from \"./islands/${spec.name}.astro\";`\n )\n .join(\"\\n\");\n const entries = specs\n .map((spec, index) => ` ${spec.name}: I${index},`)\n .join(\"\\n\");\n return `// Generated by Blume. Do not edit.\n${imports}\nexport const islandComponents = {\n${entries}\n};\n`;\n};\n\n/** The literal Astro hydration directive for an example's framework/client. */\nconst exampleDirective = (spec: ExampleSpec): string => {\n if (spec.framework === \"astro\" || !spec.client) {\n return \"\";\n }\n return spec.client === \"only\"\n ? `client:only=\"${spec.framework}\" `\n : `client:${spec.client} `;\n};\n\n/** Filesystem-safe slug for an example's generated wrapper file. */\n/**\n * A filesystem-safe, injective token for an example path. Distinct paths must\n * never share a wrapper file (`button.demo` vs `button-demo` used to collide),\n * so every non-alphanumeric character is hex-escaped rather than collapsed.\n */\nexport const exampleSlug = (path: string): string =>\n path.replaceAll(\n /[^a-zA-Z0-9]/gu,\n (char) => `_${(char.codePointAt(0) ?? 0).toString(16)}_`\n );\n\n/**\n * Generate `.blume/src/generated/examples/<slug>.astro` — a wrapper that renders\n * one example live, with its hydration directive applied (none for `.astro`).\n * Mirrors {@link islandWrapperTemplate}; `<Component>` resolves these by path.\n */\nexport const exampleWrapperTemplate = (spec: ExampleSpec): string =>\n `---\n// Generated by Blume. Do not edit.\nimport Example from ${JSON.stringify(spec.file)};\n${wrapperPropsType(\"Example\")}\n---\n<Example ${exampleDirective(spec)}{...Astro.props}><slot /></Example>\n`;\n\n/**\n * The route prefix `<Component />` preview frames are served under:\n * `{basePath}/blume-examples/<example path>`. `deployment.base` is layered on\n * top by Astro (components apply it with `withBase`).\n */\nexport const examplesRouteBase = (basePath: string): string =>\n `${basePath}/blume-examples`;\n\n/**\n * Generate `.blume/src/generated/examples.ts` — a map of example path to its live\n * wrapper component plus raw source and language for the code tab, and the route\n * base preview iframes point at. Reached by the shipped `Component.astro` and the\n * generated preview page via the `blume:examples` alias. Always written (an\n * empty object when there are no examples) so the alias resolves.\n */\nexport const exampleMapTemplate = (\n specs: ExampleSpec[],\n basePath: string\n): string => {\n const base = `export const examplesBase = ${JSON.stringify(\n examplesRouteBase(basePath)\n )};`;\n if (specs.length === 0) {\n return `// Generated by Blume. Do not edit.\n${base}\nexport const examples = {};\n`;\n }\n const imports = specs\n .map(\n (spec, index) =>\n `import E${index} from \"./examples/${exampleSlug(spec.path)}.astro\";`\n )\n .join(\"\\n\");\n const entries = specs\n .map(\n (spec, index) =>\n ` ${JSON.stringify(spec.path)}: { Component: E${index}, code: ${JSON.stringify(\n spec.source\n )}, lang: ${JSON.stringify(spec.lang)} },`\n )\n .join(\"\\n\");\n return `// Generated by Blume. Do not edit.\n${imports}\n${base}\nexport const examples = {\n${entries}\n};\n`;\n};\n\n/**\n * Generate the `<Component />` preview page — one prerendered route per\n * example under `{basePath}/blume-examples/`, rendered as a bare document\n * (no layout) that an iframe in the docs page embeds. The iframe boundary is\n * what isolates examples from the docs CSS: the only stylesheet here is the\n * example entry (`blume:examples-theme` — Tailwind, the Blume tokens, and the\n * user's configured examples css), so users can preview components styled by\n * their own design system (e.g. shadcn) with no prose styles bleeding in.\n *\n * The inline script mirrors the docs theme before first paint — same-document\n * reads of the parent's `data-theme` (same origin) with a MutationObserver for\n * live toggles — and sets both `data-theme` and a `dark` class so either\n * dark-mode convention works in user CSS. When the page is opened directly\n * (no parent), it falls back to the stored preference, then the OS setting.\n *\n * A second script reports the example's rendered height to the parent\n * (`blume:example-height` via postMessage) so the docs page can size the\n * preview pane to the content instead of guessing from the source line count.\n * A ResizeObserver keeps the report live, so examples that grow or shrink\n * after load (chat threads, accordions) stay in sync, and the frame re-reports\n * on request (`blume:example-height-request`) so a report posted before the\n * docs page's listener registered isn't lost.\n */\nexport const examplesPageTemplate = (): string =>\n `---\n// Generated by Blume. Do not edit.\nimport { examples } from \"blume:examples\";\nimport \"blume:examples-theme\";\n\n// Prerendered even in server output, like docs content.\nexport const prerender = true;\n\nexport const getStaticPaths = () =>\n Object.keys(examples).map((path) => ({ params: { path } }));\n\nconst { path } = Astro.params;\nconst entry = path ? examples[path] : undefined;\nif (!entry) {\n return new Response(null, { status: 404 });\n}\nconst Example = entry.Component;\n---\n\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta name=\"robots\" content=\"noindex\" />\n <title>{path}</title>\n <script is:inline>\n (() => {\n const root = document.documentElement;\n const apply = (theme) => {\n root.dataset.theme = theme;\n root.classList.toggle(\"dark\", theme === \"dark\");\n };\n const stored = () =>\n localStorage.getItem(\"blume-theme\") ??\n (matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\");\n try {\n const host = window.parent.document.documentElement;\n apply(host.dataset.theme ?? stored());\n new MutationObserver(() => {\n apply(host.dataset.theme ?? stored());\n }).observe(host, { attributeFilter: [\"data-theme\"] });\n } catch {\n apply(stored());\n }\n })();\n </script>\n </head>\n <!-- Flex + margin:auto centers the example and, unlike place-items, keeps\n the top edge reachable when the example outgrows the frame. -->\n <body style=\"display:flex;min-height:100svh;padding:1.5rem\">\n <div data-blume-example style=\"margin:auto\"><Example /></div>\n <script is:inline>\n (() => {\n // Report the example's rendered height so the embedding docs page can\n // size the preview pane to the content. The wrapper is observed rather\n // than the body: the body stretches to the frame's own height, so it\n // would only echo the pane back. Direct opens have no distinct parent\n // and skip out; the frame is same-origin with the docs page (see the\n // theme sync above), so the origin is pinned on both ends.\n if (window.parent === window) {\n return;\n }\n const wrapper = document.querySelector(\"[data-blume-example]\");\n if (!wrapper) {\n return;\n }\n // The body's padding frames the example; fold it into the report so\n // the parent can apply the number as-is. Read from the live value —\n // the user's examples.css is injected after Blume's defaults precisely\n // so their tokens win, so a root font-size override must be honored\n // rather than assuming 1.5rem is 48px.\n const bodyStyle = getComputedStyle(document.body);\n const paddingPx =\n parseFloat(bodyStyle.paddingTop) + parseFloat(bodyStyle.paddingBottom);\n const report = () => {\n window.parent.postMessage(\n {\n height:\n Math.ceil(wrapper.getBoundingClientRect().height) + paddingPx,\n type: \"blume:example-height\",\n },\n window.location.origin\n );\n };\n new ResizeObserver(report).observe(wrapper);\n // The parent asks for a fresh report when its listener comes up, in\n // case the first one above was posted before anyone was listening.\n window.addEventListener(\"message\", (event) => {\n if (\n event.source === window.parent &&\n event.origin === window.location.origin &&\n event.data?.type === \"blume:example-height-request\"\n ) {\n report();\n }\n });\n })();\n </script>\n </body>\n</html>\n`;\n\n/** Generate `.blume/package.json`. */\nexport const runtimePackageTemplate = (dependencies: string[] = []): string =>\n `${JSON.stringify(\n {\n dependencies: Object.fromEntries(\n [...dependencies].toSorted().map((name) => [name, \"*\"])\n ),\n name: \"blume-runtime\",\n private: true,\n type: \"module\",\n version: \"0.0.0\",\n },\n null,\n 2\n )}\\n`;\n\n/** Generate `.blume/tsconfig.json`. */\nexport const runtimeTsconfigTemplate = (): string =>\n `${JSON.stringify(\n {\n exclude: [\"dist\"],\n extends: \"astro/tsconfigs/strict\",\n include: [\".astro/types.d.ts\", \"**/*\"],\n },\n null,\n 2\n )}\\n`;\n"
11
11
  ],
12
- "mappings": "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A;AAAA,EAEJ,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAYmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gDAiC2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAyMpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAkCb,QAAQ;AAAA,gBACP,QAAQ,cACpB,QAAQ,eACJ;AAAA,+HAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BD,IAAM,yBAAyB,CAAC,YAQzB;AAAA,EACZ,MAAM,aAAa,QAAQ,aACvB;AAAA,wHACA;AAAA,EAGJ,MAAM,eAAe,QAAQ,SACzB;AAAA,yCACA;AAAA,EACJ,QAAQ,SAAS,kBAAkB,KAAK,iBACtC,wBAAwB,QAAQ,WAAW;AAAA,EAE7C,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAWmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAwDgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BA+FT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eA6Bb,QAAQ;AAAA,gBACP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwEjB,IAAM,uBAAuB,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2H3C,IAAM,2BACX,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoET,IAAM,uBACX,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8DT,IAAM,wBAAwB,MACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWK,IAAM,kBAAkB,MAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeK,IAAM,wBAAwB,MACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBK,IAAM,oBAAoB,MAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBK,IAAM,sBAAsB,CAAC,YAIlC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAMgB,KAAK,UAAU,OAAO;AAAA;AAAA;AAAA;AAMxC,IAAM,kBAAkB,CAAC,SACvB,KAAK,WAAW,SACZ,gBAAgB,KAAK,eACrB,UAAU,KAAK;AAWrB,IAAM,mBAAmB,CAAC,SACxB,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAalB,IAAM,wBAAwB,CAAC,SACpC;AAAA;AAAA,qBAEmB,KAAK,UAAU,KAAK,IAAI;AAAA,EAC3C,iBAAiB,QAAQ;AAAA;AAAA,UAEjB,gBAAgB,IAAI;AAAA;AAQvB,IAAM,oBAAoB,CAAC,UAAgC;AAAA,EAChE,IAAI,MAAM,WAAW,GAAG;AAAA,IACtB,OAAO;AAAA;AAAA;AAAA,EAGT;AAAA,EACA,MAAM,UAAU,MACb,IACC,CAAC,MAAM,UAAU,WAAW,yBAAyB,KAAK,cAC5D,EACC,KAAK;AAAA,CAAI;AAAA,EACZ,MAAM,UAAU,MACb,IAAI,CAAC,MAAM,UAAU,KAAK,KAAK,UAAU,QAAQ,EACjD,KAAK;AAAA,CAAI;AAAA,EACZ,OAAO;AAAA,EACP;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAMF,IAAM,mBAAmB,CAAC,SAA8B;AAAA,EACtD,IAAI,KAAK,cAAc,WAAW,CAAC,KAAK,QAAQ;AAAA,IAC9C,OAAO;AAAA,EACT;AAAA,EACA,OAAO,KAAK,WAAW,SACnB,gBAAgB,KAAK,gBACrB,UAAU,KAAK;AAAA;AASd,IAAM,cAAc,CAAC,SAC1B,KAAK,WACH,kBACA,CAAC,SAAS,KAAK,KAAK,YAAY,CAAC,KAAK,GAAG,SAAS,EAAE,IACtD;AAOK,IAAM,yBAAyB,CAAC,SACrC;AAAA;AAAA,sBAEoB,KAAK,UAAU,KAAK,IAAI;AAAA,EAC5C,iBAAiB,SAAS;AAAA;AAAA,WAEjB,iBAAiB,IAAI;AAAA;AAQzB,IAAM,oBAAoB,CAAC,aAChC,GAAG;AASE,IAAM,qBAAqB,CAChC,OACA,aACW;AAAA,EACX,MAAM,OAAO,+BAA+B,KAAK,UAC/C,kBAAkB,QAAQ,CAC5B;AAAA,EACA,IAAI,MAAM,WAAW,GAAG;AAAA,IACtB,OAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAGA;AAAA,EACA,MAAM,UAAU,MACb,IACC,CAAC,MAAM,UACL,WAAW,0BAA0B,YAAY,KAAK,IAAI,WAC9D,EACC,KAAK;AAAA,CAAI;AAAA,EACZ,MAAM,UAAU,MACb,IACC,CAAC,MAAM,UACL,KAAK,KAAK,UAAU,KAAK,IAAI,oBAAoB,gBAAgB,KAAK,UACpE,KAAK,MACP,YAAY,KAAK,UAAU,KAAK,IAAI,MACxC,EACC,KAAK;AAAA,CAAI;AAAA,EACZ,OAAO;AAAA,EACP;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AA4BK,IAAM,uBAAuB,MAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyGK,IAAM,yBAAyB,CAAC,eAAyB,CAAC,MAC/D,GAAG,KAAK,UACN;AAAA,EACE,cAAc,OAAO,YACnB,CAAC,GAAG,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CACxD;AAAA,EACA,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AACX,GACA,MACA,CACF;AAAA;AAGK,IAAM,0BAA0B,MACrC,GAAG,KAAK,UACN;AAAA,EACE,SAAS,CAAC,MAAM;AAAA,EAChB,SAAS;AAAA,EACT,SAAS,CAAC,qBAAqB,MAAM;AACvC,GACA,MACA,CACF;AAAA;",
13
- "debugId": "53365D3EDA449FFB64756E2164756E21",
12
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AAEA;AAiBO,IAAM,sBAAsC;AAAA,EACjD,SAAS;AAAA,EACT,QAAQ;AACV;AAsBO,IAAM,uBAAuC;AAAA,EAClD,SAAS;AACX;AAYO,IAAM,qBAAqB,CAChC,eAEA,WAAW,WAAW,aACrB,WAAW,YAAY,UAAU,WAAW,YAAY;AAkCpD,IAAM,kBAAkB,CAC7B,QACA,YACW;AAAA,EACX,QAAQ,SAAS,WAAW,OAAO;AAAA,EACnC,IAAI,WAAW,YAAY,YAAY,UAAU;AAAA,IAC/C,OAAO,KAAK,QAAQ,MAAM,WAAW,UAAU,QAAQ;AAAA,EACzD;AAAA,EACA,MAAM,OAAO,QAAQ,WAAW,KAAK,QAAQ,MAAM,MAAM;AAAA,EACzD,IAAI,mBAAmB,OAAO,UAAU,GAAG;AAAA,IACzC,OAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AAAA,EACA,OAAO;AAAA;AAcF,IAAM,uBAAuB,OAClC,QACA,YAC2B;AAAA,EAC3B,QAAQ,SAAS,WAAW,OAAO;AAAA,EACnC,IAAI,WAAW,YAAY,CAAC,SAAS;AAAA,IACnC,OAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AAAA,EACA,MAAM,MAAM,qBAAqB;AAAA,EACjC,IAAI,CAAC,KAAK;AAAA,IACR,OAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AAAA,EACA,MAAM,OAAO,KAAK,QAAQ,QAAQ,GAAG;AAAA,EACrC,MAAM,KAAK,KAAK,QAAQ,MAAM,GAAG;AAAA,EACjC,IAAI,CAAC,WAAW,IAAI,GAAG;AAAA,IACrB,OAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AAAA,EACA,MAAM,MAAM,QAAQ,EAAE,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C,MAAM,GAAG,IAAI,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,EAW7C,MAAM,GAAG,MAAM,IAAI,EAAE,WAAW,MAAM,kBAAkB,KAAK,CAAC;AAAA,EAC9D,MAAM,GAAG,MAAM,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,EAC/C,OAAO,EAAE,MAAM,OAAO,MAAM,GAAG;AAAA;;;AC3H1B,IAAM,sBAAsB,CACjC,QACA,eACkB;AAAA,EAClB,MAAM,aAAa,kBAAkB,OAAO,WAAW,IAAI;AAAA,EAC3D,MAAM,QAAkB,CAAC;AAAA,EAGzB,IAAI,cAAc,MAAM,GAAG;AAAA,IACzB,MAAM,KACJ,IAAI,aAAa,uEACnB;AAAA,EACF;AAAA,EAGA,IAAI,aAAa,MAAM,GAAG;AAAA,IACxB,MAAM,KACJ,IAAI,aAAa,6CAA6C,kBAChE;AAAA,EACF;AAAA,EAGA,IAAI,OAAO,GAAG,KAAK;AAAA,IACjB,MAAM,KACJ,IAAI,aAAa,4DACnB;AAAA,EACF;AAAA,EACA,IAAI,OAAO,IAAI,kBAAkB;AAAA,IAC/B,MAAM,KACJ,IAAI,gFACN;AAAA,EACF;AAAA,EACA,IAAI,OAAO,GAAG,QAAQ,SAAS;AAAA,IAC7B,MAAM,KACJ,IAAI,4DACN;AAAA,EACF;AAAA,EAKA,IAAI,WAAW,SAAS,GAAG,GAAG;AAAA,IAC5B,MAAM,KACJ,IAAI,6DACN;AAAA,EACF;AAAA,EACA,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAAA;;;AC5CxC,IAAM,4BAA4B,CACvC,WACA,UACA,eACe;AAAA,EAGf,MAAM,OAAO,kBAAkB,UAAU;AAAA,EACzC,OAAO,YAAY,OACf,UAAU,IAAI,CAAC,cAAc;AAAA,OACxB;AAAA,IACH,MAAM,aAAa,UAAU,SAAS,IAAI;AAAA,IAC1C,IAAI,qBAAqB,MAAM,UAAU,SAAS,EAAE;AAAA,EACtD,EAAE,IACF;AAAA;AAQC,IAAM,+BAA+B,CAC1C,WACA,UACA,eACe;AAAA,EACf,MAAM,OAAO,kBAAkB,UAAU;AAAA,EACzC,OAAO,YAAY,OACf,UAAU,IAAI,CAAC,cAAc;AAAA,OACxB;AAAA,IACH,MAAM,qBAAqB,MAAM,UAAU,SAAS,IAAI;AAAA,IACxD,IAAI,qBAAqB,MAAM,UAAU,SAAS,EAAE;AAAA,EACtD,EAAE,IACF;AAAA;AASC,IAAM,oBAAoB,CAAC,WAChC,6BACE,OAAO,WACP,OAAO,UACP,OAAO,WAAW,QAAQ,EAC5B;;;ACjCF,IAAM,oBAAoB;AAE1B,IAAM,wBAAwB;AAW9B,IAAM,cAAiC;AAAA,EACrC,QAAQ;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY;AAAA,EACd;AAAA,EACA,YAAY;AAAA,IACV,WAAW;AAAA,IACX,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY;AAAA,EACd;AAAA,EACA,YAAY;AAAA,IACV,WAAW;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY;AAAA,EACd;AACF;AAEA,IAAM,gBAAgB;AAOtB,IAAM,kBAAkB,CAAC,QACvB,KAAK,WAAW,OAAO,KAAK,IAAI,OAAO,EAAE,SAAS,IAC9C,EAAE,SAAS,IAAI,QAAQ,IACvB,CAAC;AAGA,IAAM,oBAAoB,CAAC,QAAkC;AAAA,EAClE,MAAM,WAAW,KAAK,YAAY;AAAA,EAClC,MAAM,QAAQ,KAAK,SAAS;AAAA,EAC5B,MAAM,UAAU,gBAAgB,GAAG;AAAA,EACnC,IAAI,aAAa,WAAW;AAAA,IAC1B,OAAO,KAAK,SAAS,MAAM,WAAW,MAAM;AAAA,EAC9C;AAAA,EACA,MAAM,SAAS,YAAY;AAAA,EAC3B,MAAM,YAAY,KAAK,aAAa,QAAQ,aAAa;AAAA,EACzD,IAAI,aAAa,cAAc;AAAA,IAC7B,OAAO,EAAE,cAAc,SAAS,MAAM,cAAc,MAAM;AAAA,EAC5D;AAAA,EAIA,OAAO;AAAA,IACL;AAAA,IACA,SAAS,KAAK,WAAW,QAAQ,WAAW;AAAA,OACzC;AAAA,IACH,MAAM;AAAA,IACN;AAAA,IACA,MAAM,QAAQ,QAAQ;AAAA,EACxB;AAAA;AAQK,IAAM,uBAAuB,CAAC,QAA0C;AAAA,EAC7E,MAAM,WAAW,KAAK,YAAY;AAAA,EAClC,IAAI,aAAa,WAAW;AAAA,IAC1B;AAAA,EACF;AAAA,EACA,OAAO,YAAY,WAAW,cAAc;AAAA;;;AC7FvC,IAAM,uBACX,IAAI,IAAI;AAAA,EACN,CAAC,kBAAkB,eAAe;AAAA,EAClC,CAAC,wBAAwB,qBAAqB;AAAA,EAC9C,CAAC,cAAc,WAAW;AAAA,EAC1B,CAAC,kBAAkB,eAAe;AAAA,EAClC,CAAC,iBAAiB,cAAc;AAAA,EAChC,CAAC,sBAAsB,mBAAmB;AAAA,EAC1C,CAAC,aAAa,UAAU;AAAA,EACxB,CAAC,sBAAsB,aAAa;AACtC,CAAC;AAEH,IAAM,qBAA0C,IAAI,IAClD,qBAAqB,KAAK,CAC5B;AAGA,IAAM,kBAAkB;AA6BxB,IAAM,eAAe,OAAO,IAAI,uBAAuB;AAMvD,IAAM,WAAW,MAA6B;AAAA,EAI5C,MAAM,OAAO;AAAA,EACb,KAAK,kBAAkB,EAAE,SAAS,IAAI,KAAO,SAAS,IAAI,IAAM;AAAA,EAChE,OAAO,KAAK;AAAA;AAeP,IAAM,wBAAwB,CACnC,YACsB;AAAA,EACtB,QAAQ,SAAS,SAAS,YAAY,SAAS;AAAA,EAC/C,MAAM,UAA6B,CAAC;AAAA,EACpC,WAAW,MAAM,qBAAqB,KAAK,GAAG;AAAA,IAC5C,MAAM,OAAO,QAAQ,IAAI,EAAE;AAAA,IAC3B,IAAI,QAAQ,IAAI,EAAE,MAAM,MAAM;AAAA,MAC5B;AAAA,IACF;AAAA,IACA,IAAI,SAAS,WAAW;AAAA,MACtB,QAAQ,OAAO,EAAE;AAAA,IACnB,EAAO;AAAA,MACL,QAAQ,IAAI,IAAI,IAAI;AAAA;AAAA,IAEtB,QAAQ,KAAK,EAAE;AAAA,EACjB;AAAA,EACA,IAAI,QAAQ,WAAW,GAAG;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EACA,WAAW,UAAU,SAAS;AAAA,IAC5B,WAAW,MAAM,SAAS;AAAA,MACxB,MAAM,MAAM,OAAO,YAAY,cAAc,GAAG,kBAAkB,IAAI;AAAA,MACtE,IAAI,KAAK;AAAA,QACP,OAAO,YAAY,iBAAiB,GAAG;AAAA,MACzC;AAAA,IACF;AAAA,IACA,OAAO,GAAG,KAAK,EAAE,MAAM,cAAc,CAAC;AAAA,EACxC;AAAA,EACA,OAAO;AAAA;;;AC7IT,uBAAS;AACT;AAEA,oBAAS,8BAAqB;AAwB9B,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,qBAAqB,CAAC,YAA6B;AAAA,EACvD,IAAI,CAAC,YAAW,OAAO,GAAG;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EACA,IAAI;AAAA,IAGF,MAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AAAA,IAGrD,OAAO,IAAI,eAAe;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA;AAKX,IAAM,qBAAqB,CAAC,QAC1B,mBAAmB,MAAK,KAAK,cAAc,CAAC,KAC5C,kBAAkB,KAAK,CAAC,WAAW,YAAW,MAAK,KAAK,MAAM,CAAC,CAAC;AAQlE,IAAM,oBAAoB,CAAC,UAA0B;AAAA,EACnD,IAAI,MAAM;AAAA,EACV,UAAS;AAAA,IACP,IAAI,mBAAmB,GAAG,GAAG;AAAA,MAC3B,OAAO;AAAA,IACT;AAAA,IACA,MAAM,SAAS,SAAQ,GAAG;AAAA,IAC1B,IAAI,WAAW,KAAK;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,EACR;AAAA;AAKF,IAAM,kBAAkB;AAAA,EACtB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AACV;AAGA,IAAM,kBAAkB,IAAI,IAA+B;AAAA,EACzD,CAAC,QAAQ,wBAAwB;AACnC,CAAC;AAED,IAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,+BAA+B,CAAC,YAAoC;AAAA,EAKxE,MAAM,OAAiB;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAM,eAAe,sBAAsB,IAAI,CAAC,SAC9C,MAAK,QAAQ,MAAM,IAAI,CACzB,EAAE,KAAK,CAAC,SAAS,YAAW,IAAI,CAAC;AAAA,EACjC,IAAI,cAAc;AAAA,IAChB,IAAI,aAAa,SAAS,QAAQ,QAAQ,YAAY;AAAA,IAItD,IAAI,CAAC,WAAW,WAAW,GAAG,KAAK,CAAC,WAAW,WAAW,GAAG,GAAG;AAAA,MAC9D,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,KAAK,KAAK,eAAe,KAAK,UAAU,UAAU,GAAG;AAAA,EACvD;AAAA,EACA,OAAO,KAAK,KAAK,KAAK,IAAI;AAAA;AAW5B,IAAM,uBAAuB,CAAC,eAI5B,WAAW,WAAW,YAAY,WAAW,YAAY,eACrD;AAAA,qBACA;AAQN,IAAM,mBAAmB,CAAC,YACxB,KAAK,UAAU,OAAO,EAAE,WACtB,gCACA,eACF;AAGF,IAAM,wBAAwB,CAAC,YAA2C;AAAA,EACxE,MAAM,QAAQ,CAAC,cAAc;AAAA,EAC7B,IAAI,QAAQ,UAAU;AAAA,IACpB,MAAM,KAAK,eAAe;AAAA,EAC5B;AAAA,EACA,OAAO,YAAY,MAAM,KAAK,IAAI;AAAA;AAU7B,IAAM,sBAAsB,CAAC,YAKpB;AAAA,EACd,QAAQ,QAAQ,YAAY,aAAa,aAAa;AAAA,EACtD,MAAM,OAAO,CAAC,cAAc;AAAA,EAC5B,IAAI,YAAY;AAAA,IACd,KAAK,KAAK,gBAAgB;AAAA,EAC5B;AAAA,EACA,IAAI,UAAU;AAAA,IACZ,KAAK,KAAK,cAAc;AAAA,EAC1B;AAAA,EACA,IAAI,aAAa;AAAA,IACf,KAAK,KAAK,iBAAiB;AAAA,EAC7B;AAAA,EAIA,IAAI,oBAAoB,MAAM,GAAG;AAAA,IAC/B,KAAK,KAAK,eAAe;AAAA,EAC3B;AAAA,EAGA,KAAK,KAAK,GAAG,mBAAmB,OAAO,OAAO,QAAQ,EAAE,WAAW;AAAA,EAEnE,IAAI,OAAO,GAAG,KAAK,WAAW,CAAC,OAAO,GAAG,IAAI,UAAU;AAAA,IACrD,MAAM,SAAS,qBAAqB,OAAO,GAAG,GAAG;AAAA,IACjD,IAAI,QAAQ;AAAA,MACV,KAAK,KAAK,MAAM;AAAA,IAClB;AAAA,EACF;AAAA,EACA,QAAQ,eAAe;AAAA,EACvB,IAAI,WAAW,WAAW,YAAY,WAAW,SAAS;AAAA,IACxD,MAAM,UAAU,gBAAgB,WAAW;AAAA,IAC3C,IAAI,SAAS;AAAA,MACX,KAAK,KAAK,OAAO;AAAA,IACnB;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAsCT,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,oBAAoB,CACxB,YAEA,OAAO,QAAQ,WAAW,CAAC,CAAC,EACzB,SAAS,EAAE,KAAK,OAAO,EAAE,SAAS,EAAE,MAAM,EAC1C,IACC,EAAE,MAAM,iBACN;AAAA,UAAa,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,WAAW,IACpE,EACC,KAAK,EAAE;AAGZ,IAAM,cAAc,CAAC,YACnB,QAAQ,WAAW,GAAG,QAAQ;AAchC,IAAM,cAAc,CAAC,YACnB,SAAQ,YAAY,OAAO,CAAC;AAc9B,IAAM,gBAAgB,OAAO;AAc7B,IAAM,sBAAsB,CAC1B,SACA,wBACG;AAAA,EACH,IAAI,wBAAwB,WAAW;AAAA,IACrC,OAAO,EAAE,OAAO,IAAI,MAAM,GAAG;AAAA,EAC/B;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,cACG,KAAK,UAAU,GAAG,QAAQ,qBAAqB;AAAA,IACzD,MAAM;AAAA,gBACM,KAAK,UAAU,GAAG,QAAQ,oBAAoB;AAAA,EAC5D;AAAA;AAYF,IAAM,mBAAmB,CAAC,iBACxB,eACI,+BAA+B,KAAK,UAAU,YAAY,4BAA4B,qBACtF,WAAW;AASjB,IAAM,0BAA0B,CAC9B,WACG;AAAA,EACH,IAAI,CAAC,QAAQ;AAAA,IACX,OAAO;AAAA,MACL,oBAAoB;AAAA,MACpB,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,uBAAuB;AAAA,IACzB;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,oBAAoB,OAAO,aACvB,mCAAmC,OAAO;AAAA,IAC1C;AAAA,IACJ,mBAAmB;AAAA;AAAA;AAAA;AAAA,IACnB,iBAAiB;AAAA,6FAA6I,KAAK,UACjK,OAAO,UACT;AAAA;AAAA;AAAA,IACA,uBAAuB;AAAA,EACzB;AAAA;AAQF,IAAM,oBAAoB,CAAC,WACzB,OAAO,MAAM,QAAQ,SAAS,KAAK,OAAO,MAAM,eAAe,SAAS,IACpE;AAAA,WAAc,KAAK,UAAU,OAAO,KAAK,OACzC;AAkCN,IAAM,sBAAsC,EAAE,MAAM,MAAM,SAAS,KAAK;AAExE,IAAM,sBAAsB,CAAC,YAMH;AAAA,EACxB,QAAQ,SAAS,aAAa;AAAA,EAC9B,MAAM,sBAAsB;AAAA,IAC1B,GAAI,QAAQ,YAAY,CAAC,GAAG,QAAQ,sBAAsB,IAAI,CAAC;AAAA,IAC/D,GAAG,QAAQ;AAAA,IACX,GAAG,CAAC,GAAG,IAAI,IAAI,OAAO,OAAO,QAAQ,WAAW,CAAC,CAAC,CAAC,CAAC,EACjD,SAAS,EACT,IAAI,CAAC,QAAQ,GAAG,qCAAqC;AAAA,EAC1D;AAAA,EACA,MAAM,sBAAsB;AAAA,IAG1B,GAAI,SAAS,UAAU,CAAC,iBAAiB,IAAI,CAAC;AAAA,IAC9C,GAAI,SAAS,OAAO,CAAC,gCAAgC,IAAI,CAAC;AAAA,IAM1D,GAAI,QAAQ,cAAc,QAAQ,oBAC9B,CAAC,wBAAwB,IACzB,CAAC;AAAA,EACP;AAAA,EACA,OAAO,EAAE,qBAAqB,oBAAoB;AAAA;AAkBpD,IAAM,4BAA4B,CAChC,wBACwB;AAAA,EACxB,IAAI,wBAAwB,WAAW;AAAA,IACrC,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,CAAC,sBAAsB;AAAA,MAChC,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,MAAM,aAAa,CAAC,GAAG,oBAAoB,EACxC,IACC,EAAE,IAAI,UACJ;AAAA,UAAa,KAAK,UAAU,EAAE,MAAM,KAAK,UAAU,GAAG,uBAAuB,MAAM,IACvF,EACC,KAAK,EAAE;AAAA,EACV,OAAO,EAAE,YAAY,SAAS,CAAC,GAAG,aAAa,GAAG;AAAA;AAapD,IAAM,0BAA0B,CAAC,YAM/B,QAAQ,UACJ;AAAA,EACE,oBAAoB;AAAA,EACpB,eAAe,QAAQ;AAAA,EACvB,gBACE,oBAAoB,QAAQ,QAAQ,QAAQ,aAAa,KACzD;AAAA,EACF,OAAO,QAAQ;AACjB,IACA,EAAE,OAAO,QAAQ,MAAM;AAEtB,IAAM,sBAAsB,CAAC,YAyCtB;AAAA,EACZ,QAAQ,SAAS,QAAQ,YAAY,OAAO,cAAc;AAAA,EAE1D,QAAQ,OAAO,cAAc,MAAM,oBAAoB,oBACrD,SACA,QAAQ,mBACV;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE;AAAA,EACJ;AAAA,IACE,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,aAAa;AAAA,MACX,0BAA0B,mBAAmB;AAAA,EACjD,QAAQ,eAAe;AAAA,EACvB,MAAM,iBAAiB,kBAAkB,QAAQ,OAAO;AAAA,EACxD,MAAM,SAAS,WAAW,WAAW;AAAA,EAIrC,MAAM,UAAU,CAAC,GAAG,IAAI,IAAI,CAAC,kBAAkB,QAAQ,IAAI,GAAG,QAAQ,IAAI,CAAC,CAAC;AAAA,EAE5E,QAAQ,qBAAqB,wBAAwB,oBAAoB;AAAA,IACvE,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,QAAQ;AAAA,EAC7B,CAAC;AAAA,EAED,MAAM,gBACJ,UAAU,WAAW,UACjB,wBAAwB,gBAAgB,WAAW;AAAA,IACnD;AAAA,EACN,MAAM,eAAe,MAAM;AAAA,IACzB,IAAI,CAAC,UAAU,CAAC,WAAW,SAAS;AAAA,MAClC,OAAO;AAAA,IACT;AAAA,IACA,IAAI,WAAW,YAAY,cAAc;AAAA,MACvC,OAAO,6BAA6B,OAAO;AAAA,IAC7C;AAAA,IACA,OAAO,gBAAgB,IAAI,WAAW,OAAO,KAAK;AAAA,KACjD;AAAA,EAMH,MAAM,cACJ,WAAW,YAAY,WACnB,2BAA2B,iBAAiB,KAAK,UAAU,YAAY,OAAO,CAAC,OAC/E,WAAW;AAAA,EACjB,MAAM,gBACJ,UAAU,WAAW,UAAU;AAAA,aAAgB,iBAAiB;AAAA,EAElE,MAAM,gBAAgB,qBAAqB,UAAU;AAAA,EAErD,MAAM,aAAa,WAAW,OAC1B;AAAA,UAAa,KAAK,UAAU,WAAW,IAAI,OAC3C;AAAA,EACJ,MAAM,aAAa,WAAW,OAC1B;AAAA,UAAa,KAAK,UAAU,WAAW,IAAI,OAC3C;AAAA,EACJ,MAAM,cAAc,kBAAkB,MAAM;AAAA,EAO5C,MAAM,aAAa,OAAO,OACtB;AAAA,UAAa,KAAK,UAAU;AAAA,IAC1B,eAAe,OAAO,KAAK;AAAA,IAC3B,SAAS,OAAO,KAAK,QAAQ,IAAI,CAAC,WAAW,OAAO,IAAI;AAAA,IACxD,SAAS;AAAA,MACP,qBAAqB,CAAC,OAAO,KAAK;AAAA,IACpC;AAAA,EACF,CAAC,OACD;AAAA,EAKJ,MAAM,iBAAiB,0BACrB,OAAO,WACP,OAAO,UACP,WAAW,QAAQ,EACrB;AAAA,EACA,MAAM,kBACJ,eAAe,SAAS,IACpB;AAAA,eAAkB,KAAK,UACrB,OAAO,YACL,eAAe,IAAI,CAAC,aAAa;AAAA,IAC/B,SAAS;AAAA,IACT,EAAE,aAAa,SAAS,IAAI,QAAQ,SAAS,OAAO;AAAA,EACtD,CAAC,CACH,CACF,OACA;AAAA,EAQN,MAAM,cAAc,iBAClB,OAAO,MAAM,OACb,gBAAgB,OAAO,IAAI,CAC7B;AAAA,EACA,MAAM,cAAc,YAAY,SAC5B;AAAA,YAAe,YACZ,IAAI,CAAC,SACJ,KAAK,SAAS,UACV,4CAA4C,KAAK,UAC/C,KAAK,IACP,mBAAmB,KAAK,UACtB,KAAK,WACP,iBAAiB,KAAK,UACpB,KAAK,SACP,2BAA2B,KAAK,UAC9B,KAAK,SAAS,IAAI,CAAC,YAAY;AAAA,IAC7B,MAAM,OAAiD,CAAC;AAAA,IACxD,IAAI,QAAQ,WAAW,WAAW;AAAA,MAChC,KAAK,SAAS,QAAQ;AAAA,IACxB;AAAA,IACA,IAAI,QAAQ,UAAU,WAAW;AAAA,MAC/B,KAAK,QAAQ,QAAQ;AAAA,IACvB;AAAA,IACA,OAAO;AAAA,SACF;AAAA,MACH,KAAK;AAAA,QACH,WAAW,QAAQ,GAAG,IAClB,QAAQ,MACR,MAAK,QAAQ,MAAM,QAAQ,GAAG;AAAA,MACpC;AAAA,IACF;AAAA,GACD,CACH,UACA,6BAA6B,KAAK,qBAAqB,KAAK,UAC1D,KAAK,IACP,mBAAmB,KAAK,UACtB,KAAK,WACP,eAAe,iBAAiB,KAAK,OAAO,eAAe,KAAK,UAC9D,KAAK,OACP,iBAAiB,KAAK,UAAU,KAAK,SAAS,KACpD,EACC,KAAK,IAAI,QACZ;AAAA,EACJ,MAAM,qBAAqB,sBAAsB;AAAA,IAC/C,UAAU,YAAY,SAAS;AAAA,EACjC,CAAC;AAAA,EAID,MAAM,cAAc,aAAa;AAAA,IAA0C;AAAA,EAC3E,MAAM,YAAY,WAAW;AAAA,IAAsC;AAAA,EACnE,MAAM,eAAe,cACjB;AAAA,IACA;AAAA,EACJ,MAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH,GAAI,cAAc,SAAS,iBAAiB,IAAI,CAAC,iBAAiB,IAAI,CAAC;AAAA,EACzE;AAAA,EACA,MAAM,cAAc,YAAY,aAAa,KAAK,IAAI;AAAA;AAAA,EAQtD,MAAM,sBAAsB;AAAA,EAQ5B,MAAM,aAAa,kBAAkB,WAAW,IAAI;AAAA,EAEpD,MAAM,eAAe;AAAA,IACnB,sCAAsC,KAAK,UAAU;AAAA,MACnD,UAAU,OAAO;AAAA,MACjB,YAAY,OAAO,SAAS,WAAW;AAAA,MACvC,aAAa,QAAQ;AAAA,MACrB;AAAA,MACA,gBAAgB,OAAO,SAAS;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EACA,IAAI,YAAY;AAAA,IACd,aAAa,KAAK,iBAAiB,QAAQ,iBAAiB,CAAC;AAAA,EAC/D;AAAA,EACA,IAAI,UAAU;AAAA,IACZ,aAAa,KAAK,OAAO;AAAA,EAC3B;AAAA,EACA,IAAI,aAAa;AAAA,IACf,aAAa,KAAK,UAAU;AAAA,EAC9B;AAAA,EAIA,aAAa,KACX,oBAAoB,KAAK,UACvB,wBAAwB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,SAAS,wBAAwB;AAAA,IACjC;AAAA,EACF,CAAC,CACH,IACF;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,wBAAwB,QAAQ,iBAAiB;AAAA,EAErD,OAAO;AAAA,EACP,qBAAqB;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAIA,cAAc,YAAY,eAAe,cAAc;AAAA,EACvD;AAAA,UACQ,KAAK,UAAU,QAAQ,MAAM;AAAA,YAC3B,KAAK,UAAU,GAAG,QAAQ,YAAY;AAAA,YACtC,KAAK,UAAU,YAAY,OAAO,CAAC;AAAA,eAChC,KAAK,UAAU,GAAG,QAAQ,aAAa,KAAK;AAAA,YAC/C,KAAK,UAAU,WAAW,MAAM,KAAK,gBAAgB,gBAAgB,aAAa,aAAa,cAAc,kBAAkB,aAAa;AAAA,mBACrI,aAAa,KAAK,IAAI,IAAI;AAAA;AAAA,wCAEL,KAAK,UAAU;AAAA,IACjD,UAAU,OAAO;AAAA,IACjB,YAAY,OAAO,SAAS,WAAW;AAAA,IACvC,aAAa,QAAQ;AAAA,IACrB;AAAA,IACA,gBAAgB,OAAO,SAAS;AAAA,EAClC,CAAC;AAAA;AAAA;AAAA,iBAGY,KAAK,UAAU,OAAO,SAAS,WAAW,MAAM,KAAK;AAAA,gBACtD,KAAK,UAAU,OAAO,SAAS,WAAW,MAAM,IAAI;AAAA;AAAA;AAAA,uBAG7C,gDAAgD,KAAK,UACpE,EAAE,OAAO,OAAO,SAAS,KAAK,MAAM,CACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAuBK;AAAA,gBACK,4DAA4D,KAAK,UAC3E,GAAG,QAAQ,oCACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAyBa,KAAK,UAAU,mBAAmB;AAAA,iBAClC,KAAK,UAAU,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAc5B,KAAK,UAAU,oBAAoB;AAAA;AAAA,0CAEhB,KAAK,UAAU,oBAAoB;AAAA;AAAA;AAAA;AAAA,uBAItD,KAAK,UAAU,OAAO;AAAA,4BACjB,KAAK,UAAU,YAAY;AAAA,kCACrB,KAAK,UAAU,iBAAiB;AAAA,4BACtC,KAAK,UAAU,YAAY;AAAA,iCACtB,KAAK,UAAU,gBAAgB;AAAA,yBACvC,KAAK,UAAU,SAAS,KAAK,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA,iBAK/D,KAAK,UAAU,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAShC,IAAM,mBAAmB,CAAC,WAC/B,MAAK,QAAQ,SAAS;AASxB,IAAM,mBAAmB,CAAC,MAAc,WAAkC;AAAA,EACxE,MAAM,MAAM,SAAS,MAAM,MAAM;AAAA,EACjC,OAAO,OAAO,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,WAAW,GAAG,IAAI,MAAM;AAAA;AAWlE,IAAM,gBAAgB,CAAC,SACrB,WAAW,IAAI,IAAI,cAAc,IAAI,EAAE,OAAO;AAGzC,IAAM,wBAAwB,CAAC,YAoBxB;AAAA,EACZ,QAAQ,SAAS,WAAW;AAAA,EAC5B,MAAM,aAAa,QAAQ,cAAc,iBAAiB,QAAQ,MAAM;AAAA,EACxE,MAAM,iBAAiB,QAAQ,YAAY,QAAQ,QAAQ;AAAA,EAC3D,MAAM,eAAe,QAAQ,YAAY,WAAW,OAAO,QAAQ;AAAA,EACnE,MAAM,eAAe,QAAQ,YAAY,WAAW,OAAO,QAAQ;AAAA,EAMnE,MAAM,YAAY,iBAAiB,gBAAgB,QAAQ,MAAM;AAAA,EACjE,MAAM,eAAe,YAAY,CAAC,IAAI,cAAc,IAAI,CAAC;AAAA,EAOzD,MAAM,aAAa,QAAQ,cAAc;AAAA,EACzC,MAAM,cAAc,aAChB;AAAA,IACE,GAAG;AAAA,IACH,IAAI,gBAAgB,CAAC,GAAG,IAAI,CAAC,YAAY,IAAI,SAAS;AAAA,IAOtD,GAAG,kBAAkB,QAAQ,CAAC,QAC5B,QAAQ,WAAW,CAAC,IAAI,CAAC,OAAO,QAAQ,CAC1C;AAAA,IACA,GAAG;AAAA,EACL,IACA,CAAC;AAAA,EAIL,MAAM,cAAc,QAAQ,SACxB;AAAA;AAAA;AAAA;AAAA,YAIM,KAAK,UAAU,cAAc,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAM9C;AAAA,EAEJ,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAeM,KAAK,UAAU,WAAW;AAAA,YAC7B,KAAK,UAAU,cAAc,cAAc,CAAC;AAAA;AAAA,QAEhD,KAAK,UAAU,GAAG,QAAQ,oCAAoC;AAAA;AAAA;AAAA,EAGpE;AAAA,mCACiC,QAAQ,SAAS,aAAa;AAAA;AAAA;AAMjE,IAAM,sBACJ;AAuCF,IAAM,kBAAkB,CAAC,OAA0B,CAAC,MAClD,KAAK,SAAS,IACV;AAAA,EACE,OAAO;AAAA,EACP,SAAS;AAAA,IACP;AAAA,EACF;AAAA,EACA,MAAM;AAAA,EACN,OAAO;AAAA,0BACW,KAAK,UAAU,IAAI;AAAA;AAAA;AAAA;AAAA;AAKvC,IACA,EAAE,OAAO,MAAM,SAAS,CAAC,GAAG,MAAM,4BAA4B,OAAO,GAAG;AAevE,IAAM,sBAAsB,CACjC,SACA,UACA,YACW;AAAA,EACX,QAAQ,cAAc,WAAW,cAAc,WAAW,CAAC;AAAA,EAO3D,MAAM,iBAAiB,eACnB,GAAG;AAAA;AAAA,EAA0B,iBAC7B;AAAA,EAIJ,MAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IAIA,QAAQ,SAAS,YACb,oDACA;AAAA,EACN;AAAA,EACA,IAAI,QAAQ;AAAA,EACZ,IAAI,YAAY,KAAK,UAAU,QAAQ,KAAK;AAAA,EAG5C,MAAM,eAAe,QAAQ,UACzB;AAAA,aAAgB,KAAK,UAAU,QAAQ,OAAO,OAC9C;AAAA,EACJ,IAAI,QAAQ,SAAS,WAAW;AAAA,IAC9B,QAAQ;AAAA;AAAA,4CACgC;AAAA;AAAA;AAAA,IAExC,YAAY,WAAW,KAAK,UAAU,QAAQ,KAAK;AAAA,EACrD,EAAO,SAAI,QAAQ,SAAS,cAAc;AAAA,IACxC,QAAQ,KACN,iEACF;AAAA,IACA,QAAQ;AAAA;AAAA,sBACU,KAAK,UAAU,QAAQ,SAAS,MAAM;AAAA;AAAA;AAAA,IAExD,MAAM,WAAW,YACb,4BAA4B,KAAK,UAAU,SAAS,UACpD;AAAA,IACJ,YAAY,cAAc,KAAK,UAAU,QAAQ,KAAK,IAAI;AAAA,EAC5D,EAAO,SAAI,QAAQ,SAAS,qBAAqB;AAAA,IAC/C,QAAQ,KACN,qEACF;AAAA,IACA,QAAQ;AAAA;AAAA,sBACU,KAAK,UAAU,QAAQ,SAAS;AAAA,aACzC,KAAK,UAAU,QAAQ,OAAO,KAAK;AAAA,UACtC,KAAK,UAAU,QAAQ,IAAI;AAAA;AAAA;AAAA,IAEjC,YAAY,YAAY,KAAK,UAAU,QAAQ,KAAK;AAAA,EACtD;AAAA,EAGA,IAAI,UAAU;AAAA,IACZ,QAAQ,KACN,+DACA,uCACF;AAAA,IACA,MAAM,eAAyB,CAAC;AAAA,IAChC,IAAI,cAAc;AAAA,MAChB,aAAa,KAAK,iBAAiB,KAAK,UAAU,YAAY,GAAG;AAAA,IACnE;AAAA,IACA,IAAI,WAAW;AAAA,MACb,aAAa,KAAK,cAAc,KAAK,UAAU,SAAS,GAAG;AAAA,IAC7D;AAAA,IACA,MAAM,gBACJ,aAAa,SAAS,IAAI,OAAO,aAAa,KAAK,IAAI,QAAQ;AAAA,IACjE,SAAS;AAAA,yCAA4C;AAAA;AAAA,EACvD;AAAA,EACA,MAAM,OAAO,gBAAgB,SAAS,IAAI;AAAA,EAC1C,QAAQ,KAAK,GAAG,KAAK,OAAO;AAAA,EAO5B,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BjB,MAAM,WACJ,QAAQ,SAAS,YACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAOA,oBAAoB,KAAK,UAAU,QAAQ,SAAS;AAAA;AAAA,QAEpD,KAAK,UAAU,iCAAiC,QAAQ,YAAY;AAAA;AAAA;AAAA;AAAA,EAM1E,MAAM,UAAU;AAAA;AAAA;AAAA,EAKhB,MAAM,eAAe;AAAA,IACnB,UAAU;AAAA,IACV,WACI,iBACA;AAAA,UAA0B,KAAK,UAAU,cAAc;AAAA,IAC3D;AAAA,EACF;AAAA,EACA,IAAI,aAAa,QAAQ,SAAS,cAAc;AAAA,IAC9C,aAAa,KAAK,cAAc,KAAK,UAAU,SAAS,GAAG;AAAA,EAC7D;AAAA,EACA,MAAM,OAAO;AAAA,QACP,aAAa,KAAK;AAAA,OAAW;AAAA,EACnC;AAAA;AAAA,EAEA,MAAM,SAAS,WACX;AAAA;AAAA,QAEE,KAAK,UAAU,cAAc;AAAA,EACnC,SACI;AAAA,EACJ,MAAM,UAAU,iCAAiC,KAAK;AAAA,EACtD;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ,KAAK;AAAA,CAAI;AAAA;AAAA;AAAA,EAGjB,QAAQ,KAAK;AAAA,EACb;AAAA;AAAA;AAoBK,IAAM,uBAAuB,CAAC,eACnC,aACI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASC,IAAM,yBAAyB,MACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYF,IAAM,uBAAuB;AAAA;AAG7B,IAAM,qBAAqB,CAAC,WAC1B,0EAA0E;AAAA;AAM5E,IAAM,qBACJ;AAAA;AAOF,IAAM,qBAAqB,CAAC,QAAgB,WAC1C,GAAG,uBAAuB,mBAAmB,MAAM,IAAI;AAAA;AAAA;AAAA,qDAIrD,SAAS,aAAa,KAAK,UAAU,MAAM,MAAM;AAAA;AAYrD,IAAM,qBAAqB,CACzB,QACA,YAEA,GAAG,uBAAuB,mBAAmB,MAAM;AAAA,2CACV,KAAK,UAAU,OAAO;AAAA;AAIjE,IAAM,sBAAsB,CAC1B,WACgE;AAAA,EAChE,QAAQ,OAAO;AAAA,SACR,WAAW;AAAA,MACd,OAAO,EAAE,QAAQ,WAAW,SAAS,KAAK,OAAO,QAAQ,EAAE;AAAA,IAC7D;AAAA,SACK,eAAe;AAAA,MAClB,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ,OAAO,YAAY;AAAA,UAC3B,UAAU,OAAO,YAAY;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,SACK,aAAa;AAAA,MAChB,OAAO,EAAE,QAAQ,aAAa,SAAS,KAAK,OAAO,UAAU,EAAE;AAAA,IACjE;AAAA,aACS;AAAA,MACP,OAAO;AAAA,IACT;AAAA;AAAA;AAYG,IAAM,mBAAmB,CAAC,aAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8DAQE,SAAS,UACL,gEACA;AAAA;AAAA;AAAA;AAAA;AAAA,aAMK,SAAS,OAAO,2CAA2C;AAAA;AAUjE,IAAM,uBAAuB,CAAC,WAAmC;AAAA,EACtE,QAAQ,WAAW;AAAA,EAEnB,IAAI,OAAO,aAAa,WAAW,OAAO,aAAa,cAAc;AAAA,IAGnE,MAAM,SACJ,OAAO,aAAa,UAAU,OAAO,MAAM,gBAAgB;AAAA,IAC7D,OAAO,mBAAmB,OAAO,UAAU,MAAM;AAAA,EACnD;AAAA,EAEA,MAAM,SAAS,oBAAoB,MAAM;AAAA,EACzC,IAAI,QAAQ;AAAA,IACV,OAAO,mBAAmB,OAAO,QAAQ,OAAO,OAAO;AAAA,EACzD;AAAA,EAEA,IAAI,OAAO,aAAa,cAAc;AAAA,IACpC,OAAO,GAAG,uBAAuB,mBAAmB,UAAU,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpE;AAAA,EAEA,IAAI,OAAO,aAAa,YAAY;AAAA,IAClC,OAAO,GAAG,uBAAuB,mBAAmB,UAAU,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpE;AAAA,EAGA,OAAO,GAAG;AAAA;AAAA;AAAA;AAWL,IAAM,mCAAmC,CAAC,YAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAQiB,KAAK,UAAU,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsClC,IAAM,8BAA8B,CAAC,SAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAgBE,SAAS,OAAO,kCAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2B/C,IAAM,gCAAgC,CAC3C,oBAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAUmB,KAAK,UAAU,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8E5C,IAAM,cAAc,CAAC,UAC1B,GAAG,SAAS,OAAO,GAAG;AAQjB,IAAM,sBAAsB,MACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBK,IAAM,0BAA0B,CAAC,YACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+CAM6C,KAAK,UAAU,OAAO;AAAA;AAAA;AAAA;AAM9D,IAAM,6BAA6B,CACxC,YAEA;AAAA;AAAA;AAAA,kBAGgB,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa1C,IAAM,sBAAsB,MACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCK,IAAM,sBAAsB,MACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwDK,IAAM,qBAAqB,CAChC,eAAgC,CAAC,GACjC,KAcI,CAAC,GACL,mBAAmB,UAEnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0DAUwD,KAAK,UAAU,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAM3D,KAAK,UAAU,GAAG,SAAS,CAAC,CAAC;AAAA,+CAEnD,GAAG,WAAW,KAAK,UAAU,GAAG,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAQ5C,GAAG,QAAQ,KAAK,UAAU,GAAG,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAQf,GAAG,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAgC/C,mBACI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CD,IAAM,0BAA0B,CAA+B,YAOpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQsB,KAAK,UAAU,QAAQ,eAAe,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAuBxD,QAAQ,YAAY;AAAA,eAClB,KAAK,UAAU,QAAQ,KAAK;AAAA,WAChC,KAAK,UAAU,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBvC,IAAM,0BAA0B,CAAC,gBAAyB;AAAA,EACxD,MAAM,aAAa,cACf;AAAA,IACA;AAAA,EACJ,MAAM,YAAY,cAAc;AAAA,MAAc;AAAA,EAC9C,OAAO;AAAA,IACL,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCX;AAAA;AAAA,IAEE,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmCL;AAAA;AAAA;AAAA,EAGF;AAAA;AAGK,IAAM,uBAAuB,CAAC,YAYvB;AAAA,EACZ,QAAQ,SAAS,kBAAkB,KAAK,iBACtC,wBAAwB,QAAQ,WAAW;AAAA,EAE7C,MAAM,aAAa,QAAQ,aACvB;AAAA,kGACA;AAAA,EAEJ,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAYmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gDAiC2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAyMpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAkCb,QAAQ;AAAA,gBACP,QAAQ,cACpB,QAAQ,eACJ;AAAA,+HAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BD,IAAM,yBAAyB,CAAC,YAQzB;AAAA,EACZ,MAAM,aAAa,QAAQ,aACvB;AAAA,wHACA;AAAA,EAGJ,MAAM,eAAe,QAAQ,SACzB;AAAA,yCACA;AAAA,EACJ,QAAQ,SAAS,kBAAkB,KAAK,iBACtC,wBAAwB,QAAQ,WAAW;AAAA,EAE7C,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAWmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAwDgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BA+FT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eA6Bb,QAAQ;AAAA,gBACP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwEjB,IAAM,uBAAuB,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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",
13
+ "debugId": "27833C6A2810E0DD64756E2164756E21",
14
14
  "names": []
15
15
  }