blume 1.7.0 → 1.7.2
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.
- package/CHANGELOG.md +18 -0
- package/dist/cli/{chunk-9qs6acpw.js → chunk-12dxjqk7.js} +32 -43
- package/dist/cli/{chunk-9qs6acpw.js.map → chunk-12dxjqk7.js.map} +2 -2
- package/dist/cli/{chunk-s5dsk8bj.js → chunk-196vjxp9.js} +65 -64
- package/dist/cli/chunk-196vjxp9.js.map +13 -0
- package/dist/cli/{chunk-27gtm2ym.js → chunk-2mzebbbz.js} +1 -1
- package/dist/cli/{chunk-s5e5jt53.js → chunk-2z47ypj8.js} +1 -1
- package/dist/cli/{chunk-tnskyrej.js → chunk-30e87n55.js} +15 -24
- package/dist/cli/{chunk-tnskyrej.js.map → chunk-30e87n55.js.map} +2 -2
- package/dist/cli/{chunk-4trphnvy.js → chunk-3w7b2vcx.js} +10 -13
- package/dist/cli/{chunk-4trphnvy.js.map → chunk-3w7b2vcx.js.map} +2 -2
- package/dist/cli/{chunk-v5mm027v.js → chunk-450a7rcr.js} +8 -8
- package/dist/cli/{chunk-v5mm027v.js.map → chunk-450a7rcr.js.map} +1 -1
- package/dist/cli/{chunk-5d4q7121.js → chunk-5n7t497w.js} +142 -134
- package/dist/cli/{chunk-5d4q7121.js.map → chunk-5n7t497w.js.map} +5 -5
- package/dist/cli/{chunk-xv91q4nm.js → chunk-61j18dwk.js} +37 -9
- package/dist/cli/{chunk-xv91q4nm.js.map → chunk-61j18dwk.js.map} +3 -3
- package/dist/cli/{chunk-3r94j3tc.js → chunk-688e0dde.js} +2 -2
- package/dist/cli/{chunk-vxv4x1n8.js → chunk-88by27n5.js} +2 -2
- package/dist/cli/{chunk-cfw6x4rm.js → chunk-8cd8tj54.js} +28 -35
- package/dist/cli/{chunk-cfw6x4rm.js.map → chunk-8cd8tj54.js.map} +2 -2
- package/dist/cli/{chunk-8gnpdsn1.js → chunk-9bkjd11x.js} +2 -2
- package/dist/cli/{chunk-qq9nm3qd.js → chunk-9he6crym.js} +21 -28
- package/dist/cli/{chunk-qq9nm3qd.js.map → chunk-9he6crym.js.map} +2 -2
- package/dist/cli/{chunk-jk1zwka1.js → chunk-aztttvb3.js} +27 -33
- package/dist/cli/{chunk-jk1zwka1.js.map → chunk-aztttvb3.js.map} +2 -2
- package/dist/cli/{chunk-ckh3a410.js → chunk-cvky9gb2.js} +18 -24
- package/dist/cli/{chunk-ckh3a410.js.map → chunk-cvky9gb2.js.map} +2 -2
- package/dist/cli/{chunk-kwx90v78.js → chunk-eevwt1sc.js} +23 -32
- package/dist/cli/{chunk-kwx90v78.js.map → chunk-eevwt1sc.js.map} +2 -2
- package/dist/cli/{chunk-agy5rzxy.js → chunk-ejjx8znq.js} +126 -77
- package/dist/cli/chunk-ejjx8znq.js.map +15 -0
- package/dist/cli/{chunk-ye9zdkgv.js → chunk-exeeb35e.js} +3 -3
- package/dist/cli/{chunk-v2ymm99c.js → chunk-fmceyezb.js} +41 -50
- package/dist/cli/{chunk-v2ymm99c.js.map → chunk-fmceyezb.js.map} +2 -2
- package/dist/cli/{chunk-s102bysw.js → chunk-hdm2dkd2.js} +209 -97
- package/dist/cli/{chunk-s102bysw.js.map → chunk-hdm2dkd2.js.map} +6 -5
- package/dist/cli/{chunk-zr3ygrq3.js → chunk-hs3gbh8p.js} +10 -15
- package/dist/cli/{chunk-zr3ygrq3.js.map → chunk-hs3gbh8p.js.map} +2 -2
- package/dist/cli/{chunk-n0nyat6g.js → chunk-jbj4qhfw.js} +3 -3
- package/dist/cli/{chunk-ev67ycx0.js → chunk-jq5n4avg.js} +1 -1
- package/dist/cli/{chunk-jxkxjsc1.js → chunk-mqb2ka8m.js} +22 -30
- package/dist/cli/{chunk-jxkxjsc1.js.map → chunk-mqb2ka8m.js.map} +2 -2
- package/dist/cli/{chunk-drke6t0h.js → chunk-mt76t7dj.js} +26 -34
- package/dist/cli/{chunk-drke6t0h.js.map → chunk-mt76t7dj.js.map} +2 -2
- package/dist/cli/{chunk-jtb45atp.js → chunk-n9sra6sy.js} +13 -13
- package/dist/cli/{chunk-jtb45atp.js.map → chunk-n9sra6sy.js.map} +1 -1
- package/dist/cli/{chunk-x66c5yjn.js → chunk-ppfvdcd4.js} +2 -2
- package/dist/cli/{chunk-wd27zjcz.js → chunk-q4rae3bg.js} +1 -1
- package/dist/cli/{chunk-pxj10x8y.js → chunk-ra1v2nc2.js} +1 -1
- package/dist/cli/{chunk-y3g15rvv.js → chunk-t3tj0dgr.js} +26 -33
- package/dist/cli/{chunk-y3g15rvv.js.map → chunk-t3tj0dgr.js.map} +2 -2
- package/dist/cli/{chunk-j6pxe0dt.js → chunk-tqa1s0k8.js} +4 -4
- package/dist/cli/{chunk-cbjnx4s8.js → chunk-vh9w1sgp.js} +1 -1
- package/dist/cli/{chunk-0qhq7b8q.js → chunk-vkrsvbr5.js} +13 -17
- package/dist/cli/{chunk-0qhq7b8q.js.map → chunk-vkrsvbr5.js.map} +2 -2
- package/dist/cli/{chunk-sbdqrjbb.js → chunk-vrfp10qk.js} +1 -1
- package/dist/cli/{chunk-ynacq3ev.js → chunk-wjt80jps.js} +27 -40
- package/dist/cli/{chunk-ynacq3ev.js.map → chunk-wjt80jps.js.map} +3 -4
- package/dist/cli/{chunk-18tjv4f7.js → chunk-xhtpx3ff.js} +21 -30
- package/dist/cli/{chunk-18tjv4f7.js.map → chunk-xhtpx3ff.js.map} +2 -2
- package/dist/cli/{chunk-5hs6gb7n.js → chunk-yzhm0j9q.js} +1 -1
- package/dist/cli/index.js +397 -34
- package/dist/cli/index.js.map +12 -4
- package/dist/types/components/layout/nav-utils.d.ts +15 -2
- package/dist/types/core/config-input.d.ts +33 -0
- package/dist/types/core/schema.d.ts +29 -3
- package/docs/08-faq.mdx +21 -0
- package/docs/configuration/ask-ai.mdx +63 -0
- package/docs/content/sources.mdx +2 -2
- package/package.json +1 -1
- package/src/ai/ask.ts +31 -4
- package/src/ai/cors.ts +87 -0
- package/src/astro/generate.ts +3 -0
- package/src/astro/templates.ts +192 -83
- package/src/components/content/YouTube.astro +1 -1
- package/src/components/layout/Header.astro +1 -1
- package/src/components/layout/NavTree.astro +75 -66
- package/src/components/layout/RootLayout.astro +4 -1
- package/src/components/layout/Search.astro +11 -0
- package/src/components/layout/nav-utils.ts +47 -15
- package/src/core/adapter.ts +61 -0
- package/src/core/config-input.ts +33 -0
- package/src/core/schema.ts +61 -0
- package/src/core/sources/assets.ts +162 -26
- package/src/core/sources/notion.ts +60 -1
- package/src/registry/eject.ts +3 -0
- package/src/theme/entry.ts +9 -0
- package/dist/cli/chunk-2aj8ddew.js +0 -72
- package/dist/cli/chunk-2aj8ddew.js.map +0 -10
- package/dist/cli/chunk-4xyggvgf.js +0 -21
- package/dist/cli/chunk-4xyggvgf.js.map +0 -10
- package/dist/cli/chunk-6kzzpsx8.js +0 -26
- package/dist/cli/chunk-6kzzpsx8.js.map +0 -10
- package/dist/cli/chunk-agy5rzxy.js.map +0 -15
- package/dist/cli/chunk-bcy492zc.js +0 -16
- package/dist/cli/chunk-bcy492zc.js.map +0 -10
- package/dist/cli/chunk-btfr9yvw.js +0 -41
- package/dist/cli/chunk-btfr9yvw.js.map +0 -10
- package/dist/cli/chunk-ey89bjj1.js +0 -209
- package/dist/cli/chunk-ey89bjj1.js.map +0 -11
- package/dist/cli/chunk-s5dsk8bj.js.map +0 -13
- package/dist/cli/chunk-vt8fgygt.js +0 -23
- package/dist/cli/chunk-vt8fgygt.js.map +0 -10
- /package/dist/cli/{chunk-27gtm2ym.js.map → chunk-2mzebbbz.js.map} +0 -0
- /package/dist/cli/{chunk-s5e5jt53.js.map → chunk-2z47ypj8.js.map} +0 -0
- /package/dist/cli/{chunk-3r94j3tc.js.map → chunk-688e0dde.js.map} +0 -0
- /package/dist/cli/{chunk-vxv4x1n8.js.map → chunk-88by27n5.js.map} +0 -0
- /package/dist/cli/{chunk-8gnpdsn1.js.map → chunk-9bkjd11x.js.map} +0 -0
- /package/dist/cli/{chunk-ye9zdkgv.js.map → chunk-exeeb35e.js.map} +0 -0
- /package/dist/cli/{chunk-n0nyat6g.js.map → chunk-jbj4qhfw.js.map} +0 -0
- /package/dist/cli/{chunk-ev67ycx0.js.map → chunk-jq5n4avg.js.map} +0 -0
- /package/dist/cli/{chunk-x66c5yjn.js.map → chunk-ppfvdcd4.js.map} +0 -0
- /package/dist/cli/{chunk-wd27zjcz.js.map → chunk-q4rae3bg.js.map} +0 -0
- /package/dist/cli/{chunk-pxj10x8y.js.map → chunk-ra1v2nc2.js.map} +0 -0
- /package/dist/cli/{chunk-j6pxe0dt.js.map → chunk-tqa1s0k8.js.map} +0 -0
- /package/dist/cli/{chunk-cbjnx4s8.js.map → chunk-vh9w1sgp.js.map} +0 -0
- /package/dist/cli/{chunk-sbdqrjbb.js.map → chunk-vrfp10qk.js.map} +0 -0
- /package/dist/cli/{chunk-5hs6gb7n.js.map → chunk-yzhm0j9q.js.map} +0 -0
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"import { join } from \"pathe\";\n\n/**\n * Build a local Pagefind search index over the built site. Pagefind indexes\n * every rendered page except those whose `<html>` carries\n * `data-pagefind-ignore`, which Blume stamps on non-indexable pages\n * (search-excluded, or hidden without the opt-in), so those stay out.\n *\n * Returns the number of pages indexed.\n */\nexport const buildSearchIndex = async (outDir: string): Promise<number> => {\n const pagefind = await import(\"pagefind\");\n\n const { index } = await pagefind.createIndex({});\n if (!index) {\n throw new Error(\"Failed to create Pagefind index.\");\n }\n\n // These awaits are strictly ordered, not independent: the directory must be\n // indexed before its files are written, and the index closed only after.\n // oxlint-disable-next-line react-doctor/async-parallel\n const result = await index.addDirectory({ path: outDir });\n await index.writeFiles({ outputPath: join(outDir, \"pagefind\") });\n await pagefind.close();\n\n return result.page_count;\n};\n",
|
|
9
9
|
"// html-escaper's five-entity table is XML-safe (`'` → the numeric `'`).\nimport { escape as escapeXml } from \"html-escaper\";\n\nimport {\n customStaticRoutes,\n discoverPagesSync,\n hasGeneratedChangelog,\n} from \"../astro/pages.ts\";\nimport { normalizeBasePath, withBasePath } from \"../core/base-path.ts\";\nimport type { BlumeProject } from \"../core/project-graph.ts\";\nimport { siteRoot } from \"../core/site-url.ts\";\n\n/**\n * Astro's reserved error routes. A user-authored override (`pages/404.astro`,\n * `pages/500.astro`, or a `404.md` content page — see `writeNotFoundPage` in\n * `astro/generate.ts`) is neither dynamic nor private, so it would otherwise\n * be emitted — but error pages aren't crawlable destinations and must stay out\n * of the sitemap.\n */\nconst ERROR_ROUTES = new Set([\"/404\", \"/500\"]);\n\n/** A `<lastmod>` element (W3C date) when the page has a valid modified date. */\nconst lastmodTag = (value: string | undefined): string => {\n if (!value) {\n return \"\";\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime())\n ? \"\"\n : `<lastmod>${date.toISOString().slice(0, 10)}</lastmod>`;\n};\n\n/** One emitted sitemap artifact: its dist-root filename and XML body. */\nexport interface SitemapFile {\n name: string;\n xml: string;\n}\n\n/** The build log line for an emitted sitemap set: one file, or an index. */\nexport const describeSitemapFiles = (files: readonly SitemapFile[]): string =>\n files.length === 1\n ? \"Generated sitemap.xml\"\n : `Generated sitemap.xml (index of ${files.length - 1} sitemap files)`;\n\n/**\n * The sitemaps.org cap on `<url>` entries in a single file. Beyond it,\n * `sitemap.xml` becomes a sitemap index pointing at numbered chunk files —\n * search engines reject an oversized urlset outright.\n */\nconst URLS_PER_FILE = 50_000;\n\nconst renderUrlset = (\n urls: string[]\n): string => `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urls.join(\"\\n\")}\n</urlset>\n`;\n\n/**\n * Build the sitemap files from the route manifest plus the routes the manifest\n * can't see: custom `.astro` pages (most importantly a custom landing `/`) and\n * the generated `/changelog` index. Returns null when the sitemap is disabled\n * or no `site` is configured (absolute URLs are required for a valid sitemap).\n * Drafts, hidden, and `noindex` pages are excluded.\n *\n * Sites within the per-file URL cap get the single classic `sitemap.xml`;\n * larger sites get `sitemap.xml` as a sitemap index over numbered\n * `sitemap-N.xml` chunks, all served from the same directory robots.txt\n * already points at.\n */\nexport const buildSitemapFiles = (\n project: BlumeProject\n): SitemapFile[] | null => {\n const { site } = project.config.deployment;\n if (!(site && project.config.seo.sitemap)) {\n return null;\n }\n\n const base = siteRoot(site);\n // Routes carry `basePath`; a `deployment.base` subdirectory is layered on top.\n const deployBase = normalizeBasePath(project.config.deployment.base);\n\n // Archived-version pages leave the sitemap when the version is noindexed,\n // or when their canonical points at a still-existing latest equivalent —\n // listing a URL whose canonical says \"index the other page\" invites the\n // noindexed-page-in-sitemap incoherence Docusaurus is known for. A page\n // that exists only in an archived version stays listed (self-canonical).\n const { versions } = project.config;\n const archivedById = new Map(\n (versions?.archived ?? []).map((version) => [version.id, version])\n );\n const currentKeys = versions\n ? new Set(\n project.graph.pages.flatMap((page) =>\n page.version === \"\" ? [`${page.versionKey}\\u0000${page.locale}`] : []\n )\n )\n : null;\n const archivedExcluded = (page: (typeof project.graph.pages)[number]) => {\n if (!page.version) {\n return false;\n }\n // A non-empty version always names a configured archived entry — that is\n // the only way detection assigns one.\n const archived = archivedById.get(page.version);\n return Boolean(\n archived?.noindex ||\n (archived?.canonical === \"latest\" &&\n currentKeys?.has(`${page.versionKey}\\u0000${page.locale}`))\n );\n };\n\n const seen = new Set<string>();\n const urls: string[] = [];\n const pushUrl = (route: string, lastModified?: string): void => {\n // `<loc>` must be a well-formed, XML-escaped URL: percent-encode the path,\n // then escape XML metacharacters (notably `&`) so a route like\n // `/Tips & Tricks` doesn't produce invalid XML that gets the whole sitemap\n // rejected.\n const loc = escapeXml(encodeURI(`${base}${route}`));\n if (seen.has(loc)) {\n return;\n }\n seen.add(loc);\n urls.push(` <url><loc>${loc}</loc>${lastmodTag(lastModified)}</url>`);\n };\n for (const page of project.graph.pages) {\n if (\n page.meta.draft ||\n page.meta.sidebar.hidden ||\n page.meta.seo.noindex ||\n ERROR_ROUTES.has(page.route) ||\n archivedExcluded(page)\n ) {\n continue;\n }\n pushUrl(withBasePath(deployBase, page.route), page.lastModified);\n }\n // Custom `.astro` pages and the generated changelog index mount outside\n // `basePath` (they're injected at their pattern — see `blumeIntegration`), so\n // only the deployment base layers onto their URLs.\n const userPages = project.context.pagesRoot\n ? discoverPagesSync(project.context.pagesRoot)\n : [];\n const extraRoutes = customStaticRoutes(userPages).filter(\n (route) => !ERROR_ROUTES.has(route)\n );\n if (hasGeneratedChangelog(project, userPages)) {\n extraRoutes.push(\"/changelog\");\n }\n for (const route of extraRoutes) {\n pushUrl(withBasePath(deployBase, route));\n }\n urls.sort();\n\n if (urls.length <= URLS_PER_FILE) {\n return [{ name: \"sitemap.xml\", xml: renderUrlset(urls) }];\n }\n\n const chunks: SitemapFile[] = [];\n const references: string[] = [];\n for (let start = 0; start < urls.length; start += URLS_PER_FILE) {\n const name = `sitemap-${chunks.length + 1}.xml`;\n chunks.push({\n name,\n xml: renderUrlset(urls.slice(start, start + URLS_PER_FILE)),\n });\n // Chunks sit next to sitemap.xml, so their URLs layer the same deployment\n // base robots.txt uses for the index.\n const loc = escapeXml(\n encodeURI(`${base}${withBasePath(deployBase, `/${name}`)}`)\n );\n references.push(` <sitemap><loc>${loc}</loc></sitemap>`);\n }\n const index = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${references.join(\"\\n\")}\n</sitemapindex>\n`;\n return [{ name: \"sitemap.xml\", xml: index }, ...chunks];\n};\n",
|
|
10
10
|
"import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport {\n mkdir,\n readdir,\n readFile,\n rename,\n rm,\n writeFile,\n} from \"node:fs/promises\";\n\nimport { dirname, join } from \"pathe\";\n\nimport type { ProjectContext } from \"../core/types.ts\";\nimport type { OgCardOptions, OgFont } from \"./card.ts\";\n\n/**\n * Where a build keeps rendered OG cards between runs (see {@link cardCacheKey}\n * for what invalidates one). Baked into the generated OG endpoint alongside\n * the Blume version that renders the cards.\n */\nexport interface OgCache {\n /** Absolute directory holding `<key>.png` files. */\n dir: string;\n /** The Blume version rendering the cards; part of every key. */\n version: string;\n}\n\n/**\n * The card cache directory for a project: `node_modules/.cache/blume/og`,\n * the conventional build-cache location. Vercel and Netlify restore\n * `node_modules` from their build caches, so a deploy there re-renders only\n * the cards whose inputs changed; Cloudflare Workers Builds keeps only\n * package-manager caches (and `node_modules/.astro` for a detected Astro\n * project), and a self-managed runner needs a cache step for the directory.\n * A project with no `node_modules` of its own falls back to the runtime's\n * cache dir next to Astro's and Vite's.\n */\nexport const ogCacheDir = (\n context: Pick<ProjectContext, \"outDir\" | \"root\">\n): string =>\n existsSync(join(context.root, \"node_modules\"))\n ? join(context.root, \"node_modules\", \".cache\", \"blume\", \"og\")\n : join(context.outDir, \".cache\", \"og\");\n\n/**\n * Per-process tally of cache hits and misses plus the keys this build asked\n * for, read back by the CLI after `build()` for the summary line and the\n * prune. On `globalThis` for the same reason as the integration registry: the\n * endpoint renders in the copy of this module Vite bundled for the prerender,\n * while the CLI reads from its own bundled copy.\n */\ninterface OgCacheRegistry {\n hits: number;\n misses: number;\n used: Set<string>;\n}\n\nconst REGISTRY_KEY = Symbol.for(\"blume.og-cache\");\n\ntype RegistryHost = typeof globalThis & { [REGISTRY_KEY]?: OgCacheRegistry };\n\nconst registry = (): OgCacheRegistry => {\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] ??= { hits: 0, misses: 0, used: new Set() };\n return host[REGISTRY_KEY];\n};\n\n/** Type guard: is this OG font a local file entry? */\nexport const isLocalOgFont = (\n font: OgFont\n): font is Extract<OgFont, { src: string }> =>\n typeof font !== \"string\" && \"src\" in font;\n\n// A local font file's contents digest, computed once per path per process: the\n// key must follow the file's bytes, not its mtime (a fresh CI checkout resets\n// every mtime, which would miss the whole cache on each build).\nconst localFontDigests = new Map<string, Promise<string>>();\n\nconst digestFile = async (path: string): Promise<string> =>\n createHash(\"sha256\")\n .update(await readFile(path))\n .digest(\"hex\");\n\nconst localFontDigest = (path: string): Promise<string> => {\n let digest = localFontDigests.get(path);\n if (!digest) {\n digest = digestFile(path);\n localFontDigests.set(path, digest);\n }\n return digest;\n};\n\n/**\n * The cache key of a card: a digest of everything that decides its pixels —\n * the card options (title, description, brand, logo markup, palette, footer\n * text, font families), the fonts (a local file by its contents, a Google\n * family by its request), and the Blume version, since the layout and the\n * renderer it pins ship with the package. Pre-fetched `images` are left out:\n * the endpoint never passes them.\n */\nexport const cardCacheKey = async (\n version: string,\n options: OgCardOptions\n): Promise<string> => {\n const fonts = await Promise.all(\n (options.fonts ?? []).map(async (font) =>\n isLocalOgFont(font)\n ? { ...font, digest: await localFontDigest(font.src) }\n : font\n )\n );\n const card = { ...options, fonts: undefined, images: undefined };\n return createHash(\"sha256\")\n .update(JSON.stringify({ card, fonts, version }))\n .digest(\"hex\");\n};\n\nconst cardPath = (cache: OgCache, key: string): string =>\n join(cache.dir, `${key}.png`);\n\n/** A cached card's bytes, or `null` when there is none. */\nconst readCard = async (file: string): Promise<Uint8Array | null> => {\n try {\n return await readFile(file);\n } catch {\n return null;\n }\n};\n\n// Written to a sibling temp file and renamed into place: concurrent page\n// renders may store the same key, and a reader must never see a half-written\n// card.\nconst storeCard = async (file: string, png: Uint8Array): Promise<void> => {\n await mkdir(dirname(file), { recursive: true });\n const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;\n await writeFile(tmp, png);\n await rename(tmp, file);\n};\n\n/** The in-flight renders of this process, so duplicate titles render once. */\nconst inflight = new Map<string, Promise<Uint8Array>>();\n\nconst renderAndStore = async (\n key: string,\n file: string,\n options: OgCardOptions,\n render: (options: OgCardOptions) => Promise<Uint8Array>\n): Promise<Uint8Array> => {\n try {\n const png = await render(options);\n try {\n await storeCard(file, png);\n } catch {\n // An unwritable cache (a read-only workspace) never fails the build.\n }\n return png;\n } finally {\n inflight.delete(key);\n }\n};\n\n/**\n * Serve a card from `cache`, rendering it with `render` on a miss and storing\n * the result for the next build. Without a cache every card renders; the\n * cache is only ever a shortcut.\n */\nexport const throughCardCache = async (\n cache: OgCache | undefined,\n options: OgCardOptions,\n render: (options: OgCardOptions) => Promise<Uint8Array>\n): Promise<Uint8Array> => {\n if (!cache) {\n return render(options);\n }\n const key = await cardCacheKey(cache.version, options);\n const state = registry();\n state.used.add(key);\n const file = cardPath(cache, key);\n const hit = await readCard(file);\n if (hit) {\n state.hits += 1;\n return hit;\n }\n let pending = inflight.get(key);\n if (!pending) {\n state.misses += 1;\n pending = renderAndStore(key, file, options, render);\n inflight.set(key, pending);\n }\n return pending;\n};\n\n/**\n * Remove the cards this build never asked for — a renamed page, a changed\n * description, a previous Blume version — plus any temp file a crashed build\n * left behind, so a persisted cache holds exactly the current site's cards.\n * Returns how many files were removed; a missing directory removes nothing.\n */\nexport const pruneCardCache = async (dir: string): Promise<number> => {\n const { used } = registry();\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return 0;\n }\n const stale = entries.filter(\n (name) =>\n name.endsWith(\".tmp\") ||\n (name.endsWith(\".png\") && !used.has(name.slice(0, -\".png\".length)))\n );\n await Promise.all(stale.map((name) => rm(join(dir, name), { force: true })));\n return stale.length;\n};\n\n/**\n * This process's card cache tally — how many cards a build reused and how many\n * it rendered — or `null` when no card was requested (OG cards off, or an\n * endpoint-free build).\n */\nexport const cardCacheTally = (): { hits: number; misses: number } | null => {\n const { hits, misses } = registry();\n return hits + misses === 0 ? null : { hits, misses };\n};\n\n/** Reset the tally and the used-key set (tests). */\nexport const resetCardCacheTally = (): void => {\n const state = registry();\n state.hits = 0;\n state.misses = 0;\n state.used.clear();\n};\n",
|
|
11
|
-
"import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport {\n lstat,\n mkdir,\n readFile,\n readlink,\n realpath,\n rm,\n symlink,\n} from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nimport pMap from \"p-map\";\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n normalize,\n relative,\n resolve,\n} from \"pathe\";\nimport { glob } from \"tinyglobby\";\n\nimport { OPENAPI_PATH } from \"../ai/api/paths.ts\";\nimport { buildApiSpec } from \"../ai/api/spec.ts\";\nimport { buildAskData } from \"../ai/ask-data.ts\";\nimport { askBackendRuntimeDep, resolveAskBackend } from \"../ai/ask.ts\";\nimport { buildHomeLinkHeader } from \"../ai/link-headers.ts\";\nimport { buildRawMarkdown, markdownRoutePaths } from \"../ai/markdown.ts\";\nimport type { RawMarkdownEntry } from \"../ai/markdown.ts\";\nimport { buildMcpData } from \"../ai/mcp/data.ts\";\nimport type { McpData } from \"../ai/mcp/data.ts\";\nimport { buildMcpDiscovery, buildMcpServerCard } from \"../ai/mcp/discovery.ts\";\nimport {\n hasDeferrableGroups,\n navVariants,\n} from \"../components/layout/nav-utils.ts\";\nimport { normalizeBasePath } from \"../core/base-path.ts\";\nimport { validateUsedComponents } from \"../core/component-diagnostics.ts\";\nimport { analyzeComponentOverrides } from \"../core/component-overrides.ts\";\nimport {\n collectContentAssets,\n rewriteRelativeImages,\n} from \"../core/content-assets.ts\";\nimport type {\n BlumeBanner,\n BlumeData,\n BlumeFavicon,\n BlumeLogo,\n} from \"../core/data.ts\";\nimport { BlumeError } from \"../core/diagnostics.ts\";\nimport { writeTextAtomic } from \"../core/fs-atomic.ts\";\nimport {\n apiUrl as githubApiUrl,\n editBaseUrl as githubEditBaseUrl,\n repoUrl as githubRepoUrl,\n} from \"../core/github.ts\";\nimport { EN_UI, resolveUIStrings } from \"../core/i18n-ui.ts\";\nimport { resolveFallbackLocale } from \"../core/i18n.ts\";\nimport { buildIncludeGraph } from \"../core/includes.ts\";\nimport {\n validateNavTargets,\n validateSearchPopularIcons,\n} from \"../core/nav-diagnostics.ts\";\nimport { packageRoot } from \"../core/package-root.ts\";\nimport type { BlumeProject } from \"../core/project-graph.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport { resolveDocsCollection } from \"../core/sources/resolve.ts\";\nimport { svgDimensions } from \"../core/svg-dimensions.ts\";\nimport { trimChar } from \"../core/trim.ts\";\nimport { resolveTsconfigAliases } from \"../core/tsconfig-aliases.ts\";\nimport type { Diagnostic, Navigation } from \"../core/types.ts\";\nimport { getBlumeVersion } from \"../core/version.ts\";\nimport { buildRssFeeds, renderRssFeed } from \"../deploy/rss.ts\";\nimport {\n languageIconCss,\n languageIconSlugsIn,\n} from \"../markdown/language-icon.ts\";\nimport { hasMermaidFence } from \"../markdown/mermaid.ts\";\nimport { ogCacheDir } from \"../og/cache.ts\";\nimport { missingFontFiles, resolveOgFonts } from \"../og/derive.ts\";\nimport type { DerivedOgFonts } from \"../og/derive.ts\";\nimport { resolveOgLogo } from \"../og/logo.ts\";\nimport type { ApiSpecData, OpenApiData } from \"../openapi/model.ts\";\nimport {\n builtinProxyKinds,\n hasScalarReferences,\n needsPlaygroundProxy,\n referenceRoutes,\n} from \"../openapi/references.ts\";\nimport { buildReferenceFiles } from \"../openapi/scalar.ts\";\nimport { isOpenApiSource } from \"../openapi/source.ts\";\nimport { registry } from \"../registry/registry.ts\";\nimport { buildSearchDocuments } from \"../search/documents.ts\";\nimport { resolveSearchPopular } from \"../search/popular.ts\";\nimport { searchProviderMeta, servesStaticIndex } from \"../search/providers.ts\";\nimport {\n examplesEntryTemplate,\n tailwindEntryTemplate,\n} from \"../theme/entry.ts\";\nimport {\n buildFontsCss,\n configuredFonts,\n fontLocaleCodes,\n} from \"../theme/fonts.ts\";\nimport { buildThemeCss } from \"../theme/palette.ts\";\nimport { rebaseSourceDirectives } from \"../theme/sources.ts\";\nimport { twoslashCss } from \"../theme/twoslash.ts\";\nimport { planComponentSlots } from \"./component-slots.ts\";\nimport type { ComponentSlotPlan } from \"./component-slots.ts\";\nimport {\n EXAMPLE_SCAN_GLOB,\n discoverExamples,\n exampleMarkdownLookup,\n exampleScanRoots,\n} from \"./examples.ts\";\nimport { publishDevNegotiation } from \"./integration.ts\";\nimport { discoverIslands } from \"./islands.ts\";\nimport {\n customOgRoutes,\n discoverPages,\n hasGeneratedChangelog,\n routeIsTaken,\n} from \"./pages.ts\";\nimport { publishRuntimeModules } from \"./runtime-modules.ts\";\nimport type { RuntimeModuleId } from \"./runtime-modules.ts\";\nimport {\n askComponentTemplate,\n askEndpointTemplate,\n astroConfigTemplate,\n catchAllPageTemplate,\n changelogIndexTemplate,\n contentAssetsEndpointTemplate,\n contentConfigTemplate,\n exampleMapTemplate,\n exampleWrapperTemplate,\n examplesPageTemplate,\n exampleSlug,\n islandMapTemplate,\n islandWrapperTemplate,\n apiNavigationTemplate,\n apiNotFoundTemplate,\n apiPageTemplate,\n apiPagesIndexTemplate,\n apiSearchTemplate,\n mcpEndpointTemplate,\n mcpPageFile,\n mixedbreadSearchEndpointTemplate,\n notFoundJsonTemplate,\n notFoundMarkdownTemplate,\n notFoundPageTemplate,\n ogEndpointTemplate,\n playgroundProxyTemplate,\n rawMarkdownEndpointTemplate,\n rssEndpointTemplate,\n staticJsonEndpointTemplate,\n runtimeDependencies,\n runtimePackageTemplate,\n runtimeTsconfigTemplate,\n featuresTemplate,\n navFragmentTemplate,\n searchClientTemplate,\n searchEndpointTemplate,\n stagedContentDir,\n} from \"./templates.ts\";\nimport type { ClientFeatures } from \"./templates.ts\";\n\n/** Absolute path to the Blume package `src` directory. */\nconst BLUME_SRC = join(packageRoot(), \"src\");\n\n/** Whether a module specifier resolves from a directory via node resolution. */\nconst canResolveFrom = (fromDir: string, spec: string): boolean => {\n try {\n createRequire(pathToFileURL(join(fromDir, \"_.js\")).href).resolve(spec);\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Absolute path to `babel-plugin-react-compiler`, resolved from Blume's own\n * package root (Blume ships it). Returns null when React or the compiler is off.\n *\n * The path must be absolute: @vitejs/plugin-react resolves babel plugins from\n * the *project* root, not `.blume/`, so a bare specifier fails in a user project\n * that never installed the plugin directly. Resolving from `packageRoot()` binds\n * to Blume's shipped copy regardless of the user's package manager or hoisting.\n */\nexport const resolveReactCompiler = (\n config: ResolvedConfig,\n needsReact: boolean,\n pkgDir: string = packageRoot()\n): string | null => {\n if (!(needsReact && config.react.compiler)) {\n return null;\n }\n try {\n return createRequire(pathToFileURL(join(pkgDir, \"_.js\")).href).resolve(\n \"babel-plugin-react-compiler\"\n );\n } catch {\n return null;\n }\n};\n\n/**\n * Warning (as a spreadable list) for the case where the React Compiler was\n * requested but its plugin couldn't be resolved — so the build silently drops\n * to uncompiled output rather than failing. Exported for testing.\n */\nexport const reactCompilerWarnings = (\n config: ResolvedConfig,\n needsReact: boolean,\n compilerPath: string | null\n): string[] =>\n needsReact && config.react.compiler && !compilerPath\n ? [\n \"React Compiler is enabled but `babel-plugin-react-compiler` could not be resolved; falling back to an uncompiled build. Reinstall Blume, or set `react: { compiler: false }` to silence this.\",\n ]\n : [];\n\n/** Resolve Astro's package.json directly inside a node_modules directory. */\nconst resolveAstroPackageJson = (modulesDir: string): string | null => {\n try {\n return realpathSync(join(modulesDir, \"astro\", \"package.json\"));\n } catch {\n return null;\n }\n};\n\n/**\n * The `astro` package reachable through the normal node_modules ancestor walk\n * from a generated runtime — its realpath'd `package.json` plus the\n * `node_modules` directory the walk found it in — or null when none resolves.\n *\n * This deliberately does not use `createRequire().resolve()`. pnpm's generated\n * bin shim adds Blume's virtual-store dependencies to `NODE_PATH`, which\n * CommonJS resolution honors but ESM package resolution ignores. The generated\n * Astro config uses ESM imports, so treating a NODE_PATH-only result as\n * reachable skips the dependency link and makes `import \"astro/config\"` fail.\n * Walking the physical node_modules ancestors mirrors the lookup that config\n * actually gets.\n *\n * The containing directory matters as much as the package: under an isolated\n * linker the walk can find a store-deduped astro in a directory that holds\n * nothing else of Blume's, so \"the right astro resolves\" does not imply \"the\n * integrations resolve\" — callers must check where the hit came from.\n */\nconst resolvedAstroHit = (\n fromDir: string\n): { modulesDir: string; pkg: string } | null => {\n let dir = normalize(fromDir);\n while (true) {\n const modulesDir = join(dir, \"node_modules\");\n const pkg = resolveAstroPackageJson(modulesDir);\n if (pkg) {\n return { modulesDir, pkg };\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return null;\n }\n dir = parent;\n }\n};\n\n/**\n * Whether two paths name the same physical directory (realpath equality).\n * Exported for testing.\n */\nexport const sameRealDir = (a: string, b: string): boolean => {\n try {\n return realpathSync(a) === realpathSync(b);\n } catch {\n return false;\n }\n};\n\n/**\n * The two places an installer can put Blume's dependencies:\n * - `<blume>/node_modules` — deps nested under the package (workspace source,\n * or npm nesting them away from a conflicting hoisted copy)\n * - `dirname(<blume>)` — deps as siblings in the store (isolated/pnpm)\n *\n * `packageRoot()` resolves to Blume's real on-disk path (Node follows the\n * install symlink), so its parent is the store's package directory where the\n * isolated linker places the siblings.\n */\nconst depsCandidates = (pkgDir: string): string[] => [\n join(pkgDir, \"node_modules\"),\n dirname(pkgDir),\n];\n\n/** First dependency candidate containing the package dir `segments`, or null. */\nconst candidateHolding = (\n pkgDir: string,\n ...segments: string[]\n): string | null =>\n depsCandidates(pkgDir).find((dir) => existsSync(join(dir, ...segments))) ??\n null;\n\n/**\n * Locate the directory that holds Blume's installed dependencies (Astro and its\n * integrations).\n *\n * With a clean hoisted install this is moot — the deps sit in a `node_modules`\n * the generated `.blume/` already walks up into, and {@link ensureDepsLink}\n * short-circuits before we need it. But under isolated linkers (Bun's\n * `isolated` mode, pnpm) Blume's deps are NOT hoisted into the project; they\n * live beside the Blume package in a virtual store, invisible to the upward\n * walk from `.blume/` — so probe the {@link depsCandidates}.\n *\n * Astro alone is a bad probe: an npm split install (an `overrides` pin plus an\n * incremental install) hoists `astro` to the project root while Blume's other\n * deps stay nested, and probing for astro then picks the root directory — one\n * that holds none of them. Prefer a candidate with the full set (astro beside\n * `@astrojs/mdx`, the integration every generated runtime declares), then one\n * with the integrations (astro hoisted away — the rest of Blume's deps sit\n * there too), then one with astro alone.\n */\nconst holdsAstro = (dir: string): boolean => existsSync(join(dir, \"astro\"));\nconst holdsMdx = (dir: string): boolean =>\n existsSync(join(dir, \"@astrojs\", \"mdx\"));\n\nexport const blumeDepsDir = (pkgDir: string = packageRoot()): string | null => {\n const candidates = depsCandidates(pkgDir);\n return (\n candidates.find((dir) => holdsAstro(dir) && holdsMdx(dir)) ??\n candidates.find(holdsMdx) ??\n candidates.find(holdsAstro) ??\n null\n );\n};\n\n/**\n * Create `link` as a directory symlink to `target`, falling back to a junction.\n *\n * The type only matters on Windows, and there a junction is the wrong first\n * choice: Windows can't follow a *relative* symlink reached through a\n * junction (it resolves the relative target against the junction-side path,\n * so it lands outside the store and every lookup is ENOENT), and Bun's\n * isolated linker writes exactly those into Blume's dependency directory\n * whenever it holds symlink privilege. A directory symlink traverses them\n * fine. Without that privilege (no Developer Mode, non-admin shell) creating\n * one fails, so fall back to a junction — and in that session the installer\n * had no privilege either, so the deps are absolute junctions a junction can\n * follow. Exported for testing.\n */\nexport const symlinkDir = async (\n target: string,\n link: string\n): Promise<void> => {\n try {\n await symlink(target, link, \"dir\");\n } catch {\n await symlink(target, link, \"junction\");\n }\n};\n\n/**\n * Point `link` at Blume's dependency directory via a `node_modules` link,\n * replacing a stale link we own and leaving a real directory untouched.\n *\n * `lstat`, not `existsSync`, so a broken link (target since moved) is still\n * detected — `existsSync` follows the link and reports a dangling one as absent.\n */\nconst linkDepsJunction = async (\n link: string,\n depsDir: string\n): Promise<void> => {\n let existing: Awaited<ReturnType<typeof lstat>> | null;\n try {\n existing = await lstat(link);\n } catch {\n existing = null;\n }\n if (existing) {\n if (!existing.isSymbolicLink()) {\n return;\n }\n // Already pointing at the right target — leave it alone. This runs on\n // every dev regeneration, and an unconditional rm+recreate opens a window\n // in which the Vite server's module resolution races a missing\n // `node_modules` and 500s intermittently.\n try {\n if (resolve(dirname(link), await readlink(link)) === resolve(depsDir)) {\n return;\n }\n } catch {\n // Unreadable link — replace it below.\n }\n await rm(link, { force: true });\n }\n await mkdir(dirname(link), { recursive: true });\n await symlinkDir(depsDir, link);\n};\n\n/** Read the `version` field of a `package.json`, or null when unreadable. */\nconst readPkgVersion = (pkgJsonPath: string | null): string | null => {\n if (!pkgJsonPath) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")).version ?? null;\n } catch {\n return null;\n }\n};\n\n/**\n * Build the diagnostic for a split-layout Astro conflict that a symlink can't\n * repair: a different Astro is hoisted to the project root, shadowing Blume's,\n * and `@astrojs/mdx` binds to the wrong copy. `blumeAstroPkg`/`shadowAstroPkg`\n * are the resolved `astro/package.json` paths for Blume's set and the one the\n * runtime actually resolves.\n */\nconst astroConflictWarning = (\n blumeAstroPkg: string | null,\n shadowAstroPkg: string | null\n): string => {\n const blume = readPkgVersion(blumeAstroPkg);\n const shadow = readPkgVersion(shadowAstroPkg);\n const versions =\n blume && shadow\n ? `astro@${shadow} shadowing Blume's astro@${blume}`\n : \"a second copy of Astro shadowing Blume's\";\n const pin = blume ?? \"<Blume's astro version>\";\n return `Astro version conflict: another dependency hoisted ${versions} to the project root, so @astrojs/mdx binds to the wrong copy and the build fails on a missing export (e.g. \"chunkToString\"). A single symlink can't reconcile a split install — pin Blume's Astro by adding a package.json \"overrides\" (npm/bun/pnpm) or \"resolutions\" (yarn) entry { \"astro\": \"${pin}\" }, then reinstall. Run \\`npm ls astro\\` to find the dependency pulling the older copy.`;\n};\n\n/**\n * Drop a `.blume/node_modules` junction that resolves a *different* Blume than\n * the one running. A restored build cache (e.g. Vercel's) can resurrect the\n * junction pointing into a superseded store directory — blume@1.1.0's isolated\n * deps dir after 1.1.1 was installed. Releases rarely bump Astro, so the stale\n * target still resolves the very same astro and every astro-based probe in\n * {@link ensureDepsLink} passes through the link — while the `blume/*` imports\n * in the freshly generated config load the previous release, crashing on any\n * export added since. Staleness is judged by realpath: the link is stale\n * exactly when the directory behind it holds a `blume` that isn't `pkgDir`.\n * A target with no `blume` entry (the workspace layout links\n * `packages/blume/node_modules`, which holds only the deps) resolves Blume\n * through the normal ancestor walk and stays. Real directories stay too,\n * mirroring {@link linkDepsJunction} — we only ever remove a link we own.\n */\nconst dropStaleDepsLink = async (\n link: string,\n pkgDir: string\n): Promise<void> => {\n let existing: Awaited<ReturnType<typeof lstat>>;\n try {\n existing = await lstat(link);\n } catch {\n return;\n }\n if (!existing.isSymbolicLink()) {\n return;\n }\n let linkedBlume: string;\n let runningBlume: string;\n try {\n linkedBlume = await realpath(join(link, \"blume\"));\n runningBlume = await realpath(pkgDir);\n } catch {\n return;\n }\n if (linkedBlume !== runningBlume) {\n await rm(link, { force: true });\n }\n};\n\n/**\n * Make the generated runtime resolve Astro and its integrations against Blume's\n * own dependency set. Three failure modes this repairs:\n *\n * - Astro is *unreachable* from `.blume/` (workspaces under isolated linkers,\n * pnpm) — the deps live in a store the upward walk can't see.\n * - Astro *resolves to the wrong copy* — a hoisted sibling pinned an older\n * major (e.g. `astro@6` for a type-only import) that shadows Blume's\n * `astro@7`, so `@astrojs/mdx@7` binds to it and crashes the build on a\n * missing export. Resolving merely *an* astro isn't enough; it must be the\n * same one Blume uses.\n * - The *integrations* are unreachable while astro is fine — npm's split\n * install. An `overrides` pin plus an incremental `npm install` hoists\n * astro to the project root (deleting Blume's nested copy) but leaves\n * `@astrojs/mdx` and friends nested under `blume/node_modules`, where the\n * upward walk from `.blume/` can't see them. The same shape arises under\n * an isolated linker when the workspace itself declares astro at a version\n * matching Blume's: the store dedupes both to one copy, so the walk finds\n * the \"correct\" astro through the workspace's own direct-dep symlink — in\n * a node_modules holding none of Blume's other deps.\n *\n * The repair is the same symlink: Blume's dependency directory linked in as\n * `.blume/node_modules` so the generated config's bare specifiers (`astro`,\n * `@astrojs/mdx`, …) bind to a consistent set. That's safe when the linked\n * directory holds the full set, or when it holds only the integrations but the\n * runtime already resolves Blume's astro — the junction has no `astro` entry,\n * so astro lookups fall through to the hoisted copy the integrations bind to\n * anyway. What it can't fix is the inverse split: Blume's astro nested under a\n * *conflicting* hoisted astro with the integrations hoisted away from it. No\n * single directory yields a consistent set there; only a root `overrides`/\n * `resolutions` pin does, so we return a diagnostic naming the conflict rather\n * than silently shipping a runtime that crashes downstream. Returns the\n * warning, or null when nothing needs saying.\n */\nexport const ensureDepsLink = async (\n outDir: string,\n pkgDir: string = packageRoot()\n): Promise<string | null> => {\n const astroDir = candidateHolding(pkgDir, \"astro\");\n if (!astroDir) {\n return null;\n }\n const mdxDir = candidateHolding(pkgDir, \"@astrojs\", \"mdx\");\n const blumeAstro = resolveAstroPackageJson(astroDir);\n // Before probing what `.blume/` resolves, drop a cache-restored junction\n // that binds it to a superseded Blume — the probes below would otherwise\n // pass right through it (same astro, older blume) and leave it in place.\n await dropStaleDepsLink(join(outDir, \"node_modules\"), pkgDir);\n const outDirHit = resolvedAstroHit(outDir);\n // `.blume/` resolves the very same astro Blume's deps provide.\n const astroCorrect = blumeAstro !== null && outDirHit?.pkg === blumeAstro;\n // Clean hoisted install: astro is correct, found in Blume's own dependency\n // directory, and the integrations sit beside it — the same walk resolves\n // them too, so there is nothing to do. Requiring the walk to land in\n // `astroDir` itself (not merely resolve an identical astro) matters under\n // isolated linkers: a workspace that declares astro at a version matching\n // Blume's gets a store-deduped symlink in its own node_modules, so the walk\n // finds the \"correct\" astro in a directory holding only the workspace's\n // direct deps — none of Blume's integrations (issue #103).\n const walkLandsInDeps =\n astroCorrect &&\n outDirHit !== null &&\n sameRealDir(outDirHit.modulesDir, astroDir);\n if (walkLandsInDeps && mdxDir === astroDir) {\n return null;\n }\n // Linking the integrations' directory yields a consistent set when it also\n // holds Blume's astro (the unreachable and repairable-conflict cases) or\n // when the correct astro is reachable without it (the npm split install).\n // Any existing link here is stale and gets replaced.\n if (mdxDir && (mdxDir === astroDir || astroCorrect)) {\n await linkDepsJunction(join(outDir, \"node_modules\"), mdxDir);\n return null;\n }\n // Split layout: Blume's astro is nested (a conflicting astro took the root\n // spot) but @astrojs/mdx hoisted away from it, binding to the shadow. Only a\n // root pin fixes this — surface it.\n return astroConflictWarning(blumeAstro, outDirHit?.pkg ?? null);\n};\n\n/**\n * Vite plugin that makes Blume's externalized runtime deps (zod, shiki, sharp,\n * `takumi-js`, …) resolvable when Astro executes the static prerender\n * bundle under an isolated linker (Bun's `isolated` mode, pnpm).\n *\n * Astro's static build emits a self-contained SSR bundle to\n * `<outDir>/.prerender/` and `import()`s it in-process to generate the HTML.\n * That bundle externalizes Blume's render-time deps, so Node resolves them at\n * prerender time by walking up from `.prerender/chunks/*.mjs`. {@link\n * ensureDepsLink} only repairs resolution rooted at `.blume/`; `.prerender/`\n * lives under `dist/`, a separate tree an isolated linker never hoists Blume's\n * deps into — so the import dies with `Cannot find package 'zod'`. We drop the\n * same `node_modules` junction into the prerender root, mirroring\n * `.blume/node_modules`, so every externalized specifier — native bindings\n * included, which can't be bundled — resolves. Astro deletes `.prerender/` once\n * generation finishes (and the junction with it: `fs.rm` unlinks symlinks, it\n * never follows them), so nothing leaks into the published `dist/`.\n *\n * Keyed off the output dir's basename (`.prerender`) — the name Astro 7 gives\n * the prerender build for both static (`<outDir>/.prerender/`) and server\n * (`<build.server>/.prerender/`) output — so it fires for exactly that build.\n * Inert in dev, where there is no build and `writeBundle` never runs.\n */\nexport interface PrerenderDepsPlugin {\n name: string;\n writeBundle: (options: { dir?: string }) => Promise<void>;\n}\n\nexport const prerenderDepsPlugin = (\n pkgDir: string = packageRoot()\n): PrerenderDepsPlugin => ({\n name: \"blume:prerender-deps\",\n writeBundle: async (options) => {\n if (!options.dir || basename(options.dir) !== \".prerender\") {\n return;\n }\n const depsDir = blumeDepsDir(pkgDir);\n if (!depsDir) {\n return;\n }\n await linkDepsJunction(join(options.dir, \"node_modules\"), depsDir);\n },\n});\n\n/** Astro integration package each non-React island framework needs installed. */\nconst ISLAND_FRAMEWORK_DEPS = new Map([\n [\"svelte\", \"@astrojs/svelte\"],\n [\"vue\", \"@astrojs/vue\"],\n]);\n\n/**\n * Adapter package the project must install itself for each deployment\n * platform whose adapter Blume doesn't ship. Node and Vercel ship with Blume,\n * so they never need this.\n */\nconst DEPLOYMENT_ADAPTER_DEPS = new Map([\n [\"cloudflare\", \"@astrojs/cloudflare\"],\n [\"netlify\", \"@astrojs/netlify\"],\n]);\n\n/**\n * Warn when a Vue/Svelte island is present but its Astro integration isn't\n * installed — Vite would otherwise fail opaquely on the generated config import.\n * React ships with Blume, so it never needs this.\n */\nconst islandFrameworkWarnings = (\n frameworks: Set<string>,\n root: string\n): string[] => {\n const warnings: string[] = [];\n for (const framework of frameworks) {\n const dep = ISLAND_FRAMEWORK_DEPS.get(framework);\n if (dep && !canResolveFrom(root, dep)) {\n warnings.push(\n `Islands use ${framework}, which needs \"${dep}\". Install it (e.g. \\`npm install ${dep} ${framework}\\`).`\n );\n }\n }\n return warnings;\n};\n\n/**\n * Warn when the resolved server-output adapter is one the project must install\n * itself (Netlify/Cloudflare; Node and Vercel ship with Blume). The generated\n * astro.config.mjs imports the adapter package directly — and on those\n * platforms the adapter is even auto-selected from env vars — so warn early\n * rather than let the build die with an opaque ERR_MODULE_NOT_FOUND from the\n * hidden generated config. Availability mirrors the search-provider check: a\n * dep resolves from the project root or from the Blume package itself.\n * `pkgDir` is injectable for testing.\n */\nexport const deploymentAdapterWarnings = (\n deployment: ResolvedConfig[\"deployment\"],\n root: string,\n pkgDir: string = packageRoot()\n): string[] => {\n const dep =\n deployment.output === \"server\" && deployment.adapter\n ? DEPLOYMENT_ADAPTER_DEPS.get(deployment.adapter)\n : undefined;\n if (dep && !(canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep))) {\n return [\n `Deployment adapter \"${deployment.adapter}\" needs \"${dep}\", which isn't installed. Run \\`npm install ${dep}\\` (or your package manager's equivalent).`,\n ];\n }\n return [];\n};\n\n/**\n * Warn when the configured search provider's SDK is missing. Provider SDKs are\n * optional peers; warn (rather than fail opaquely in Vite) when the package\n * isn't installed. A dep is available if the project installed it (resolves\n * from the root) OR Blume ships it (resolves from the Blume package — the same\n * set the `.blume` deps link exposes to the build). Resolving from the project\n * root alone falsely flagged a shipped SDK like Orama (the default provider)\n * as missing whenever it wasn't hoisted into the project, e.g. under isolated\n * linkers. We resolve from each package's real location rather than through\n * the `.blume` junction, which can't be traversed reliably for store-symlinked\n * deps. `pkgDir` is injectable for testing.\n */\nexport const searchProviderWarnings = (\n provider: ResolvedConfig[\"search\"][\"provider\"],\n root: string,\n pkgDir: string = packageRoot()\n): string[] => {\n const warnings: string[] = [];\n for (const dep of searchProviderMeta(provider).runtimeDeps) {\n if (!(canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep))) {\n warnings.push(\n `Search provider \"${provider}\" needs \"${dep}\", which isn't installed. Run \\`npm install ${dep}\\` (or your package manager's equivalent).`\n );\n }\n }\n return warnings;\n};\n\n/**\n * Warn when the Ask AI backend's provider SDK is missing. Like search provider\n * SDKs, these are optional peers the project must install (only `gateway`\n * needs nothing beyond the core `ai` package Blume ships) — warn early with\n * the package name rather than let Vite fail to resolve the import opaquely.\n * Same resolution rule as {@link searchProviderWarnings}: available if the\n * project installed it or Blume can resolve it. `pkgDir` is injectable for\n * testing.\n */\nexport const askProviderWarnings = (\n ask: ResolvedConfig[\"ai\"][\"ask\"],\n root: string,\n pkgDir: string = packageRoot()\n): string[] => {\n // An external `endpoint` means no generated route, so no SDK is imported.\n if (!ask?.enabled || ask.endpoint) {\n return [];\n }\n const dep = askBackendRuntimeDep(ask);\n if (!dep || canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep)) {\n return [];\n }\n return [\n `Ask AI provider \"${ask.provider}\" needs \"${dep}\", which isn't installed. Run \\`npm install ${dep}\\` (or your package manager's equivalent).`,\n ];\n};\n\n/** Absolute path to the configured `examples.css`, or null when unset. */\nconst examplesCssFile = (\n root: string,\n config: ResolvedConfig\n): string | null =>\n config.examples.css ? join(root, config.examples.css) : null;\n\n/**\n * Write the per-example preview route (`{basePath}/blume-examples/<path>`)\n * that `<Component />` iframes embed — the iframe boundary is what isolates\n * previews from the docs CSS. Nested under `basePath` in the filesystem so\n * the routes stay reachable behind a proxy that only forwards the base;\n * pruneOrphans clears a stale copy when `basePath` changes or the last\n * example is removed. Returns (as a spreadable list) a warning when the\n * configured `examples.css` doesn't exist.\n */\nconst writeExamplesPreview = async (options: {\n config: ResolvedConfig;\n hasExamples: boolean;\n root: string;\n srcDir: string;\n write: (path: string, content: string) => Promise<boolean>;\n}): Promise<string[]> => {\n const { config, hasExamples, root, srcDir, write } = options;\n if (hasExamples) {\n await write(\n join(\n srcDir,\n \"pages\",\n ...config.basePath.split(\"/\").filter(Boolean),\n \"blume-examples\",\n \"[...path].astro\"\n ),\n examplesPageTemplate()\n );\n }\n const cssFile = examplesCssFile(root, config);\n return cssFile && !existsSync(cssFile)\n ? [\n `examples.css points at \"${config.examples.css}\", which doesn't exist; previews render without it.`,\n ]\n : [];\n};\n\n/** Read a file's contents, or return an empty string if it is absent. */\nconst readOptional = async (path: string | null): Promise<string> => {\n if (!path) {\n return \"\";\n }\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return \"\";\n }\n};\n\n/**\n * Read a user stylesheet (`theme.css`, `examples.css`) that gets inlined into\n * a generated Tailwind entry under `outputDir`, re-rooting its relative\n * `@source` paths so they still resolve from where the author wrote them.\n */\nconst readUserCss = async (\n file: string | null,\n outputDir: string\n): Promise<string> => {\n const css = await readOptional(file);\n return file\n ? rebaseSourceDirectives(css, { from: file, to: outputDir })\n : css;\n};\n\n/** Heuristically detect whether the project uses React islands. */\nexport const detectNeedsReact = async (root: string): Promise<boolean> => {\n const matches = await glob([\"**/*.{tsx,jsx}\"], {\n cwd: root,\n ignore: [\"**/node_modules/**\", \"**/.blume/**\", \"**/dist/**\"],\n onlyFiles: true,\n });\n return matches.length > 0;\n};\n\n/** Block math (`$$…$$`) or an explicitly authored `<Math …>` component. */\nconst containsMath = (content: string): boolean =>\n content.includes(\"$$\") || content.includes(\"<Math\");\n\n/** Ceiling on concurrent content-file reads; unbounded fan-out risks EMFILE. */\nconst READ_CONCURRENCY = 16;\n\n/**\n * Detect whether the project can render math: block math (`$$…$$`) or an\n * explicit `<Math>` tag in any local `.md`/`.mdx`, or in staged (non-filesystem)\n * source bodies. Drives whether the generated runtime imports the `<Math>`\n * component and KaTeX's stylesheet, so a math-free site ships no KaTeX CSS.\n * Math parsing itself is always on but block-only, so one of those literals is\n * a necessary condition — no false negatives. A stray `$$` (e.g. inside a code\n * fence) merely over-includes the idempotent import, which is harmless.\n */\nexport const detectUsesMath = async (\n root: string,\n staged: Iterable<string> = []\n): Promise<boolean> => {\n const files = await glob([\"**/*.{md,mdx}\"], {\n cwd: root,\n ignore: [\"**/node_modules/**\", \"**/.blume/**\", \"**/dist/**\"],\n onlyFiles: true,\n });\n const contents = await pMap(files, (file) => readOptional(join(root, file)), {\n concurrency: READ_CONCURRENCY,\n });\n return [...contents, ...staged].some(containsMath);\n};\n\nconst hashConfigSource = (source: string): string =>\n createHash(\"sha256\").update(source).digest(\"hex\");\n\nconst loadIntegrationBridge = async (\n config: ResolvedConfig,\n context: BlumeProject[\"context\"]\n): Promise<Parameters<typeof astroConfigTemplate>[0][\"integrationBridge\"]> => {\n if (config.integrations.length === 0 || !context.configFile) {\n return;\n }\n return {\n configFile: relative(context.outDir, context.configFile),\n sourceHash: hashConfigSource(await readOptional(context.configFile)),\n };\n};\n\nconst writeIfChanged = async (\n path: string,\n content: string\n): Promise<boolean> => {\n let existing: string | null = null;\n try {\n existing = await readFile(path, \"utf-8\");\n } catch {\n existing = null;\n }\n if (existing === content) {\n return false;\n }\n // Atomic temp-write + rename, so a watching dev server never observes a\n // missing or half-written file mid-regeneration.\n await writeTextAtomic(path, content);\n return true;\n};\n\n/**\n * Delete generated files under `srcDir` that this pass didn't (re)write. The\n * generator emits many files conditionally — an Ask AI endpoint, OG images, a\n * search index, RSS feeds, reference pages, the MCP server — so toggling a\n * feature off would otherwise leave a stale file behind, and a leftover\n * server-rendered endpoint breaks the static build. `writeIfChanged` only ever\n * adds or updates, so this closes the loop. Scoped to `.blume/src`, so it never\n * touches Astro's `dist/`, `.astro/` cache, or the symlinked `node_modules`\n * (all of which live outside `src`). `written` holds normalized absolute paths.\n */\nexport const pruneOrphans = async (\n srcDir: string,\n written: Set<string>\n): Promise<void> => {\n const existing = await glob(\"**/*\", {\n absolute: true,\n cwd: srcDir,\n onlyFiles: true,\n });\n const removals: Promise<void>[] = [];\n for (const path of existing) {\n const normalized = normalize(path);\n if (!written.has(normalized)) {\n removals.push(rm(normalized, { force: true }));\n }\n }\n await Promise.all(removals);\n};\n\n/**\n * Collect staged (non-filesystem) page bodies keyed by their Astro entry id, so\n * i18n duplicates of one entry collapse to a single materialized file. Shared\n * with `eject`, which materializes the same bodies into the owned project.\n */\nexport const collectStaged = (project: BlumeProject): Map<string, string> => {\n const staged = new Map<string, string>();\n for (const page of project.graph.pages) {\n if (page.collection === \"staged\" && page.entryId && page.body) {\n // A colocated `./image.png` reference resolves against `.blume/content`\n // once the body is materialized there, where the file does not exist.\n // Point it at the served original instead — the same rewrite the\n // agent-facing Markdown gets.\n const text = page.sourcePath\n ? rewriteRelativeImages({\n deployBase: project.config.deployment.base,\n projectRoot: project.context.root,\n source: page.body.text,\n sourcePath: page.sourcePath,\n })\n : page.body.text;\n staged.set(page.entryId, text);\n }\n }\n return staged;\n};\n\n/**\n * Materialize staged source bodies under `.blume/content` and prune orphans in\n * that tree (separate from `.blume/src`), so a removed remote entry is cleaned up.\n */\nconst writeStagedContent = async (\n out: string,\n staged: Map<string, string>\n): Promise<void> => {\n const contentDir = stagedContentDir(out);\n const written = new Set<string>();\n await Promise.all(\n [...staged].map(async ([entryId, text]) => {\n const path = join(contentDir, entryId);\n written.add(normalize(path));\n await writeIfChanged(path, text);\n })\n );\n if (existsSync(contentDir)) {\n await pruneOrphans(contentDir, written);\n }\n};\n\ninterface LogoDimensions {\n height: number;\n width: number;\n}\n\n/**\n * Read dimensions from an SVG's explicit size or its view box, with the same\n * root-tag parser og/card.ts uses for the OG brand mark so the header and the\n * card can't disagree about one logo. An SVG with no usable size collapses to\n * undefined.\n */\nconst logoDimensions = (svg: string | undefined): LogoDimensions | undefined =>\n svg ? (svgDimensions(svg) ?? undefined) : undefined;\n\n/** Read a local SVG logo from the project root or public directory. */\nconst readLogoSvg = (\n project: BlumeProject,\n source: string | undefined\n): string | undefined => {\n if (!source?.toLowerCase().endsWith(\".svg\")) {\n return;\n }\n const rel = source.replace(/^\\//u, \"\");\n const file = [\n join(project.context.root, \"public\", rel),\n join(project.context.root, rel),\n ].find((path) => existsSync(path));\n return file ? readFileSync(file, \"utf-8\") : undefined;\n};\n\n/** Narrows a config union's string shorthand from its object form. */\nconst isStringShorthand = <T>(value: T | string): value is string =>\n typeof value === \"string\";\n\n/**\n * The URL behind the header's repo mark. A string is used as-is: `github`\n * drives the per-page edit link, the header mark and the manifest's\n * `repository` together, so a project whose docs repo is private has to unset\n * all three, and would otherwise have no way to point the mark at anything.\n */\nconst headerRepoUrl = (\n repo: boolean | string,\n derived: string | null\n): string | null => {\n if (isStringShorthand(repo)) {\n return repo;\n }\n return repo ? derived : null;\n};\n\n/**\n * Resolve the configured logo. A single SVG is read and inlined so a\n * `currentColor` logo follows the theme; other images keep their URL for an\n * `<img>`. The file is looked up under `public/` and the project root.\n */\nconst resolveLogo = (project: BlumeProject): BlumeLogo | null => {\n const { logo } = project.config;\n if (!logo) {\n return null;\n }\n const config = isStringShorthand(logo) ? { image: logo } : logo;\n // `text` is passed through verbatim: `undefined` lets the brand fall back to\n // the site title, `\"\"` renders the mark alone (a logo with the wordmark baked\n // in).\n const { href, image: source, text } = config;\n const image = isStringShorthand(source) ? { light: source } : source;\n const light = image?.light ?? image?.dark;\n const dark = image?.dark ?? image?.light;\n const alt = image?.alt ?? \"\";\n const brandHref = href ?? \"/\";\n const lightSvg = readLogoSvg(project, light);\n const darkSvg = dark === light ? lightSvg : readLogoSvg(project, dark);\n\n if (light && light === dark && lightSvg) {\n return { alt, href: brandHref, svg: lightSvg, text };\n }\n\n const lightDimensions = logoDimensions(lightSvg);\n const darkDimensions = logoDimensions(darkSvg);\n const dimensions =\n lightDimensions || darkDimensions\n ? { dark: darkDimensions, light: lightDimensions }\n : undefined;\n return { alt, dark, dimensions, href: brandHref, light, text };\n};\n\n/**\n * Favicon filenames Blume auto-detects, in priority order. Mirrors the Next.js\n * convention: an `icon.*` or `favicon.*` file in `public/` or the project root\n * becomes the site favicon, no config required.\n */\nconst FAVICON_CANDIDATES = [\n \"icon.svg\",\n \"favicon.svg\",\n \"icon.png\",\n \"favicon.png\",\n \"favicon.ico\",\n \"icon.ico\",\n];\n\n/**\n * Derive the `-dark` sibling of an icon filename (`icon.svg` → `icon-dark.svg`),\n * inserting the suffix before the extension.\n */\nconst darkSibling = (name: string): string =>\n name.replace(/\\.(?=[^.]+$)/u, \"-dark.\");\n\n/** `<link type>` MIME for the favicon extensions we recognize. */\nconst FAVICON_TYPES = new Map([\n [\"ico\", \"image/x-icon\"],\n [\"jpeg\", \"image/jpeg\"],\n [\"jpg\", \"image/jpeg\"],\n [\"png\", \"image/png\"],\n [\"svg\", \"image/svg+xml\"],\n]);\n\n/** Infer the `<link type>` MIME from a filename, when we recognize the extension. */\nconst faviconType = (name: string): string | undefined => {\n const ext = name.split(\".\").pop()?.toLowerCase();\n return ext ? FAVICON_TYPES.get(ext) : undefined;\n};\n\n/** Read a file and encode it as a `data:` URI of the given MIME type. */\nconst inlineDataUri = (file: string, type: string): string =>\n `data:${type};base64,${readFileSync(file).toString(\"base64\")}`;\n\n/**\n * The bundled Blume favicon, inlined as a data URI so it needs no public file.\n * The mark is dark, so it ships with a light-on-transparent dark-scheme variant —\n * otherwise it disappears against dark browser chrome.\n */\nconst defaultFavicon = (): BlumeFavicon => ({\n dark: {\n href: inlineDataUri(\n join(BLUME_SRC, \"assets\", \"icon-dark.png\"),\n \"image/png\"\n ),\n type: \"image/png\",\n },\n href: inlineDataUri(join(BLUME_SRC, \"assets\", \"icon.png\"), \"image/png\"),\n type: \"image/png\",\n});\n\n/**\n * Apple touch icon filenames Blume auto-detects, in priority order. Mirrors the\n * Next.js `apple-icon.*` convention (plus the `apple-touch-icon.png` most favicon\n * generators emit): a match in `public/` or the project root becomes the iOS\n * home-screen icon, no config required.\n */\nconst APPLE_ICON_CANDIDATES = [\n \"apple-icon.png\",\n \"apple-icon.jpg\",\n \"apple-icon.jpeg\",\n \"apple-touch-icon.png\",\n];\n\n/**\n * Resolve an icon file by convention. A candidate in `public/` is served as-is\n * and referenced by URL; one at the project root is inlined as a data URI (the\n * root isn't a served directory). Returns null when the project ships none.\n */\nconst resolveIconFile = (\n project: BlumeProject,\n candidates: string[]\n): BlumeFavicon | null => {\n const { root } = project.context;\n for (const name of candidates) {\n if (existsSync(join(root, \"public\", name))) {\n return { href: `/${name}`, type: faviconType(name) };\n }\n }\n for (const name of candidates) {\n const file = join(root, name);\n if (existsSync(file)) {\n const type = faviconType(name);\n return { href: inlineDataUri(file, type ?? \"image/x-icon\"), type };\n }\n }\n return null;\n};\n\n/**\n * Resolve the site favicon by convention, falling back to the bundled Blume mark\n * when the project ships no `icon.*`/`favicon.*` file. The dark-scheme variant\n * is anchored to the resolved icon: its `-dark` sibling (e.g. `icon.svg` →\n * `icon-dark.svg`) in the same directory — never an unrelated `-dark` file, so a\n * stale or foreign `favicon-dark.*` can't silently pair with a different mark.\n * A `-dark` file with no light sibling is the site's only mark and is used for\n * both schemes, mirroring how `resolveLogo` treats a single-variant image.\n */\nconst resolveFavicon = (project: BlumeProject): BlumeFavicon => {\n const { root } = project.context;\n for (const name of FAVICON_CANDIDATES) {\n if (existsSync(join(root, \"public\", name))) {\n const type = faviconType(name);\n const sibling = darkSibling(name);\n return existsSync(join(root, \"public\", sibling))\n ? { dark: { href: `/${sibling}`, type }, href: `/${name}`, type }\n : { href: `/${name}`, type };\n }\n }\n for (const name of FAVICON_CANDIDATES) {\n const file = join(root, name);\n if (existsSync(file)) {\n const type = faviconType(name);\n const mime = type ?? \"image/x-icon\";\n const siblingFile = join(root, darkSibling(name));\n return existsSync(siblingFile)\n ? {\n dark: { href: inlineDataUri(siblingFile, mime), type },\n href: inlineDataUri(file, mime),\n type,\n }\n : { href: inlineDataUri(file, mime), type };\n }\n }\n return (\n resolveIconFile(project, FAVICON_CANDIDATES.map(darkSibling)) ??\n defaultFavicon()\n );\n};\n\n/**\n * Resolve the Apple touch icon by convention, or null when the project ships\n * none (unlike the favicon, there's no bundled default). Note: iOS ignores\n * `data:`-URI apple-touch-icons, so a `public/` file (served by URL) is the\n * reliable path; a root-level file is still inlined for symmetry with favicons.\n * Deliberately no `-dark` sibling detection here: iOS ignores `media` on\n * `apple-touch-icon` links, so a dark variant could never be served.\n */\nconst resolveAppleIcon = (project: BlumeProject): BlumeFavicon | null =>\n resolveIconFile(project, APPLE_ICON_CANDIDATES);\n\n/** Normalize the banner config (string shorthand or object) for the runtime. */\nconst resolveBanner = (config: ResolvedConfig): BlumeBanner | null => {\n const { banner } = config;\n if (!banner) {\n return null;\n }\n if (isStringShorthand(banner)) {\n return { content: banner, dismissible: false, key: banner };\n }\n return {\n content: banner.content,\n dismissible: banner.dismissible,\n key: banner.id ?? banner.content,\n link: banner.link,\n };\n};\n\n/**\n * The OG card's brand mark: a `seo.og.logo` of `false` opts out of any mark,\n * a configured SVG wins over the site logo, and a non-SVG value resolves to\n * `undefined` (the card falls back to the accent-initial tile).\n */\nconst resolveOgMark = (\n project: BlumeProject,\n siteLogo: string | undefined\n): string | false | undefined => {\n const configured = project.config.seo.og.logo;\n if (configured === false) {\n return false;\n }\n if (configured) {\n return resolveOgLogo(project, configured);\n }\n return siteLogo;\n};\n\n/**\n * The OG card's footer site text. A `seo.og.site` override wins (`false`\n * hides it); the default is the deployment site's host plus the normalized\n * deployment base — on a subpath deploy (a GitHub Pages project site) the\n * bare host is the platform's shared apex, not this site (#139).\n */\nconst resolveOgSite = (config: ResolvedConfig): string | undefined => {\n const configured = config.seo.og.site;\n if (configured === false) {\n return;\n }\n if (configured !== undefined) {\n return configured;\n }\n return config.deployment.site\n ? `${new URL(config.deployment.site).host}${normalizeBasePath(\n config.deployment.base\n )}`\n : undefined;\n};\n\n/**\n * The OG card's site-wide subtitle: `seo.og.description` (`false` omits it)\n * over the site description. The generated endpoint prefers a page's own\n * description and falls back to this.\n */\nconst resolveOgDescription = (config: ResolvedConfig): string | undefined => {\n const configured = config.seo.og.description;\n if (configured === false) {\n return;\n }\n return configured ?? config.description;\n};\n\n/**\n * Repo coordinates for content components. `host` and the derived `api` ride\n * along so a card on an Enterprise site links and queries that instance rather\n * than the public one.\n */\nconst resolveGithubData = (\n github: ResolvedConfig[\"github\"]\n): BlumeData[\"config\"][\"github\"] =>\n github\n ? {\n api: githubApiUrl(github),\n host: github.host,\n owner: github.owner,\n repo: github.repo,\n }\n : null;\n\n/** Serialize the content graph into the data module the runtime consumes. */\nexport const buildRuntimeData = (project: BlumeProject): string => {\n const { config, context, graph, manifest } = project;\n const { github } = config;\n const repoUrl = github ? githubRepoUrl(github) : null;\n const editBase = github ? githubEditBaseUrl(github) : null;\n const logo = resolveLogo(project);\n const ogLogo = resolveOgMark(project, logo?.svg);\n\n const editUrlFor = (sourcePath?: string): string | null => {\n if (!(editBase && sourcePath)) {\n return null;\n }\n const rel = relative(context.root, sourcePath).split(\"\\\\\").join(\"/\");\n // The edit path is repo-relative: `github.dir` places the project inside\n // the repo, so a source above the project dir (a monorepo vault beside the\n // docs app) still resolves to an in-repo file. A path that escapes the\n // repo itself has nothing to edit — fabricating one yields a 404 link.\n // `dir` is a bare string in the schema, so a leading slash (`/apps/docs`)\n // is trimmed rather than read as an absolute path — which would drop the\n // link from every page of a site that has always written it that way.\n const editDir = trimChar(github?.dir ?? \"\", \"/\");\n const editPath = normalize(editDir ? join(editDir, rel) : rel);\n if (editPath.startsWith(\"..\") || isAbsolute(editPath)) {\n return null;\n }\n return `${editBase}/${editPath}`;\n };\n\n const { i18n } = config;\n\n // Resolve the header repo link per locale. API references no longer add a tab\n // automatically — authors point a `navigation.tabs` entry at the reference\n // route to surface it (see `referenceRoutes`).\n const markUrl = headerRepoUrl(config.navigation.repo, repoUrl);\n const withRepoUrl = (nav: Navigation): Navigation => ({\n ...nav,\n repoUrl: markUrl,\n });\n\n // Resolved UI dictionaries: one per locale under i18n, English baseline\n // otherwise. Threaded into chrome so the catch-all can pick the active locale.\n const uiByLocale = i18n\n ? Object.fromEntries(\n i18n.locales.map(({ code }) => [\n code,\n resolveUIStrings(code, {\n defaultLocale: i18n.defaultLocale,\n overrides: i18n.ui,\n }),\n ])\n )\n : {};\n const defaultUi = i18n\n ? resolveUIStrings(i18n.defaultLocale, {\n defaultLocale: i18n.defaultLocale,\n overrides: i18n.ui,\n })\n : EN_UI;\n\n const navigationByLocale = i18n\n ? Object.fromEntries(\n i18n.locales.map(({ code }) => [\n code,\n withRepoUrl(\n graph.navigationByLocale[code] ?? {\n actions: [],\n cta: null,\n featured: [],\n selectors: [],\n sidebar: [],\n tabs: [],\n }\n ),\n ])\n )\n : {};\n\n const data: BlumeData = {\n config: {\n analytics: config.analytics ?? null,\n appleIcon: resolveAppleIcon(project),\n ask: config.ai.ask?.enabled\n ? {\n endpoint: config.ai.ask.endpoint ?? null,\n suggestions: config.ai.ask.suggestions,\n }\n : null,\n banner: resolveBanner(config),\n basePath: config.basePath,\n codeThemes: config.markdown.codeBlocks.theme,\n codeWrap: config.markdown.code.wrap,\n dateFormat: config.dateFormat,\n description: config.description,\n discovery: {\n agentReadability: config.seo.agentReadability,\n api: config.ai.api,\n llmsTxt: config.ai.llmsTxt.enabled,\n // Mirrors `buildSitemapFiles`: no site, no sitemap.\n sitemap: config.seo.sitemap && Boolean(config.deployment.site),\n },\n favicon: resolveFavicon(project),\n feedback: config.feedback,\n github: resolveGithubData(github),\n i18n: i18n\n ? {\n defaultLocale: i18n.defaultLocale,\n // The locale fallback content is rendered from, so the catch-all can\n // set the content direction to the language it's actually written in.\n fallbackLocale: resolveFallbackLocale(i18n),\n hideDefaultLocalePrefix: i18n.hideDefaultLocalePrefix,\n locales: i18n.locales.map(({ code, dir, label }) => ({\n code,\n dir,\n label,\n })),\n }\n : null,\n // `undefined` members drop out of the JSON snapshot; the null keeps the\n // \"nothing configured\" case explicit for the layouts.\n identity:\n config.seo.organization || config.seo.software\n ? {\n organization: config.seo.organization,\n software: config.seo.software,\n }\n : null,\n imageZoom: config.markdown.imageZoom,\n logo,\n mcp: config.ai.mcp.enabled\n ? {\n name: config.ai.mcp.name ?? config.title,\n route: config.ai.mcp.route,\n }\n : null,\n // `og.enabled` is resolved to a definite boolean in `loadConfig`; coerce\n // the optional schema type so the serialized shape stays `boolean`.\n // Card fonts are baked into the generated OG endpoint (they can carry\n // absolute build-machine paths), not serialized here — this snapshot\n // ends up in every page's client data.\n og: {\n description: resolveOgDescription(config),\n enabled: config.seo.og.enabled ?? false,\n logo: ogLogo,\n palette: config.seo.og.palette,\n site: resolveOgSite(config),\n },\n openInChat: config.ai.openInChat,\n repoUrl,\n search: {\n enabled: config.search.provider !== \"none\",\n popular: resolveSearchPopular(config.search.popular, config.basePath),\n provider: config.search.provider,\n },\n site: config.deployment.site ?? null,\n structuredData: config.seo.structuredData,\n theme: config.theme,\n title: config.title,\n toc: config.toc,\n versions: config.versions ?? null,\n webmcp: {\n enabled: config.ai.webmcp,\n llms: config.ai.llmsTxt.enabled,\n },\n x: config.seo.x,\n },\n feeds: buildRssFeeds(project).map((feed) => ({\n href: feed.path,\n title: feed.title,\n })),\n // CSS variables for Astro's <Font> component; matches the astro.config\n // `fonts:` entries derived from the same theme.fonts config (and the\n // same locale-derived subsets, so preloads cover the scripts pages use).\n fontCssVars: configuredFonts(\n config.theme.fonts,\n fontLocaleCodes(config.i18n)\n ),\n navigation: withRepoUrl(graph.navigation),\n // Per-locale navigation; the catch-all selects the active locale's tree.\n navigationByLocale,\n // Per-archived-version navigation; the catch-all selects by the route's\n // version, then locale.\n navigationByVersion: Object.fromEntries(\n Object.entries(graph.navigationByVersion).map(([id, byLocale]) => [\n id,\n Object.fromEntries(\n Object.entries(byLocale).map(([code, nav]) => [\n code,\n withRepoUrl(nav),\n ])\n ),\n ])\n ),\n routes: manifest.routes.map((route) => ({\n alternates: route.alternates,\n collection: route.collection,\n description: route.description ?? null,\n draft: route.draft,\n editUrl: route.editUrl ?? editUrlFor(route.sourcePath),\n entryId: route.entryId,\n fallback: route.fallback ?? false,\n hidden: route.hidden,\n id: route.id,\n indexable: route.indexable,\n lastModified: route.lastModified ?? null,\n locale: route.locale,\n path: route.path,\n title: route.title,\n version: route.version,\n versionAlternates: route.versionAlternates,\n })),\n // Default-locale chrome strings (English baseline when not under i18n).\n ui: defaultUi,\n // Per-locale chrome strings, selected by the catch-all under i18n.\n uiByLocale,\n };\n return `${JSON.stringify(data, null, 2)}\\n`;\n};\n\n/** The resolved plan for the hosted MCP server within a single generate pass. */\ninterface McpPlan {\n /** Directory holding the injected discovery endpoints (`.blume/src/blume-mcp`). */\n dir: string;\n /** `.well-known` discovery routes to inject as prerendered pages. */\n discoveryPages: { entrypoint: string; pattern: string }[];\n enabled: boolean;\n route: string;\n srcDir: string;\n warnings: string[];\n}\n\n/**\n * Decide whether (and how) to generate the MCP server. Skipped — with a\n * warning — when a content page or a custom `.astro` page already occupies its\n * route, so the user's page keeps working instead of colliding.\n */\nconst planMcp = (\n project: BlumeProject,\n srcDir: string,\n userPages: { pattern: string }[]\n): McpPlan => {\n const { config } = project;\n const { route } = config.ai.mcp;\n const dir = join(srcDir, \"blume-mcp\");\n const base: McpPlan = {\n dir,\n discoveryPages: [],\n enabled: false,\n route,\n srcDir,\n warnings: [],\n };\n if (!config.ai.mcp.enabled) {\n return base;\n }\n if (routeIsTaken(userPages, project.graph.pages, route)) {\n return {\n ...base,\n warnings: [\n `MCP server route \"${route}\" is already used by a content or custom page; the MCP server was not generated. Set a different \"ai.mcp.route\" in blume.config.ts.`,\n ],\n };\n }\n return {\n ...base,\n discoveryPages: [\n {\n entrypoint: join(dir, \"discovery.ts\"),\n pattern: \"/.well-known/mcp.json\",\n },\n {\n entrypoint: join(dir, \"server-card.ts\"),\n pattern: \"/.well-known/mcp/server-card.json\",\n },\n ],\n enabled: true,\n };\n};\n\n/** A pass's runtime data modules, published together once every writer ran. */\ntype RuntimeModules = Map<RuntimeModuleId, string>;\n\n/**\n * The agent data snapshot (`blume:mcp-data`) behind the MCP server and the\n * JSON docs API: built once per pass when either is on, published to the\n * runtime modules, and handed to both writers. Null when neither needs it.\n */\nconst publishAgentData = async (\n project: BlumeProject,\n plans: { api: ApiPlan; mcp: McpPlan },\n modules: RuntimeModules\n): Promise<McpData | null> => {\n if (!(plans.mcp.enabled || plans.api.enabled)) {\n return null;\n }\n const data = await buildMcpData(project);\n modules.set(\"blume:mcp-data\", JSON.stringify(data));\n return data;\n};\n\n/** Write the MCP server endpoint and discovery documents. */\nconst writeMcpFiles = async (\n plan: McpPlan,\n write: (path: string, content: string) => Promise<boolean>,\n data: McpData | null\n): Promise<void> => {\n if (!(plan.enabled && data)) {\n return;\n }\n const discoveryInput = {\n base: data.base,\n name: data.name,\n route: plan.route,\n site: data.site,\n version: data.version,\n };\n await Promise.all([\n write(\n join(plan.srcDir, \"pages\", mcpPageFile(plan.route)),\n mcpEndpointTemplate()\n ),\n write(\n join(plan.dir, \"discovery.ts\"),\n staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))\n ),\n write(\n join(plan.dir, \"server-card.ts\"),\n staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput))\n ),\n ]);\n};\n\n/** The resolved plan for the JSON docs API within a single generate pass. */\ninterface ApiPlan {\n /**\n * Whether the `/api/` catch-all (JSON 404s) is written: server output, no\n * user page owning a rest route under `/api/`, and no content page served\n * from the `/api` namespace (the catch-all would outrank those pages).\n */\n catchAll: boolean;\n enabled: boolean;\n /** Whether the live endpoints (search) are written — server output only. */\n server: boolean;\n /**\n * Whether `/openapi.json` is generated: skipped when a `public/openapi.json`\n * or a user page owns the route, so a site can publish its own description.\n */\n spec: boolean;\n srcDir: string;\n}\n\n/** Whether a user page pattern is a rest route under `/api/` (`/api/[...x]`). */\nconst ownsApiRest = (page: { pattern: string }): boolean =>\n page.pattern.startsWith(\"/api/[\");\n\n/**\n * Whether a content route lives in the `/api` namespace — a docs section\n * about an API commonly does (`content/api/overview.md` → `/api/overview`).\n * Astro ranks `/api/[...path]` above the content catch-all (`/[...slug]`),\n * so the JSON 404 route would shadow those pages wherever routing decides\n * (the dev server, adapters that don't serve prerendered files first).\n */\nconst contentUnderApi = (page: { route: string }): boolean =>\n page.route === \"/api\" || page.route.startsWith(\"/api/\");\n\n/**\n * Decide what the JSON docs API generates. The prerendered endpoints always\n * ride along when the feature is on (they live under Blume's own `/api/docs/`\n * namespace); the live ones need server output; the OpenAPI description yields\n * to one the project ships itself.\n */\nconst planApi = (\n project: BlumeProject,\n srcDir: string,\n userPages: { pattern: string }[]\n): ApiPlan => {\n const { config, context } = project;\n const server = config.deployment.output === \"server\";\n return {\n catchAll:\n server &&\n !userPages.some(ownsApiRest) &&\n !project.graph.pages.some(contentUnderApi),\n enabled: config.ai.api,\n server,\n spec:\n !routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) &&\n !existsSync(join(context.root, \"public\", \"openapi.json\")),\n srcDir,\n };\n};\n\n/**\n * Write the JSON docs API: the prerendered page index, per-page documents, and\n * navigation; on server output the search endpoint and the `/api/` catch-all;\n * and the OpenAPI description of the whole agent-facing surface. The MCP\n * route reaches the description only when the server was actually planned (a\n * collision can disable it), so it never advertises an endpoint that isn't\n * there.\n */\nconst writeApiFiles = async (\n project: BlumeProject,\n plan: ApiPlan,\n write: (path: string, content: string) => Promise<boolean>,\n data: McpData | null,\n mcp: McpPlan\n): Promise<void> => {\n if (!(plan.enabled && data)) {\n return;\n }\n const { config } = project;\n const mcpRoute = mcp.enabled ? mcp.route : null;\n const apiDir = join(plan.srcDir, \"pages\", \"api\");\n const writes = [\n write(join(apiDir, \"docs\", \"pages.json.ts\"), apiPagesIndexTemplate()),\n write(\n join(apiDir, \"docs\", \"pages\", \"[...route].json.ts\"),\n apiPageTemplate()\n ),\n write(join(apiDir, \"docs\", \"navigation.json.ts\"), apiNavigationTemplate()),\n ];\n if (plan.server) {\n writes.push(write(join(apiDir, \"docs\", \"search.ts\"), apiSearchTemplate()));\n }\n if (plan.catchAll) {\n writes.push(\n write(\n join(apiDir, \"[...path].ts\"),\n apiNotFoundTemplate({ base: data.base, site: data.site })\n )\n );\n }\n if (plan.spec) {\n writes.push(\n write(\n join(plan.srcDir, \"pages\", \"openapi.json.ts\"),\n staticJsonEndpointTemplate(\n buildApiSpec({\n agentReadability: config.seo.agentReadability,\n base: data.base,\n description: config.description,\n llmsTxt: config.ai.llmsTxt.enabled,\n mcpRoute,\n name: config.title,\n search: plan.server,\n site: data.site,\n version: data.version,\n })\n )\n )\n );\n }\n await Promise.all(writes);\n};\n\n/**\n * Decide whether to generate the playground's built-in CORS proxy endpoint.\n * Only the Blume renderer's playground with `proxy: true` needs it — a proxy\n * URL string points at an external service, and `false` sends requests\n * directly. Injected at `/_api-proxy` (rather than written under `pages/`)\n * because Astro treats `_`-prefixed page files as private; the endpoint's own\n * `prerender = false` export wins over the injection default.\n */\nconst planPlaygroundProxy = (config: ResolvedConfig, srcDir: string) => ({\n enabled: needsPlaygroundProxy(config),\n entrypoint: join(srcDir, \"blume-openapi\", \"api-proxy.ts\"),\n pattern: \"/_api-proxy\",\n});\n\n/**\n * The origins the built-in proxy is allowed to reach: one per absolute\n * `servers[].url` across the parsed specs. This is the endpoint's whole trust\n * boundary — the client sends the target as a query parameter, and a reader's\n * custom base URL is not a documented server — so it is derived here, at build\n * time, from the same documents the operation pages render.\n *\n * Relative (`/v1`) and templated (`{env}.api.example.com`) server URLs carry no\n * origin to allow and are skipped; AsyncAPI documents declare `servers` as a\n * map and contribute nothing (the proxy is OpenAPI-only).\n */\nconst specOriginsOf = (spec: ApiSpecData): string[] => {\n const origins = new Set<string>();\n // A GraphQL schema names no servers; its configured live endpoint is the\n // one origin the playground targets.\n if (spec.endpoint !== undefined) {\n try {\n origins.add(new URL(spec.endpoint).origin);\n } catch {\n // Not an absolute URL: nothing to allow.\n }\n }\n // SAFETY: `document` is arbitrary parsed JSON; the assertion only names\n // the optional `servers` shape, and every access below re-checks it —\n // `Array.isArray(servers)` guards the list and `server.url ?? \"\"` the url.\n const { servers } = spec.document as { servers?: { url?: string }[] };\n for (const server of Array.isArray(servers) ? servers : []) {\n const url = server.url ?? \"\";\n // `new URL(\"https://{region}.api.example.com\")` parses — the braces land\n // in the hostname — so templated URLs need an explicit check or their\n // junk literal becomes an allowlist entry no real request can match.\n if (url.includes(\"{\")) {\n continue;\n }\n try {\n origins.add(new URL(url).origin);\n } catch {\n // Not an absolute URL: nothing to allow.\n }\n }\n return [...origins];\n};\n\nconst specOrigins = (data: OpenApiData): string[] =>\n [...new Set(Object.values(data).flatMap(specOriginsOf))].toSorted();\n\n/**\n * Build-time diagnostics for playground sends the built-in proxy would refuse.\n * The baked-in allowlist pools every documented origin, but each spec's\n * playground only ever targets that spec's own servers/endpoint — so a\n * non-empty pool can still leave one spec's Send 403ing on every request.\n * Hence the check is per spec: any spec routed through the built-in proxy\n * whose own origins came out empty (no absolute `servers[].url`, no absolute\n * GraphQL `endpoint`) gets a warning naming it.\n */\nconst proxyAllowlistWarnings = (\n config: ResolvedConfig,\n data: OpenApiData\n): string[] => {\n const kinds = builtinProxyKinds(config);\n const warnings: string[] = [];\n for (const spec of Object.values(data)) {\n if (!kinds.includes(spec.kind) || specOriginsOf(spec).length > 0) {\n continue;\n }\n warnings.push(\n spec.kind === \"graphql\"\n ? `The \"${spec.label}\" GraphQL reference (${spec.route}) has playground.proxy: true, but no absolute endpoint is configured for it, so the built-in proxy has no origin to allow and will refuse every request its playground sends. Set the graphql block's (or the source's) \\`endpoint\\` to the live GraphQL URL, or point playground.proxy at an external proxy URL.`\n : `The \"${spec.label}\" reference (${spec.route}) has playground.proxy: true, but its spec declares no absolute servers[].url (relative and templated URLs carry no origin), so the built-in proxy has no origin to allow and will refuse every request its playground sends. Add an absolute server URL to the spec, or point playground.proxy at an external proxy URL.`\n );\n }\n return warnings;\n};\n\n/**\n * Write the Ask AI endpoint and, unless the backend runs its own retrieval\n * (Inkeep), the grounding snapshot the endpoint queries at request time. A no-op\n * when Ask AI is disabled.\n */\nconst writeAskFiles = async (\n project: BlumeProject,\n srcDir: string,\n write: (path: string, content: string) => Promise<boolean>,\n modules: RuntimeModules\n): Promise<void> => {\n const { ask } = project.config.ai;\n if (!(ask?.enabled && !ask.endpoint)) {\n return;\n }\n const grounded = ask.provider !== \"inkeep\";\n if (grounded) {\n modules.set(\"blume:ask-data\", JSON.stringify(await buildAskData(project)));\n }\n await write(\n join(srcDir, \"pages\", \"api\", \"ask.ts\"),\n askEndpointTemplate(resolveAskBackend(ask), grounded, {\n instructions: ask.instructions,\n retrieval: ask.retrieval,\n })\n );\n};\n\n/**\n * Write the default 404 page at Astro's reserved `src/pages/404.astro` path so\n * static builds emit `dist/404.html`, plus its Markdown twin at `404.md.ts`\n * (`dist/404.md`) for agents that ask a missing URL for Markdown and its JSON\n * twin at `404.json.ts` (`dist/404.json`, RFC 9457 problem details) for those\n * that ask for JSON. All three are skipped when the project already owns\n * `/404` (a custom `pages/404.astro` or a `404.md` content page), letting it\n * be fully overridden without a route collision; `pruneOrphans` then removes\n * any previously-generated copies.\n */\nconst writeNotFoundPage = async (\n write: (path: string, content: string) => Promise<boolean>,\n srcDir: string,\n pages: { pattern: string }[],\n contentPages: { route: string }[]\n): Promise<void> => {\n if (routeIsTaken(pages, contentPages, \"/404\")) {\n return;\n }\n await Promise.all([\n write(join(srcDir, \"pages\", \"404.astro\"), notFoundPageTemplate()),\n write(join(srcDir, \"pages\", \"404.md.ts\"), notFoundMarkdownTemplate()),\n write(join(srcDir, \"pages\", \"404.json.ts\"), notFoundJsonTemplate()),\n ]);\n};\n\n/**\n * Flatten a diagnostic to a single warning line, appending the suggestion when\n * one exists. Exported for testing.\n */\nexport const diagnosticWarning = (diagnostic: Diagnostic): string =>\n diagnostic.suggestion\n ? `${diagnostic.message} ${diagnostic.suggestion}`\n : diagnostic.message;\n\nexport interface GenerateResult {\n /** Whether any structural file changed (config/page/content config). */\n structuralChange: boolean;\n /** Non-fatal warnings raised while generating (e.g. a missing API spec). */\n warnings: string[];\n}\n\n/**\n * Statically analyze the user's `components.ts` (never executing it) and plan the\n * generated `components.ts` module plus any hydration wrappers. Returns the plan\n * and the analyzer's warnings; a project with no components file gets an empty\n * plan and no warnings.\n */\nconst buildComponentSlots = async (\n componentsFile: string | null\n): Promise<{\n plan: ComponentSlotPlan;\n /** MDX tags the overrides define (for the unknown-component check). */\n tags: string[];\n warnings: string[];\n}> => {\n const analysis = componentsFile\n ? analyzeComponentOverrides(\n await readFile(componentsFile, \"utf-8\"),\n componentsFile\n )\n : null;\n return {\n plan: planComponentSlots(componentsFile, analysis),\n tags: analysis\n ? [...analysis.mdx, ...analysis.islands].map((entry) => entry.key)\n : [],\n warnings: analysis ? analysis.warnings : [],\n };\n};\n\n/** The OG endpoint fonts for a scanned project (see {@link resolveOgFonts}). */\nconst projectOgFonts = (project: BlumeProject): DerivedOgFonts =>\n resolveOgFonts(\n {\n ogFonts: project.config.seo.og.fonts,\n themeFonts: project.config.theme.fonts,\n themeFontsConfigured: project.themeFontsConfigured,\n },\n project.context.root\n );\n\n/**\n * Fail generation when a configured local font file is missing. Warning and\n * continuing is not an option here — the path is emitted into the Astro\n * config and the OG endpoint, which would crash later with a bare ENOENT.\n */\nconst assertFontFilesExist = (project: BlumeProject): void => {\n const { config, context } = project;\n const missing = missingFontFiles(\n { ogFonts: config.seo.og.fonts ?? [], themeFonts: config.theme.fonts },\n context.root\n );\n if (missing.length > 0) {\n throw new BlumeError({\n code: \"BLUME_FONT_FILE_MISSING\",\n message: `Configured font file(s) not found: ${missing.join(\", \")}. Font paths resolve relative to the project root.`,\n severity: \"error\",\n });\n }\n};\n\n/**\n * The client libraries a site needs (see `featuresTemplate`): the EPUB\n * generator when `export.epub` is on, and the Mermaid element when any page's\n * source has a mermaid fence — read from the raw-Markdown mirrors (every\n * route's verbatim source) and, for sources that carry their text on the\n * page record, the record itself.\n */\nexport const clientFeaturesFrom = (\n project: BlumeProject,\n rawMarkdown: Record<string, RawMarkdownEntry>\n): ClientFeatures => ({\n epub: project.config.export.epub,\n mermaid:\n Object.values(rawMarkdown).some((entry) =>\n hasMermaidFence(entry.mdx ?? entry.md ?? \"\")\n ) ||\n project.graph.pages.some(\n (page) => page.body !== undefined && hasMermaidFence(page.body.text)\n ),\n});\n\n/**\n * The theme's code-block icon rules for the languages the site's Markdown\n * uses (see `languageIconCss`), read from the raw-Markdown mirrors and the\n * page records that carry their text.\n */\nexport const languageIconCssFrom = (\n project: BlumeProject,\n rawMarkdown: Record<string, RawMarkdownEntry>\n): string =>\n languageIconCss(\n languageIconSlugsIn(\n [\n ...Object.values(rawMarkdown).map(\n (entry) => entry.mdx ?? entry.md ?? \"\"\n ),\n ...project.graph.pages.map((page) => page.body?.text ?? \"\"),\n ].join(\"\\n\")\n )\n );\n\n/** {@link languageIconCssFrom} over a fresh read of the raw Markdown (eject). */\nexport const languageIconCssFor = async (\n project: BlumeProject\n): Promise<string> =>\n languageIconCssFrom(project, await buildRawMarkdown(project));\n\n/**\n * The deferred sidebar fragments page, only when some group is a disclosure\n * or a drill-in panel — a flat sidebar renders every row on every page, so\n * there is nothing to fetch. A previous pass's page is an orphan the\n * generator removes when the sidebar goes flat again.\n */\nconst writeNavFragments = (\n write: (path: string, content: string) => Promise<boolean>,\n srcDir: string,\n navFragments: boolean\n): Promise<boolean> =>\n navFragments\n ? write(\n join(\n srcDir,\n \"pages\",\n \"blume-nav\",\n \"[version]\",\n \"[locale]\",\n \"[id].astro\"\n ),\n navFragmentTemplate()\n )\n : Promise.resolve(false);\n\n/** {@link clientFeaturesFrom} over a fresh read of the raw Markdown (eject). */\nexport const clientFeaturesFor = async (\n project: BlumeProject\n): Promise<ClientFeatures> =>\n clientFeaturesFrom(project, await buildRawMarkdown(project));\n\n/**\n * Write (or update) the generated `.blume/` Astro runtime for a project.\n * Only files whose content changed are rewritten so Vite HMR stays fast.\n */\nexport const generateRuntime = async (\n project: BlumeProject\n): Promise<GenerateResult> => {\n const { context, config } = project;\n assertFontFilesExist(project);\n const out = context.outDir;\n const srcDir = join(out, \"src\");\n const generatedDir = join(srcDir, \"generated\");\n const askPath = join(srcDir, \"generated\", \"Ask.astro\");\n const themePath = join(srcDir, \"generated\", \"app.css\");\n const searchClientPath = join(srcDir, \"generated\", \"search-client.ts\");\n const featuresPath = join(srcDir, \"generated\", \"features.ts\");\n const examplesPath = join(srcDir, \"generated\", \"examples.ts\");\n const examplesThemePath = join(srcDir, \"generated\", \"examples.css\");\n\n // Record every file this pass writes so orphans (from a now-disabled feature)\n // can be pruned afterwards. `write` wraps the atomic writer and tracks paths.\n const written = new Set<string>();\n const write = (path: string, content: string): Promise<boolean> => {\n written.add(normalize(path));\n return writeIfChanged(path, content);\n };\n // The data snapshots the generated pages import (`blume:data`, the search\n // index, …) are collected here and published in memory at the end of the\n // pass — see `runtime-modules.ts`. An id a feature leaves unset is\n // unpublished, the in-memory counterpart of `pruneOrphans`.\n const modules: RuntimeModules = new Map();\n\n const depsLinkWarning = await ensureDepsLink(out);\n\n // The dev negotiation inputs. Published in memory (below) rather than baked\n // into the generated config, so a content-route change never rewrites\n // `astro.config.mjs` — which would restart the dev server in place.\n const contentRoutes = markdownRoutePaths(project);\n const homeLinkHeader =\n buildHomeLinkHeader(config, contentRoutes) ?? undefined;\n\n const askEnabled = config.ai.ask?.enabled ?? false;\n const exportPdf = config.export.pdf;\n const exportEpub = config.export.epub;\n // Every route's source Markdown: published as `blume:raw-markdown` below,\n // and inspected here for the client features the site needs.\n const rawMarkdown = await buildRawMarkdown(project);\n const clientFeatures = clientFeaturesFrom(project, rawMarkdown);\n const navFragments = navVariants(project.graph).some(({ navigation }) =>\n hasDeferrableGroups(navigation.sidebar)\n );\n const languageIcons = languageIconCssFrom(project, rawMarkdown);\n // Staged (non-filesystem) sources materialize into `.blume/content`; keyed by\n // entryId so i18n duplicates of one entry write a single file. Collected here\n // so math detection also sees staged bodies (they never live under root).\n const staged = collectStaged(project);\n // Statically analyze `components.ts` overrides (never executed): drives the\n // `islands` group, hydration on layout/mdx overrides, string-path resolution,\n // and the \"framework component with no client mode\" diagnostic. Independent of\n // the discovery reads, so it joins the same parallel batch.\n const [\n pages,\n detectedReact,\n usesMath,\n userTheme,\n userExamplesCss,\n integrationBridge,\n islandDiscovery,\n exampleDiscovery,\n componentSlots,\n ] = await Promise.all([\n context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),\n detectNeedsReact(context.root),\n detectUsesMath(context.root, staged.values()),\n readUserCss(context.themeFile, generatedDir),\n readUserCss(examplesCssFile(context.root, config), generatedDir),\n loadIntegrationBridge(config, context),\n discoverIslands(context.root),\n discoverExamples(context.root, config.examples.source),\n buildComponentSlots(context.componentsFile),\n ]);\n const {\n plan: slotPlan,\n tags: overrideTags,\n warnings: overrideWarnings,\n } = componentSlots;\n // Expose the discovered examples for agent-facing Markdown downleveling\n // (`<Component>` → source) before any consumer (raw `.md`, MCP, llms) runs.\n project.examples = exampleMarkdownLookup(exampleDiscovery.examples);\n\n // Each island/example framework enables its Astro renderer. React also\n // switches on for any project `.tsx`/`.jsx` and for Ask AI; Vue/Svelte are\n // island/example-driven. `.astro` examples need no renderer. Component\n // overrides referencing a framework component enable its renderer too.\n const frameworks = new Set<string>([\n ...islandDiscovery.islands.map((island) => island.framework),\n ...exampleDiscovery.examples.map((example) => example.framework),\n ...slotPlan.frameworks,\n ]);\n const needsReact = detectedReact || askEnabled || frameworks.has(\"react\");\n const needsVue = frameworks.has(\"vue\");\n const needsSvelte = frameworks.has(\"svelte\");\n\n // Absolute path to the React Compiler babel plugin (null when off). Resolved\n // here, Node-side, so the generated config points babel straight at Blume's\n // shipped copy — see resolveReactCompiler. Any unresolved-but-requested\n // warning is folded into `warnings` below (declared later).\n const reactCompilerPath = resolveReactCompiler(config, needsReact);\n\n // Custom pages that should get a generated OG card (the home most of all).\n // Computed before the MCP `.well-known` routes are appended below — those are\n // private and filtered out anyway, but the intent is the user's pages.\n const ogRoutes = customOgRoutes(pages, config.title, config.seo.og.titles);\n\n // Whether the generated `/changelog` index exists — shared by the OG endpoint\n // (which adds the index's own card) and the page write below. Computed here,\n // before the MCP discovery pages are appended, on the user's own pages.\n const changelogIndex = hasGeneratedChangelog(project, pages);\n\n // The hosted MCP server. The `.well-known` discovery docs are injected as\n // prerendered routes alongside user pages; the server endpoint itself is a\n // normal (server-rendered) page written by `writeMcpFiles`.\n const mcp = planMcp(project, srcDir, pages);\n pages.push(...mcp.discoveryPages);\n\n // The JSON docs API shares the MCP server's snapshot; build it once when\n // either is on.\n const api = planApi(project, srcDir, pages);\n const agentData = await publishAgentData(project, { api, mcp }, modules);\n\n // The parsed OpenAPI specs behind the `blume:openapi` alias, also the source\n // of the proxy's origin allowlist below. The source parsed them during the\n // scan, so reading them here is free.\n const openApiSource = project.sources.find(isOpenApiSource);\n const openApiData = openApiSource ? openApiSource.openApiData() : {};\n\n // The playground's built-in CORS proxy rides the same injection path as the\n // MCP discovery docs; the endpoint itself opts out of prerendering.\n const playgroundProxy = planPlaygroundProxy(config, srcDir);\n if (playgroundProxy.enabled) {\n pages.push({\n entrypoint: playgroundProxy.entrypoint,\n pattern: playgroundProxy.pattern,\n });\n }\n // Computed once: the endpoint template bakes it in below. A spec that\n // contributes no origin of its own gets a per-spec diagnostic\n // (`proxyAllowlistWarnings`) — the proxy would refuse its every send.\n const proxyOrigins = specOrigins(openApiData);\n\n const hasStaged = staged.size > 0;\n // Only emit a project-scanning `docs` collection when a filesystem source\n // actually feeds it. An all-staged project (openapi/notion/…) has only staged\n // sources, so the `docs` glob would otherwise scan (and watch) the whole\n // project root for nothing — see contentConfigTemplate.\n const hasFilesystemSource = project.sources.some((source) => !source.staged);\n const docsCollection = resolveDocsCollection(config, context);\n\n // All of these write to distinct generated paths and never read one another's\n // output, so the structural files, the per-convention hydration wrappers, and\n // the Ask/MCP writers all run in one parallel batch. Only the structural\n // writes' change flags feed `structuralChange`, so they stay a nested group.\n const [structural] = await Promise.all([\n Promise.all([\n write(\n join(out, \"astro.config.mjs\"),\n astroConfigTemplate({\n aliases: resolveTsconfigAliases(context.root),\n askPath,\n config,\n contentRoot: docsCollection.base,\n contentRoutes,\n context,\n examplesPath,\n examplesThemePath,\n features: clientFeatures,\n featuresPath,\n integrationBridge,\n needsReact,\n needsSvelte,\n needsVue,\n pages,\n reactCompilerPath,\n searchClientPath,\n themePath,\n })\n ),\n write(\n join(out, \"package.json\"),\n runtimePackageTemplate(\n runtimeDependencies({ config, needsReact, needsSvelte, needsVue })\n )\n ),\n write(join(out, \"tsconfig.json\"), runtimeTsconfigTemplate()),\n write(\n join(srcDir, \"content.config.ts\"),\n contentConfigTemplate({\n collection: docsCollection,\n config,\n context,\n filesystem: hasFilesystemSource,\n staged: hasStaged,\n })\n ),\n write(\n join(srcDir, \"pages\", \"[...slug].astro\"),\n catchAllPageTemplate({\n exportEpub,\n exportPdf,\n mathEnabled: usesMath,\n navFragments,\n needsReact,\n })\n ),\n writeNavFragments(write, srcDir, navFragments),\n // The header's Ask trigger, behind the `blume:ask` alias. Always written\n // (even when Ask is off, as a component that renders nothing) so the alias\n // resolves — the same contract as `blume:search-client`.\n write(askPath, askComponentTemplate(askEnabled)),\n write(join(srcDir, \"generated\", \"components.ts\"), slotPlan.module),\n write(\n join(srcDir, \"generated\", \"islands.ts\"),\n islandMapTemplate(islandDiscovery.islands)\n ),\n write(\n join(srcDir, \"generated\", \"examples.ts\"),\n exampleMapTemplate(exampleDiscovery.examples, config.basePath)\n ),\n // The isolated Tailwind entry for `<Component />` preview frames: only\n // the project (and an out-of-root examples directory) is scanned, so the\n // docs theme never reaches a preview. Anything further afield — a sibling\n // package the examples import — is the user's `@source` in examples.css.\n write(\n examplesThemePath,\n examplesEntryTemplate({\n configTokens: buildThemeCss(config.theme),\n sources: exampleScanRoots(context.root, exampleDiscovery.dir).map(\n (dir) => `${dir}/${EXAMPLE_SCAN_GLOB}`\n ),\n userCss: userExamplesCss,\n })\n ),\n write(\n themePath,\n tailwindEntryTemplate({\n configTokens: `${buildThemeCss(config.theme)}${buildFontsCss(config.theme.fonts)}`,\n languageIcons,\n sources: [\n `${BLUME_SRC}/**/*.{astro,ts,tsx}`,\n `${context.root}/**/*.{astro,mdx,ts,tsx}`,\n ],\n twoslashCss: twoslashCss(),\n userTheme,\n })\n ),\n ]),\n // Per-island hydration wrappers for the `islands/` convention. The map\n // module (written above, always) imports these; orphans from removed\n // islands are pruned at the end of the pass.\n Promise.all(\n islandDiscovery.islands.map((island) =>\n write(\n join(srcDir, \"generated\", \"islands\", `${island.name}.astro`),\n islandWrapperTemplate(island)\n )\n )\n ),\n // Per-override hydration wrappers for `defineComponents` islands and\n // `client:*` layout/mdx overrides. The generated `components.ts` (written\n // above) imports these; orphans from removed overrides are pruned at the\n // end of the pass.\n Promise.all(\n slotPlan.wrappers.map((wrapper) =>\n write(\n join(srcDir, \"generated\", \"component-slots\", `${wrapper.name}.astro`),\n wrapper.content\n )\n )\n ),\n // Per-example live wrappers for the `examples/` convention, resolved by\n // `<Component path>` through the `examples.ts` map (written above, always).\n Promise.all(\n exampleDiscovery.examples.map((example) =>\n write(\n join(\n srcDir,\n \"generated\",\n \"examples\",\n `${exampleSlug(example.path)}.astro`\n ),\n exampleWrapperTemplate(example)\n )\n )\n ),\n writeAskFiles(project, srcDir, write, modules),\n writeMcpFiles(mcp, write, agentData),\n writeApiFiles(project, api, write, agentData, mcp),\n playgroundProxy.enabled\n ? write(playgroundProxy.entrypoint, playgroundProxyTemplate(proxyOrigins))\n : Promise.resolve(false),\n ]);\n\n if (config.seo.og.enabled) {\n await write(\n join(srcDir, \"pages\", \"og\", \"[...slug].png.ts\"),\n ogEndpointTemplate(\n ogRoutes,\n {\n ...projectOgFonts(project),\n cache: {\n dir: ogCacheDir(project.context),\n version: getBlumeVersion(),\n },\n pageDescriptions: config.seo.og.description !== false,\n },\n changelogIndex\n )\n );\n }\n\n // Changelog index (`/changelog`), rendered through the Update timeline layout.\n if (changelogIndex) {\n await write(\n join(srcDir, \"pages\", \"changelog.astro\"),\n changelogIndexTemplate({\n exportEpub,\n exportPdf,\n needsReact,\n staged: hasStaged,\n })\n );\n }\n\n // Three independent writes: the per-example preview routes that\n // `<Component />` iframes embed (returning a warning when the configured\n // examples.css is missing), the default 404 page (`/404`, unless the project\n // already owns the route), and the provider-specific client loader behind\n // the `blume:search-client` alias — always (re)generated so the alias\n // resolves even when search is disabled.\n const [examplesWarnings] = await Promise.all([\n writeExamplesPreview({\n config,\n hasExamples: exampleDiscovery.examples.length > 0,\n root: context.root,\n srcDir,\n write,\n }),\n writeNotFoundPage(write, srcDir, pages, project.graph.pages),\n write(searchClientPath, searchClientTemplate(config)),\n write(featuresPath, featuresTemplate(clientFeatures)),\n ]);\n\n // Client-loaded providers (orama, flexsearch) ship a static index + endpoint.\n if (servesStaticIndex(config.search.provider)) {\n const documents = await buildSearchDocuments(project);\n modules.set(\"blume:search-index\", JSON.stringify(documents));\n await write(\n join(srcDir, \"pages\", \"blume-search.json.ts\"),\n searchEndpointTemplate()\n );\n }\n\n // Mixedbread proxies queries through a server endpoint that holds the key.\n if (config.search.provider === \"mixedbread\") {\n await write(\n join(srcDir, \"pages\", \"api\", \"search.ts\"),\n mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? \"\")\n );\n }\n\n // The include graph (partial → including pages) behind `includeHmrPlugin`:\n // editing a partial invalidates every page that splices it. Written even\n // when empty so the plugin's configured path always resolves.\n await write(\n join(srcDir, \"generated\", \"includes.json\"),\n `${JSON.stringify(buildIncludeGraph(project.graph.pages))}\\n`\n );\n\n modules.set(\"blume:raw-markdown\", JSON.stringify(rawMarkdown));\n // The originals behind the rewritten `/blume-assets/content/…` references in\n // the agent-facing Markdown, plus the endpoint that serves them (and the\n // remote-source assets materialized under `.blume/public/blume-assets`).\n const contentAssets = await collectContentAssets(project);\n modules.set(\"blume:content-assets\", JSON.stringify(contentAssets));\n await Promise.all([\n write(\n join(srcDir, \"pages\", \"[...slug].md.ts\"),\n rawMarkdownEndpointTemplate(\"md\")\n ),\n write(\n join(srcDir, \"pages\", \"[...slug].mdx.ts\"),\n rawMarkdownEndpointTemplate(\"mdx\")\n ),\n write(\n join(srcDir, \"pages\", \"blume-assets\", \"[...asset].ts\"),\n contentAssetsEndpointTemplate(\n join(project.context.outDir, \"public\", \"blume-assets\")\n )\n ),\n ]);\n\n // Automatic RSS feeds for blog/changelog content types (a no-op when no such\n // pages exist or no deployment.site is configured).\n const feeds = buildRssFeeds(project);\n if (feeds.length > 0) {\n const feedXml = Object.fromEntries(\n feeds.map((feed) => [feed.type, renderRssFeed(feed)])\n );\n modules.set(\"blume:rss\", JSON.stringify(feedXml));\n await write(\n join(srcDir, \"pages\", \"[section]\", \"rss.xml.ts\"),\n rssEndpointTemplate()\n );\n }\n\n // Scalar-rendered API/AsyncAPI reference pages (`renderer: \"scalar\"`). One\n // self-contained page per source, mounted on its configured route and\n // regenerated each run.\n const warnings: string[] = [\n ...(depsLinkWarning ? [depsLinkWarning] : []),\n ...proxyAllowlistWarnings(config, openApiData),\n ...reactCompilerWarnings(config, needsReact, reactCompilerPath),\n ...mcp.warnings,\n ...islandDiscovery.warnings,\n ...exampleDiscovery.warnings,\n ...examplesWarnings,\n ...overrideWarnings,\n ];\n\n // Missing-navigation-target check, now that every servable route is known:\n // content routes, custom `.astro` pages, the generated changelog, and any\n // OpenAPI reference routes (so a tab an author points at one still validates).\n const navTargetRoutes = new Set<string>([\n ...project.graph.routes.keys(),\n ...pages.map((page) => page.pattern),\n ...referenceRoutes(config),\n ]);\n if (changelogIndex) {\n navTargetRoutes.add(\"/changelog\");\n }\n // Curated `search.popular` icons live outside the navigation model, so they\n // miss `validateNavIcons` in the graph build — they're checked here too,\n // where the search config is known. A typo otherwise just renders the\n // default glyph.\n warnings.push(\n ...[\n ...validateNavTargets(project.graph.navigation, navTargetRoutes),\n ...validateSearchPopularIcons(config.search.popular),\n ].map(diagnosticWarning)\n );\n\n // Unknown-component check: a `<Tag>` in MDX that isn't a built-in, an island,\n // or a `components.ts` override. Needs the project's own components, known here.\n const knownComponentTags = new Set<string>([\n ...islandDiscovery.islands.map((island) => island.name),\n ...overrideTags,\n ]);\n // Missing-dependency preflights: the search provider's SDK, the Ask AI\n // backend's provider SDK, the deployment adapter's package, and — since\n // React ships with Blume while Vue/Svelte don't — any island framework's\n // Astro integration. Warn early rather than let Vite fail to resolve them\n // opaquely.\n warnings.push(\n ...validateUsedComponents(\n project.graph.pages,\n knownComponentTags,\n new Set(registry.map((item) => item.name))\n ).map(diagnosticWarning),\n ...searchProviderWarnings(config.search.provider, context.root),\n ...askProviderWarnings(config.ai.ask, context.root),\n ...deploymentAdapterWarnings(config.deployment, context.root),\n ...islandFrameworkWarnings(frameworks, context.root)\n );\n if (hasScalarReferences(config)) {\n const references = await buildReferenceFiles({\n config,\n contentRoutes: new Set(project.graph.pages.map((page) => page.route)),\n root: context.root,\n });\n warnings.push(...references.warnings);\n await Promise.all(\n references.files.map((file) =>\n write(join(srcDir, \"pages\", file.pagePath), file.content)\n )\n );\n }\n\n // `blume:openapi` is always published — even as `{}` — so the import resolves\n // whether or not a reference is enabled; the specs were parsed during the\n // scan, so this is just serialization. `blume:data` is the page data every\n // layout reads. Neither is \"structural\" for Astro; publishing hot-reloads.\n modules.set(\"blume:data\", buildRuntimeData(project));\n modules.set(\"blume:openapi\", JSON.stringify(openApiData));\n // These write to distinct trees and never read one another, so they batch.\n // `writeStagedContent` owns the `.blume/content` tree (its own pruning),\n // outside `.blume/src`, so a removed remote entry doesn't linger.\n await Promise.all([\n write(\n join(out, \"blume.manifest.json\"),\n `${JSON.stringify(project.manifest, null, 2)}\\n`\n ),\n writeStagedContent(out, staged),\n ]);\n\n // Remove anything under `.blume/src` this pass didn't write — e.g. an Ask AI\n // endpoint left behind after the feature was switched off.\n await pruneOrphans(srcDir, written);\n\n // Publish last, once every page that imports a module is on disk: a live\n // dev server invalidates the changed modules and reloads the browser against\n // the finished tree, never a half-written one.\n publishDevNegotiation({ contentRoutes, homeLinkHeader });\n publishRuntimeModules(modules);\n\n return { structuralChange: structural.some(Boolean), warnings };\n};\n",
|
|
11
|
+
"import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport {\n lstat,\n mkdir,\n readFile,\n readlink,\n realpath,\n rm,\n symlink,\n} from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nimport pMap from \"p-map\";\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n normalize,\n relative,\n resolve,\n} from \"pathe\";\nimport { glob } from \"tinyglobby\";\n\nimport { OPENAPI_PATH } from \"../ai/api/paths.ts\";\nimport { buildApiSpec } from \"../ai/api/spec.ts\";\nimport { buildAskData } from \"../ai/ask-data.ts\";\nimport { askBackendRuntimeDep, resolveAskBackend } from \"../ai/ask.ts\";\nimport { buildHomeLinkHeader } from \"../ai/link-headers.ts\";\nimport { buildRawMarkdown, markdownRoutePaths } from \"../ai/markdown.ts\";\nimport type { RawMarkdownEntry } from \"../ai/markdown.ts\";\nimport { buildMcpData } from \"../ai/mcp/data.ts\";\nimport type { McpData } from \"../ai/mcp/data.ts\";\nimport { buildMcpDiscovery, buildMcpServerCard } from \"../ai/mcp/discovery.ts\";\nimport {\n hasDeferrableGroups,\n navVariants,\n} from \"../components/layout/nav-utils.ts\";\nimport { normalizeBasePath } from \"../core/base-path.ts\";\nimport { validateUsedComponents } from \"../core/component-diagnostics.ts\";\nimport { analyzeComponentOverrides } from \"../core/component-overrides.ts\";\nimport {\n collectContentAssets,\n rewriteRelativeImages,\n} from \"../core/content-assets.ts\";\nimport type {\n BlumeBanner,\n BlumeData,\n BlumeFavicon,\n BlumeLogo,\n} from \"../core/data.ts\";\nimport { BlumeError } from \"../core/diagnostics.ts\";\nimport { writeTextAtomic } from \"../core/fs-atomic.ts\";\nimport {\n apiUrl as githubApiUrl,\n editBaseUrl as githubEditBaseUrl,\n repoUrl as githubRepoUrl,\n} from \"../core/github.ts\";\nimport { EN_UI, resolveUIStrings } from \"../core/i18n-ui.ts\";\nimport { resolveFallbackLocale } from \"../core/i18n.ts\";\nimport { buildIncludeGraph } from \"../core/includes.ts\";\nimport {\n validateNavTargets,\n validateSearchPopularIcons,\n} from \"../core/nav-diagnostics.ts\";\nimport { packageRoot } from \"../core/package-root.ts\";\nimport type { BlumeProject } from \"../core/project-graph.ts\";\nimport type { ResolvedConfig } from \"../core/schema.ts\";\nimport { resolveDocsCollection } from \"../core/sources/resolve.ts\";\nimport { svgDimensions } from \"../core/svg-dimensions.ts\";\nimport { trimChar } from \"../core/trim.ts\";\nimport { resolveTsconfigAliases } from \"../core/tsconfig-aliases.ts\";\nimport type { Diagnostic, Navigation } from \"../core/types.ts\";\nimport { getBlumeVersion } from \"../core/version.ts\";\nimport { buildRssFeeds, renderRssFeed } from \"../deploy/rss.ts\";\nimport {\n languageIconCss,\n languageIconSlugsIn,\n} from \"../markdown/language-icon.ts\";\nimport { hasMermaidFence } from \"../markdown/mermaid.ts\";\nimport { ogCacheDir } from \"../og/cache.ts\";\nimport { missingFontFiles, resolveOgFonts } from \"../og/derive.ts\";\nimport type { DerivedOgFonts } from \"../og/derive.ts\";\nimport { resolveOgLogo } from \"../og/logo.ts\";\nimport type { ApiSpecData, OpenApiData } from \"../openapi/model.ts\";\nimport {\n builtinProxyKinds,\n hasScalarReferences,\n needsPlaygroundProxy,\n referenceRoutes,\n} from \"../openapi/references.ts\";\nimport { buildReferenceFiles } from \"../openapi/scalar.ts\";\nimport { isOpenApiSource } from \"../openapi/source.ts\";\nimport { registry } from \"../registry/registry.ts\";\nimport { buildSearchDocuments } from \"../search/documents.ts\";\nimport { resolveSearchPopular } from \"../search/popular.ts\";\nimport { searchProviderMeta, servesStaticIndex } from \"../search/providers.ts\";\nimport {\n examplesEntryTemplate,\n tailwindEntryTemplate,\n} from \"../theme/entry.ts\";\nimport {\n buildFontsCss,\n configuredFonts,\n fontLocaleCodes,\n} from \"../theme/fonts.ts\";\nimport { buildThemeCss } from \"../theme/palette.ts\";\nimport { rebaseSourceDirectives } from \"../theme/sources.ts\";\nimport { twoslashCss } from \"../theme/twoslash.ts\";\nimport { planComponentSlots } from \"./component-slots.ts\";\nimport type { ComponentSlotPlan } from \"./component-slots.ts\";\nimport {\n EXAMPLE_SCAN_GLOB,\n discoverExamples,\n exampleMarkdownLookup,\n exampleScanRoots,\n} from \"./examples.ts\";\nimport { publishDevNegotiation } from \"./integration.ts\";\nimport { discoverIslands } from \"./islands.ts\";\nimport {\n customOgRoutes,\n discoverPages,\n hasGeneratedChangelog,\n routeIsTaken,\n} from \"./pages.ts\";\nimport { publishRuntimeModules } from \"./runtime-modules.ts\";\nimport type { RuntimeModuleId } from \"./runtime-modules.ts\";\nimport {\n askComponentTemplate,\n askEndpointTemplate,\n astroConfigTemplate,\n catchAllPageTemplate,\n changelogIndexTemplate,\n contentAssetsEndpointTemplate,\n contentConfigTemplate,\n exampleMapTemplate,\n exampleWrapperTemplate,\n examplesPageTemplate,\n exampleSlug,\n islandMapTemplate,\n islandWrapperTemplate,\n apiNavigationTemplate,\n apiNotFoundTemplate,\n apiPageTemplate,\n apiPagesIndexTemplate,\n apiSearchTemplate,\n mcpEndpointTemplate,\n mcpPageFile,\n mixedbreadSearchEndpointTemplate,\n notFoundJsonTemplate,\n notFoundMarkdownTemplate,\n notFoundPageTemplate,\n ogEndpointTemplate,\n playgroundProxyTemplate,\n rawMarkdownEndpointTemplate,\n rssEndpointTemplate,\n staticJsonEndpointTemplate,\n runtimeDependencies,\n runtimePackageTemplate,\n runtimeTsconfigTemplate,\n featuresTemplate,\n navFragmentTemplate,\n searchClientTemplate,\n searchEndpointTemplate,\n stagedContentDir,\n} from \"./templates.ts\";\nimport type { ClientFeatures } from \"./templates.ts\";\n\n/** Absolute path to the Blume package `src` directory. */\nconst BLUME_SRC = join(packageRoot(), \"src\");\n\n/** Whether a module specifier resolves from a directory via node resolution. */\nconst canResolveFrom = (fromDir: string, spec: string): boolean => {\n try {\n createRequire(pathToFileURL(join(fromDir, \"_.js\")).href).resolve(spec);\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Absolute path to `babel-plugin-react-compiler`, resolved from Blume's own\n * package root (Blume ships it). Returns null when React or the compiler is off.\n *\n * The path must be absolute: @vitejs/plugin-react resolves babel plugins from\n * the *project* root, not `.blume/`, so a bare specifier fails in a user project\n * that never installed the plugin directly. Resolving from `packageRoot()` binds\n * to Blume's shipped copy regardless of the user's package manager or hoisting.\n */\nexport const resolveReactCompiler = (\n config: ResolvedConfig,\n needsReact: boolean,\n pkgDir: string = packageRoot()\n): string | null => {\n if (!(needsReact && config.react.compiler)) {\n return null;\n }\n try {\n return createRequire(pathToFileURL(join(pkgDir, \"_.js\")).href).resolve(\n \"babel-plugin-react-compiler\"\n );\n } catch {\n return null;\n }\n};\n\n/**\n * Warning (as a spreadable list) for the case where the React Compiler was\n * requested but its plugin couldn't be resolved — so the build silently drops\n * to uncompiled output rather than failing. Exported for testing.\n */\nexport const reactCompilerWarnings = (\n config: ResolvedConfig,\n needsReact: boolean,\n compilerPath: string | null\n): string[] =>\n needsReact && config.react.compiler && !compilerPath\n ? [\n \"React Compiler is enabled but `babel-plugin-react-compiler` could not be resolved; falling back to an uncompiled build. Reinstall Blume, or set `react: { compiler: false }` to silence this.\",\n ]\n : [];\n\n/** Resolve Astro's package.json directly inside a node_modules directory. */\nconst resolveAstroPackageJson = (modulesDir: string): string | null => {\n try {\n return realpathSync(join(modulesDir, \"astro\", \"package.json\"));\n } catch {\n return null;\n }\n};\n\n/**\n * The `astro` package reachable through the normal node_modules ancestor walk\n * from a generated runtime — its realpath'd `package.json` plus the\n * `node_modules` directory the walk found it in — or null when none resolves.\n *\n * This deliberately does not use `createRequire().resolve()`. pnpm's generated\n * bin shim adds Blume's virtual-store dependencies to `NODE_PATH`, which\n * CommonJS resolution honors but ESM package resolution ignores. The generated\n * Astro config uses ESM imports, so treating a NODE_PATH-only result as\n * reachable skips the dependency link and makes `import \"astro/config\"` fail.\n * Walking the physical node_modules ancestors mirrors the lookup that config\n * actually gets.\n *\n * The containing directory matters as much as the package: under an isolated\n * linker the walk can find a store-deduped astro in a directory that holds\n * nothing else of Blume's, so \"the right astro resolves\" does not imply \"the\n * integrations resolve\" — callers must check where the hit came from.\n */\nconst resolvedAstroHit = (\n fromDir: string\n): { modulesDir: string; pkg: string } | null => {\n let dir = normalize(fromDir);\n while (true) {\n const modulesDir = join(dir, \"node_modules\");\n const pkg = resolveAstroPackageJson(modulesDir);\n if (pkg) {\n return { modulesDir, pkg };\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return null;\n }\n dir = parent;\n }\n};\n\n/**\n * Whether two paths name the same physical directory (realpath equality).\n * Exported for testing.\n */\nexport const sameRealDir = (a: string, b: string): boolean => {\n try {\n return realpathSync(a) === realpathSync(b);\n } catch {\n return false;\n }\n};\n\n/**\n * The two places an installer can put Blume's dependencies:\n * - `<blume>/node_modules` — deps nested under the package (workspace source,\n * or npm nesting them away from a conflicting hoisted copy)\n * - `dirname(<blume>)` — deps as siblings in the store (isolated/pnpm)\n *\n * `packageRoot()` resolves to Blume's real on-disk path (Node follows the\n * install symlink), so its parent is the store's package directory where the\n * isolated linker places the siblings.\n */\nconst depsCandidates = (pkgDir: string): string[] => [\n join(pkgDir, \"node_modules\"),\n dirname(pkgDir),\n];\n\n/** First dependency candidate containing the package dir `segments`, or null. */\nconst candidateHolding = (\n pkgDir: string,\n ...segments: string[]\n): string | null =>\n depsCandidates(pkgDir).find((dir) => existsSync(join(dir, ...segments))) ??\n null;\n\n/**\n * Locate the directory that holds Blume's installed dependencies (Astro and its\n * integrations).\n *\n * With a clean hoisted install this is moot — the deps sit in a `node_modules`\n * the generated `.blume/` already walks up into, and {@link ensureDepsLink}\n * short-circuits before we need it. But under isolated linkers (Bun's\n * `isolated` mode, pnpm) Blume's deps are NOT hoisted into the project; they\n * live beside the Blume package in a virtual store, invisible to the upward\n * walk from `.blume/` — so probe the {@link depsCandidates}.\n *\n * Astro alone is a bad probe: an npm split install (an `overrides` pin plus an\n * incremental install) hoists `astro` to the project root while Blume's other\n * deps stay nested, and probing for astro then picks the root directory — one\n * that holds none of them. Prefer a candidate with the full set (astro beside\n * `@astrojs/mdx`, the integration every generated runtime declares), then one\n * with the integrations (astro hoisted away — the rest of Blume's deps sit\n * there too), then one with astro alone.\n */\nconst holdsAstro = (dir: string): boolean => existsSync(join(dir, \"astro\"));\nconst holdsMdx = (dir: string): boolean =>\n existsSync(join(dir, \"@astrojs\", \"mdx\"));\n\nexport const blumeDepsDir = (pkgDir: string = packageRoot()): string | null => {\n const candidates = depsCandidates(pkgDir);\n return (\n candidates.find((dir) => holdsAstro(dir) && holdsMdx(dir)) ??\n candidates.find(holdsMdx) ??\n candidates.find(holdsAstro) ??\n null\n );\n};\n\n/**\n * Create `link` as a directory symlink to `target`, falling back to a junction.\n *\n * The type only matters on Windows, and there a junction is the wrong first\n * choice: Windows can't follow a *relative* symlink reached through a\n * junction (it resolves the relative target against the junction-side path,\n * so it lands outside the store and every lookup is ENOENT), and Bun's\n * isolated linker writes exactly those into Blume's dependency directory\n * whenever it holds symlink privilege. A directory symlink traverses them\n * fine. Without that privilege (no Developer Mode, non-admin shell) creating\n * one fails, so fall back to a junction — and in that session the installer\n * had no privilege either, so the deps are absolute junctions a junction can\n * follow. Exported for testing.\n */\nexport const symlinkDir = async (\n target: string,\n link: string\n): Promise<void> => {\n try {\n await symlink(target, link, \"dir\");\n } catch {\n await symlink(target, link, \"junction\");\n }\n};\n\n/**\n * Point `link` at Blume's dependency directory via a `node_modules` link,\n * replacing a stale link we own and leaving a real directory untouched.\n *\n * `lstat`, not `existsSync`, so a broken link (target since moved) is still\n * detected — `existsSync` follows the link and reports a dangling one as absent.\n */\nconst linkDepsJunction = async (\n link: string,\n depsDir: string\n): Promise<void> => {\n let existing: Awaited<ReturnType<typeof lstat>> | null;\n try {\n existing = await lstat(link);\n } catch {\n existing = null;\n }\n if (existing) {\n if (!existing.isSymbolicLink()) {\n return;\n }\n // Already pointing at the right target — leave it alone. This runs on\n // every dev regeneration, and an unconditional rm+recreate opens a window\n // in which the Vite server's module resolution races a missing\n // `node_modules` and 500s intermittently.\n try {\n if (resolve(dirname(link), await readlink(link)) === resolve(depsDir)) {\n return;\n }\n } catch {\n // Unreadable link — replace it below.\n }\n await rm(link, { force: true });\n }\n await mkdir(dirname(link), { recursive: true });\n await symlinkDir(depsDir, link);\n};\n\n/** Read the `version` field of a `package.json`, or null when unreadable. */\nconst readPkgVersion = (pkgJsonPath: string | null): string | null => {\n if (!pkgJsonPath) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")).version ?? null;\n } catch {\n return null;\n }\n};\n\n/**\n * Build the diagnostic for a split-layout Astro conflict that a symlink can't\n * repair: a different Astro is hoisted to the project root, shadowing Blume's,\n * and `@astrojs/mdx` binds to the wrong copy. `blumeAstroPkg`/`shadowAstroPkg`\n * are the resolved `astro/package.json` paths for Blume's set and the one the\n * runtime actually resolves.\n */\nconst astroConflictWarning = (\n blumeAstroPkg: string | null,\n shadowAstroPkg: string | null\n): string => {\n const blume = readPkgVersion(blumeAstroPkg);\n const shadow = readPkgVersion(shadowAstroPkg);\n const versions =\n blume && shadow\n ? `astro@${shadow} shadowing Blume's astro@${blume}`\n : \"a second copy of Astro shadowing Blume's\";\n const pin = blume ?? \"<Blume's astro version>\";\n return `Astro version conflict: another dependency hoisted ${versions} to the project root, so @astrojs/mdx binds to the wrong copy and the build fails on a missing export (e.g. \"chunkToString\"). A single symlink can't reconcile a split install — pin Blume's Astro by adding a package.json \"overrides\" (npm/bun/pnpm) or \"resolutions\" (yarn) entry { \"astro\": \"${pin}\" }, then reinstall. Run \\`npm ls astro\\` to find the dependency pulling the older copy.`;\n};\n\n/**\n * Drop a `.blume/node_modules` junction that resolves a *different* Blume than\n * the one running. A restored build cache (e.g. Vercel's) can resurrect the\n * junction pointing into a superseded store directory — blume@1.1.0's isolated\n * deps dir after 1.1.1 was installed. Releases rarely bump Astro, so the stale\n * target still resolves the very same astro and every astro-based probe in\n * {@link ensureDepsLink} passes through the link — while the `blume/*` imports\n * in the freshly generated config load the previous release, crashing on any\n * export added since. Staleness is judged by realpath: the link is stale\n * exactly when the directory behind it holds a `blume` that isn't `pkgDir`.\n * A target with no `blume` entry (the workspace layout links\n * `packages/blume/node_modules`, which holds only the deps) resolves Blume\n * through the normal ancestor walk and stays. Real directories stay too,\n * mirroring {@link linkDepsJunction} — we only ever remove a link we own.\n */\nconst dropStaleDepsLink = async (\n link: string,\n pkgDir: string\n): Promise<void> => {\n let existing: Awaited<ReturnType<typeof lstat>>;\n try {\n existing = await lstat(link);\n } catch {\n return;\n }\n if (!existing.isSymbolicLink()) {\n return;\n }\n let linkedBlume: string;\n let runningBlume: string;\n try {\n linkedBlume = await realpath(join(link, \"blume\"));\n runningBlume = await realpath(pkgDir);\n } catch {\n return;\n }\n if (linkedBlume !== runningBlume) {\n await rm(link, { force: true });\n }\n};\n\n/**\n * Make the generated runtime resolve Astro and its integrations against Blume's\n * own dependency set. Three failure modes this repairs:\n *\n * - Astro is *unreachable* from `.blume/` (workspaces under isolated linkers,\n * pnpm) — the deps live in a store the upward walk can't see.\n * - Astro *resolves to the wrong copy* — a hoisted sibling pinned an older\n * major (e.g. `astro@6` for a type-only import) that shadows Blume's\n * `astro@7`, so `@astrojs/mdx@7` binds to it and crashes the build on a\n * missing export. Resolving merely *an* astro isn't enough; it must be the\n * same one Blume uses.\n * - The *integrations* are unreachable while astro is fine — npm's split\n * install. An `overrides` pin plus an incremental `npm install` hoists\n * astro to the project root (deleting Blume's nested copy) but leaves\n * `@astrojs/mdx` and friends nested under `blume/node_modules`, where the\n * upward walk from `.blume/` can't see them. The same shape arises under\n * an isolated linker when the workspace itself declares astro at a version\n * matching Blume's: the store dedupes both to one copy, so the walk finds\n * the \"correct\" astro through the workspace's own direct-dep symlink — in\n * a node_modules holding none of Blume's other deps.\n *\n * The repair is the same symlink: Blume's dependency directory linked in as\n * `.blume/node_modules` so the generated config's bare specifiers (`astro`,\n * `@astrojs/mdx`, …) bind to a consistent set. That's safe when the linked\n * directory holds the full set, or when it holds only the integrations but the\n * runtime already resolves Blume's astro — the junction has no `astro` entry,\n * so astro lookups fall through to the hoisted copy the integrations bind to\n * anyway. What it can't fix is the inverse split: Blume's astro nested under a\n * *conflicting* hoisted astro with the integrations hoisted away from it. No\n * single directory yields a consistent set there; only a root `overrides`/\n * `resolutions` pin does, so we return a diagnostic naming the conflict rather\n * than silently shipping a runtime that crashes downstream. Returns the\n * warning, or null when nothing needs saying.\n */\nexport const ensureDepsLink = async (\n outDir: string,\n pkgDir: string = packageRoot()\n): Promise<string | null> => {\n const astroDir = candidateHolding(pkgDir, \"astro\");\n if (!astroDir) {\n return null;\n }\n const mdxDir = candidateHolding(pkgDir, \"@astrojs\", \"mdx\");\n const blumeAstro = resolveAstroPackageJson(astroDir);\n // Before probing what `.blume/` resolves, drop a cache-restored junction\n // that binds it to a superseded Blume — the probes below would otherwise\n // pass right through it (same astro, older blume) and leave it in place.\n await dropStaleDepsLink(join(outDir, \"node_modules\"), pkgDir);\n const outDirHit = resolvedAstroHit(outDir);\n // `.blume/` resolves the very same astro Blume's deps provide.\n const astroCorrect = blumeAstro !== null && outDirHit?.pkg === blumeAstro;\n // Clean hoisted install: astro is correct, found in Blume's own dependency\n // directory, and the integrations sit beside it — the same walk resolves\n // them too, so there is nothing to do. Requiring the walk to land in\n // `astroDir` itself (not merely resolve an identical astro) matters under\n // isolated linkers: a workspace that declares astro at a version matching\n // Blume's gets a store-deduped symlink in its own node_modules, so the walk\n // finds the \"correct\" astro in a directory holding only the workspace's\n // direct deps — none of Blume's integrations (issue #103).\n const walkLandsInDeps =\n astroCorrect &&\n outDirHit !== null &&\n sameRealDir(outDirHit.modulesDir, astroDir);\n if (walkLandsInDeps && mdxDir === astroDir) {\n return null;\n }\n // Linking the integrations' directory yields a consistent set when it also\n // holds Blume's astro (the unreachable and repairable-conflict cases) or\n // when the correct astro is reachable without it (the npm split install).\n // Any existing link here is stale and gets replaced.\n if (mdxDir && (mdxDir === astroDir || astroCorrect)) {\n await linkDepsJunction(join(outDir, \"node_modules\"), mdxDir);\n return null;\n }\n // Split layout: Blume's astro is nested (a conflicting astro took the root\n // spot) but @astrojs/mdx hoisted away from it, binding to the shadow. Only a\n // root pin fixes this — surface it.\n return astroConflictWarning(blumeAstro, outDirHit?.pkg ?? null);\n};\n\n/**\n * Vite plugin that makes Blume's externalized runtime deps (zod, shiki, sharp,\n * `takumi-js`, …) resolvable when Astro executes the static prerender\n * bundle under an isolated linker (Bun's `isolated` mode, pnpm).\n *\n * Astro's static build emits a self-contained SSR bundle to\n * `<outDir>/.prerender/` and `import()`s it in-process to generate the HTML.\n * That bundle externalizes Blume's render-time deps, so Node resolves them at\n * prerender time by walking up from `.prerender/chunks/*.mjs`. {@link\n * ensureDepsLink} only repairs resolution rooted at `.blume/`; `.prerender/`\n * lives under `dist/`, a separate tree an isolated linker never hoists Blume's\n * deps into — so the import dies with `Cannot find package 'zod'`. We drop the\n * same `node_modules` junction into the prerender root, mirroring\n * `.blume/node_modules`, so every externalized specifier — native bindings\n * included, which can't be bundled — resolves. Astro deletes `.prerender/` once\n * generation finishes (and the junction with it: `fs.rm` unlinks symlinks, it\n * never follows them), so nothing leaks into the published `dist/`.\n *\n * Keyed off the output dir's basename (`.prerender`) — the name Astro 7 gives\n * the prerender build for both static (`<outDir>/.prerender/`) and server\n * (`<build.server>/.prerender/`) output — so it fires for exactly that build.\n * Inert in dev, where there is no build and `writeBundle` never runs.\n */\nexport interface PrerenderDepsPlugin {\n name: string;\n writeBundle: (options: { dir?: string }) => Promise<void>;\n}\n\nexport const prerenderDepsPlugin = (\n pkgDir: string = packageRoot()\n): PrerenderDepsPlugin => ({\n name: \"blume:prerender-deps\",\n writeBundle: async (options) => {\n if (!options.dir || basename(options.dir) !== \".prerender\") {\n return;\n }\n const depsDir = blumeDepsDir(pkgDir);\n if (!depsDir) {\n return;\n }\n await linkDepsJunction(join(options.dir, \"node_modules\"), depsDir);\n },\n});\n\n/** Astro integration package each non-React island framework needs installed. */\nconst ISLAND_FRAMEWORK_DEPS = new Map([\n [\"svelte\", \"@astrojs/svelte\"],\n [\"vue\", \"@astrojs/vue\"],\n]);\n\n/**\n * Adapter package the project must install itself for each deployment\n * platform whose adapter Blume doesn't ship. Node and Vercel ship with Blume,\n * so they never need this.\n */\nconst DEPLOYMENT_ADAPTER_DEPS = new Map([\n [\"cloudflare\", \"@astrojs/cloudflare\"],\n [\"netlify\", \"@astrojs/netlify\"],\n]);\n\n/**\n * Warn when a Vue/Svelte island is present but its Astro integration isn't\n * installed — Vite would otherwise fail opaquely on the generated config import.\n * React ships with Blume, so it never needs this.\n */\nconst islandFrameworkWarnings = (\n frameworks: Set<string>,\n root: string\n): string[] => {\n const warnings: string[] = [];\n for (const framework of frameworks) {\n const dep = ISLAND_FRAMEWORK_DEPS.get(framework);\n if (dep && !canResolveFrom(root, dep)) {\n warnings.push(\n `Islands use ${framework}, which needs \"${dep}\". Install it (e.g. \\`npm install ${dep} ${framework}\\`).`\n );\n }\n }\n return warnings;\n};\n\n/**\n * Warn when the resolved server-output adapter is one the project must install\n * itself (Netlify/Cloudflare; Node and Vercel ship with Blume). The generated\n * astro.config.mjs imports the adapter package directly — and on those\n * platforms the adapter is even auto-selected from env vars — so warn early\n * rather than let the build die with an opaque ERR_MODULE_NOT_FOUND from the\n * hidden generated config. Availability mirrors the search-provider check: a\n * dep resolves from the project root or from the Blume package itself.\n * `pkgDir` is injectable for testing.\n */\nexport const deploymentAdapterWarnings = (\n deployment: ResolvedConfig[\"deployment\"],\n root: string,\n pkgDir: string = packageRoot()\n): string[] => {\n const dep =\n deployment.output === \"server\" && deployment.adapter\n ? DEPLOYMENT_ADAPTER_DEPS.get(deployment.adapter)\n : undefined;\n if (dep && !(canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep))) {\n return [\n `Deployment adapter \"${deployment.adapter}\" needs \"${dep}\", which isn't installed. Run \\`npm install ${dep}\\` (or your package manager's equivalent).`,\n ];\n }\n return [];\n};\n\n/**\n * Warn when the configured search provider's SDK is missing. Provider SDKs are\n * optional peers; warn (rather than fail opaquely in Vite) when the package\n * isn't installed. A dep is available if the project installed it (resolves\n * from the root) OR Blume ships it (resolves from the Blume package — the same\n * set the `.blume` deps link exposes to the build). Resolving from the project\n * root alone falsely flagged a shipped SDK like Orama (the default provider)\n * as missing whenever it wasn't hoisted into the project, e.g. under isolated\n * linkers. We resolve from each package's real location rather than through\n * the `.blume` junction, which can't be traversed reliably for store-symlinked\n * deps. `pkgDir` is injectable for testing.\n */\nexport const searchProviderWarnings = (\n provider: ResolvedConfig[\"search\"][\"provider\"],\n root: string,\n pkgDir: string = packageRoot()\n): string[] => {\n const warnings: string[] = [];\n for (const dep of searchProviderMeta(provider).runtimeDeps) {\n if (!(canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep))) {\n warnings.push(\n `Search provider \"${provider}\" needs \"${dep}\", which isn't installed. Run \\`npm install ${dep}\\` (or your package manager's equivalent).`\n );\n }\n }\n return warnings;\n};\n\n/**\n * Warn when the Ask AI backend's provider SDK is missing. Like search provider\n * SDKs, these are optional peers the project must install (only `gateway`\n * needs nothing beyond the core `ai` package Blume ships) — warn early with\n * the package name rather than let Vite fail to resolve the import opaquely.\n * Same resolution rule as {@link searchProviderWarnings}: available if the\n * project installed it or Blume can resolve it. `pkgDir` is injectable for\n * testing.\n */\nexport const askProviderWarnings = (\n ask: ResolvedConfig[\"ai\"][\"ask\"],\n root: string,\n pkgDir: string = packageRoot()\n): string[] => {\n // An external `endpoint` means no generated route, so no SDK is imported.\n if (!ask?.enabled || ask.endpoint) {\n return [];\n }\n const dep = askBackendRuntimeDep(ask);\n if (!dep || canResolveFrom(root, dep) || canResolveFrom(pkgDir, dep)) {\n return [];\n }\n return [\n `Ask AI provider \"${ask.provider}\" needs \"${dep}\", which isn't installed. Run \\`npm install ${dep}\\` (or your package manager's equivalent).`,\n ];\n};\n\n/** Absolute path to the configured `examples.css`, or null when unset. */\nconst examplesCssFile = (\n root: string,\n config: ResolvedConfig\n): string | null =>\n config.examples.css ? join(root, config.examples.css) : null;\n\n/**\n * Write the per-example preview route (`{basePath}/blume-examples/<path>`)\n * that `<Component />` iframes embed — the iframe boundary is what isolates\n * previews from the docs CSS. Nested under `basePath` in the filesystem so\n * the routes stay reachable behind a proxy that only forwards the base;\n * pruneOrphans clears a stale copy when `basePath` changes or the last\n * example is removed. Returns (as a spreadable list) a warning when the\n * configured `examples.css` doesn't exist.\n */\nconst writeExamplesPreview = async (options: {\n config: ResolvedConfig;\n hasExamples: boolean;\n root: string;\n srcDir: string;\n write: (path: string, content: string) => Promise<boolean>;\n}): Promise<string[]> => {\n const { config, hasExamples, root, srcDir, write } = options;\n if (hasExamples) {\n await write(\n join(\n srcDir,\n \"pages\",\n ...config.basePath.split(\"/\").filter(Boolean),\n \"blume-examples\",\n \"[...path].astro\"\n ),\n examplesPageTemplate()\n );\n }\n const cssFile = examplesCssFile(root, config);\n return cssFile && !existsSync(cssFile)\n ? [\n `examples.css points at \"${config.examples.css}\", which doesn't exist; previews render without it.`,\n ]\n : [];\n};\n\n/** Read a file's contents, or return an empty string if it is absent. */\nconst readOptional = async (path: string | null): Promise<string> => {\n if (!path) {\n return \"\";\n }\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return \"\";\n }\n};\n\n/**\n * Read a user stylesheet (`theme.css`, `examples.css`) that gets inlined into\n * a generated Tailwind entry under `outputDir`, re-rooting its relative\n * `@source` paths so they still resolve from where the author wrote them.\n */\nconst readUserCss = async (\n file: string | null,\n outputDir: string\n): Promise<string> => {\n const css = await readOptional(file);\n return file\n ? rebaseSourceDirectives(css, { from: file, to: outputDir })\n : css;\n};\n\n/** Heuristically detect whether the project uses React islands. */\nexport const detectNeedsReact = async (root: string): Promise<boolean> => {\n const matches = await glob([\"**/*.{tsx,jsx}\"], {\n cwd: root,\n ignore: [\"**/node_modules/**\", \"**/.blume/**\", \"**/dist/**\"],\n onlyFiles: true,\n });\n return matches.length > 0;\n};\n\n/** Block math (`$$…$$`) or an explicitly authored `<Math …>` component. */\nconst containsMath = (content: string): boolean =>\n content.includes(\"$$\") || content.includes(\"<Math\");\n\n/** Ceiling on concurrent content-file reads; unbounded fan-out risks EMFILE. */\nconst READ_CONCURRENCY = 16;\n\n/**\n * Detect whether the project can render math: block math (`$$…$$`) or an\n * explicit `<Math>` tag in any local `.md`/`.mdx`, or in staged (non-filesystem)\n * source bodies. Drives whether the generated runtime imports the `<Math>`\n * component and KaTeX's stylesheet, so a math-free site ships no KaTeX CSS.\n * Math parsing itself is always on but block-only, so one of those literals is\n * a necessary condition — no false negatives. A stray `$$` (e.g. inside a code\n * fence) merely over-includes the idempotent import, which is harmless.\n */\nexport const detectUsesMath = async (\n root: string,\n staged: Iterable<string> = []\n): Promise<boolean> => {\n const files = await glob([\"**/*.{md,mdx}\"], {\n cwd: root,\n ignore: [\"**/node_modules/**\", \"**/.blume/**\", \"**/dist/**\"],\n onlyFiles: true,\n });\n const contents = await pMap(files, (file) => readOptional(join(root, file)), {\n concurrency: READ_CONCURRENCY,\n });\n return [...contents, ...staged].some(containsMath);\n};\n\nconst hashConfigSource = (source: string): string =>\n createHash(\"sha256\").update(source).digest(\"hex\");\n\nconst loadIntegrationBridge = async (\n config: ResolvedConfig,\n context: BlumeProject[\"context\"]\n): Promise<Parameters<typeof astroConfigTemplate>[0][\"integrationBridge\"]> => {\n if (config.integrations.length === 0 || !context.configFile) {\n return;\n }\n return {\n configFile: relative(context.outDir, context.configFile),\n sourceHash: hashConfigSource(await readOptional(context.configFile)),\n };\n};\n\nconst writeIfChanged = async (\n path: string,\n content: string\n): Promise<boolean> => {\n let existing: string | null = null;\n try {\n existing = await readFile(path, \"utf-8\");\n } catch {\n existing = null;\n }\n if (existing === content) {\n return false;\n }\n // Atomic temp-write + rename, so a watching dev server never observes a\n // missing or half-written file mid-regeneration.\n await writeTextAtomic(path, content);\n return true;\n};\n\n/**\n * Delete generated files under `srcDir` that this pass didn't (re)write. The\n * generator emits many files conditionally — an Ask AI endpoint, OG images, a\n * search index, RSS feeds, reference pages, the MCP server — so toggling a\n * feature off would otherwise leave a stale file behind, and a leftover\n * server-rendered endpoint breaks the static build. `writeIfChanged` only ever\n * adds or updates, so this closes the loop. Scoped to `.blume/src`, so it never\n * touches Astro's `dist/`, `.astro/` cache, or the symlinked `node_modules`\n * (all of which live outside `src`). `written` holds normalized absolute paths.\n */\nexport const pruneOrphans = async (\n srcDir: string,\n written: Set<string>\n): Promise<void> => {\n const existing = await glob(\"**/*\", {\n absolute: true,\n cwd: srcDir,\n onlyFiles: true,\n });\n const removals: Promise<void>[] = [];\n for (const path of existing) {\n const normalized = normalize(path);\n if (!written.has(normalized)) {\n removals.push(rm(normalized, { force: true }));\n }\n }\n await Promise.all(removals);\n};\n\n/**\n * Collect staged (non-filesystem) page bodies keyed by their Astro entry id, so\n * i18n duplicates of one entry collapse to a single materialized file. Shared\n * with `eject`, which materializes the same bodies into the owned project.\n */\nexport const collectStaged = (project: BlumeProject): Map<string, string> => {\n const staged = new Map<string, string>();\n for (const page of project.graph.pages) {\n if (page.collection === \"staged\" && page.entryId && page.body) {\n // A colocated `./image.png` reference resolves against `.blume/content`\n // once the body is materialized there, where the file does not exist.\n // Point it at the served original instead — the same rewrite the\n // agent-facing Markdown gets.\n const text = page.sourcePath\n ? rewriteRelativeImages({\n deployBase: project.config.deployment.base,\n projectRoot: project.context.root,\n source: page.body.text,\n sourcePath: page.sourcePath,\n })\n : page.body.text;\n staged.set(page.entryId, text);\n }\n }\n return staged;\n};\n\n/**\n * Materialize staged source bodies under `.blume/content` and prune orphans in\n * that tree (separate from `.blume/src`), so a removed remote entry is cleaned up.\n */\nconst writeStagedContent = async (\n out: string,\n staged: Map<string, string>\n): Promise<void> => {\n const contentDir = stagedContentDir(out);\n const written = new Set<string>();\n await Promise.all(\n [...staged].map(async ([entryId, text]) => {\n const path = join(contentDir, entryId);\n written.add(normalize(path));\n await writeIfChanged(path, text);\n })\n );\n if (existsSync(contentDir)) {\n await pruneOrphans(contentDir, written);\n }\n};\n\ninterface LogoDimensions {\n height: number;\n width: number;\n}\n\n/**\n * Read dimensions from an SVG's explicit size or its view box, with the same\n * root-tag parser og/card.ts uses for the OG brand mark so the header and the\n * card can't disagree about one logo. An SVG with no usable size collapses to\n * undefined.\n */\nconst logoDimensions = (svg: string | undefined): LogoDimensions | undefined =>\n svg ? (svgDimensions(svg) ?? undefined) : undefined;\n\n/** Read a local SVG logo from the project root or public directory. */\nconst readLogoSvg = (\n project: BlumeProject,\n source: string | undefined\n): string | undefined => {\n if (!source?.toLowerCase().endsWith(\".svg\")) {\n return;\n }\n const rel = source.replace(/^\\//u, \"\");\n const file = [\n join(project.context.root, \"public\", rel),\n join(project.context.root, rel),\n ].find((path) => existsSync(path));\n return file ? readFileSync(file, \"utf-8\") : undefined;\n};\n\n/** Narrows a config union's string shorthand from its object form. */\nconst isStringShorthand = <T>(value: T | string): value is string =>\n typeof value === \"string\";\n\n/**\n * The URL behind the header's repo mark. A string is used as-is: `github`\n * drives the per-page edit link, the header mark and the manifest's\n * `repository` together, so a project whose docs repo is private has to unset\n * all three, and would otherwise have no way to point the mark at anything.\n */\nconst headerRepoUrl = (\n repo: boolean | string,\n derived: string | null\n): string | null => {\n if (isStringShorthand(repo)) {\n return repo;\n }\n return repo ? derived : null;\n};\n\n/**\n * Resolve the configured logo. A single SVG is read and inlined so a\n * `currentColor` logo follows the theme; other images keep their URL for an\n * `<img>`. The file is looked up under `public/` and the project root.\n */\nconst resolveLogo = (project: BlumeProject): BlumeLogo | null => {\n const { logo } = project.config;\n if (!logo) {\n return null;\n }\n const config = isStringShorthand(logo) ? { image: logo } : logo;\n // `text` is passed through verbatim: `undefined` lets the brand fall back to\n // the site title, `\"\"` renders the mark alone (a logo with the wordmark baked\n // in).\n const { href, image: source, text } = config;\n const image = isStringShorthand(source) ? { light: source } : source;\n const light = image?.light ?? image?.dark;\n const dark = image?.dark ?? image?.light;\n const alt = image?.alt ?? \"\";\n const brandHref = href ?? \"/\";\n const lightSvg = readLogoSvg(project, light);\n const darkSvg = dark === light ? lightSvg : readLogoSvg(project, dark);\n\n if (light && light === dark && lightSvg) {\n return { alt, href: brandHref, svg: lightSvg, text };\n }\n\n const lightDimensions = logoDimensions(lightSvg);\n const darkDimensions = logoDimensions(darkSvg);\n const dimensions =\n lightDimensions || darkDimensions\n ? { dark: darkDimensions, light: lightDimensions }\n : undefined;\n return { alt, dark, dimensions, href: brandHref, light, text };\n};\n\n/**\n * Favicon filenames Blume auto-detects, in priority order. Mirrors the Next.js\n * convention: an `icon.*` or `favicon.*` file in `public/` or the project root\n * becomes the site favicon, no config required.\n */\nconst FAVICON_CANDIDATES = [\n \"icon.svg\",\n \"favicon.svg\",\n \"icon.png\",\n \"favicon.png\",\n \"favicon.ico\",\n \"icon.ico\",\n];\n\n/**\n * Derive the `-dark` sibling of an icon filename (`icon.svg` → `icon-dark.svg`),\n * inserting the suffix before the extension.\n */\nconst darkSibling = (name: string): string =>\n name.replace(/\\.(?=[^.]+$)/u, \"-dark.\");\n\n/** `<link type>` MIME for the favicon extensions we recognize. */\nconst FAVICON_TYPES = new Map([\n [\"ico\", \"image/x-icon\"],\n [\"jpeg\", \"image/jpeg\"],\n [\"jpg\", \"image/jpeg\"],\n [\"png\", \"image/png\"],\n [\"svg\", \"image/svg+xml\"],\n]);\n\n/** Infer the `<link type>` MIME from a filename, when we recognize the extension. */\nconst faviconType = (name: string): string | undefined => {\n const ext = name.split(\".\").pop()?.toLowerCase();\n return ext ? FAVICON_TYPES.get(ext) : undefined;\n};\n\n/** Read a file and encode it as a `data:` URI of the given MIME type. */\nconst inlineDataUri = (file: string, type: string): string =>\n `data:${type};base64,${readFileSync(file).toString(\"base64\")}`;\n\n/**\n * The bundled Blume favicon, inlined as a data URI so it needs no public file.\n * The mark is dark, so it ships with a light-on-transparent dark-scheme variant —\n * otherwise it disappears against dark browser chrome.\n */\nconst defaultFavicon = (): BlumeFavicon => ({\n dark: {\n href: inlineDataUri(\n join(BLUME_SRC, \"assets\", \"icon-dark.png\"),\n \"image/png\"\n ),\n type: \"image/png\",\n },\n href: inlineDataUri(join(BLUME_SRC, \"assets\", \"icon.png\"), \"image/png\"),\n type: \"image/png\",\n});\n\n/**\n * Apple touch icon filenames Blume auto-detects, in priority order. Mirrors the\n * Next.js `apple-icon.*` convention (plus the `apple-touch-icon.png` most favicon\n * generators emit): a match in `public/` or the project root becomes the iOS\n * home-screen icon, no config required.\n */\nconst APPLE_ICON_CANDIDATES = [\n \"apple-icon.png\",\n \"apple-icon.jpg\",\n \"apple-icon.jpeg\",\n \"apple-touch-icon.png\",\n];\n\n/**\n * Resolve an icon file by convention. A candidate in `public/` is served as-is\n * and referenced by URL; one at the project root is inlined as a data URI (the\n * root isn't a served directory). Returns null when the project ships none.\n */\nconst resolveIconFile = (\n project: BlumeProject,\n candidates: string[]\n): BlumeFavicon | null => {\n const { root } = project.context;\n for (const name of candidates) {\n if (existsSync(join(root, \"public\", name))) {\n return { href: `/${name}`, type: faviconType(name) };\n }\n }\n for (const name of candidates) {\n const file = join(root, name);\n if (existsSync(file)) {\n const type = faviconType(name);\n return { href: inlineDataUri(file, type ?? \"image/x-icon\"), type };\n }\n }\n return null;\n};\n\n/**\n * Resolve the site favicon by convention, falling back to the bundled Blume mark\n * when the project ships no `icon.*`/`favicon.*` file. The dark-scheme variant\n * is anchored to the resolved icon: its `-dark` sibling (e.g. `icon.svg` →\n * `icon-dark.svg`) in the same directory — never an unrelated `-dark` file, so a\n * stale or foreign `favicon-dark.*` can't silently pair with a different mark.\n * A `-dark` file with no light sibling is the site's only mark and is used for\n * both schemes, mirroring how `resolveLogo` treats a single-variant image.\n */\nconst resolveFavicon = (project: BlumeProject): BlumeFavicon => {\n const { root } = project.context;\n for (const name of FAVICON_CANDIDATES) {\n if (existsSync(join(root, \"public\", name))) {\n const type = faviconType(name);\n const sibling = darkSibling(name);\n return existsSync(join(root, \"public\", sibling))\n ? { dark: { href: `/${sibling}`, type }, href: `/${name}`, type }\n : { href: `/${name}`, type };\n }\n }\n for (const name of FAVICON_CANDIDATES) {\n const file = join(root, name);\n if (existsSync(file)) {\n const type = faviconType(name);\n const mime = type ?? \"image/x-icon\";\n const siblingFile = join(root, darkSibling(name));\n return existsSync(siblingFile)\n ? {\n dark: { href: inlineDataUri(siblingFile, mime), type },\n href: inlineDataUri(file, mime),\n type,\n }\n : { href: inlineDataUri(file, mime), type };\n }\n }\n return (\n resolveIconFile(project, FAVICON_CANDIDATES.map(darkSibling)) ??\n defaultFavicon()\n );\n};\n\n/**\n * Resolve the Apple touch icon by convention, or null when the project ships\n * none (unlike the favicon, there's no bundled default). Note: iOS ignores\n * `data:`-URI apple-touch-icons, so a `public/` file (served by URL) is the\n * reliable path; a root-level file is still inlined for symmetry with favicons.\n * Deliberately no `-dark` sibling detection here: iOS ignores `media` on\n * `apple-touch-icon` links, so a dark variant could never be served.\n */\nconst resolveAppleIcon = (project: BlumeProject): BlumeFavicon | null =>\n resolveIconFile(project, APPLE_ICON_CANDIDATES);\n\n/** Normalize the banner config (string shorthand or object) for the runtime. */\nconst resolveBanner = (config: ResolvedConfig): BlumeBanner | null => {\n const { banner } = config;\n if (!banner) {\n return null;\n }\n if (isStringShorthand(banner)) {\n return { content: banner, dismissible: false, key: banner };\n }\n return {\n content: banner.content,\n dismissible: banner.dismissible,\n key: banner.id ?? banner.content,\n link: banner.link,\n };\n};\n\n/**\n * The OG card's brand mark: a `seo.og.logo` of `false` opts out of any mark,\n * a configured SVG wins over the site logo, and a non-SVG value resolves to\n * `undefined` (the card falls back to the accent-initial tile).\n */\nconst resolveOgMark = (\n project: BlumeProject,\n siteLogo: string | undefined\n): string | false | undefined => {\n const configured = project.config.seo.og.logo;\n if (configured === false) {\n return false;\n }\n if (configured) {\n return resolveOgLogo(project, configured);\n }\n return siteLogo;\n};\n\n/**\n * The OG card's footer site text. A `seo.og.site` override wins (`false`\n * hides it); the default is the deployment site's host plus the normalized\n * deployment base — on a subpath deploy (a GitHub Pages project site) the\n * bare host is the platform's shared apex, not this site (#139).\n */\nconst resolveOgSite = (config: ResolvedConfig): string | undefined => {\n const configured = config.seo.og.site;\n if (configured === false) {\n return;\n }\n if (configured !== undefined) {\n return configured;\n }\n return config.deployment.site\n ? `${new URL(config.deployment.site).host}${normalizeBasePath(\n config.deployment.base\n )}`\n : undefined;\n};\n\n/**\n * The OG card's site-wide subtitle: `seo.og.description` (`false` omits it)\n * over the site description. The generated endpoint prefers a page's own\n * description and falls back to this.\n */\nconst resolveOgDescription = (config: ResolvedConfig): string | undefined => {\n const configured = config.seo.og.description;\n if (configured === false) {\n return;\n }\n return configured ?? config.description;\n};\n\n/**\n * Repo coordinates for content components. `host` and the derived `api` ride\n * along so a card on an Enterprise site links and queries that instance rather\n * than the public one.\n */\nconst resolveGithubData = (\n github: ResolvedConfig[\"github\"]\n): BlumeData[\"config\"][\"github\"] =>\n github\n ? {\n api: githubApiUrl(github),\n host: github.host,\n owner: github.owner,\n repo: github.repo,\n }\n : null;\n\n/** Serialize the content graph into the data module the runtime consumes. */\nexport const buildRuntimeData = (project: BlumeProject): string => {\n const { config, context, graph, manifest } = project;\n const { github } = config;\n const repoUrl = github ? githubRepoUrl(github) : null;\n const editBase = github ? githubEditBaseUrl(github) : null;\n const logo = resolveLogo(project);\n const ogLogo = resolveOgMark(project, logo?.svg);\n\n const editUrlFor = (sourcePath?: string): string | null => {\n if (!(editBase && sourcePath)) {\n return null;\n }\n const rel = relative(context.root, sourcePath).split(\"\\\\\").join(\"/\");\n // The edit path is repo-relative: `github.dir` places the project inside\n // the repo, so a source above the project dir (a monorepo vault beside the\n // docs app) still resolves to an in-repo file. A path that escapes the\n // repo itself has nothing to edit — fabricating one yields a 404 link.\n // `dir` is a bare string in the schema, so a leading slash (`/apps/docs`)\n // is trimmed rather than read as an absolute path — which would drop the\n // link from every page of a site that has always written it that way.\n const editDir = trimChar(github?.dir ?? \"\", \"/\");\n const editPath = normalize(editDir ? join(editDir, rel) : rel);\n if (editPath.startsWith(\"..\") || isAbsolute(editPath)) {\n return null;\n }\n return `${editBase}/${editPath}`;\n };\n\n const { i18n } = config;\n\n // Resolve the header repo link per locale. API references no longer add a tab\n // automatically — authors point a `navigation.tabs` entry at the reference\n // route to surface it (see `referenceRoutes`).\n const markUrl = headerRepoUrl(config.navigation.repo, repoUrl);\n const withRepoUrl = (nav: Navigation): Navigation => ({\n ...nav,\n repoUrl: markUrl,\n });\n\n // Resolved UI dictionaries: one per locale under i18n, English baseline\n // otherwise. Threaded into chrome so the catch-all can pick the active locale.\n const uiByLocale = i18n\n ? Object.fromEntries(\n i18n.locales.map(({ code }) => [\n code,\n resolveUIStrings(code, {\n defaultLocale: i18n.defaultLocale,\n overrides: i18n.ui,\n }),\n ])\n )\n : {};\n const defaultUi = i18n\n ? resolveUIStrings(i18n.defaultLocale, {\n defaultLocale: i18n.defaultLocale,\n overrides: i18n.ui,\n })\n : EN_UI;\n\n const navigationByLocale = i18n\n ? Object.fromEntries(\n i18n.locales.map(({ code }) => [\n code,\n withRepoUrl(\n graph.navigationByLocale[code] ?? {\n actions: [],\n cta: null,\n featured: [],\n selectors: [],\n sidebar: [],\n tabs: [],\n }\n ),\n ])\n )\n : {};\n\n const data: BlumeData = {\n config: {\n analytics: config.analytics ?? null,\n appleIcon: resolveAppleIcon(project),\n ask: config.ai.ask?.enabled\n ? {\n endpoint: config.ai.ask.endpoint ?? null,\n suggestions: config.ai.ask.suggestions,\n }\n : null,\n banner: resolveBanner(config),\n basePath: config.basePath,\n codeThemes: config.markdown.codeBlocks.theme,\n codeWrap: config.markdown.code.wrap,\n dateFormat: config.dateFormat,\n description: config.description,\n discovery: {\n agentReadability: config.seo.agentReadability,\n api: config.ai.api,\n llmsTxt: config.ai.llmsTxt.enabled,\n // Mirrors `buildSitemapFiles`: no site, no sitemap.\n sitemap: config.seo.sitemap && Boolean(config.deployment.site),\n },\n favicon: resolveFavicon(project),\n feedback: config.feedback,\n github: resolveGithubData(github),\n i18n: i18n\n ? {\n defaultLocale: i18n.defaultLocale,\n // The locale fallback content is rendered from, so the catch-all can\n // set the content direction to the language it's actually written in.\n fallbackLocale: resolveFallbackLocale(i18n),\n hideDefaultLocalePrefix: i18n.hideDefaultLocalePrefix,\n locales: i18n.locales.map(({ code, dir, label }) => ({\n code,\n dir,\n label,\n })),\n }\n : null,\n // `undefined` members drop out of the JSON snapshot; the null keeps the\n // \"nothing configured\" case explicit for the layouts.\n identity:\n config.seo.organization || config.seo.software\n ? {\n organization: config.seo.organization,\n software: config.seo.software,\n }\n : null,\n imageZoom: config.markdown.imageZoom,\n logo,\n mcp: config.ai.mcp.enabled\n ? {\n name: config.ai.mcp.name ?? config.title,\n route: config.ai.mcp.route,\n }\n : null,\n // `og.enabled` is resolved to a definite boolean in `loadConfig`; coerce\n // the optional schema type so the serialized shape stays `boolean`.\n // Card fonts are baked into the generated OG endpoint (they can carry\n // absolute build-machine paths), not serialized here — this snapshot\n // ends up in every page's client data.\n og: {\n description: resolveOgDescription(config),\n enabled: config.seo.og.enabled ?? false,\n logo: ogLogo,\n palette: config.seo.og.palette,\n site: resolveOgSite(config),\n },\n openInChat: config.ai.openInChat,\n repoUrl,\n search: {\n enabled: config.search.provider !== \"none\",\n popular: resolveSearchPopular(config.search.popular, config.basePath),\n provider: config.search.provider,\n },\n site: config.deployment.site ?? null,\n structuredData: config.seo.structuredData,\n theme: config.theme,\n title: config.title,\n toc: config.toc,\n versions: config.versions ?? null,\n webmcp: {\n enabled: config.ai.webmcp,\n llms: config.ai.llmsTxt.enabled,\n },\n x: config.seo.x,\n },\n feeds: buildRssFeeds(project).map((feed) => ({\n href: feed.path,\n title: feed.title,\n })),\n // CSS variables for Astro's <Font> component; matches the astro.config\n // `fonts:` entries derived from the same theme.fonts config (and the\n // same locale-derived subsets, so preloads cover the scripts pages use).\n fontCssVars: configuredFonts(\n config.theme.fonts,\n fontLocaleCodes(config.i18n)\n ),\n navigation: withRepoUrl(graph.navigation),\n // Per-locale navigation; the catch-all selects the active locale's tree.\n navigationByLocale,\n // Per-archived-version navigation; the catch-all selects by the route's\n // version, then locale.\n navigationByVersion: Object.fromEntries(\n Object.entries(graph.navigationByVersion).map(([id, byLocale]) => [\n id,\n Object.fromEntries(\n Object.entries(byLocale).map(([code, nav]) => [\n code,\n withRepoUrl(nav),\n ])\n ),\n ])\n ),\n routes: manifest.routes.map((route) => ({\n alternates: route.alternates,\n collection: route.collection,\n description: route.description ?? null,\n draft: route.draft,\n editUrl: route.editUrl ?? editUrlFor(route.sourcePath),\n entryId: route.entryId,\n fallback: route.fallback ?? false,\n hidden: route.hidden,\n id: route.id,\n indexable: route.indexable,\n lastModified: route.lastModified ?? null,\n locale: route.locale,\n path: route.path,\n title: route.title,\n version: route.version,\n versionAlternates: route.versionAlternates,\n })),\n // Default-locale chrome strings (English baseline when not under i18n).\n ui: defaultUi,\n // Per-locale chrome strings, selected by the catch-all under i18n.\n uiByLocale,\n };\n return `${JSON.stringify(data, null, 2)}\\n`;\n};\n\n/** The resolved plan for the hosted MCP server within a single generate pass. */\ninterface McpPlan {\n /** Directory holding the injected discovery endpoints (`.blume/src/blume-mcp`). */\n dir: string;\n /** `.well-known` discovery routes to inject as prerendered pages. */\n discoveryPages: { entrypoint: string; pattern: string }[];\n enabled: boolean;\n route: string;\n srcDir: string;\n warnings: string[];\n}\n\n/**\n * Decide whether (and how) to generate the MCP server. Skipped — with a\n * warning — when a content page or a custom `.astro` page already occupies its\n * route, so the user's page keeps working instead of colliding.\n */\nconst planMcp = (\n project: BlumeProject,\n srcDir: string,\n userPages: { pattern: string }[]\n): McpPlan => {\n const { config } = project;\n const { route } = config.ai.mcp;\n const dir = join(srcDir, \"blume-mcp\");\n const base: McpPlan = {\n dir,\n discoveryPages: [],\n enabled: false,\n route,\n srcDir,\n warnings: [],\n };\n if (!config.ai.mcp.enabled) {\n return base;\n }\n if (routeIsTaken(userPages, project.graph.pages, route)) {\n return {\n ...base,\n warnings: [\n `MCP server route \"${route}\" is already used by a content or custom page; the MCP server was not generated. Set a different \"ai.mcp.route\" in blume.config.ts.`,\n ],\n };\n }\n return {\n ...base,\n discoveryPages: [\n {\n entrypoint: join(dir, \"discovery.ts\"),\n pattern: \"/.well-known/mcp.json\",\n },\n {\n entrypoint: join(dir, \"server-card.ts\"),\n pattern: \"/.well-known/mcp/server-card.json\",\n },\n ],\n enabled: true,\n };\n};\n\n/** A pass's runtime data modules, published together once every writer ran. */\ntype RuntimeModules = Map<RuntimeModuleId, string>;\n\n/**\n * The agent data snapshot (`blume:mcp-data`) behind the MCP server and the\n * JSON docs API: built once per pass when either is on, published to the\n * runtime modules, and handed to both writers. Null when neither needs it.\n */\nconst publishAgentData = async (\n project: BlumeProject,\n plans: { api: ApiPlan; mcp: McpPlan },\n modules: RuntimeModules\n): Promise<McpData | null> => {\n if (!(plans.mcp.enabled || plans.api.enabled)) {\n return null;\n }\n const data = await buildMcpData(project);\n modules.set(\"blume:mcp-data\", JSON.stringify(data));\n return data;\n};\n\n/** Write the MCP server endpoint and discovery documents. */\nconst writeMcpFiles = async (\n plan: McpPlan,\n write: (path: string, content: string) => Promise<boolean>,\n data: McpData | null\n): Promise<void> => {\n if (!(plan.enabled && data)) {\n return;\n }\n const discoveryInput = {\n base: data.base,\n name: data.name,\n route: plan.route,\n site: data.site,\n version: data.version,\n };\n await Promise.all([\n write(\n join(plan.srcDir, \"pages\", mcpPageFile(plan.route)),\n mcpEndpointTemplate()\n ),\n write(\n join(plan.dir, \"discovery.ts\"),\n staticJsonEndpointTemplate(buildMcpDiscovery(discoveryInput))\n ),\n write(\n join(plan.dir, \"server-card.ts\"),\n staticJsonEndpointTemplate(buildMcpServerCard(discoveryInput))\n ),\n ]);\n};\n\n/** The resolved plan for the JSON docs API within a single generate pass. */\ninterface ApiPlan {\n /**\n * Whether the `/api/` catch-all (JSON 404s) is written: server output, no\n * user page owning a rest route under `/api/`, and no content page served\n * from the `/api` namespace (the catch-all would outrank those pages).\n */\n catchAll: boolean;\n enabled: boolean;\n /** Whether the live endpoints (search) are written — server output only. */\n server: boolean;\n /**\n * Whether `/openapi.json` is generated: skipped when a `public/openapi.json`\n * or a user page owns the route, so a site can publish its own description.\n */\n spec: boolean;\n srcDir: string;\n}\n\n/** Whether a user page pattern is a rest route under `/api/` (`/api/[...x]`). */\nconst ownsApiRest = (page: { pattern: string }): boolean =>\n page.pattern.startsWith(\"/api/[\");\n\n/**\n * Whether a content route lives in the `/api` namespace — a docs section\n * about an API commonly does (`content/api/overview.md` → `/api/overview`).\n * Astro ranks `/api/[...path]` above the content catch-all (`/[...slug]`),\n * so the JSON 404 route would shadow those pages wherever routing decides\n * (the dev server, adapters that don't serve prerendered files first).\n */\nconst contentUnderApi = (page: { route: string }): boolean =>\n page.route === \"/api\" || page.route.startsWith(\"/api/\");\n\n/**\n * Decide what the JSON docs API generates. The prerendered endpoints always\n * ride along when the feature is on (they live under Blume's own `/api/docs/`\n * namespace); the live ones need server output; the OpenAPI description yields\n * to one the project ships itself.\n */\nconst planApi = (\n project: BlumeProject,\n srcDir: string,\n userPages: { pattern: string }[]\n): ApiPlan => {\n const { config, context } = project;\n const server = config.deployment.output === \"server\";\n return {\n catchAll:\n server &&\n !userPages.some(ownsApiRest) &&\n !project.graph.pages.some(contentUnderApi),\n enabled: config.ai.api,\n server,\n spec:\n !routeIsTaken(userPages, project.graph.pages, OPENAPI_PATH) &&\n !existsSync(join(context.root, \"public\", \"openapi.json\")),\n srcDir,\n };\n};\n\n/**\n * Write the JSON docs API: the prerendered page index, per-page documents, and\n * navigation; on server output the search endpoint and the `/api/` catch-all;\n * and the OpenAPI description of the whole agent-facing surface. The MCP\n * route reaches the description only when the server was actually planned (a\n * collision can disable it), so it never advertises an endpoint that isn't\n * there.\n */\nconst writeApiFiles = async (\n project: BlumeProject,\n plan: ApiPlan,\n write: (path: string, content: string) => Promise<boolean>,\n data: McpData | null,\n mcp: McpPlan\n): Promise<void> => {\n if (!(plan.enabled && data)) {\n return;\n }\n const { config } = project;\n const mcpRoute = mcp.enabled ? mcp.route : null;\n const apiDir = join(plan.srcDir, \"pages\", \"api\");\n const writes = [\n write(join(apiDir, \"docs\", \"pages.json.ts\"), apiPagesIndexTemplate()),\n write(\n join(apiDir, \"docs\", \"pages\", \"[...route].json.ts\"),\n apiPageTemplate()\n ),\n write(join(apiDir, \"docs\", \"navigation.json.ts\"), apiNavigationTemplate()),\n ];\n if (plan.server) {\n writes.push(write(join(apiDir, \"docs\", \"search.ts\"), apiSearchTemplate()));\n }\n if (plan.catchAll) {\n writes.push(\n write(\n join(apiDir, \"[...path].ts\"),\n apiNotFoundTemplate({ base: data.base, site: data.site })\n )\n );\n }\n if (plan.spec) {\n writes.push(\n write(\n join(plan.srcDir, \"pages\", \"openapi.json.ts\"),\n staticJsonEndpointTemplate(\n buildApiSpec({\n agentReadability: config.seo.agentReadability,\n base: data.base,\n description: config.description,\n llmsTxt: config.ai.llmsTxt.enabled,\n mcpRoute,\n name: config.title,\n search: plan.server,\n site: data.site,\n version: data.version,\n })\n )\n )\n );\n }\n await Promise.all(writes);\n};\n\n/**\n * Decide whether to generate the playground's built-in CORS proxy endpoint.\n * Only the Blume renderer's playground with `proxy: true` needs it — a proxy\n * URL string points at an external service, and `false` sends requests\n * directly. Injected at `/_api-proxy` (rather than written under `pages/`)\n * because Astro treats `_`-prefixed page files as private; the endpoint's own\n * `prerender = false` export wins over the injection default.\n */\nconst planPlaygroundProxy = (config: ResolvedConfig, srcDir: string) => ({\n enabled: needsPlaygroundProxy(config),\n entrypoint: join(srcDir, \"blume-openapi\", \"api-proxy.ts\"),\n pattern: \"/_api-proxy\",\n});\n\n/**\n * The origins the built-in proxy is allowed to reach: one per absolute\n * `servers[].url` across the parsed specs. This is the endpoint's whole trust\n * boundary — the client sends the target as a query parameter, and a reader's\n * custom base URL is not a documented server — so it is derived here, at build\n * time, from the same documents the operation pages render.\n *\n * Relative (`/v1`) and templated (`{env}.api.example.com`) server URLs carry no\n * origin to allow and are skipped; AsyncAPI documents declare `servers` as a\n * map and contribute nothing (the proxy is OpenAPI-only).\n */\nconst specOriginsOf = (spec: ApiSpecData): string[] => {\n const origins = new Set<string>();\n // A GraphQL schema names no servers; its configured live endpoint is the\n // one origin the playground targets.\n if (spec.endpoint !== undefined) {\n try {\n origins.add(new URL(spec.endpoint).origin);\n } catch {\n // Not an absolute URL: nothing to allow.\n }\n }\n // SAFETY: `document` is arbitrary parsed JSON; the assertion only names\n // the optional `servers` shape, and every access below re-checks it —\n // `Array.isArray(servers)` guards the list and `server.url ?? \"\"` the url.\n const { servers } = spec.document as { servers?: { url?: string }[] };\n for (const server of Array.isArray(servers) ? servers : []) {\n const url = server.url ?? \"\";\n // `new URL(\"https://{region}.api.example.com\")` parses — the braces land\n // in the hostname — so templated URLs need an explicit check or their\n // junk literal becomes an allowlist entry no real request can match.\n if (url.includes(\"{\")) {\n continue;\n }\n try {\n origins.add(new URL(url).origin);\n } catch {\n // Not an absolute URL: nothing to allow.\n }\n }\n return [...origins];\n};\n\nconst specOrigins = (data: OpenApiData): string[] =>\n [...new Set(Object.values(data).flatMap(specOriginsOf))].toSorted();\n\n/**\n * Build-time diagnostics for playground sends the built-in proxy would refuse.\n * The baked-in allowlist pools every documented origin, but each spec's\n * playground only ever targets that spec's own servers/endpoint — so a\n * non-empty pool can still leave one spec's Send 403ing on every request.\n * Hence the check is per spec: any spec routed through the built-in proxy\n * whose own origins came out empty (no absolute `servers[].url`, no absolute\n * GraphQL `endpoint`) gets a warning naming it.\n */\nconst proxyAllowlistWarnings = (\n config: ResolvedConfig,\n data: OpenApiData\n): string[] => {\n const kinds = builtinProxyKinds(config);\n const warnings: string[] = [];\n for (const spec of Object.values(data)) {\n if (!kinds.includes(spec.kind) || specOriginsOf(spec).length > 0) {\n continue;\n }\n warnings.push(\n spec.kind === \"graphql\"\n ? `The \"${spec.label}\" GraphQL reference (${spec.route}) has playground.proxy: true, but no absolute endpoint is configured for it, so the built-in proxy has no origin to allow and will refuse every request its playground sends. Set the graphql block's (or the source's) \\`endpoint\\` to the live GraphQL URL, or point playground.proxy at an external proxy URL.`\n : `The \"${spec.label}\" reference (${spec.route}) has playground.proxy: true, but its spec declares no absolute servers[].url (relative and templated URLs carry no origin), so the built-in proxy has no origin to allow and will refuse every request its playground sends. Add an absolute server URL to the spec, or point playground.proxy at an external proxy URL.`\n );\n }\n return warnings;\n};\n\n/**\n * Write the Ask AI endpoint and, unless the backend runs its own retrieval\n * (Inkeep), the grounding snapshot the endpoint queries at request time. A no-op\n * when Ask AI is disabled.\n */\nconst writeAskFiles = async (\n project: BlumeProject,\n srcDir: string,\n write: (path: string, content: string) => Promise<boolean>,\n modules: RuntimeModules\n): Promise<void> => {\n const { ask } = project.config.ai;\n if (!(ask?.enabled && !ask.endpoint)) {\n return;\n }\n const grounded = ask.provider !== \"inkeep\";\n if (grounded) {\n modules.set(\"blume:ask-data\", JSON.stringify(await buildAskData(project)));\n }\n await write(\n join(srcDir, \"pages\", \"api\", \"ask.ts\"),\n askEndpointTemplate(resolveAskBackend(ask), grounded, {\n cors: ask.cors,\n instructions: ask.instructions,\n reasoning: ask.reasoning,\n retrieval: ask.retrieval,\n })\n );\n};\n\n/**\n * Write the default 404 page at Astro's reserved `src/pages/404.astro` path so\n * static builds emit `dist/404.html`, plus its Markdown twin at `404.md.ts`\n * (`dist/404.md`) for agents that ask a missing URL for Markdown and its JSON\n * twin at `404.json.ts` (`dist/404.json`, RFC 9457 problem details) for those\n * that ask for JSON. All three are skipped when the project already owns\n * `/404` (a custom `pages/404.astro` or a `404.md` content page), letting it\n * be fully overridden without a route collision; `pruneOrphans` then removes\n * any previously-generated copies.\n */\nconst writeNotFoundPage = async (\n write: (path: string, content: string) => Promise<boolean>,\n srcDir: string,\n pages: { pattern: string }[],\n contentPages: { route: string }[]\n): Promise<void> => {\n if (routeIsTaken(pages, contentPages, \"/404\")) {\n return;\n }\n await Promise.all([\n write(join(srcDir, \"pages\", \"404.astro\"), notFoundPageTemplate()),\n write(join(srcDir, \"pages\", \"404.md.ts\"), notFoundMarkdownTemplate()),\n write(join(srcDir, \"pages\", \"404.json.ts\"), notFoundJsonTemplate()),\n ]);\n};\n\n/**\n * Flatten a diagnostic to a single warning line, appending the suggestion when\n * one exists. Exported for testing.\n */\nexport const diagnosticWarning = (diagnostic: Diagnostic): string =>\n diagnostic.suggestion\n ? `${diagnostic.message} ${diagnostic.suggestion}`\n : diagnostic.message;\n\nexport interface GenerateResult {\n /** Whether any structural file changed (config/page/content config). */\n structuralChange: boolean;\n /** Non-fatal warnings raised while generating (e.g. a missing API spec). */\n warnings: string[];\n}\n\n/**\n * Statically analyze the user's `components.ts` (never executing it) and plan the\n * generated `components.ts` module plus any hydration wrappers. Returns the plan\n * and the analyzer's warnings; a project with no components file gets an empty\n * plan and no warnings.\n */\nconst buildComponentSlots = async (\n componentsFile: string | null\n): Promise<{\n plan: ComponentSlotPlan;\n /** MDX tags the overrides define (for the unknown-component check). */\n tags: string[];\n warnings: string[];\n}> => {\n const analysis = componentsFile\n ? analyzeComponentOverrides(\n await readFile(componentsFile, \"utf-8\"),\n componentsFile\n )\n : null;\n return {\n plan: planComponentSlots(componentsFile, analysis),\n tags: analysis\n ? [...analysis.mdx, ...analysis.islands].map((entry) => entry.key)\n : [],\n warnings: analysis ? analysis.warnings : [],\n };\n};\n\n/** The OG endpoint fonts for a scanned project (see {@link resolveOgFonts}). */\nconst projectOgFonts = (project: BlumeProject): DerivedOgFonts =>\n resolveOgFonts(\n {\n ogFonts: project.config.seo.og.fonts,\n themeFonts: project.config.theme.fonts,\n themeFontsConfigured: project.themeFontsConfigured,\n },\n project.context.root\n );\n\n/**\n * Fail generation when a configured local font file is missing. Warning and\n * continuing is not an option here — the path is emitted into the Astro\n * config and the OG endpoint, which would crash later with a bare ENOENT.\n */\nconst assertFontFilesExist = (project: BlumeProject): void => {\n const { config, context } = project;\n const missing = missingFontFiles(\n { ogFonts: config.seo.og.fonts ?? [], themeFonts: config.theme.fonts },\n context.root\n );\n if (missing.length > 0) {\n throw new BlumeError({\n code: \"BLUME_FONT_FILE_MISSING\",\n message: `Configured font file(s) not found: ${missing.join(\", \")}. Font paths resolve relative to the project root.`,\n severity: \"error\",\n });\n }\n};\n\n/**\n * The client libraries a site needs (see `featuresTemplate`): the EPUB\n * generator when `export.epub` is on, and the Mermaid element when any page's\n * source has a mermaid fence — read from the raw-Markdown mirrors (every\n * route's verbatim source) and, for sources that carry their text on the\n * page record, the record itself.\n */\nexport const clientFeaturesFrom = (\n project: BlumeProject,\n rawMarkdown: Record<string, RawMarkdownEntry>\n): ClientFeatures => ({\n epub: project.config.export.epub,\n mermaid:\n Object.values(rawMarkdown).some((entry) =>\n hasMermaidFence(entry.mdx ?? entry.md ?? \"\")\n ) ||\n project.graph.pages.some(\n (page) => page.body !== undefined && hasMermaidFence(page.body.text)\n ),\n});\n\n/**\n * The theme's code-block icon rules for the languages the site's Markdown\n * uses (see `languageIconCss`), read from the raw-Markdown mirrors and the\n * page records that carry their text.\n */\nexport const languageIconCssFrom = (\n project: BlumeProject,\n rawMarkdown: Record<string, RawMarkdownEntry>\n): string =>\n languageIconCss(\n languageIconSlugsIn(\n [\n ...Object.values(rawMarkdown).map(\n (entry) => entry.mdx ?? entry.md ?? \"\"\n ),\n ...project.graph.pages.map((page) => page.body?.text ?? \"\"),\n ].join(\"\\n\")\n )\n );\n\n/** {@link languageIconCssFrom} over a fresh read of the raw Markdown (eject). */\nexport const languageIconCssFor = async (\n project: BlumeProject\n): Promise<string> =>\n languageIconCssFrom(project, await buildRawMarkdown(project));\n\n/**\n * The deferred sidebar fragments page, only when some group is a disclosure\n * or a drill-in panel — a flat sidebar renders every row on every page, so\n * there is nothing to fetch. A previous pass's page is an orphan the\n * generator removes when the sidebar goes flat again.\n */\nconst writeNavFragments = (\n write: (path: string, content: string) => Promise<boolean>,\n srcDir: string,\n navFragments: boolean\n): Promise<boolean> =>\n navFragments\n ? write(\n join(\n srcDir,\n \"pages\",\n \"blume-nav\",\n \"[version]\",\n \"[locale]\",\n \"[id].astro\"\n ),\n navFragmentTemplate()\n )\n : Promise.resolve(false);\n\n/** {@link clientFeaturesFrom} over a fresh read of the raw Markdown (eject). */\nexport const clientFeaturesFor = async (\n project: BlumeProject\n): Promise<ClientFeatures> =>\n clientFeaturesFrom(project, await buildRawMarkdown(project));\n\n/**\n * Write (or update) the generated `.blume/` Astro runtime for a project.\n * Only files whose content changed are rewritten so Vite HMR stays fast.\n */\nexport const generateRuntime = async (\n project: BlumeProject\n): Promise<GenerateResult> => {\n const { context, config } = project;\n assertFontFilesExist(project);\n const out = context.outDir;\n const srcDir = join(out, \"src\");\n const generatedDir = join(srcDir, \"generated\");\n const askPath = join(srcDir, \"generated\", \"Ask.astro\");\n const themePath = join(srcDir, \"generated\", \"app.css\");\n const searchClientPath = join(srcDir, \"generated\", \"search-client.ts\");\n const featuresPath = join(srcDir, \"generated\", \"features.ts\");\n const examplesPath = join(srcDir, \"generated\", \"examples.ts\");\n const examplesThemePath = join(srcDir, \"generated\", \"examples.css\");\n\n // Record every file this pass writes so orphans (from a now-disabled feature)\n // can be pruned afterwards. `write` wraps the atomic writer and tracks paths.\n const written = new Set<string>();\n const write = (path: string, content: string): Promise<boolean> => {\n written.add(normalize(path));\n return writeIfChanged(path, content);\n };\n // The data snapshots the generated pages import (`blume:data`, the search\n // index, …) are collected here and published in memory at the end of the\n // pass — see `runtime-modules.ts`. An id a feature leaves unset is\n // unpublished, the in-memory counterpart of `pruneOrphans`.\n const modules: RuntimeModules = new Map();\n\n const depsLinkWarning = await ensureDepsLink(out);\n\n // The dev negotiation inputs. Published in memory (below) rather than baked\n // into the generated config, so a content-route change never rewrites\n // `astro.config.mjs` — which would restart the dev server in place.\n const contentRoutes = markdownRoutePaths(project);\n const homeLinkHeader =\n buildHomeLinkHeader(config, contentRoutes) ?? undefined;\n\n const askEnabled = config.ai.ask?.enabled ?? false;\n const exportPdf = config.export.pdf;\n const exportEpub = config.export.epub;\n // Every route's source Markdown: published as `blume:raw-markdown` below,\n // and inspected here for the client features the site needs.\n const rawMarkdown = await buildRawMarkdown(project);\n const clientFeatures = clientFeaturesFrom(project, rawMarkdown);\n const navFragments = navVariants(project.graph).some(({ navigation }) =>\n hasDeferrableGroups(navigation.sidebar)\n );\n const languageIcons = languageIconCssFrom(project, rawMarkdown);\n // Staged (non-filesystem) sources materialize into `.blume/content`; keyed by\n // entryId so i18n duplicates of one entry write a single file. Collected here\n // so math detection also sees staged bodies (they never live under root).\n const staged = collectStaged(project);\n // Statically analyze `components.ts` overrides (never executed): drives the\n // `islands` group, hydration on layout/mdx overrides, string-path resolution,\n // and the \"framework component with no client mode\" diagnostic. Independent of\n // the discovery reads, so it joins the same parallel batch.\n const [\n pages,\n detectedReact,\n usesMath,\n userTheme,\n userExamplesCss,\n integrationBridge,\n islandDiscovery,\n exampleDiscovery,\n componentSlots,\n ] = await Promise.all([\n context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),\n detectNeedsReact(context.root),\n detectUsesMath(context.root, staged.values()),\n readUserCss(context.themeFile, generatedDir),\n readUserCss(examplesCssFile(context.root, config), generatedDir),\n loadIntegrationBridge(config, context),\n discoverIslands(context.root),\n discoverExamples(context.root, config.examples.source),\n buildComponentSlots(context.componentsFile),\n ]);\n const {\n plan: slotPlan,\n tags: overrideTags,\n warnings: overrideWarnings,\n } = componentSlots;\n // Expose the discovered examples for agent-facing Markdown downleveling\n // (`<Component>` → source) before any consumer (raw `.md`, MCP, llms) runs.\n project.examples = exampleMarkdownLookup(exampleDiscovery.examples);\n\n // Each island/example framework enables its Astro renderer. React also\n // switches on for any project `.tsx`/`.jsx` and for Ask AI; Vue/Svelte are\n // island/example-driven. `.astro` examples need no renderer. Component\n // overrides referencing a framework component enable its renderer too.\n const frameworks = new Set<string>([\n ...islandDiscovery.islands.map((island) => island.framework),\n ...exampleDiscovery.examples.map((example) => example.framework),\n ...slotPlan.frameworks,\n ]);\n const needsReact = detectedReact || askEnabled || frameworks.has(\"react\");\n const needsVue = frameworks.has(\"vue\");\n const needsSvelte = frameworks.has(\"svelte\");\n\n // Absolute path to the React Compiler babel plugin (null when off). Resolved\n // here, Node-side, so the generated config points babel straight at Blume's\n // shipped copy — see resolveReactCompiler. Any unresolved-but-requested\n // warning is folded into `warnings` below (declared later).\n const reactCompilerPath = resolveReactCompiler(config, needsReact);\n\n // Custom pages that should get a generated OG card (the home most of all).\n // Computed before the MCP `.well-known` routes are appended below — those are\n // private and filtered out anyway, but the intent is the user's pages.\n const ogRoutes = customOgRoutes(pages, config.title, config.seo.og.titles);\n\n // Whether the generated `/changelog` index exists — shared by the OG endpoint\n // (which adds the index's own card) and the page write below. Computed here,\n // before the MCP discovery pages are appended, on the user's own pages.\n const changelogIndex = hasGeneratedChangelog(project, pages);\n\n // The hosted MCP server. The `.well-known` discovery docs are injected as\n // prerendered routes alongside user pages; the server endpoint itself is a\n // normal (server-rendered) page written by `writeMcpFiles`.\n const mcp = planMcp(project, srcDir, pages);\n pages.push(...mcp.discoveryPages);\n\n // The JSON docs API shares the MCP server's snapshot; build it once when\n // either is on.\n const api = planApi(project, srcDir, pages);\n const agentData = await publishAgentData(project, { api, mcp }, modules);\n\n // The parsed OpenAPI specs behind the `blume:openapi` alias, also the source\n // of the proxy's origin allowlist below. The source parsed them during the\n // scan, so reading them here is free.\n const openApiSource = project.sources.find(isOpenApiSource);\n const openApiData = openApiSource ? openApiSource.openApiData() : {};\n\n // The playground's built-in CORS proxy rides the same injection path as the\n // MCP discovery docs; the endpoint itself opts out of prerendering.\n const playgroundProxy = planPlaygroundProxy(config, srcDir);\n if (playgroundProxy.enabled) {\n pages.push({\n entrypoint: playgroundProxy.entrypoint,\n pattern: playgroundProxy.pattern,\n });\n }\n // Computed once: the endpoint template bakes it in below. A spec that\n // contributes no origin of its own gets a per-spec diagnostic\n // (`proxyAllowlistWarnings`) — the proxy would refuse its every send.\n const proxyOrigins = specOrigins(openApiData);\n\n const hasStaged = staged.size > 0;\n // Only emit a project-scanning `docs` collection when a filesystem source\n // actually feeds it. An all-staged project (openapi/notion/…) has only staged\n // sources, so the `docs` glob would otherwise scan (and watch) the whole\n // project root for nothing — see contentConfigTemplate.\n const hasFilesystemSource = project.sources.some((source) => !source.staged);\n const docsCollection = resolveDocsCollection(config, context);\n\n // All of these write to distinct generated paths and never read one another's\n // output, so the structural files, the per-convention hydration wrappers, and\n // the Ask/MCP writers all run in one parallel batch. Only the structural\n // writes' change flags feed `structuralChange`, so they stay a nested group.\n const [structural] = await Promise.all([\n Promise.all([\n write(\n join(out, \"astro.config.mjs\"),\n astroConfigTemplate({\n aliases: resolveTsconfigAliases(context.root),\n askPath,\n config,\n contentRoot: docsCollection.base,\n contentRoutes,\n context,\n examplesPath,\n examplesThemePath,\n features: clientFeatures,\n featuresPath,\n integrationBridge,\n needsReact,\n needsSvelte,\n needsVue,\n pages,\n reactCompilerPath,\n searchClientPath,\n themePath,\n })\n ),\n write(\n join(out, \"package.json\"),\n runtimePackageTemplate(\n runtimeDependencies({ config, needsReact, needsSvelte, needsVue })\n )\n ),\n write(join(out, \"tsconfig.json\"), runtimeTsconfigTemplate()),\n write(\n join(srcDir, \"content.config.ts\"),\n contentConfigTemplate({\n collection: docsCollection,\n config,\n context,\n filesystem: hasFilesystemSource,\n staged: hasStaged,\n })\n ),\n write(\n join(srcDir, \"pages\", \"[...slug].astro\"),\n catchAllPageTemplate({\n exportEpub,\n exportPdf,\n mathEnabled: usesMath,\n navFragments,\n needsReact,\n })\n ),\n writeNavFragments(write, srcDir, navFragments),\n // The header's Ask trigger, behind the `blume:ask` alias. Always written\n // (even when Ask is off, as a component that renders nothing) so the alias\n // resolves — the same contract as `blume:search-client`.\n write(askPath, askComponentTemplate(askEnabled)),\n write(join(srcDir, \"generated\", \"components.ts\"), slotPlan.module),\n write(\n join(srcDir, \"generated\", \"islands.ts\"),\n islandMapTemplate(islandDiscovery.islands)\n ),\n write(\n join(srcDir, \"generated\", \"examples.ts\"),\n exampleMapTemplate(exampleDiscovery.examples, config.basePath)\n ),\n // The isolated Tailwind entry for `<Component />` preview frames: only\n // the project (and an out-of-root examples directory) is scanned, so the\n // docs theme never reaches a preview. Anything further afield — a sibling\n // package the examples import — is the user's `@source` in examples.css.\n write(\n examplesThemePath,\n examplesEntryTemplate({\n configTokens: buildThemeCss(config.theme),\n sources: exampleScanRoots(context.root, exampleDiscovery.dir).map(\n (dir) => `${dir}/${EXAMPLE_SCAN_GLOB}`\n ),\n userCss: userExamplesCss,\n })\n ),\n write(\n themePath,\n tailwindEntryTemplate({\n configTokens: `${buildThemeCss(config.theme)}${buildFontsCss(config.theme.fonts)}`,\n languageIcons,\n sources: [\n `${BLUME_SRC}/**/*.{astro,ts,tsx}`,\n `${context.root}/**/*.{astro,mdx,ts,tsx}`,\n ],\n twoslashCss: twoslashCss(),\n userTheme,\n })\n ),\n ]),\n // Per-island hydration wrappers for the `islands/` convention. The map\n // module (written above, always) imports these; orphans from removed\n // islands are pruned at the end of the pass.\n Promise.all(\n islandDiscovery.islands.map((island) =>\n write(\n join(srcDir, \"generated\", \"islands\", `${island.name}.astro`),\n islandWrapperTemplate(island)\n )\n )\n ),\n // Per-override hydration wrappers for `defineComponents` islands and\n // `client:*` layout/mdx overrides. The generated `components.ts` (written\n // above) imports these; orphans from removed overrides are pruned at the\n // end of the pass.\n Promise.all(\n slotPlan.wrappers.map((wrapper) =>\n write(\n join(srcDir, \"generated\", \"component-slots\", `${wrapper.name}.astro`),\n wrapper.content\n )\n )\n ),\n // Per-example live wrappers for the `examples/` convention, resolved by\n // `<Component path>` through the `examples.ts` map (written above, always).\n Promise.all(\n exampleDiscovery.examples.map((example) =>\n write(\n join(\n srcDir,\n \"generated\",\n \"examples\",\n `${exampleSlug(example.path)}.astro`\n ),\n exampleWrapperTemplate(example)\n )\n )\n ),\n writeAskFiles(project, srcDir, write, modules),\n writeMcpFiles(mcp, write, agentData),\n writeApiFiles(project, api, write, agentData, mcp),\n playgroundProxy.enabled\n ? write(playgroundProxy.entrypoint, playgroundProxyTemplate(proxyOrigins))\n : Promise.resolve(false),\n ]);\n\n if (config.seo.og.enabled) {\n await write(\n join(srcDir, \"pages\", \"og\", \"[...slug].png.ts\"),\n ogEndpointTemplate(\n ogRoutes,\n {\n ...projectOgFonts(project),\n cache: {\n dir: ogCacheDir(project.context),\n version: getBlumeVersion(),\n },\n pageDescriptions: config.seo.og.description !== false,\n },\n changelogIndex\n )\n );\n }\n\n // Changelog index (`/changelog`), rendered through the Update timeline layout.\n if (changelogIndex) {\n await write(\n join(srcDir, \"pages\", \"changelog.astro\"),\n changelogIndexTemplate({\n exportEpub,\n exportPdf,\n mathEnabled: usesMath,\n needsReact,\n staged: hasStaged,\n })\n );\n }\n\n // Three independent writes: the per-example preview routes that\n // `<Component />` iframes embed (returning a warning when the configured\n // examples.css is missing), the default 404 page (`/404`, unless the project\n // already owns the route), and the provider-specific client loader behind\n // the `blume:search-client` alias — always (re)generated so the alias\n // resolves even when search is disabled.\n const [examplesWarnings] = await Promise.all([\n writeExamplesPreview({\n config,\n hasExamples: exampleDiscovery.examples.length > 0,\n root: context.root,\n srcDir,\n write,\n }),\n writeNotFoundPage(write, srcDir, pages, project.graph.pages),\n write(searchClientPath, searchClientTemplate(config)),\n write(featuresPath, featuresTemplate(clientFeatures)),\n ]);\n\n // Client-loaded providers (orama, flexsearch) ship a static index + endpoint.\n if (servesStaticIndex(config.search.provider)) {\n const documents = await buildSearchDocuments(project);\n modules.set(\"blume:search-index\", JSON.stringify(documents));\n await write(\n join(srcDir, \"pages\", \"blume-search.json.ts\"),\n searchEndpointTemplate()\n );\n }\n\n // Mixedbread proxies queries through a server endpoint that holds the key.\n if (config.search.provider === \"mixedbread\") {\n await write(\n join(srcDir, \"pages\", \"api\", \"search.ts\"),\n mixedbreadSearchEndpointTemplate(config.search.mixedbread?.storeId ?? \"\")\n );\n }\n\n // The include graph (partial → including pages) behind `includeHmrPlugin`:\n // editing a partial invalidates every page that splices it. Written even\n // when empty so the plugin's configured path always resolves.\n await write(\n join(srcDir, \"generated\", \"includes.json\"),\n `${JSON.stringify(buildIncludeGraph(project.graph.pages))}\\n`\n );\n\n modules.set(\"blume:raw-markdown\", JSON.stringify(rawMarkdown));\n // The originals behind the rewritten `/blume-assets/content/…` references in\n // the agent-facing Markdown, plus the endpoint that serves them (and the\n // remote-source assets materialized under `.blume/public/blume-assets`).\n const contentAssets = await collectContentAssets(project);\n modules.set(\"blume:content-assets\", JSON.stringify(contentAssets));\n await Promise.all([\n write(\n join(srcDir, \"pages\", \"[...slug].md.ts\"),\n rawMarkdownEndpointTemplate(\"md\")\n ),\n write(\n join(srcDir, \"pages\", \"[...slug].mdx.ts\"),\n rawMarkdownEndpointTemplate(\"mdx\")\n ),\n write(\n join(srcDir, \"pages\", \"blume-assets\", \"[...asset].ts\"),\n contentAssetsEndpointTemplate(\n join(project.context.outDir, \"public\", \"blume-assets\")\n )\n ),\n ]);\n\n // Automatic RSS feeds for blog/changelog content types (a no-op when no such\n // pages exist or no deployment.site is configured).\n const feeds = buildRssFeeds(project);\n if (feeds.length > 0) {\n const feedXml = Object.fromEntries(\n feeds.map((feed) => [feed.type, renderRssFeed(feed)])\n );\n modules.set(\"blume:rss\", JSON.stringify(feedXml));\n await write(\n join(srcDir, \"pages\", \"[section]\", \"rss.xml.ts\"),\n rssEndpointTemplate()\n );\n }\n\n // Scalar-rendered API/AsyncAPI reference pages (`renderer: \"scalar\"`). One\n // self-contained page per source, mounted on its configured route and\n // regenerated each run.\n const warnings: string[] = [\n ...(depsLinkWarning ? [depsLinkWarning] : []),\n ...proxyAllowlistWarnings(config, openApiData),\n ...reactCompilerWarnings(config, needsReact, reactCompilerPath),\n ...mcp.warnings,\n ...islandDiscovery.warnings,\n ...exampleDiscovery.warnings,\n ...examplesWarnings,\n ...overrideWarnings,\n ];\n\n // Missing-navigation-target check, now that every servable route is known:\n // content routes, custom `.astro` pages, the generated changelog, and any\n // OpenAPI reference routes (so a tab an author points at one still validates).\n const navTargetRoutes = new Set<string>([\n ...project.graph.routes.keys(),\n ...pages.map((page) => page.pattern),\n ...referenceRoutes(config),\n ]);\n if (changelogIndex) {\n navTargetRoutes.add(\"/changelog\");\n }\n // Curated `search.popular` icons live outside the navigation model, so they\n // miss `validateNavIcons` in the graph build — they're checked here too,\n // where the search config is known. A typo otherwise just renders the\n // default glyph.\n warnings.push(\n ...[\n ...validateNavTargets(project.graph.navigation, navTargetRoutes),\n ...validateSearchPopularIcons(config.search.popular),\n ].map(diagnosticWarning)\n );\n\n // Unknown-component check: a `<Tag>` in MDX that isn't a built-in, an island,\n // or a `components.ts` override. Needs the project's own components, known here.\n const knownComponentTags = new Set<string>([\n ...islandDiscovery.islands.map((island) => island.name),\n ...overrideTags,\n ]);\n // Missing-dependency preflights: the search provider's SDK, the Ask AI\n // backend's provider SDK, the deployment adapter's package, and — since\n // React ships with Blume while Vue/Svelte don't — any island framework's\n // Astro integration. Warn early rather than let Vite fail to resolve them\n // opaquely.\n warnings.push(\n ...validateUsedComponents(\n project.graph.pages,\n knownComponentTags,\n new Set(registry.map((item) => item.name))\n ).map(diagnosticWarning),\n ...searchProviderWarnings(config.search.provider, context.root),\n ...askProviderWarnings(config.ai.ask, context.root),\n ...deploymentAdapterWarnings(config.deployment, context.root),\n ...islandFrameworkWarnings(frameworks, context.root)\n );\n if (hasScalarReferences(config)) {\n const references = await buildReferenceFiles({\n config,\n contentRoutes: new Set(project.graph.pages.map((page) => page.route)),\n root: context.root,\n });\n warnings.push(...references.warnings);\n await Promise.all(\n references.files.map((file) =>\n write(join(srcDir, \"pages\", file.pagePath), file.content)\n )\n );\n }\n\n // `blume:openapi` is always published — even as `{}` — so the import resolves\n // whether or not a reference is enabled; the specs were parsed during the\n // scan, so this is just serialization. `blume:data` is the page data every\n // layout reads. Neither is \"structural\" for Astro; publishing hot-reloads.\n modules.set(\"blume:data\", buildRuntimeData(project));\n modules.set(\"blume:openapi\", JSON.stringify(openApiData));\n // These write to distinct trees and never read one another, so they batch.\n // `writeStagedContent` owns the `.blume/content` tree (its own pruning),\n // outside `.blume/src`, so a removed remote entry doesn't linger.\n await Promise.all([\n write(\n join(out, \"blume.manifest.json\"),\n `${JSON.stringify(project.manifest, null, 2)}\\n`\n ),\n writeStagedContent(out, staged),\n ]);\n\n // Remove anything under `.blume/src` this pass didn't write — e.g. an Ask AI\n // endpoint left behind after the feature was switched off.\n await pruneOrphans(srcDir, written);\n\n // Publish last, once every page that imports a module is on disk: a live\n // dev server invalidates the changed modules and reloads the browser against\n // the finished tree, never a half-written one.\n publishDevNegotiation({ contentRoutes, homeLinkHeader });\n publishRuntimeModules(modules);\n\n return { structuralChange: structural.some(Boolean), warnings };\n};\n",
|
|
12
12
|
"/**\n * RFC 9457 problem details — the one error shape every Blume JSON endpoint\n * returns, so an agent that hits a missing page, a bad query, or an unknown\n * API route always gets a stable machine-readable `code`, a human-readable\n * `detail`, and a `resolution` telling it where to go next.\n */\n\nexport const PROBLEM_TYPE = \"application/problem+json\";\n\n/** A recovery link carried on a problem (the 404's \"where to look next\"). */\nexport interface ProblemLink {\n href: string;\n label: string;\n}\n\nexport interface Problem {\n /** Stable, screaming-snake error code for programmatic handling. */\n code: string;\n /** Human-readable explanation specific to this occurrence. */\n detail: string;\n /** The request path the problem occurred on, when known. */\n instance?: string;\n /** Recovery links, when the problem has somewhere useful to send the caller. */\n links?: ProblemLink[];\n /** What to do next — the hint agents act on. */\n resolution: string;\n status: number;\n title: string;\n /** Problem type URI; `about:blank` when the status code says it all. */\n type: string;\n}\n\n/** The problem's members, with `type` defaulting to `about:blank`. */\nexport const problem = (\n input: Omit<Problem, \"type\"> & { type?: string }\n): Problem => {\n const body: Problem = {\n code: input.code,\n detail: input.detail,\n resolution: input.resolution,\n status: input.status,\n title: input.title,\n type: input.type ?? \"about:blank\",\n };\n if (input.instance !== undefined) {\n body.instance = input.instance;\n }\n if (input.links !== undefined) {\n body.links = input.links;\n }\n return body;\n};\n\n/** A `Response` carrying the problem as `application/problem+json`. */\nexport const problemResponse = (\n input: Omit<Problem, \"type\"> & { type?: string }\n): Response => {\n const body = problem(input);\n return new Response(`${JSON.stringify(body, null, 2)}\\n`, {\n headers: { \"Content-Type\": `${PROBLEM_TYPE}; charset=utf-8` },\n status: body.status,\n });\n};\n",
|
|
13
13
|
"import { apiNamePhrase } from \"../../core/api-name.ts\";\nimport { withBasePath } from \"../../core/base-path.ts\";\nimport { absoluteUrl, siteRoot } from \"../../core/site-url.ts\";\nimport {\n API_NAVIGATION_PATH,\n API_PAGE_PATH,\n API_PAGES_PATH,\n API_SEARCH_PATH,\n} from \"./paths.ts\";\nimport { PROBLEM_TYPE } from \"./problem.ts\";\n\n/**\n * The OpenAPI 3.1 description of a Blume site's machine-readable surface,\n * served at `/openapi.json`. It documents the JSON docs API (`/api/docs/…`)\n * in full — one `operationId` and description per operation, typed\n * parameters, response schemas, and the RFC 9457 problem shape every error\n * uses — and lists the text surfaces alongside (the `.md` mirrors, `llms.txt`,\n * `llms-full.txt`, `agent-readability.json`) plus the MCP endpoint, so a\n * function-calling framework that ingests OpenAPI gets the same reach an MCP\n * client has. Generated per build from config, so it only describes what the\n * deployed site actually serves.\n */\n\n/** What the document needs to know about the site. */\nexport interface ApiSpecInput {\n /** Whether `agent-readability.json` is published. */\n agentReadability: boolean;\n /** Normalized `deployment.base` (`\"\"` or `/seg`). */\n base: string;\n description?: string;\n /** Whether `llms.txt`/`llms-full.txt` are published. */\n llmsTxt: boolean;\n /** The MCP server's route, or null when the server is off. */\n mcpRoute: string | null;\n name: string;\n /** Whether the live search endpoint exists (server output only). */\n search: boolean;\n site: string | null;\n /** The generating Blume version — the API contract's version. */\n version: string;\n}\n\n/** A schema reference into `components.schemas`. */\ninterface SchemaRef {\n $ref: string;\n}\n\n/** An inline schema, as the text and generic-object responses use. */\ninterface InlineSchema {\n type: string;\n}\n\ninterface MediaType {\n schema: InlineSchema | SchemaRef;\n}\n\n/** A response object: its description and the media types it may carry. */\ninterface ResponseObject {\n content?: Record<string, MediaType>;\n description: string;\n}\n\n/** A parameter object, as this builder emits it. */\ninterface Parameter {\n description: string;\n explode?: boolean;\n in: \"path\" | \"query\";\n name: string;\n required: boolean;\n schema: object;\n style?: \"deepObject\" | \"form\";\n}\n\n/** An operation object, as this builder emits it. */\nexport interface Operation {\n description: string;\n operationId: string;\n parameters?: Parameter[];\n requestBody?: { content: Record<string, MediaType>; required: boolean };\n responses: Record<string, ResponseObject>;\n summary: string;\n tags: string[];\n}\n\n/** A path item: the HTTP methods this builder emits. */\nexport interface PathItem {\n get?: Operation;\n post?: Operation;\n}\n\ninterface Tag {\n description: string;\n name: string;\n}\n\ninterface Info {\n description: string;\n title: string;\n version: string;\n \"x-generator\": string;\n}\n\n/** The OpenAPI document, as this builder emits it. */\nexport interface ApiSpecDocument {\n components: { schemas: typeof schemas };\n externalDocs?: { description: string; url: string };\n info: Info;\n openapi: \"3.1.0\";\n paths: Record<string, PathItem>;\n security: never[];\n servers: { description: string; url: string }[];\n tags: Tag[];\n}\n\nconst JSON_TYPE = \"application/json\";\nconst MARKDOWN_TYPE = \"text/markdown\";\nconst TEXT_TYPE = \"text/plain\";\n\nconst ref = (name: string): SchemaRef => ({\n $ref: `#/components/schemas/${name}`,\n});\n\nconst jsonResponse = (description: string, schema: string): ResponseObject => ({\n content: { [JSON_TYPE]: { schema: ref(schema) } },\n description,\n});\n\nconst problemResponse = (description: string): ResponseObject => ({\n content: { [PROBLEM_TYPE]: { schema: ref(\"Problem\") } },\n description,\n});\n\nconst textResponse = (description: string, type: string): ResponseObject => ({\n content: { [type]: { schema: { type: \"string\" } } },\n description,\n});\n\nconst string = (description: string) => ({ description, type: \"string\" });\n\nconst facetsSchema = {\n additionalProperties: { type: \"string\" },\n description:\n \"Facet values the site declares for the page's content type (`content.types.<type>.facets`), key → value.\",\n type: \"object\",\n};\n\nconst versionProperty = {\n description:\n 'Docs version the page belongs to on a versioned site: `\"\"` for the current docs, else an archived version id. Absent on unversioned sites.',\n type: \"string\",\n};\n\n/** The shared filter parameters of the search operation. */\nconst searchParameters: Parameter[] = [\n {\n description: \"The search query.\",\n in: \"query\",\n name: \"q\",\n required: true,\n schema: { minLength: 1, type: \"string\" },\n },\n {\n description: \"Maximum hits to return (default 8, at most 20).\",\n in: \"query\",\n name: \"limit\",\n required: false,\n schema: { default: 8, maximum: 20, minimum: 1, type: \"integer\" },\n },\n {\n description:\n \"Only include pages of these content types (frontmatter `type`, e.g. `doc`, `rfc`). Comma-separated or repeated. Omit for every type.\",\n explode: false,\n in: \"query\",\n name: \"contentTypes\",\n required: false,\n schema: { items: { type: \"string\" }, type: \"array\" },\n style: \"form\",\n },\n {\n description:\n \"Only include pages in this locale (e.g. `fr`). Omit for every language.\",\n in: \"query\",\n name: \"locale\",\n required: false,\n schema: { type: \"string\" },\n },\n {\n description:\n \"Docs version to scope to on a versioned site: `latest` (the default — current docs only), `all`, or an archived version id. Ignored when the site is unversioned.\",\n in: \"query\",\n name: \"version\",\n required: false,\n schema: { type: \"string\" },\n },\n {\n description:\n \"Only include pages matching every facet, as `filters[key]=value` pairs (e.g. `filters[status]=enforced`). Facets are metadata the site declares per content type; the page index shows each page's values.\",\n explode: true,\n in: \"query\",\n name: \"filters\",\n required: false,\n schema: { additionalProperties: { type: \"string\" }, type: \"object\" },\n style: \"deepObject\",\n },\n];\n\nconst schemas = {\n JsonRpcRequest: {\n description: \"A JSON-RPC 2.0 request, as the Model Context Protocol sends.\",\n properties: {\n id: { description: \"Request id (absent on notifications).\" },\n jsonrpc: { const: \"2.0\", type: \"string\" },\n method: string(\"The MCP method, e.g. `initialize` or `tools/call`.\"),\n params: { description: \"Method parameters.\", type: \"object\" },\n },\n required: [\"jsonrpc\", \"method\"],\n type: \"object\",\n },\n JsonRpcResponse: {\n description: \"A JSON-RPC 2.0 response: a `result` or an `error`.\",\n properties: {\n error: {\n properties: {\n code: { type: \"integer\" },\n data: {},\n message: { type: \"string\" },\n },\n required: [\"code\", \"message\"],\n type: \"object\",\n },\n id: {},\n jsonrpc: { const: \"2.0\", type: \"string\" },\n result: { type: \"object\" },\n },\n required: [\"jsonrpc\"],\n type: \"object\",\n },\n NavLink: {\n properties: {\n href: string(\"Link target — an internal route or an external URL.\"),\n icon: string(\"Optional icon name.\"),\n label: { type: \"string\" },\n },\n required: [\"href\", \"label\"],\n type: \"object\",\n },\n NavNode: {\n description:\n \"A sidebar entry: a page (linking to its route) or a group holding further nodes.\",\n oneOf: [\n {\n properties: {\n badge: { type: \"string\" },\n deprecated: { type: \"boolean\" },\n description: { type: \"string\" },\n icon: { type: \"string\" },\n kind: { const: \"page\", type: \"string\" },\n label: { type: \"string\" },\n pageId: string(\"The page's stable content id.\"),\n route: string(\"The page's route.\"),\n },\n required: [\"kind\", \"label\", \"pageId\", \"route\"],\n type: \"object\",\n },\n {\n properties: {\n badge: { type: \"string\" },\n children: { items: ref(\"NavNode\"), type: \"array\" },\n collapsed: { type: \"boolean\" },\n icon: { type: \"string\" },\n kind: { const: \"group\", type: \"string\" },\n label: { type: \"string\" },\n path: string(\"The group's route prefix (not necessarily a page).\"),\n route: string(\"The group's index page route, when it has one.\"),\n },\n required: [\"children\", \"kind\", \"label\"],\n type: \"object\",\n },\n ],\n },\n NavSelector: {\n description:\n \"A top-level partition selector (products, versions, languages).\",\n properties: {\n items: {\n items: {\n properties: {\n description: { type: \"string\" },\n label: { type: \"string\" },\n path: { type: \"string\" },\n tag: { type: \"string\" },\n },\n required: [\"label\", \"path\"],\n type: \"object\",\n },\n type: \"array\",\n },\n kind: { type: \"string\" },\n label: { type: \"string\" },\n },\n required: [\"items\", \"kind\", \"label\"],\n type: \"object\",\n },\n NavTab: {\n properties: {\n href: string(\n \"The clickable target when it differs from `path` (the section's first page).\"\n ),\n icon: { type: \"string\" },\n label: { type: \"string\" },\n path: string(\"The tab's section prefix.\"),\n },\n required: [\"label\", \"path\"],\n type: \"object\",\n },\n Navigation: {\n description:\n \"The docs navigation model: header tabs, the sidebar tree, partition selectors, and pinned links.\",\n properties: {\n actions: { items: ref(\"NavLink\"), type: \"array\" },\n cta: { oneOf: [ref(\"NavLink\"), { type: \"null\" }] },\n featured: { items: ref(\"NavLink\"), type: \"array\" },\n repoUrl: { type: [\"string\", \"null\"] },\n root: string(\"The tree root's route (`/`, or a locale/version prefix).\"),\n selectors: { items: ref(\"NavSelector\"), type: \"array\" },\n sidebar: { items: ref(\"NavNode\"), type: \"array\" },\n tabs: { items: ref(\"NavTab\"), type: \"array\" },\n },\n required: [\"featured\", \"selectors\", \"sidebar\", \"tabs\"],\n type: \"object\",\n },\n Page: {\n allOf: [\n ref(\"PageSummary\"),\n {\n properties: {\n markdown: string(\n \"The page as agent Markdown: frontmatter included, components downleveled to plain Markdown.\"\n ),\n },\n required: [\"markdown\"],\n type: \"object\",\n },\n ],\n description: \"A page's index entry plus its full Markdown body.\",\n },\n PageSummary: {\n properties: {\n contentType: string(\"The page's content type (frontmatter `type`).\"),\n description: { type: \"string\" },\n facets: facetsSchema,\n json: {\n description:\n \"This page's JSON representation (the `getPage` operation).\",\n format: \"uri-reference\",\n type: \"string\",\n },\n lastModified: {\n description: \"ISO 8601 last-modified date, when known.\",\n type: [\"string\", \"null\"],\n },\n locale: string(\"The page's locale code.\"),\n markdownUrl: {\n description:\n \"The page's raw-Markdown mirror (the `getPageMarkdown` operation).\",\n format: \"uri-reference\",\n type: \"string\",\n },\n route: string(\n \"The page's route (`/guides/install`); the key every other operation takes.\"\n ),\n title: { type: \"string\" },\n url: {\n description: \"Where the rendered page is served.\",\n format: \"uri-reference\",\n type: \"string\",\n },\n version: versionProperty,\n },\n required: [\n \"contentType\",\n \"json\",\n \"lastModified\",\n \"locale\",\n \"markdownUrl\",\n \"route\",\n \"title\",\n \"url\",\n ],\n type: \"object\",\n },\n PagesIndex: {\n properties: {\n count: { type: \"integer\" },\n generator: string(\"The Blume version that built the site.\"),\n pages: { items: ref(\"PageSummary\"), type: \"array\" },\n site: { type: [\"string\", \"null\"] },\n },\n required: [\"count\", \"generator\", \"pages\", \"site\"],\n type: \"object\",\n },\n Problem: {\n description:\n \"RFC 9457 problem details, with a stable code and a resolution hint.\",\n properties: {\n code: string(\"Stable error code (e.g. `PAGE_NOT_FOUND`).\"),\n detail: string(\"Human-readable explanation of this occurrence.\"),\n instance: string(\"The request path the problem occurred on.\"),\n links: {\n description: \"Recovery links, when there is somewhere useful to go.\",\n items: {\n properties: { href: { type: \"string\" }, label: { type: \"string\" } },\n required: [\"href\", \"label\"],\n type: \"object\",\n },\n type: \"array\",\n },\n resolution: string(\"What to do next.\"),\n status: { type: \"integer\" },\n title: { type: \"string\" },\n type: string(\"Problem type URI; `about:blank` by default.\"),\n },\n required: [\"code\", \"detail\", \"resolution\", \"status\", \"title\", \"type\"],\n type: \"object\",\n },\n SearchHit: {\n properties: {\n contentType: { type: \"string\" },\n excerpt: string(\"The page description, else the start of its content.\"),\n facets: facetsSchema,\n route: string(\"The page's route; pass it to `getPage`.\"),\n title: { type: \"string\" },\n url: { format: \"uri-reference\", type: \"string\" },\n version: versionProperty,\n },\n required: [\"excerpt\", \"route\", \"title\", \"url\"],\n type: \"object\",\n },\n SearchResponse: {\n properties: {\n count: { type: \"integer\" },\n query: { type: \"string\" },\n results: { items: ref(\"SearchHit\"), type: \"array\" },\n },\n required: [\"count\", \"query\", \"results\"],\n type: \"object\",\n },\n};\n\nconst ROUTE_PARAM: Parameter = {\n description:\n \"The page route without its leading slash (`guides/install`), or `index` for the home page. May contain slashes.\",\n in: \"path\",\n name: \"route\",\n required: true,\n schema: { type: \"string\" },\n};\n\n/** The document's `servers[0].url`: the site origin plus base, or the base. */\nconst serverUrl = (input: ApiSpecInput): string => {\n if (input.site) {\n return input.base\n ? absoluteUrl(input.site, input.base)\n : siteRoot(input.site);\n }\n return input.base || \"/\";\n};\n\n/** Build the OpenAPI document. Plain data, ready to serialize. */\nexport const buildApiSpec = (input: ApiSpecInput): ApiSpecDocument => {\n const pathEntries: [string, PathItem][] = [\n [\n API_PAGES_PATH,\n {\n get: {\n description:\n \"Every documentation page with its route, title, description, content type, locale, facets, and the URLs of its rendered, Markdown, and JSON forms. Unfiltered; on a versioned site every version is listed with its `version`. Use it to enumerate the docs or to find a page when search is too narrow.\",\n operationId: \"listPages\",\n responses: {\n \"200\": jsonResponse(\"The page index.\", \"PagesIndex\"),\n default: problemResponse(\"An error, as problem details.\"),\n },\n summary: \"List every page\",\n tags: [\"Pages\"],\n },\n },\n ],\n [\n API_PAGE_PATH,\n {\n get: {\n description:\n \"A single page as JSON: its index entry plus the page's agent Markdown (frontmatter included, components downleveled to plain Markdown). Take `route` from `listPages` or `searchDocs`.\",\n operationId: \"getPage\",\n parameters: [ROUTE_PARAM],\n responses: {\n \"200\": jsonResponse(\"The page.\", \"Page\"),\n \"404\": problemResponse(\"No page has that route.\"),\n default: problemResponse(\"An error, as problem details.\"),\n },\n summary: \"Get a page as JSON\",\n tags: [\"Pages\"],\n },\n },\n ],\n [\n API_NAVIGATION_PATH,\n {\n get: {\n description:\n \"The navigation tree (header tabs and the sidebar hierarchy) as readers see it, for the default locale and the current docs.\",\n operationId: \"getNavigation\",\n responses: {\n \"200\": jsonResponse(\"The navigation tree.\", \"Navigation\"),\n default: problemResponse(\"An error, as problem details.\"),\n },\n summary: \"Get the navigation tree\",\n tags: [\"Navigation\"],\n },\n },\n ],\n ];\n if (input.search) {\n pathEntries.push([\n API_SEARCH_PATH,\n {\n get: {\n description:\n \"Full-text search across the documentation. Returns matching pages with their title, route, content type, and a short excerpt; narrow by content type, locale, version, or facet. Use it first to discover relevant pages, then `getPage` to read one in full.\",\n operationId: \"searchDocs\",\n parameters: searchParameters,\n responses: {\n \"200\": jsonResponse(\n \"The matching pages, best first.\",\n \"SearchResponse\"\n ),\n \"400\": problemResponse(\"The query was missing or blank.\"),\n default: problemResponse(\"An error, as problem details.\"),\n },\n summary: \"Search the docs\",\n tags: [\"Search\"],\n },\n },\n ]);\n }\n pathEntries.push([\n \"/{route}.md\",\n {\n get: {\n description:\n \"A page's raw-Markdown mirror: append `.md` to any page URL. Components are downleveled to plain Markdown; `.mdx` serves the source as written. The same body the `getPage` operation carries in its `markdown` field.\",\n operationId: \"getPageMarkdown\",\n parameters: [ROUTE_PARAM],\n responses: {\n \"200\": textResponse(\"The page as Markdown.\", MARKDOWN_TYPE),\n \"404\": textResponse(\n \"No page has that route; the body lists where to look next.\",\n MARKDOWN_TYPE\n ),\n },\n summary: \"Get a page as Markdown\",\n tags: [\"Markdown\"],\n },\n },\n ]);\n if (input.llmsTxt) {\n pathEntries.push(\n [\n \"/llms.txt\",\n {\n get: {\n description:\n \"The llms.txt index: the site's summary, when to use it, and every page with a one-line description, grouped by section.\",\n operationId: \"getLlmsTxt\",\n responses: {\n \"200\": textResponse(\"The index.\", TEXT_TYPE),\n },\n summary: \"Get llms.txt\",\n tags: [\"Markdown\"],\n },\n },\n ],\n [\n \"/llms-full.txt\",\n {\n get: {\n description:\n \"The full Markdown of every current-docs page in one file.\",\n operationId: \"getLlmsFullTxt\",\n responses: {\n \"200\": textResponse(\"Every page's Markdown.\", TEXT_TYPE),\n },\n summary: \"Get llms-full.txt\",\n tags: [\"Markdown\"],\n },\n },\n ]\n );\n }\n if (input.agentReadability) {\n pathEntries.push([\n \"/agent-readability.json\",\n {\n get: {\n description:\n \"A manifest indexing every agent-facing artifact the site publishes — this API, the Markdown mirrors, llms.txt, the MCP server, feeds, and the sitemap.\",\n operationId: \"getAgentReadability\",\n responses: {\n \"200\": {\n content: { [JSON_TYPE]: { schema: { type: \"object\" } } },\n description: \"The manifest.\",\n },\n },\n summary: \"Get the agent-readability manifest\",\n tags: [\"Discovery\"],\n },\n },\n ]);\n }\n if (input.mcpRoute) {\n pathEntries.push([\n input.mcpRoute,\n {\n post: {\n description:\n \"The Model Context Protocol server (Streamable HTTP, stateless, JSON responses). Tools: `search_docs`, `get_page`, `list_pages`, `get_navigation` — the same operations this API exposes — plus every page as a `text/markdown` resource. Discovery document at `/.well-known/mcp.json`.\",\n operationId: \"mcp\",\n requestBody: {\n content: { [JSON_TYPE]: { schema: ref(\"JsonRpcRequest\") } },\n required: true,\n },\n responses: {\n \"200\": jsonResponse(\"The JSON-RPC response.\", \"JsonRpcResponse\"),\n },\n summary: \"Call the MCP server\",\n tags: [\"MCP\"],\n },\n },\n ]);\n }\n\n const tags: Tag[] = [\n { description: \"Enumerate and read documentation pages.\", name: \"Pages\" },\n ...(input.search\n ? [{ description: \"Full-text search over the docs.\", name: \"Search\" }]\n : []),\n { description: \"How the docs are organized.\", name: \"Navigation\" },\n { description: \"Plain-text and Markdown surfaces.\", name: \"Markdown\" },\n ...(input.agentReadability\n ? [{ description: \"Agent discovery documents.\", name: \"Discovery\" }]\n : []),\n ...(input.mcpRoute\n ? [{ description: \"The Model Context Protocol endpoint.\", name: \"MCP\" }]\n : []),\n ];\n\n const info: Info = {\n description: [\n `Read-only JSON API over the ${input.name} documentation${input.description ? `: ${input.description}` : \".\"}`,\n \"Every operation is public and needs no authentication. Errors are RFC 9457 problem details (`application/problem+json`) with a stable `code`, a `detail`, and a `resolution` hint.\",\n ].join(\"\\n\\n\"),\n title: apiNamePhrase(input.name),\n version: input.version,\n \"x-generator\": `blume@${input.version}`,\n };\n const document: ApiSpecDocument = {\n components: { schemas },\n info,\n openapi: \"3.1.0\",\n paths: Object.fromEntries(pathEntries),\n security: [],\n servers: [{ description: input.name, url: serverUrl(input) }],\n tags,\n };\n if (input.site) {\n document.externalDocs = {\n description: `${input.name} documentation`,\n url: absoluteUrl(input.site, withBasePath(input.base, \"/\")),\n };\n }\n return document;\n};\n",
|
|
14
14
|
"import type { BlumeProject } from \"../core/project-graph.ts\";\nimport { buildSearchDocuments } from \"../search/documents.ts\";\nimport type { AskData } from \"./ask-context.ts\";\n\n/**\n * Build the grounding snapshot the Ask AI endpoint serves. Like the MCP server,\n * Ask AI is independent of on-page search, so documents are indexed even when the\n * search provider is `none` (`includeWhenDisabled`). `locale` is kept (unlike the\n * MCP snapshot) so retrieval can be filtered to the current page's language, and\n * content is kept as Markdown so grounding sees fenced code examples — the model\n * answers \"what does the config look like?\" from the docs instead of declining.\n * The reader is an AI agent, so `<Visibility>` resolves for the agents audience\n * (web-only content removed, agents-only unwrapped) and components downlevel to\n * Markdown, both matching llms-full.txt.\n */\nexport const buildAskData = async (project: BlumeProject): Promise<AskData> => {\n const documents = await buildSearchDocuments(project, {\n audience: \"agents\",\n content: \"markdown\",\n includeWhenDisabled: true,\n });\n return {\n defaultLocale: project.config.i18n?.defaultLocale,\n documents: documents.map((doc) => ({\n content: doc.content,\n description: doc.description,\n locale: doc.locale,\n route: doc.route,\n title: doc.title,\n })),\n site: project.config.deployment.site ?? null,\n };\n};\n",
|
|
15
15
|
"import { withBasePath } from \"../../core/base-path.ts\";\nimport { absoluteUrl, siteRoot } from \"../../core/site-url.ts\";\nimport { trimChar } from \"../../core/trim.ts\";\nimport { MCP_TOOLS } from \"./tools.ts\";\nimport type { McpToolMeta } from \"./tools.ts\";\n\n/** Inputs needed to describe the MCP server in discovery documents. */\nexport interface McpDiscoveryInput {\n /** Normalized `deployment.base` (`\"\"` or `/seg`); the route is base-less. */\n base: string;\n name: string;\n route: string;\n site: string | null;\n version: string;\n}\n\n/** The MCP server's address — absolute when a site is configured. */\nconst serverUrl = (input: McpDiscoveryInput): string => {\n // The endpoint is a generated Astro page, so it's served under\n // `deployment.base` like every other route (the sitemap/llms.txt convention).\n const path = withBasePath(input.base, input.route);\n // Concatenate rather than `new URL(path, site)` — a root-absolute path\n // would drop the base path of a subpath deployment (`acme.com/docs`).\n return input.site ? absoluteUrl(input.site, path) : path;\n};\n\n/**\n * The `/.well-known/mcp.json` discovery document: the minimal pointer agents use\n * to find the server and its transport.\n */\nexport const buildMcpDiscovery = (input: McpDiscoveryInput) => ({\n servers: [\n {\n name: input.name,\n transport: \"streamable-http\",\n url: serverUrl(input),\n },\n ],\n});\n\n/** The published `/v1/` Server Card schema (SEP-2127 extension). */\nconst SERVER_CARD_SCHEMA =\n \"https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json\";\n\n/** The schema caps `description` (and `title`) at 100 characters. */\nconst CARD_TEXT_MAX = 100;\n\nconst truncate = (text: string): string =>\n text.length > CARD_TEXT_MAX ? `${text.slice(0, CARD_TEXT_MAX - 1)}…` : text;\n\n// The server-card schema constrains `name` to `namespace/server` in ASCII\n// (`^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$`), so the display name cannot reuse the\n// route slugifier, which keeps Unicode letters. Decompose (NFKD) and drop\n// combining marks first so an accented name transliterates (`Café` → `cafe`)\n// instead of losing the letter.\nconst NON_ASCII_SLUG = /[^a-z0-9]+/gu;\nconst COMBINING_MARKS = /\\p{M}+/gu;\n\nconst asciiSlugify = (text: string): string =>\n trimChar(\n text\n .normalize(\"NFKD\")\n .replace(COMBINING_MARKS, \"\")\n .toLowerCase()\n .replace(NON_ASCII_SLUG, \"-\"),\n \"-\"\n );\n\n/**\n * The card's identity in the schema's reverse-DNS `namespace/server` form:\n * the site hostname reversed (`useblume.dev` → `dev.useblume`), or\n * `localhost` when no site is configured, plus the slugged display name (an\n * entirely non-ASCII name falls back to `docs`).\n */\nconst reverseDnsName = (input: McpDiscoveryInput): string => {\n let namespace = \"localhost\";\n if (input.site) {\n try {\n namespace = new URL(input.site).hostname\n .split(\".\")\n .toReversed()\n .join(\".\");\n } catch {\n // Not a parsable URL; the local namespace is honest enough.\n }\n }\n return `${namespace}/${asciiSlugify(input.name) || \"docs\"}`;\n};\n\nconst HTTP_URL = /^https?:\\/\\//u;\n\n/**\n * The `/.well-known/mcp/server-card.json` document. The core follows the\n * SEP-2127 Server Card extension schema (`$schema`, reverse-DNS `name`,\n * `remotes` — which the schema requires to be absolute, so it appears only\n * when a `site` is configured). Alongside it ride initialize-shaped compat\n * fields (`serverInfo`, `capabilities`, `transports`) for scanners built\n * against the SEP's earlier revision, plus Blume's advertised tool set —\n * schema-legal extras (`additionalProperties` is open), and the tool list is\n * genuinely static for a docs server, unlike the dynamic servers the spec\n * excludes primitives for. Full input schemas are served live via\n * `tools/list`.\n */\nexport interface McpServerCard {\n $schema: string;\n capabilities: {\n resources: { listChanged: boolean; subscribe: boolean };\n tools: { listChanged: boolean };\n };\n description: string;\n name: string;\n /** Absolute endpoints only — present when a `site` is configured. */\n remotes?: { type: string; url: string }[];\n serverInfo: { name: string; version: string };\n title: string;\n tools: McpToolMeta[];\n transport: string;\n transports: { endpoint: string; type: string }[];\n url: string;\n version: string;\n websiteUrl?: string;\n}\n\nexport const buildMcpServerCard = (input: McpDiscoveryInput): McpServerCard => {\n const url = serverUrl(input);\n const card: McpServerCard = {\n $schema: SERVER_CARD_SCHEMA,\n // Resources mirror the page list (one `text/markdown` resource per page);\n // a rebuilt site replaces the server wholesale, so nothing changes live.\n capabilities: {\n resources: { listChanged: false, subscribe: false },\n tools: { listChanged: false },\n },\n description: truncate(\n `Model Context Protocol server for the ${input.name} documentation.`\n ),\n name: reverseDnsName(input),\n serverInfo: { name: input.name, version: input.version },\n title: truncate(input.name),\n tools: MCP_TOOLS.map((tool) => ({\n annotations: tool.annotations,\n description: tool.description,\n name: tool.name,\n title: tool.title,\n })),\n transport: \"streamable-http\",\n transports: [{ endpoint: url, type: \"streamable-http\" }],\n url,\n version: input.version,\n };\n if (HTTP_URL.test(url)) {\n card.remotes = [{ type: \"streamable-http\", url }];\n }\n if (input.site) {\n card.websiteUrl = siteRoot(input.site);\n }\n return card;\n};\n",
|
|
16
|
-
"import { isRootTab, isUnderPath } from \"../../core/navigation.ts\";\nimport type { NavNode, NavTab, Navigation } from \"../../core/types.ts\";\n\n/** A flat, ordered page reference used for previous/next pagination. */\nexport interface FlatPage {\n route: string;\n label: string;\n deprecated?: boolean;\n}\n\n/** A breadcrumb segment; `route` is absent for non-clickable group ancestors. */\nexport interface Crumb {\n label: string;\n route?: string;\n}\n\n/** Flatten the sidebar tree into ordered internal page links. */\nexport const flattenPages = (nodes: NavNode[]): FlatPage[] => {\n const out: FlatPage[] = [];\n const seen = new Set<string>();\n const add = (page: FlatPage): void => {\n if (seen.has(page.route)) {\n return;\n }\n seen.add(page.route);\n out.push(page);\n };\n const walk = (items: NavNode[]): void => {\n for (const item of items) {\n if (item.kind === \"group\") {\n if (item.route) {\n add({ label: item.label, route: item.route });\n }\n walk(item.children);\n } else if (item.pageId) {\n // Skip external links (no backing page).\n add(\n item.deprecated\n ? { deprecated: true, label: item.label, route: item.route }\n : { label: item.label, route: item.route }\n );\n }\n }\n };\n walk(nodes);\n return out;\n};\n\n/** Find the breadcrumb trail (group ancestors + page) for a route. */\nexport const findBreadcrumbs = (nodes: NavNode[], route: string): Crumb[] => {\n const search = (items: NavNode[], trail: Crumb[]): Crumb[] | null => {\n for (const item of items) {\n if (item.kind === \"page\") {\n if (item.route === route) {\n return [...trail, { label: item.label, route: item.route }];\n }\n } else {\n const crumb: Crumb = item.route\n ? { label: item.label, route: item.route }\n : { label: item.label };\n if (item.route === route) {\n return [...trail, crumb];\n }\n const found = search(item.children, [...trail, crumb]);\n if (found) {\n return found;\n }\n }\n }\n return null;\n };\n return search(nodes, []) ?? [];\n};\n\n/**\n * The tab whose `path` is the longest prefix of `route`. The root tab (`/`)\n * acts as the fallback when no more specific tab matches.\n */\nexport const activeTabForRoute = (\n tabs: NavTab[],\n route: string\n): NavTab | null => {\n let match: NavTab | null = null;\n for (const tab of tabs) {\n if (!isUnderPath(route, tab.path)) {\n continue;\n }\n if (!match || tab.path.length > match.path.length) {\n match = tab;\n }\n }\n return match;\n};\n\n/**\n * The tab to mark as the current one (`aria-current`) for `route`. Same\n * longest-prefix match as {@link activeTabForRoute}, except inside an archived\n * version tree: the root tab claims every archived route through its\n * spans-everything fallback while its link points back at the current docs, so\n * no tab is genuinely current there.\n */\nexport const currentTabForRoute = (\n tabs: NavTab[],\n route: string,\n root = \"/\"\n): NavTab | null => {\n const tab = activeTabForRoute(tabs, route);\n // The root tab sitting away from the tree root means the tree is a version\n // snapshot in a different path space — the tab matched as a fallback, not\n // because it owns the route.\n if (tab && isRootTab(tab, root) && tab.path !== root) {\n return null;\n }\n return tab;\n};\n\n/**\n * The children of the group whose path is `base`, searched at any depth — so a\n * content tree wrapped in a top-level container group still resolves to the\n * right section. Returns null when no group sits exactly at `base`.\n */\nconst sectionChildren = (nodes: NavNode[], base: string): NavNode[] | null => {\n for (const node of nodes) {\n if (node.kind !== \"group\") {\n continue;\n }\n if (node.path === base || node.route === base) {\n return node.children;\n }\n const deeper = sectionChildren(node.children, base);\n if (deeper) {\n return deeper;\n }\n }\n return null;\n};\n\n/** Whether a group maps to a header tab (matched on its path or link route). */\nconst isTabSection = (node: NavNode, tabPaths: Set<string>): boolean => {\n if (node.kind !== \"group\") {\n return false;\n }\n const byPath = node.path !== undefined && tabPaths.has(node.path);\n const byRoute = node.route !== undefined && tabPaths.has(node.route);\n return byPath || byRoute;\n};\n\n/**\n * Drop the groups that already own a header tab from the tree, at any depth —\n * so a root/un-tabbed route lists only the pages outside every tab's section\n * instead of duplicating each tab as a sidebar group. A container left empty by\n * this pruning is dropped too, so no bare heading is stranded. The root tab\n * spans everything, so it never removes anything.\n */\nconst withoutTabSections = (\n nodes: NavNode[],\n tabs: NavTab[],\n root: string\n): NavNode[] => {\n const tabPaths = new Set<string>();\n for (const tab of tabs) {\n if (!isRootTab(tab, root)) {\n tabPaths.add(tab.path);\n }\n }\n if (tabPaths.size === 0) {\n return nodes;\n }\n const prune = (items: NavNode[]): NavNode[] => {\n const kept: NavNode[] = [];\n for (const item of items) {\n if (isTabSection(item, tabPaths)) {\n continue;\n }\n if (item.kind === \"group\") {\n // A container left empty by pruning is dropped, so no bare heading is\n // stranded.\n const children = prune(item.children);\n if (children.length > 0) {\n kept.push({ ...item, children });\n }\n } else {\n kept.push(item);\n }\n }\n return kept;\n };\n return prune(nodes);\n};\n\n/**\n * Scope the sidebar to the active tab's section. With tabs configured, a route\n * under one tab shows only that tab's group — so a multi-section site (e.g.\n * Adapters / API / AI tabs) drills each tab into its own pages instead of one\n * global tree, the way Fumadocs' root folders do. On a route under no tab (or\n * the root tab), the tab-owned groups are hidden so the root sidebar shows\n * only pages that don't belong to a tab.\n *\n * `root` is the tree root (`Navigation.root`), localized and based like tab\n * paths — under i18n or a `basePath` the root tab sits at `/en` or `/docs`,\n * not `/`, and a bare-`/` comparison would misread it as a section tab (a\n * root-level `(group)` folder's path is exactly that prefix, so the sidebar\n * collapsed to that one group or blanked entirely). In an archived version\n * tree the root is versionized (`/v1.0`) while tab paths stay in current-docs\n * space, so root-tab checks use {@link isRootTab} containment, not equality:\n * the root tab owns no group in a snapshot, and misreading it as a section\n * tab blanked the archived sidebar.\n *\n * When a matched tab owns no sidebar group — a standalone page like the\n * generated changelog timeline (`/changelog`), or a tab whose source produced\n * no pages — the sidebar is empty. It must not fall back to the full tree: that\n * would leak every *other* tab's section (e.g. the OpenAPI operations) onto the\n * page. On a route under no tab, hiding the tab sections falls back to the full\n * sidebar only when it would otherwise blank, so an un-tabbed route stays full.\n */\nexport const sidebarForRoute = (\n sidebar: NavNode[],\n tabs: NavTab[],\n route: string,\n root = \"/\"\n): NavNode[] => {\n const tab = activeTabForRoute(tabs, route);\n if (tab && !isRootTab(tab, root)) {\n return sectionChildren(sidebar, tab.path) ?? [];\n }\n const scoped = withoutTabSections(sidebar, tabs, root);\n return scoped.length > 0 ? scoped : sidebar;\n};\n\n/** Resolve previous/next pages around the current route. */\nexport const getPagination = (flat: FlatPage[], route: string) => {\n const index = flat.findIndex((page) => page.route === route);\n if (index === -1) {\n return { next: null, prev: null };\n }\n return {\n next: flat[index + 1] ?? null,\n prev: index > 0 ? (flat[index - 1] ?? null) : null,\n };\n};\n\n/**\n * A stable id for every group in a sidebar — `g<n>` by pre-order position in\n * the full tree. The layout hands `NavTree` a scoped view of that tree (a\n * tab's section, or the sidebar minus the tab sections), so positions within\n * the rendered slice differ from page to page; these ids name the same group\n * everywhere, which the drill-in panels and the deferred-section fragments\n * (`/blume-nav/…`) rely on. Keyed by node identity: the scoped views reuse\n * the full tree's node objects.\n */\nexport const navGroupIds = (sidebar: NavNode[]): Map<NavNode, string> => {\n const ids = new Map<NavNode, string>();\n const walk = (nodes: NavNode[]): void => {\n for (const node of nodes) {\n if (node.kind === \"group\") {\n ids.set(node, `g${ids.size}`);\n walk(node.children);\n }\n }\n };\n walk(sidebar);\n return ids;\n};\n\n/** Whether any group in a sidebar renders as a disclosure or a drill-in panel. */\nexport const hasDeferrableGroups = (sidebar: NavNode[]): boolean =>\n sidebar.some(\n (node) =>\n node.kind === \"group\" &&\n ((node.display ?? \"flat\") !== \"flat\" ||\n hasDeferrableGroups(node.children))\n );\n\n/** One of the navigation trees a site renders, by URL segment. */\nexport interface NavVariant {\n /** `current`, or an archived version id. */\n version: string;\n /** `default`, or a locale code. */\n locale: string;\n navigation: Navigation;\n}\n\n/**\n * Every navigation tree the runtime data holds — the default, each locale's,\n * and each archived version's per locale — keyed the way the deferred\n * sidebar fragments' URLs are (`/blume-nav/<version>/<locale>/…`). An\n * unlocalized version tree is keyed by `\"\"` in the data; it maps to\n * `default` here.\n */\nexport const navVariants = (data: {\n navigation: Navigation;\n navigationByLocale: Record<string, Navigation>;\n navigationByVersion: Record<string, Record<string, Navigation>>;\n}): NavVariant[] => [\n { locale: \"default\", navigation: data.navigation, version: \"current\" },\n ...Object.entries(data.navigationByLocale).map(([locale, navigation]) => ({\n locale,\n navigation,\n version: \"current\",\n })),\n ...Object.entries(data.navigationByVersion).flatMap(([version, byLocale]) =>\n Object.entries(byLocale).map(([locale, navigation]) => ({\n locale: locale || \"default\",\n navigation,\n version,\n }))\n ),\n];\n",
|
|
16
|
+
"import { isRootTab, isUnderPath } from \"../../core/navigation.ts\";\nimport type { NavNode, NavTab, Navigation } from \"../../core/types.ts\";\n\n/** A flat, ordered page reference used for previous/next pagination. */\nexport interface FlatPage {\n route: string;\n label: string;\n deprecated?: boolean;\n}\n\n/** A breadcrumb segment; `route` is absent for non-clickable group ancestors. */\nexport interface Crumb {\n label: string;\n route?: string;\n}\n\n/** Flatten the sidebar tree into ordered internal page links. */\nexport const flattenPages = (nodes: NavNode[]): FlatPage[] => {\n const out: FlatPage[] = [];\n const seen = new Set<string>();\n const add = (page: FlatPage): void => {\n if (seen.has(page.route)) {\n return;\n }\n seen.add(page.route);\n out.push(page);\n };\n const walk = (items: NavNode[]): void => {\n for (const item of items) {\n if (item.kind === \"group\") {\n if (item.route) {\n add({ label: item.label, route: item.route });\n }\n walk(item.children);\n } else if (item.pageId) {\n // Skip external links (no backing page).\n add(\n item.deprecated\n ? { deprecated: true, label: item.label, route: item.route }\n : { label: item.label, route: item.route }\n );\n }\n }\n };\n walk(nodes);\n return out;\n};\n\n/** Find the breadcrumb trail (group ancestors + page) for a route. */\nexport const findBreadcrumbs = (nodes: NavNode[], route: string): Crumb[] => {\n const search = (items: NavNode[], trail: Crumb[]): Crumb[] | null => {\n for (const item of items) {\n if (item.kind === \"page\") {\n if (item.route === route) {\n return [...trail, { label: item.label, route: item.route }];\n }\n } else {\n const crumb: Crumb = item.route\n ? { label: item.label, route: item.route }\n : { label: item.label };\n if (item.route === route) {\n return [...trail, crumb];\n }\n const found = search(item.children, [...trail, crumb]);\n if (found) {\n return found;\n }\n }\n }\n return null;\n };\n return search(nodes, []) ?? [];\n};\n\n/**\n * The tab whose `path` is the longest prefix of `route`. The root tab (`/`)\n * acts as the fallback when no more specific tab matches.\n */\nexport const activeTabForRoute = (\n tabs: NavTab[],\n route: string\n): NavTab | null => {\n let match: NavTab | null = null;\n for (const tab of tabs) {\n if (!isUnderPath(route, tab.path)) {\n continue;\n }\n if (!match || tab.path.length > match.path.length) {\n match = tab;\n }\n }\n return match;\n};\n\n/**\n * The tab to mark as the current one (`aria-current`) for `route`. Same\n * longest-prefix match as {@link activeTabForRoute}, except inside an archived\n * version tree: the root tab claims every archived route through its\n * spans-everything fallback while its link points back at the current docs, so\n * no tab is genuinely current there.\n */\nexport const currentTabForRoute = (\n tabs: NavTab[],\n route: string,\n root = \"/\"\n): NavTab | null => {\n const tab = activeTabForRoute(tabs, route);\n // The root tab sitting away from the tree root means the tree is a version\n // snapshot in a different path space — the tab matched as a fallback, not\n // because it owns the route.\n if (tab && isRootTab(tab, root) && tab.path !== root) {\n return null;\n }\n return tab;\n};\n\n/**\n * The children of the group whose path is `base`, searched at any depth — so a\n * content tree wrapped in a top-level container group still resolves to the\n * right section. Returns null when no group sits exactly at `base`.\n */\nconst sectionChildren = (nodes: NavNode[], base: string): NavNode[] | null => {\n for (const node of nodes) {\n if (node.kind !== \"group\") {\n continue;\n }\n if (node.path === base || node.route === base) {\n return node.children;\n }\n const deeper = sectionChildren(node.children, base);\n if (deeper) {\n return deeper;\n }\n }\n return null;\n};\n\n/** Whether a group maps to a header tab (matched on its path or link route). */\nconst isTabSection = (node: NavNode, tabPaths: Set<string>): boolean => {\n if (node.kind !== \"group\") {\n return false;\n }\n const byPath = node.path !== undefined && tabPaths.has(node.path);\n const byRoute = node.route !== undefined && tabPaths.has(node.route);\n return byPath || byRoute;\n};\n\n/**\n * Drop the groups that already own a header tab from the tree, at any depth —\n * so a root/un-tabbed route lists only the pages outside every tab's section\n * instead of duplicating each tab as a sidebar group. A container left empty by\n * this pruning is dropped too, so no bare heading is stranded. The root tab\n * spans everything, so it never removes anything.\n *\n * A group with no tab section anywhere beneath it is kept as the same object:\n * the stable group ids (`navGroupIds`) and the build-time subtree cache are\n * both keyed by node identity, so a copy would lose its id — its collapsed\n * fragment was then requested by a positional name no route serves — and\n * re-render on every page. A container that did lose a section is rebuilt,\n * so it has no id: the deferred fragments render from the full tree, which\n * would put the section back, so `NavTree` renders such a container in full\n * instead (its untouched children still defer by their own ids).\n */\nconst withoutTabSections = (\n nodes: NavNode[],\n tabs: NavTab[],\n root: string\n): NavNode[] => {\n const tabPaths = new Set<string>();\n for (const tab of tabs) {\n if (!isRootTab(tab, root)) {\n tabPaths.add(tab.path);\n }\n }\n if (tabPaths.size === 0) {\n return nodes;\n }\n const prune = (items: NavNode[]): NavNode[] => {\n const kept: NavNode[] = [];\n for (const item of items) {\n if (isTabSection(item, tabPaths)) {\n continue;\n }\n if (item.kind === \"group\") {\n const children = prune(item.children);\n if (\n children.length === item.children.length &&\n children.every((child, index) => child === item.children[index])\n ) {\n kept.push(item);\n } else if (children.length > 0) {\n // A container left empty by pruning is dropped, so no bare heading\n // is stranded.\n kept.push({ ...item, children });\n }\n } else {\n kept.push(item);\n }\n }\n return kept;\n };\n return prune(nodes);\n};\n\n/**\n * Scope the sidebar to the active tab's section. With tabs configured, a route\n * under one tab shows only that tab's group — so a multi-section site (e.g.\n * Adapters / API / AI tabs) drills each tab into its own pages instead of one\n * global tree, the way Fumadocs' root folders do. On a route under no tab (or\n * the root tab), the tab-owned groups are hidden so the root sidebar shows\n * only pages that don't belong to a tab.\n *\n * `root` is the tree root (`Navigation.root`), localized and based like tab\n * paths — under i18n or a `basePath` the root tab sits at `/en` or `/docs`,\n * not `/`, and a bare-`/` comparison would misread it as a section tab (a\n * root-level `(group)` folder's path is exactly that prefix, so the sidebar\n * collapsed to that one group or blanked entirely). In an archived version\n * tree the root is versionized (`/v1.0`) while tab paths stay in current-docs\n * space, so root-tab checks use {@link isRootTab} containment, not equality:\n * the root tab owns no group in a snapshot, and misreading it as a section\n * tab blanked the archived sidebar.\n *\n * When a matched tab owns no sidebar group — a standalone page like the\n * generated changelog timeline (`/changelog`), or a tab whose source produced\n * no pages — the sidebar is empty. It must not fall back to the full tree: that\n * would leak every *other* tab's section (e.g. the OpenAPI operations) onto the\n * page. On a route under no tab, hiding the tab sections falls back to the full\n * sidebar only when it would otherwise blank, so an un-tabbed route stays full.\n */\nexport const sidebarForRoute = (\n sidebar: NavNode[],\n tabs: NavTab[],\n route: string,\n root = \"/\"\n): NavNode[] => {\n const tab = activeTabForRoute(tabs, route);\n if (tab && !isRootTab(tab, root)) {\n return sectionChildren(sidebar, tab.path) ?? [];\n }\n const scoped = withoutTabSections(sidebar, tabs, root);\n return scoped.length > 0 ? scoped : sidebar;\n};\n\n/** Resolve previous/next pages around the current route. */\nexport const getPagination = (flat: FlatPage[], route: string) => {\n const index = flat.findIndex((page) => page.route === route);\n if (index === -1) {\n return { next: null, prev: null };\n }\n return {\n next: flat[index + 1] ?? null,\n prev: index > 0 ? (flat[index - 1] ?? null) : null,\n };\n};\n\n/**\n * A stable id for every group in a sidebar — `g<n>` by pre-order position in\n * the full tree. The layout hands `NavTree` a scoped view of that tree (a\n * tab's section, or the sidebar minus the tab sections), so positions within\n * the rendered slice differ from page to page; these ids name the same group\n * everywhere, which the drill-in panels and the deferred-section fragments\n * (`/blume-nav/…`) rely on. Keyed by node identity: the scoped views reuse\n * the full tree's node objects.\n */\nexport const navGroupIds = (sidebar: NavNode[]): Map<NavNode, string> => {\n const ids = new Map<NavNode, string>();\n const walk = (nodes: NavNode[]): void => {\n for (const node of nodes) {\n if (node.kind === \"group\") {\n ids.set(node, `g${ids.size}`);\n walk(node.children);\n }\n }\n };\n walk(sidebar);\n return ids;\n};\n\n/** Whether any group in a sidebar renders as a disclosure or a drill-in panel. */\nexport const hasDeferrableGroups = (sidebar: NavNode[]): boolean =>\n sidebar.some(\n (node) =>\n node.kind === \"group\" &&\n ((node.display ?? \"flat\") !== \"flat\" ||\n hasDeferrableGroups(node.children))\n );\n\n/** One of the navigation trees a site renders, by URL segment. */\nexport interface NavVariant {\n /** `current`, or an archived version id. */\n version: string;\n /** `default`, or a locale code. */\n locale: string;\n navigation: Navigation;\n}\n\n/**\n * The locale whose code must not appear as a fragment URL segment: the\n * default locale while its URL prefix is hidden. Astro's i18n routing 404s any\n * page URL carrying that locale's code as a segment (it expects the default\n * locale to be unprefixed), so its trees are keyed `default` instead, the same\n * way its page routes drop the prefix. `null` when every locale is prefixed\n * or the site is single-locale.\n */\nexport const hiddenDefaultLocale = (\n i18n: { defaultLocale: string; hideDefaultLocalePrefix: boolean } | null\n): string | null => (i18n?.hideDefaultLocalePrefix ? i18n.defaultLocale : null);\n\n/**\n * Every navigation tree the runtime data holds — the default, each locale's,\n * and each archived version's per locale — keyed the way the deferred\n * sidebar fragments' URLs are (`/blume-nav/<version>/<locale>/…`). An\n * unlocalized version tree is keyed by `\"\"` in the data; it maps to\n * `default` here, as does the hidden-prefix default locale's (see\n * `hiddenDefaultLocale`), whose current tree is `data.navigation` already.\n */\nexport const navVariants = (\n data: {\n navigation: Navigation;\n navigationByLocale: Record<string, Navigation>;\n navigationByVersion: Record<string, Record<string, Navigation>>;\n },\n hiddenDefault: string | null = null\n): NavVariant[] => [\n { locale: \"default\", navigation: data.navigation, version: \"current\" },\n ...Object.entries(data.navigationByLocale)\n .filter(([locale]) => locale !== hiddenDefault)\n .map(([locale, navigation]) => ({\n locale,\n navigation,\n version: \"current\",\n })),\n ...Object.entries(data.navigationByVersion).flatMap(([version, byLocale]) =>\n Object.entries(byLocale).map(([locale, navigation]) => ({\n locale: locale && locale !== hiddenDefault ? locale : \"default\",\n navigation,\n version,\n }))\n ),\n];\n",
|
|
17
17
|
"/**\n * The MDX component tags Blume ships (the keys of the catch-all's component map,\n * plus composed sub-parts like `Color.Item`/`Tree.File`). Used by the\n * missing-component diagnostic to tell an unknown `<Tag>` from a built-in. Keep\n * in sync with the component map in `astro/templates.ts`.\n */\nexport const BUILTIN_MDX_TAGS = new Set<string>([\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 // Conditionally imported by the catch-all, but `detectUsesMath` matches any\n // authored `<Math`, so it is always wired wherever it can appear.\n \"Math\",\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]);\n",
|
|
18
18
|
"import { BUILTIN_MDX_TAGS } from \"./builtin-tags.ts\";\nimport type { Diagnostic, PageRecord } from \"./types.ts\";\n\n/** `CardGroup` → `card-group`, matching registry item names. */\nconst toKebab = (tag: string): string =>\n tag\n .replaceAll(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, \"$<lower>-$<upper>\")\n .toLowerCase();\n\n/**\n * Warn when an `.mdx` page uses a `<Component>` tag that resolves to nothing —\n * a built-in, an island, or a `components.ts` override — so a typo surfaces as a\n * friendly diagnostic (with a `blume add` hint where one exists) instead of a raw\n * MDX \"X is not defined\" build error. `extraTags` are the project's own known\n * components (islands + overrides); `registryNames` gates the install hint.\n */\nexport const validateUsedComponents = (\n pages: PageRecord[],\n extraTags: Set<string>,\n registryNames: Set<string>\n): Diagnostic[] => {\n const diagnostics: Diagnostic[] = [];\n const seen = new Set<string>();\n for (const page of pages) {\n for (const tag of page.componentsUsed ?? []) {\n if (BUILTIN_MDX_TAGS.has(tag) || extraTags.has(tag) || seen.has(tag)) {\n continue;\n }\n seen.add(tag);\n const name = toKebab(tag);\n const suggestion = registryNames.has(name)\n ? `Run \\`blume add ${name}\\` to install it, or register <${tag}> in components.ts (mdx).`\n : `Register <${tag}> in components.ts (mdx), or add an islands/${tag}.tsx component.`;\n diagnostics.push({\n code: \"BLUME_UNKNOWN_COMPONENT\",\n file: page.sourcePath ?? page.id,\n message: `<${tag}> is used in ${page.route} but isn't a known component.`,\n severity: \"warning\",\n suggestion,\n });\n }\n }\n return diagnostics;\n};\n",
|
|
19
19
|
"import { existsSync } from \"node:fs\";\n\nimport { dirname, extname, isAbsolute, resolve } from \"pathe\";\nimport ts from \"typescript\";\n\nimport type { HydrationMode } from \"./schema.ts\";\n\n/**\n * Static analysis of a user `components.ts`/`.tsx`.\n *\n * Astro can only hydrate a component it imports *statically by path*, so to honor\n * hydration on overrides (the `islands` group and `client:*` layout/mdx\n * descriptors) Blume needs each override's source path and client mode at\n * generate time — before Vite compiles anything. We read that here by parsing the\n * file with the TypeScript compiler API (never executing it, so `.astro`/React\n * imports don't need a Node loader).\n *\n * Only statically-analyzable authoring is understood: a default export that is an\n * object literal or a `defineComponents({ ... })` call, with entries that are\n * imported identifiers, path strings, or `{ component, client, media }` object\n * literals. Anything else falls back to the runtime overrides object (which can\n * still render a static component, just not hydrate it).\n */\n\nexport type OverrideFramework = \"react\" | \"svelte\" | \"vue\";\n\n/** How a wrapper should import an override's component. */\nexport interface OverrideImport {\n /** Framework inferred from the file extension, or null (e.g. `.astro`). */\n framework: OverrideFramework | null;\n /** Exported name to import: `\"default\"` or a named export. */\n name: string;\n /** Absolute path (for relative/absolute specifiers) or a bare specifier. */\n path: string;\n}\n\n/** A normalized override entry, keyed by its MDX tag / layout-slot name. */\nexport interface NormalizedOverride {\n /** Present when the override should hydrate; drives the `client:*` directive. */\n client?: HydrationMode;\n /**\n * True when the value is a bare imported identifier, so the runtime overrides\n * object already holds a usable component (no generated import needed for a\n * non-hydrated entry). False for path strings and `{ component }` descriptors.\n */\n identifier: boolean;\n key: string;\n /** Media query for `client: \"media\"`. */\n media?: string;\n /**\n * How to obtain the component. `null` means it couldn't be resolved to a file,\n * so the runtime overrides object is used (static render only).\n */\n source: OverrideImport | null;\n}\n\nexport interface ComponentOverrideAnalysis {\n islands: NormalizedOverride[];\n layout: NormalizedOverride[];\n mdx: NormalizedOverride[];\n warnings: string[];\n}\n\nconst GROUPS = [\"mdx\", \"layout\", \"islands\"] as const;\nconst GROUP_SET = new Set<string>(GROUPS);\ntype Group = (typeof GROUPS)[number];\n\nconst isGroup = (name: string): name is Group => GROUP_SET.has(name);\n\nconst FRAMEWORK_BY_EXT = new Map<string, OverrideFramework>([\n [\"jsx\", \"react\"],\n [\"svelte\", \"svelte\"],\n [\"tsx\", \"react\"],\n [\"vue\", \"vue\"],\n]);\n\nconst FRAMEWORK_LABEL = {\n react: \"React\",\n svelte: \"Svelte\",\n vue: \"Vue\",\n} satisfies Record<OverrideFramework, string>;\n\n/** Extensions probed (in order) when a specifier omits one. */\nconst COMPONENT_EXTS = [\n \"astro\",\n \"tsx\",\n \"ts\",\n \"jsx\",\n \"js\",\n \"mjs\",\n \"vue\",\n \"svelte\",\n];\n\nconst HYDRATION_MODES: ReadonlySet<string> = new Set<HydrationMode>([\n \"idle\",\n \"load\",\n \"media\",\n \"only\",\n \"visible\",\n]);\n\nconst isHydrationMode = (value: string): value is HydrationMode =>\n HYDRATION_MODES.has(value);\n\ninterface ImportBinding {\n /** Exported name: `\"default\"` or a named export. */\n imported: string;\n specifier: string;\n}\n\n/** An override's declared component before framework/path resolution. */\ninterface RawDescriptor {\n client?: HydrationMode;\n hadComponent: boolean;\n media?: string;\n source: OverrideImport | null;\n}\n\nconst emptyAnalysis = (): ComponentOverrideAnalysis => ({\n islands: [],\n layout: [],\n mdx: [],\n warnings: [],\n});\n\nconst propName = (name: ts.PropertyName): string | undefined =>\n ts.isIdentifier(name) || ts.isStringLiteral(name) ? name.text : undefined;\n\n/** Record the bindings declared by one import statement into `map`. */\nconst addImportBindings = (\n map: Map<string, ImportBinding>,\n statement: ts.Statement\n): void => {\n if (\n !ts.isImportDeclaration(statement) ||\n !ts.isStringLiteral(statement.moduleSpecifier)\n ) {\n return;\n }\n const specifier = statement.moduleSpecifier.text;\n const clause = statement.importClause;\n if (!clause) {\n return;\n }\n if (clause.name) {\n map.set(clause.name.text, { imported: \"default\", specifier });\n }\n const named = clause.namedBindings;\n if (named && ts.isNamedImports(named)) {\n for (const element of named.elements) {\n map.set(element.name.text, {\n imported: (element.propertyName ?? element.name).text,\n specifier,\n });\n }\n }\n};\n\n/** Map each local binding name to the module + exported name it came from. */\nconst collectImports = (\n sourceFile: ts.SourceFile\n): Map<string, ImportBinding> => {\n const map = new Map<string, ImportBinding>();\n for (const statement of sourceFile.statements) {\n addImportBindings(map, statement);\n }\n return map;\n};\n\n/** Unwrap `defineComponents({...})`, `({...})`, or `{...} as T` to the object. */\nconst unwrapObject = (\n expression: ts.Expression\n): ts.ObjectLiteralExpression | undefined => {\n if (ts.isObjectLiteralExpression(expression)) {\n return expression;\n }\n if (ts.isCallExpression(expression)) {\n const [arg] = expression.arguments;\n return arg && ts.isObjectLiteralExpression(arg) ? arg : undefined;\n }\n if (\n ts.isAsExpression(expression) ||\n ts.isParenthesizedExpression(expression)\n ) {\n return unwrapObject(expression.expression);\n }\n return undefined;\n};\n\nconst findDefaultExportObject = (\n sourceFile: ts.SourceFile\n): ts.ObjectLiteralExpression | undefined => {\n for (const statement of sourceFile.statements) {\n if (ts.isExportAssignment(statement) && !statement.isExportEquals) {\n return unwrapObject(statement.expression);\n }\n }\n return undefined;\n};\n\nconst probeExtension = (base: string): string | null => {\n for (const extension of COMPONENT_EXTS) {\n const candidate = `${base}.${extension}`;\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n return null;\n};\n\n/** Resolve a module specifier to a wrapper-importable path + framework. */\nconst toImport = (\n specifier: string,\n imported: string,\n dir: string\n): OverrideImport => {\n const relative = specifier.startsWith(\".\") || isAbsolute(specifier);\n let path = specifier;\n let extension = extname(specifier).slice(1).toLowerCase();\n if (relative) {\n const absolute = isAbsolute(specifier)\n ? specifier\n : resolve(dir, specifier);\n if (extension) {\n path = absolute;\n } else {\n const probed = probeExtension(absolute);\n path = probed ?? absolute;\n extension = probed ? extname(probed).slice(1).toLowerCase() : \"\";\n }\n }\n return {\n framework: FRAMEWORK_BY_EXT.get(extension) ?? null,\n name: imported,\n path,\n };\n};\n\nconst resolveIdentifier = (\n name: string,\n imports: Map<string, ImportBinding>,\n dir: string\n): OverrideImport | null => {\n const binding = imports.get(name);\n return binding ? toImport(binding.specifier, binding.imported, dir) : null;\n};\n\n/** Fold one descriptor-object property into the accumulating descriptor. */\nconst applyDescriptorProperty = (\n descriptor: RawDescriptor,\n property: ts.ObjectLiteralElementLike,\n imports: Map<string, ImportBinding>,\n dir: string\n): void => {\n if (ts.isShorthandPropertyAssignment(property)) {\n if (property.name.text === \"component\") {\n descriptor.hadComponent = true;\n descriptor.source = resolveIdentifier(property.name.text, imports, dir);\n }\n return;\n }\n if (!ts.isPropertyAssignment(property)) {\n return;\n }\n const name = propName(property.name);\n const init = property.initializer;\n if (name === \"component\") {\n descriptor.hadComponent = true;\n if (ts.isStringLiteral(init)) {\n descriptor.source = toImport(init.text, \"default\", dir);\n } else if (ts.isIdentifier(init)) {\n descriptor.source = resolveIdentifier(init.text, imports, dir);\n }\n } else if (\n name === \"client\" &&\n ts.isStringLiteral(init) &&\n isHydrationMode(init.text)\n ) {\n descriptor.client = init.text;\n } else if (name === \"media\" && ts.isStringLiteral(init)) {\n descriptor.media = init.text;\n }\n};\n\nconst readDescriptor = (\n object: ts.ObjectLiteralExpression,\n imports: Map<string, ImportBinding>,\n dir: string\n): RawDescriptor => {\n const descriptor: RawDescriptor = { hadComponent: false, source: null };\n for (const property of object.properties) {\n applyDescriptorProperty(descriptor, property, imports, dir);\n }\n return descriptor;\n};\n\n/** Apply cross-cutting validation and produce the final normalized override. */\nconst finalize = (\n key: string,\n group: Group,\n descriptor: RawDescriptor,\n label: string,\n identifier: boolean,\n warnings: string[]\n): NormalizedOverride | null => {\n const { client, media, source } = descriptor;\n\n if (group === \"islands\") {\n if (!source) {\n warnings.push(\n `Island override \"${key}\" couldn't be resolved to a file. Reference it by an imported component or a path string with an extension.`\n );\n return null;\n }\n if (!source.framework) {\n warnings.push(\n `Island override \"${key}\" (${label}) is not a React, Vue, or Svelte component; only framework components can be islands.`\n );\n return null;\n }\n }\n\n if (client === \"media\" && !media) {\n warnings.push(\n `Override \"${key}\" uses client: \"media\" but no \\`media\\` query was given; it will hydrate as if \\`client: \"load\"\\`.`\n );\n }\n\n if (client === \"only\" && source && !source.framework) {\n warnings.push(\n `Override \"${key}\" uses client: \"only\" but its framework couldn't be inferred; reference a .tsx/.jsx/.vue/.svelte file.`\n );\n }\n\n if (!client && source?.framework) {\n warnings.push(\n `Override \"${key}\" points to a ${FRAMEWORK_LABEL[source.framework]} component (${label}) but has no hydration mode, so it renders as static HTML with no interactivity. Add one, e.g. \\`${key}: { component: ${JSON.stringify(label)}, client: \"load\" }\\`.`\n );\n }\n\n const normalized: NormalizedOverride = { identifier, key, source };\n if (client) {\n normalized.client = client;\n }\n if (media) {\n normalized.media = media;\n }\n return normalized;\n};\n\nconst normalizeEntry = (\n entry: ts.ObjectLiteralElementLike,\n group: Group,\n imports: Map<string, ImportBinding>,\n dir: string,\n warnings: string[]\n): NormalizedOverride | null => {\n const defaultClient: HydrationMode | undefined =\n group === \"islands\" ? \"visible\" : undefined;\n\n if (ts.isShorthandPropertyAssignment(entry)) {\n const name = entry.name.text;\n return finalize(\n name,\n group,\n {\n client: defaultClient,\n hadComponent: true,\n source: resolveIdentifier(name, imports, dir),\n },\n name,\n true,\n warnings\n );\n }\n\n if (!ts.isPropertyAssignment(entry)) {\n return null;\n }\n const key = propName(entry.name);\n if (!key) {\n return null;\n }\n const value = entry.initializer;\n\n if (ts.isIdentifier(value)) {\n return finalize(\n key,\n group,\n {\n client: defaultClient,\n hadComponent: true,\n source: resolveIdentifier(value.text, imports, dir),\n },\n value.text,\n true,\n warnings\n );\n }\n if (ts.isStringLiteral(value)) {\n return finalize(\n key,\n group,\n {\n client: defaultClient,\n hadComponent: true,\n source: toImport(value.text, \"default\", dir),\n },\n value.text,\n false,\n warnings\n );\n }\n if (ts.isObjectLiteralExpression(value)) {\n const descriptor = readDescriptor(value, imports, dir);\n if (!descriptor.hadComponent) {\n warnings.push(\n `Override \"${key}\" is an object without a \\`component\\` field; expected \\`{ component, client }\\`.`\n );\n return null;\n }\n if (!descriptor.source) {\n warnings.push(\n `Override \"${key}\"'s \\`component\\` couldn't be resolved to a file. Reference an imported component or a path string with an extension.`\n );\n return null;\n }\n return finalize(\n key,\n group,\n { ...descriptor, client: descriptor.client ?? defaultClient },\n key,\n false,\n warnings\n );\n }\n\n // An inline function/expression: keep it on the runtime object (static only).\n return { identifier: false, key, source: null };\n};\n\n/** Normalize one top-level `{ mdx | layout | islands }` group into `result`. */\nconst collectGroupOverrides = (\n property: ts.ObjectLiteralElementLike,\n imports: Map<string, ImportBinding>,\n dir: string,\n result: ComponentOverrideAnalysis\n): void => {\n if (!ts.isPropertyAssignment(property)) {\n return;\n }\n const name = propName(property.name);\n if (\n !(name && isGroup(name)) ||\n !ts.isObjectLiteralExpression(property.initializer)\n ) {\n return;\n }\n for (const entry of property.initializer.properties) {\n const normalized = normalizeEntry(\n entry,\n name,\n imports,\n dir,\n result.warnings\n );\n if (normalized) {\n result[name].push(normalized);\n }\n }\n};\n\n/**\n * Parse a user `components.ts`/`.tsx` and return its normalized overrides. Never\n * executes the file. On a parse failure or unrecognized shape, returns empty\n * groups so generation falls back to the plain runtime overrides object.\n */\nexport const analyzeComponentOverrides = (\n source: string,\n filePath: string\n): ComponentOverrideAnalysis => {\n const result = emptyAnalysis();\n const sourceFile = ts.createSourceFile(\n filePath,\n source,\n ts.ScriptTarget.Latest,\n true,\n filePath.endsWith(\"tsx\") ? ts.ScriptKind.TSX : ts.ScriptKind.TS\n );\n\n const object = findDefaultExportObject(sourceFile);\n if (!object) {\n return result;\n }\n\n const imports = collectImports(sourceFile);\n const dir = dirname(filePath);\n\n for (const property of object.properties) {\n collectGroupOverrides(property, imports, dir, result);\n }\n\n return result;\n};\n",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
"import type { ResolvedConfig } from \"../core/schema.ts\";\n\nconst FALLBACK_ACCENT = \"oklch(0.62 0.16 250)\";\n\n/**\n * Named accent presets mapped to OKLCH values. The single source of truth for\n * preset colors: the theme CSS and the OG card (og/card.ts) both resolve from\n * this table, so a site and its social cards can't disagree about \"blue\".\n */\nexport const ACCENTS = {\n blue: FALLBACK_ACCENT,\n green: \"oklch(0.6 0.16 150)\",\n orange: \"oklch(0.68 0.17 50)\",\n pink: \"oklch(0.65 0.2 350)\",\n purple: \"oklch(0.58 0.2 290)\",\n red: \"oklch(0.58 0.22 25)\",\n teal: \"oklch(0.6 0.12 195)\",\n} satisfies Record<string, string>;\n\n/**\n * Whether a raw config value names an accent preset. `hasOwn` keeps a value\n * like \"constructor\" from resolving an Object.prototype member — which would\n * stringify a function into the generated CSS, breaking the rule (the exact\n * breakout {@link safeColor} exists to prevent).\n */\nexport const isAccentPreset = (value: string): value is keyof typeof ACCENTS =>\n Object.hasOwn(ACCENTS, value);\n\n// Characters valid in a CSS color value (hex, rgb/hsl/oklch functions, named\n// colors). Anything else — notably `;`, `{`, `}` — could break out of the\n// declaration and inject rules, so such a value is rejected.\nconst CSS_COLOR = /^[\\w\\s#%.,()/+-]+$/u;\n\n/** Pass a raw color through only if it can't break out of a CSS declaration. */\nconst safeColor = (value: string, fallback: string): string =>\n CSS_COLOR.test(value.trim()) ? value.trim() : fallback;\n\n/** Resolve a named preset or fall back to {@link safeColor}. */\nconst presetOrColor = (value: string): string =>\n isAccentPreset(value) ? ACCENTS[value] : safeColor(value, FALLBACK_ACCENT);\n\n/** Like {@link safeColor} but drops an unsafe/absent value to `null`. */\nconst safeColorOrNull = (value: string | undefined): string | null =>\n value && CSS_COLOR.test(value.trim()) ? value.trim() : null;\n\nconst RADII = {\n lg: \"0.75rem\",\n md: \"0.5rem\",\n none: \"0\",\n sm: \"0.25rem\",\n} satisfies Record<ResolvedConfig[\"theme\"][\"radius\"], string>;\n\nconst cssString = (value: string): string => JSON.stringify(value);\n\nconst backgroundImageCss = (image: string): string =>\n `url(${cssString(image)})`;\n\nconst cssToken = (name: string, value?: string | null): string[] =>\n value ? [` ${name}: ${value};`] : [];\n\nconst themeRootCss = (\n theme: ResolvedConfig[\"theme\"],\n options: {\n accent: string;\n action: string | null;\n radius: string;\n }\n): string =>\n [\n ` --blume-accent: ${options.accent};`,\n ...cssToken(\"--blume-action\", options.action),\n ...cssToken(\n \"--blume-action-foreground\",\n options.action ? \"oklch(1 0 0)\" : null\n ),\n ...cssToken(\"--blume-background\", safeColorOrNull(theme.background?.light)),\n ...cssToken(\n \"--blume-background-image\",\n theme.backgroundImage?.light\n ? backgroundImageCss(theme.backgroundImage.light)\n : null\n ),\n ` --blume-radius: ${options.radius};`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\nconst themeDarkCss = (\n theme: ResolvedConfig[\"theme\"],\n options: {\n accent: string;\n action: string | null;\n }\n): string => {\n // Mode-shared tokens (accent, action) must be re-declared here: the base\n // stylesheet's own `:root[data-theme=\"dark\"]` block outranks the `:root`\n // config tokens on specificity, so without this block dark mode would\n // silently keep its neutral defaults and ignore the config.\n const tokens = [\n ` --blume-accent: ${options.accent};`,\n \" --blume-accent-foreground: oklch(1 0 0);\",\n ...cssToken(\"--blume-action\", options.action),\n ...cssToken(\n \"--blume-action-foreground\",\n options.action ? \"oklch(1 0 0)\" : null\n ),\n ...cssToken(\"--blume-background\", safeColorOrNull(theme.background?.dark)),\n ...cssToken(\n \"--blume-background-image\",\n theme.backgroundImage?.dark\n ? backgroundImageCss(theme.backgroundImage.dark)\n : null\n ),\n ].filter(Boolean);\n return `:root[data-theme=\"dark\"] {\n${tokens.join(\"\\n\")}\n}\n`;\n};\n\n/** Per-mode accent CSS colors. */\nexport interface AccentColors {\n dark: string;\n light: string;\n}\n\n/**\n * Resolve the configured accent to per-mode CSS colors. A named accent\n * resolves to its preset; any other value is treated as a raw CSS color so\n * users can pass arbitrary colors without a config change. A string accent\n * has already been normalized by the config schema to the same color for\n * both modes.\n */\nexport const resolveAccent = (\n theme: ResolvedConfig[\"theme\"]\n): AccentColors => ({\n dark: presetOrColor(theme.accent.dark),\n light: presetOrColor(theme.accent.light),\n});\n\n/** Resolve the configured radius preset to a CSS length. */\nexport const resolveRadius = (theme: ResolvedConfig[\"theme\"]): string =>\n RADII[theme.radius];\n\n/**\n * Compile theme config into CSS custom properties. A named accent resolves to\n * its preset; any other value is treated as a raw CSS color so users can pass\n * arbitrary colors without a config change.\n */\nexport const buildThemeCss = (theme: ResolvedConfig[\"theme\"]): string => {\n const accent = resolveAccent(theme);\n const action = theme.action ? presetOrColor(theme.action) : null;\n const radius = RADII[theme.radius];\n const root = themeRootCss(theme, {\n accent: accent.light,\n action,\n radius,\n });\n const dark = themeDarkCss(theme, {\n accent: accent.dark,\n action,\n });\n\n return `/* Generated by Blume from theme config. */\n:root {\n${root}\n}\n${dark}`;\n};\n",
|
|
28
28
|
"import { withBasePath } from \"../core/base-path.ts\";\n\n/** A resolved search empty-state link passed to the Search dialog. */\nexport interface SearchPopularPage {\n /** Built-in icon name; `Search.astro` resolves it to markup at render time. */\n icon?: string;\n label: string;\n route: string;\n}\n\n/**\n * Map configured `search.popular` entries to `{ route, label }` for Search.\n *\n * Curated hrefs are authored as if mounted at root, so `basePath` is applied\n * here — matching `navigation.featured` and tab paths, and agreeing with the\n * sidebar fallback these entries replace (whose routes are already based via\n * `page.route`). `withBasePath` is idempotent and skips external URLs.\n *\n * `deployment.base` is deliberately *not* applied: routes stay deploy-base-less\n * so `createLinkRow` can prefix it at click time, same as sidebar-derived pages.\n *\n * `icon` stays a name here (like `navigation.featured`): the icon set is a\n * server-only module, so `Search.astro` resolves it to inline SVG at render.\n */\nexport const resolveSearchPopular = (\n popular: { href: string; icon?: string; label: string }[],\n basePath: string\n): SearchPopularPage[] =>\n popular.map(({ href, icon, label }) => {\n const page: SearchPopularPage = {\n label,\n route: withBasePath(basePath, href),\n };\n if (icon) {\n page.icon = icon;\n }\n return page;\n });\n",
|
|
29
29
|
"/**\n * Vertical padding of a highlighted code block, shared by the theme (which\n * emits it as CSS) and `<Component>` (which estimates a source pane's SSR\n * height from it) so the two cannot drift.\n */\n\n/** Top and bottom inset of a plain prose block with no chrome, in rem. */\nexport const CODE_PADDING_BLOCK_REM = 1;\n",
|
|
30
|
-
"import { CODE_PADDING_BLOCK_REM } from \"./code-block-padding.ts\";\n\n/**\n * Bottom inset of the scrolling code element, in rem: keeps a horizontal\n * scrollbar thumb off the last line's descenders. It is carved out of the\n * pre's block padding rather than added to it, so a block's height is the\n * same whether or not it scrolls.\n */\nconst CODE_SCROLL_INSET_REM = 0.375;\n\ninterface TailwindEntryOptions {\n /**\n * Globs to scan for utility classes. Typically the Blume package source and\n * the user's project (node_modules is skipped automatically).\n */\n sources: string[];\n /** Config-derived token overrides (`:root { --blume-accent: ... }`). */\n configTokens: string;\n /** Raw contents of the user's theme.css, if any. */\n userTheme: string;\n /** Twoslash rich-renderer styles (for fences with the `twoslash` meta). */\n twoslashCss?: string;\n /** The code-block language icon rules (`languageIconCss`), if any. */\n languageIcons?: string;\n}\n\n/** Dark mode is driven by `data-theme` on the root element (both sheets). */\nconst DARK_VARIANT = `/* Dark mode is driven by data-theme on the <html> element. */\n@custom-variant dark (&:where([data-theme=\"dark\"], [data-theme=\"dark\"] *));`;\n\n/** Keep browser-provided UI in sync with the active theme in both sheets. */\nconst COLOR_SCHEME_DEFAULTS = `:root {\n color-scheme: light;\n}\n\n:root[data-theme=\"dark\"] {\n color-scheme: dark;\n}`;\n\n/**\n * The default `--blume-*` design tokens (light + dark), shared by the app\n * sheet and the isolated example-preview sheet so previews inherit the site's\n * palette by default.\n */\nconst TOKEN_DEFAULTS = `:root {\n --blume-background: oklch(1 0 0);\n --blume-background-image: none;\n --blume-background-image-repeat: no-repeat;\n --blume-background-image-size: cover;\n --blume-foreground: oklch(0.145 0 0);\n --blume-muted: oklch(0.965 0 0);\n /* 5.28:1 on the page background. The headroom over 4.5:1 is the point: muted\n text is 14px body copy routinely set on a tinted surface (callouts, badges,\n panels), and each tint costs a few tenths. */\n --blume-muted-foreground: oklch(0.53 0 0);\n --blume-border: oklch(0.88 0.006 260 / 0.72);\n --blume-accent: oklch(0.145 0 0);\n --blume-accent-foreground: oklch(1 0 0);\n --blume-action: var(--blume-accent);\n --blume-action-foreground: var(--blume-accent-foreground);\n --blume-code-background: oklch(0.99 0 0);\n /* Shiki notation transformers: line/word highlight, diff add/remove. */\n --blume-code-highlight: oklch(0.55 0.16 255 / 0.1);\n --blume-code-highlight-border: oklch(0.55 0.16 255 / 0.55);\n --blume-code-add: oklch(0.72 0.16 150 / 0.16);\n --blume-code-add-border: oklch(0.52 0.15 150 / 0.7);\n --blume-code-remove: oklch(0.66 0.21 22 / 0.16);\n --blume-code-remove-border: oklch(0.55 0.2 22 / 0.7);\n --blume-code-word: oklch(0.55 0.16 255 / 0.16);\n --blume-code-word-border: oklch(0.55 0.16 255 / 0.5);\n --blume-radius: 0.75rem;\n\n /* Max width of the prose content column (article, breadcrumb, TOC, feedback,\n pagination, last-updated). Override to re-measure the whole column at once. */\n --blume-content-width: 42rem;\n\n /*\n * Font tokens resolve through optional src variables that Astro's Fonts API\n * populates (via theme.fonts). When unset they fall back to the system\n * stacks, so the default look is unchanged. The display font defaults to the\n * body font.\n */\n --blume-font-body: var(\n --blume-font-body-src,\n ui-sans-serif,\n system-ui,\n -apple-system,\n \"Segoe UI\",\n Roboto,\n Helvetica,\n Arial,\n sans-serif\n );\n --blume-font-mono: var(\n --blume-font-mono-src,\n ui-monospace,\n \"SF Mono\",\n \"Cascadia Code\",\n \"Source Code Pro\",\n Menlo,\n Consolas,\n monospace\n );\n --blume-font-display: var(--blume-font-display-src, var(--blume-font-body));\n}\n\n:root[data-theme=\"dark\"] {\n --blume-background: oklch(0.085 0 0);\n --blume-background-image: none;\n --blume-background-image-repeat: no-repeat;\n --blume-background-image-size: cover;\n --blume-foreground: oklch(0.96 0 0);\n --blume-muted: oklch(0.16 0 0);\n --blume-muted-foreground: oklch(0.68 0 0);\n --blume-border: oklch(0.24 0 0 / 0.8);\n --blume-accent: oklch(0.96 0 0);\n --blume-accent-foreground: oklch(0.085 0 0);\n --blume-action: var(--blume-accent);\n --blume-action-foreground: var(--blume-accent-foreground);\n --blume-code-background: oklch(0.12 0 0);\n /* Brighter tints read better over the dark code surface. */\n --blume-code-highlight: oklch(0.7 0.14 255 / 0.16);\n --blume-code-highlight-border: oklch(0.7 0.14 255 / 0.6);\n --blume-code-add: oklch(0.78 0.17 150 / 0.2);\n --blume-code-add-border: oklch(0.72 0.16 150 / 0.7);\n --blume-code-remove: oklch(0.72 0.21 22 / 0.22);\n --blume-code-remove-border: oklch(0.7 0.2 22 / 0.7);\n --blume-code-word: oklch(0.7 0.14 255 / 0.22);\n --blume-code-word-border: oklch(0.7 0.14 255 / 0.55);\n}`;\n\n/**\n * Tailwind theme mapping from `--blume-*` tokens to utility-facing names\n * (`bg-background`, `border-border`, `rounded-blume`, the font stacks).\n * Shared by both sheets so example code written against Blume's utility\n * vocabulary renders identically inside the isolated preview frame.\n */\nconst THEME_MAPPING = `@theme inline {\n --color-background: var(--blume-background);\n --color-foreground: var(--blume-foreground);\n --color-muted: var(--blume-muted);\n --color-muted-foreground: var(--blume-muted-foreground);\n --color-border: var(--blume-border);\n --color-accent: var(--blume-accent);\n --color-accent-foreground: var(--blume-accent-foreground);\n --color-action: var(--blume-action);\n --color-action-foreground: var(--blume-action-foreground);\n --color-code: var(--blume-code-background);\n --radius-blume: var(--blume-radius);\n --container-content: var(--blume-content-width);\n --font-sans: var(--blume-font-body);\n --font-mono: var(--blume-font-mono);\n --font-display: var(--blume-font-display);\n}`;\n\n/**\n * Build the single Tailwind v4 entry stylesheet for the generated runtime.\n *\n * Everything flows through one Tailwind-processed file so utilities are\n * generated and design tokens cascade deterministically:\n * base defaults -> config tokens -> user theme.css.\n */\nexport const tailwindEntryTemplate = (options: TailwindEntryOptions): string =>\n `/* Generated by Blume. Do not edit. */\n@import \"tailwindcss\";\n@plugin \"@tailwindcss/typography\";\n\n/* Scan Blume's components and the user's project for utility classes. */\n${options.sources.map((source) => `@source \"${source}\";`).join(\"\\n\")}\n\n${DARK_VARIANT}\n\n${COLOR_SCHEME_DEFAULTS}\n\n${TOKEN_DEFAULTS}\n\n${THEME_MAPPING}\n\n@layer base {\n /* Nothing refuses to shrink below its intrinsic content width. This global\n min-width reset defuses the classic flex/grid overflow — a long or\n truncating child forcing its container (and the page) past the viewport\n edge — so components don't need per-element min-w-0 overrides. */\n * {\n min-width: 0;\n }\n /* Interactive controls get a pointer cursor unless disabled. */\n button:not(:disabled),\n [role=\"button\"]:not(:disabled) {\n cursor: pointer;\n }\n html {\n scroll-behavior: smooth;\n scroll-padding-top: 4.5rem;\n text-rendering: optimizeLegibility;\n }\n /* Headings use the display font (defaults to the body font when unset).\n The tightened tracking is part of the theme, not the font: display-tuned\n families bake it into their metrics, but a text family promoted to\n headings (including the Inter default) reads loose without it. -0.05em\n was matched visually against Inter Tight, the previous display default. */\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: var(--font-display);\n letter-spacing: -0.05em;\n }\n :focus-visible {\n outline: 2px solid var(--blume-accent);\n outline-offset: 2px;\n border-radius: 2px;\n }\n body {\n background-attachment: fixed;\n background-image: var(--blume-background-image);\n background-position: center top;\n background-repeat: var(--blume-background-image-repeat);\n background-size: var(--blume-background-image-size);\n }\n @media (prefers-reduced-motion: reduce) {\n html {\n scroll-behavior: auto;\n }\n }\n}\n\n/* Same-origin navigations ride Astro's client router (the layouts render\n ClientRouter), which owns the page-transition styling — including its own\n prefers-reduced-motion guard — so the theme declares nothing about it. The\n cross-document view-transition opt-in that briefly lived here is\n deliberately gone: mixing it with the client router double-animates the\n full-load navigations the router hands back to the browser. */\n\n/* Code reads left-to-right regardless of page direction; only the surrounding\n chrome mirrors for RTL. Inline code is isolated so LTR identifiers don't\n disturb the bidi flow of right-to-left prose. */\n[dir=\"rtl\"] pre,\n[dir=\"rtl\"] .prose pre {\n direction: ltr;\n text-align: left;\n}\n[dir=\"rtl\"] :not(pre) > code {\n unicode-bidi: isolate;\n}\n\n/* The sidebar's rows. A docs site renders every sidebar row on every page,\n so a large site's HTML is mostly this markup — one utility per row kind\n instead of the dozen classes each expands to keeps every page (and the\n build's HTML output) small. Kept in sync with NavTree.astro: a page row,\n a page-mode group's drill-in button, a collapsible group's summary and\n the link inside it, and a flat group's heading and the link inside it. */\n@utility blume-nav-link {\n @apply block rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:font-medium aria-[current=page]:text-foreground;\n}\n@utility blume-nav-drill {\n @apply flex w-full items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-left font-medium text-foreground text-sm transition-colors hover:bg-muted;\n}\n@utility blume-nav-summary {\n @apply flex cursor-pointer list-none items-center gap-1.5 rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground [&::-webkit-details-marker]:hidden;\n}\n@utility blume-nav-summary-link {\n @apply -my-1 flex flex-1 items-center gap-1.5 rounded py-1 transition-colors aria-[current=page]:text-foreground aria-[current=page]:font-semibold;\n}\n@utility blume-nav-heading {\n @apply mb-2 flex items-center gap-1.5 px-2.5 font-medium text-foreground text-sm;\n}\n@utility blume-nav-heading-link {\n @apply -ml-1 flex flex-1 items-center gap-1.5 rounded-[0.65rem] px-1 py-0.5 text-foreground transition-colors hover:bg-muted aria-[current=page]:bg-muted;\n}\n\n/* Theme Tailwind Typography (prose) with Blume tokens. */\n.prose {\n --tw-prose-body: var(--blume-foreground);\n --tw-prose-headings: var(--blume-foreground);\n --tw-prose-lead: var(--blume-muted-foreground);\n --tw-prose-links: var(--blume-foreground);\n --tw-prose-bold: var(--blume-foreground);\n --tw-prose-counters: var(--blume-muted-foreground);\n --tw-prose-bullets: var(--blume-muted-foreground);\n --tw-prose-hr: var(--blume-border);\n --tw-prose-quotes: var(--blume-muted-foreground);\n --tw-prose-quote-borders: var(--blume-border);\n --tw-prose-captions: var(--blume-muted-foreground);\n --tw-prose-code: var(--blume-foreground);\n --tw-prose-pre-code: var(--blume-foreground);\n --tw-prose-pre-bg: var(--blume-code-background);\n --tw-prose-th-borders: var(--blume-border);\n --tw-prose-td-borders: var(--blume-border);\n color: var(--blume-muted-foreground);\n font-size: 0.875rem;\n line-height: 1.7;\n /* An unbreakable run — an API permission, a broker list, a bare URL used as\n its own link text, an OpenAPI operation title of the form\n \\`METHOD /very/long/{path}\\`, a module-qualified name in a generated\n reference — paints past the content column, and nothing between the\n paragraph and the viewport clips it, so it lands in the document's scroll\n width and drags the page sideways on a phone. Inherited, so headings and\n inline code are covered too; the only re-declarations below are the\n opt-in code-wrap mode and Twoslash, which want different values.\n \\`break-word\\` and not \\`anywhere\\`: only \\`anywhere\\` reduces min-content,\n which is what sizes \\`table-layout: auto\\` columns, so it would resize\n every table on the site. The flip side is that a token in a table cell\n still never breaks — the column grows to fit it — so wide tables rely on\n the .blume-table-scroll wrapper, not on this. */\n overflow-wrap: break-word;\n}\n\n/* No letter-spacing here: prose headings inherit the base h1-h6 rule's\n display tracking, same as headings outside the prose column. */\n.prose :where(h1, h2, h3, h4) {\n font-weight: 500;\n}\n\n.prose :where(h1) {\n font-size: 3rem;\n line-height: 1.1;\n margin: 0 0 1rem;\n}\n\n.prose :where(h2) {\n font-size: 1.875rem;\n line-height: 1.2;\n margin-top: 3rem;\n}\n\n.prose :where(h3) {\n font-size: 1.25rem;\n line-height: 1.35;\n}\n\n.prose :where(h4) {\n color: var(--blume-muted-foreground);\n font-size: 0.875rem;\n line-height: 1.4;\n}\n\n.prose :where(h1, h2, h3, h4, h5, h6) a {\n color: inherit;\n font-weight: inherit;\n text-decoration: none;\n}\n\n/* Auto-generated heading permalinks (markdown.headingAnchors): the whole\n heading links to its own id, with a muted “#” revealed on hover or keyboard\n focus so the link is discoverable without cluttering the heading at rest. */\n.prose :where(h2, h3, h4, h5, h6) a.blume-heading-anchor::after {\n content: \"#\";\n color: var(--blume-muted-foreground);\n margin-inline-start: 0.35em;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n.prose :where(h2, h3, h4, h5, h6) a.blume-heading-anchor:hover::after,\n.prose :where(h2, h3, h4, h5, h6) a.blume-heading-anchor:focus-visible::after {\n opacity: 1;\n}\n\n/* A [toc]-marked heading exists only for the table of contents: it stays in\n the flow as a zero-height, invisible anchor target so its TOC entry (and any\n deep link) still has somewhere to scroll to, without rendering on the page. */\n.prose :where(.blume-toc-only) {\n border: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n padding: 0;\n visibility: hidden;\n}\n\n.prose :where(h2:first-child) {\n border-top: 0;\n padding-top: 0;\n}\n\n.prose :where(p, ul, ol) {\n margin-top: 1rem;\n margin-bottom: 1rem;\n}\n\n.prose :where(strong) {\n font-weight: 600;\n}\n\n.prose :where(a) {\n color: var(--blume-foreground);\n font-weight: 500;\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: 1px;\n text-underline-offset: 0.2em;\n}\n\n.prose :where(a[data-blume-card]) {\n color: inherit;\n font-weight: inherit;\n text-decoration: none;\n}\n\n.prose :where(hr) {\n margin: 2.5rem 0;\n}\n\n.prose :where(pre) {\n background: transparent;\n border: 1px solid var(--blume-border);\n border-radius: var(--blume-radius);\n color: var(--blume-foreground);\n font-family: var(--font-mono);\n font-size: 0.8125rem;\n line-height: 1.55;\n margin: 1.5rem 0;\n overflow-x: auto;\n padding: ${CODE_PADDING_BLOCK_REM}rem 0;\n position: relative;\n}\n\n.prose :where(pre.astro-code) {\n background: transparent !important;\n color: var(--shiki-light, var(--blume-foreground)) !important;\n}\n\n:root[data-theme=\"dark\"] .prose :where(pre.astro-code) {\n color: var(--shiki-dark, var(--blume-foreground)) !important;\n}\n\n.prose :where(pre.astro-code span) {\n background: transparent !important;\n color: var(--shiki-light, inherit);\n font-style: var(--shiki-light-font-style, inherit);\n font-weight: var(--shiki-light-font-weight, inherit);\n text-decoration: var(--shiki-light-text-decoration, inherit);\n}\n\n:root[data-theme=\"dark\"] .prose :where(pre.astro-code span) {\n color: var(--shiki-dark, inherit);\n font-style: var(--shiki-dark-font-style, inherit);\n font-weight: var(--shiki-dark-font-weight, inherit);\n text-decoration: var(--shiki-dark-text-decoration, inherit);\n}\n\n/* The Diff component (@pierre/diffs) renders into a declarative shadow root and\n themes itself with light-dark(). Drive that from Blume's data-theme instead\n of the OS, scoped to the diff host: the custom property pierces the shadow\n boundary, where the appended host color-scheme rule consumes it. */\nblume-diff {\n --blume-diff-color-scheme: light;\n display: block;\n}\n\n:root[data-theme=\"dark\"] blume-diff {\n --blume-diff-color-scheme: dark;\n}\n\n.prose :where(pre[data-language]) {\n padding-top: 3.75rem;\n}\n\n.prose :where(pre[data-language])::before {\n align-items: center;\n border-bottom: 1px solid var(--blume-border);\n color: var(--blume-muted-foreground);\n content: attr(data-language);\n display: flex;\n font-family: var(--font-sans);\n font-size: 0.75rem;\n font-weight: 500;\n height: 2.75rem;\n left: 0;\n padding: 0 3.25rem 0 1rem;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.prose :where(pre[data-title])::before {\n content: attr(data-title);\n}\n\n/* Language icon (simple-icons) sits at the header's left edge; the label shifts\n right to make room. Injected at build time by the language-icon transformer.\n The icon is gated on data-language (the header bar), not just data-icon: the\n transformer runs whenever icons are on, but a header-less standalone\n CodeBlock (no title) never gets data-language, so without this gate the\n absolutely-positioned icon would overlap the first code line. Fenced code\n and titled blocks always have a header, so the icon shows there. */\n.prose > :where(pre[data-language][data-icon])::after {\n content: \"\";\n height: 0.875rem;\n left: 1rem;\n -webkit-mask-position: center;\n -webkit-mask-repeat: no-repeat;\n -webkit-mask-size: contain;\n mask-position: center;\n mask-repeat: no-repeat;\n mask-size: contain;\n pointer-events: none;\n position: absolute;\n top: 0.875rem;\n width: 0.875rem;\n}\n\n.prose > :where(pre[data-language][data-icon])::before {\n padding-left: 2.5rem;\n}\n\n/* One mask rule per language the site's Markdown uses (see\n markdown/language-icon.ts); the ::after above only gets a color and a mask\n from these, so a block whose language has no rule paints nothing. */\n${options.languageIcons ?? \"\"}\n\n.prose :where(pre code) {\n background: transparent;\n border-radius: 0;\n color: inherit;\n font-size: inherit;\n font-weight: 400;\n padding: 0;\n}\n\n/* Long lines scroll inside the code element, not the pre: the pre stays static\n so its absolute header bar (::before) and copy button don't drift with the\n scroll. The pre's horizontal padding lives here so content still scrolls\n edge-to-edge past it. Two contexts opt out: twoslash blocks (popups must\n escape any scroll container — see theme/twoslash.ts), and the API request\n panel, which owns its code layout and keeps the copy control in the panel\n header. Every other component that hosts a code block — Tabs, CodeGroup,\n Steps, Callout, Card, Accordion — is real prose content and keeps the inset,\n even though its chrome wrapper is not-prose. */\n.prose :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *) > code) {\n display: block;\n /* Tall blocks scroll vertically in place instead of taking the page. Both\n axes live on the code element for the same reason: the pre stays static\n so the header bar and copy button never drift with the scroll. */\n max-height: 24rem;\n overflow: auto;\n /* The small bottom inset keeps the horizontal thumb off the last line's\n descenders now that scrollbars are visible. The pre gives up the same\n amount below (next rule), so the inset adds no height to the block. */\n padding: 0 1.25rem ${CODE_SCROLL_INSET_REM}rem;\n /* Thin theme-colored scrollbars, matching the sidebar treatment, so a\n height-capped block reads as scrollable instead of simply ending.\n Safari before 18.2 supports neither property and falls back to the\n platform-default scrollbar — acceptable, since macOS overlays it. */\n scrollbar-color: var(--blume-border) transparent;\n scrollbar-width: thin;\n}\n\n/* The scroller's bottom inset comes out of the pre's own block padding: the\n text still sits one full inset above the frame's bottom edge, the thumb sits\n in the gap, and a one-line command is no taller than it was before the\n scroller existed. */\n.prose :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *):has(> code)) {\n padding-bottom: calc(${CODE_PADDING_BLOCK_REM}rem - ${CODE_SCROLL_INSET_REM}rem);\n}\n\n/* The dark border token is too close to the page background to read as a\n scrollbar thumb; derive a brighter one from the muted foreground instead. */\n:root[data-theme=\"dark\"]\n .prose\n :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *) > code) {\n scrollbar-color: color-mix(in oklab, var(--blume-muted-foreground) 55%, transparent)\n transparent;\n}\n\n/* Word wrap (markdown.code.wrap): long lines wrap instead of scrolling. The\n attribute is set on <body> from config; default code keeps \\`white-space: pre\\`. */\n[data-blume-code-wrap] pre,\n[data-blume-code-wrap] pre code {\n overflow-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.prose :where(table) {\n font-size: 0.8125rem;\n}\n\n/* Scroll wide tables in place; the wrapper is added by the blume:table-wrap hast\n plugin. The border+radius frames the scroll viewport so a clipped wide table\n reads as scrollable rather than cut off, and carries the table's vertical\n rhythm (the inner table's own margin is zeroed so it fills the frame). */\n.blume-table-scroll {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n margin: 1.5rem 0;\n border: 1px solid var(--blume-border);\n border-radius: var(--blume-radius);\n}\n.blume-table-scroll > table {\n margin: 0;\n}\n/* Restore inner padding on every cell. Typography zeroes the first/last cell's\n inline padding so a borderless table aligns to the prose margin; inside the\n framed wrapper that leaves edge text touching the border. The :is() selector\n outweighs Typography's :where()-scoped rules so the outer columns get it too.\n\n The block padding is 0.75rem against a table line-height near 1.7: at 0.5rem a\n cell whose content wrapped put MORE space between its own two lines than\n between itself and the next row, so a table of wrapping cells read as one\n block rather than as rows. The inline padding stays where it was, deliberately\n — widening it comes out of column width in a capped article, and on one corpus\n that pushed cells fitting on two lines onto three. */\n.blume-table-scroll :is(th, td) {\n padding: 0.75rem;\n}\n/* Keep column labels on one line so a two-word header does not wrap into a\n ragged stack; the table just scrolls a little wider instead. Body cells keep\n wrapping so a wide table stays a scroll away, not an endless horizontal run. */\n.blume-table-scroll th {\n white-space: nowrap;\n}\n\n/* GFM renders cells as <td><code> directly, which the descendant form alone\n never matches (a cell is not its own descendant). */\n.prose :where(td, th) > code,\n.prose :where(td, th) :not(pre) > code {\n white-space: normal;\n}\n\nblume-tabs pre,\n.not-prose > div > pre {\n background: var(--blume-code-background);\n}\n\n/* The Component source pane fills its tab's fixed height (set inline to match the\n preview tab) and scrolls the inner code element, leaving the pre static so the\n copy button — absolute, pinned to the pre — doesn't drift while it scrolls. */\npre.blume-source {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\npre.blume-source > code {\n flex: 1;\n /* The pane's measured height is authoritative (it can exceed the prose\n 24rem cap), so undo the generic prose max-height: the code must fill\n whatever height the tab was given. */\n max-height: none;\n min-height: 0;\n overflow: auto;\n}\n\n/* Code blocks inside tabs sit flush; the tab container owns the frame. These\n rules are unlayered like the base \\`pre\\` styles, so they win over Tailwind's\n layered utilities (which a class on the panel cannot). The second selector\n covers <CodeGroup>, where each code block IS the panel (a direct child of the\n tab content wrapper) rather than a <pre> nested inside a <Tab>. */\nblume-tabs [data-blume-tab-panel] > pre,\nblume-tabs [data-blume-tab-content] > pre {\n /* Important to beat the astro-code background rule above; the tab container\n owns the surface, so the code sits directly on it. */\n background: transparent !important;\n border: 0;\n border-radius: 0;\n margin: 0;\n}\n\n/* These contexts drop the language bar (\\`::before\\` is cleared below), so the\n bar's padding goes with it and the block keeps the plain inset. Unscoped on\n purpose: <CodeBlock> wraps its pre in its own \\`.prose\\` below the component\n chrome, so without this a titled block on a page with no prose column\n (PageLayout) would keep the 3.75rem bar padding under a cleared bar. */\nblume-tabs pre[data-language],\n.not-prose pre[data-language] {\n padding-top: ${CODE_PADDING_BLOCK_REM}rem;\n}\n\n/* Where no language bar holds the copy button — a flush block in tabs or a\n not-prose component, a bar-less block in prose — the docs layout still pins\n one over the block's top-right corner, so a first line long enough to reach\n it would end underneath. A code switcher (CodeGroup, ts2js) hosts the button\n in its tab strip instead and needs nothing here; for every block that keeps\n an overlay button, give the scrolling code element enough end padding that\n the line's tail clears the button at the end of its scroll. Keyed on the\n injected button itself (which the playground's client-created response pre\n never gets), and \\`.prose\\`-scoped to outrank the base \\`:where(pre code)\\`\n inset. Not a vertical inset — that reserved a strip above every one-line\n command and read as a rendering bug. */\n.prose :is(blume-tabs pre, .not-prose pre, pre:not([data-language])):not(.twoslash, .twoslash pre, blume-panel-tabs *):has(> [data-blume-copy]) > code {\n padding-inline-end: 3.5rem;\n}\n\nblume-tabs pre[data-language]::before,\n.not-prose pre[data-language]::before {\n content: none;\n}\n\n/* Pre-hydration layout-shift guard. The horizontal trigger row and\n single-panel visibility are built by the <blume-tabs> custom element's JS:\n until it upgrades, the trigger row is empty and every panel is in normal flow,\n so the browser paints all panels stacked vertically (e.g. all four\n package-manager commands at once) before JS hides them. While the element is\n :not(:defined), show only the first panel and reserve the trigger row's height\n so nothing jumps when JS takes over. The child selector covers both <Tab>\n panels and <CodeGroup> raw code blocks (which only gain\n [data-blume-tab-panel] from JS). */\nblume-tabs:not(:defined) [data-blume-tab-content] > *:nth-child(n + 2) {\n display: none;\n}\n\nblume-tabs:not(:defined) [data-blume-tablist] {\n /* Matches a trigger's height: py-2.5 + text-xs line-height + border-b-2. */\n min-height: 2.375rem;\n}\n\nblume-tabs:not(:defined)[data-dropdown=\"true\"] [data-blume-tablist] {\n /* Dropdown variant: p-3 padding around a select (py-2 + text-sm + border). */\n min-height: 3.875rem;\n}\n\n/* Code blocks inside request/response example panels sit flush; the panel owns\n the frame. Unlayered (like the tab rules) so they beat the base \\`pre\\` styles\n that a class on the panel cannot. */\n[data-blume-code-panel] pre {\n background: transparent !important;\n border: 0;\n border-radius: 0;\n margin: 0;\n}\n\n/* Opt-in line numbers (\\`\\`\\`ts file.ts lineNumbers): a counter-driven gutter that\n works in prose and flush (tab / API panel) code blocks alike. */\npre[data-line-numbers] code {\n counter-reset: line;\n}\n\npre[data-line-numbers] .line::before {\n color: var(--blume-muted-foreground);\n content: counter(line);\n counter-increment: line;\n display: inline-block;\n margin-right: 1.25rem;\n text-align: right;\n user-select: none;\n width: 1.25rem;\n}\n\n/* Shiki notation transformers (on by default). The notation comments are\n stripped from the output; these style the classes they leave behind. A styled\n line becomes a full-width inline-block so its background fills the row; plain\n lines are left untouched, so blocks without notations render as before. */\n.line.highlighted,\n.line.diff {\n display: inline-block;\n width: 100%;\n}\n\n/* The backgrounds need !important to beat the \\`pre.astro-code span\\` rule above,\n which forces token spans transparent; these line/word spans are exceptions. */\n.line.highlighted {\n background-color: var(--blume-code-highlight) !important;\n box-shadow: inset 2px 0 0 0 var(--blume-code-highlight-border);\n}\n\n.line.diff.add {\n background-color: var(--blume-code-add) !important;\n box-shadow: inset 2px 0 0 0 var(--blume-code-add-border);\n}\n\n.line.diff.remove {\n background-color: var(--blume-code-remove) !important;\n box-shadow: inset 2px 0 0 0 var(--blume-code-remove-border);\n}\n\n/* Word highlight (\\`// [!code word:x]\\`) wraps matches in an inline span. The\n element selector keeps it ahead of the transparent token-span rule. */\nspan.highlighted-word {\n background-color: var(--blume-code-word) !important;\n border-radius: 0.25rem;\n box-shadow: 0 0 0 1px var(--blume-code-word-border);\n padding: 0.1em 0.2em;\n}\n\n/* Focus (\\`// [!code focus]\\`): dim and blur the rest; reveal on hover. */\npre:has(.line.focused) .line:not(.focused) {\n filter: blur(0.085rem);\n opacity: 0.5;\n transition:\n filter 0.2s ease,\n opacity 0.2s ease;\n}\n\npre:has(.line.focused):hover .line:not(.focused) {\n filter: none;\n opacity: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n pre:has(.line.focused) .line:not(.focused) {\n transition: none;\n }\n}\n\n@media (max-width: 640px) {\n .prose :where(h1) {\n font-size: 2.25rem;\n }\n\n .prose :where(h2) {\n font-size: 1.625rem;\n }\n}\n\n.prose :not(pre) > code:not(:where([class~=\"not-prose\"] *)) {\n background: var(--blume-code-background);\n padding: 0.15em 0.35em;\n border-radius: 0.3rem;\n font-family: var(--font-mono);\n font-weight: 500;\n}\n\n.prose :not(pre) > code::before,\n.prose :not(pre) > code::after {\n content: none;\n}\n\n/* Inline code highlighting: Shiki colors the tokens of a \\`code\\`{:lang} snippet\n via the same dual-theme CSS variables as fenced blocks, keeping the inline\n pill background. Always on — it only fires on the trailing {:lang} marker. */\n.prose code.blume-inline-code span {\n color: var(--shiki-light);\n}\n\n:root[data-theme=\"dark\"] .prose code.blume-inline-code span {\n color: var(--shiki-dark);\n}\n\n/* Print / \"Save as PDF\" (the page-actions Export → PDF runs window.print()).\n Strip the surrounding chrome so the printout is just the article. */\n@media print {\n [data-blume-banner],\n header,\n aside,\n [data-blume-page-actions],\n #blume-content > nav,\n #blume-content > details {\n display: none !important;\n }\n\n /* Paper can't scroll: uncap the code scroller so long blocks print in\n full, same as tab panels are force-expanded below. */\n .prose :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *) > code) {\n max-height: none;\n overflow: visible;\n }\n\n #blume-content {\n padding: 0 !important;\n }\n\n .prose {\n margin: 0 !important;\n max-width: none !important;\n }\n\n /* Reveal collapsed tab panels so their content isn't dropped from the print. */\n blume-tabs [data-blume-tab-panel] {\n display: block !important;\n }\n\n /* Keep code/callout backgrounds (subject to the dialog's \"Background graphics\"\n toggle). */\n pre,\n .prose :not(pre) > code {\n -webkit-print-color-adjust: exact;\n print-color-adjust: exact;\n }\n}\n\n/* Twoslash rich-renderer styles (used by fences with the \\`twoslash\\` meta). */\n${options.twoslashCss ?? \"\"}\n\n/* Token overrides: config first, then the user's theme.css (highest priority). */\n${options.configTokens}\n${options.userTheme}\n`;\n\ninterface ExamplesEntryOptions {\n /** Config-derived token overrides (`:root { --blume-accent: ... }`). */\n configTokens: string;\n /** Globs to scan for utility classes (the project and examples directory). */\n sources: string[];\n /** Raw contents of the configured `examples.css`, if any. */\n userCss: string;\n}\n\n/**\n * Build the Tailwind entry for `<Component />` preview frames. Each example\n * renders in its own iframe so none of the app sheet above — prose typography,\n * component chrome, base overrides — can reach it. This sheet provides only\n * what an example needs to look like it does in an app: Tailwind (preflight +\n * utilities scanned from the example sources), the `--blume-*` tokens and\n * their utility mapping (so `bg-background`-style classes keep working and\n * previews follow the site palette by default), and the user's example CSS\n * (shadcn variables, `@theme` mappings, custom styles) last so it wins.\n */\nexport const examplesEntryTemplate = (options: ExamplesEntryOptions): string =>\n `/* Generated by Blume. Do not edit. */\n@import \"tailwindcss\";\n\n/* Scan the project (and an out-of-root examples directory) for utility classes. */\n${options.sources.map((source) => `@source \"${source}\";`).join(\"\\n\")}\n\n${DARK_VARIANT}\n\n${COLOR_SCHEME_DEFAULTS}\n\n${TOKEN_DEFAULTS}\n\n${THEME_MAPPING}\n\n/* Frame defaults: readable text in both modes, transparent so the docs pane's\n surface shows through. Base layer, so any user/example CSS wins. */\n@layer base {\n body {\n background: transparent;\n color: var(--blume-foreground);\n }\n}\n\n/* Token overrides: config first, then the configured examples css (highest\n priority) — the place for shadcn variables and other component tokens. */\n${options.configTokens}\n${options.userCss}\n`;\n",
|
|
30
|
+
"import { CODE_PADDING_BLOCK_REM } from \"./code-block-padding.ts\";\n\n/**\n * Bottom inset of the scrolling code element, in rem: keeps a horizontal\n * scrollbar thumb off the last line's descenders. It is carved out of the\n * pre's block padding rather than added to it, so a block's height is the\n * same whether or not it scrolls.\n */\nconst CODE_SCROLL_INSET_REM = 0.375;\n\ninterface TailwindEntryOptions {\n /**\n * Globs to scan for utility classes. Typically the Blume package source and\n * the user's project (node_modules is skipped automatically).\n */\n sources: string[];\n /** Config-derived token overrides (`:root { --blume-accent: ... }`). */\n configTokens: string;\n /** Raw contents of the user's theme.css, if any. */\n userTheme: string;\n /** Twoslash rich-renderer styles (for fences with the `twoslash` meta). */\n twoslashCss?: string;\n /** The code-block language icon rules (`languageIconCss`), if any. */\n languageIcons?: string;\n}\n\n/** Dark mode is driven by `data-theme` on the root element (both sheets). */\nconst DARK_VARIANT = `/* Dark mode is driven by data-theme on the <html> element. */\n@custom-variant dark (&:where([data-theme=\"dark\"], [data-theme=\"dark\"] *));`;\n\n/** Keep browser-provided UI in sync with the active theme in both sheets. */\nconst COLOR_SCHEME_DEFAULTS = `:root {\n color-scheme: light;\n}\n\n:root[data-theme=\"dark\"] {\n color-scheme: dark;\n}`;\n\n/**\n * The default `--blume-*` design tokens (light + dark), shared by the app\n * sheet and the isolated example-preview sheet so previews inherit the site's\n * palette by default.\n */\nconst TOKEN_DEFAULTS = `:root {\n --blume-background: oklch(1 0 0);\n --blume-background-image: none;\n --blume-background-image-repeat: no-repeat;\n --blume-background-image-size: cover;\n --blume-foreground: oklch(0.145 0 0);\n --blume-muted: oklch(0.965 0 0);\n /* 5.28:1 on the page background. The headroom over 4.5:1 is the point: muted\n text is 14px body copy routinely set on a tinted surface (callouts, badges,\n panels), and each tint costs a few tenths. */\n --blume-muted-foreground: oklch(0.53 0 0);\n --blume-border: oklch(0.88 0.006 260 / 0.72);\n --blume-accent: oklch(0.145 0 0);\n --blume-accent-foreground: oklch(1 0 0);\n --blume-action: var(--blume-accent);\n --blume-action-foreground: var(--blume-accent-foreground);\n --blume-code-background: oklch(0.99 0 0);\n /* Shiki notation transformers: line/word highlight, diff add/remove. */\n --blume-code-highlight: oklch(0.55 0.16 255 / 0.1);\n --blume-code-highlight-border: oklch(0.55 0.16 255 / 0.55);\n --blume-code-add: oklch(0.72 0.16 150 / 0.16);\n --blume-code-add-border: oklch(0.52 0.15 150 / 0.7);\n --blume-code-remove: oklch(0.66 0.21 22 / 0.16);\n --blume-code-remove-border: oklch(0.55 0.2 22 / 0.7);\n --blume-code-word: oklch(0.55 0.16 255 / 0.16);\n --blume-code-word-border: oklch(0.55 0.16 255 / 0.5);\n --blume-radius: 0.75rem;\n\n /* Max width of the prose content column (article, breadcrumb, TOC, feedback,\n pagination, last-updated). Override to re-measure the whole column at once. */\n --blume-content-width: 42rem;\n\n /*\n * Font tokens resolve through optional src variables that Astro's Fonts API\n * populates (via theme.fonts). When unset they fall back to the system\n * stacks, so the default look is unchanged. The display font defaults to the\n * body font.\n */\n --blume-font-body: var(\n --blume-font-body-src,\n ui-sans-serif,\n system-ui,\n -apple-system,\n \"Segoe UI\",\n Roboto,\n Helvetica,\n Arial,\n sans-serif\n );\n --blume-font-mono: var(\n --blume-font-mono-src,\n ui-monospace,\n \"SF Mono\",\n \"Cascadia Code\",\n \"Source Code Pro\",\n Menlo,\n Consolas,\n monospace\n );\n --blume-font-display: var(--blume-font-display-src, var(--blume-font-body));\n}\n\n:root[data-theme=\"dark\"] {\n --blume-background: oklch(0.085 0 0);\n --blume-background-image: none;\n --blume-background-image-repeat: no-repeat;\n --blume-background-image-size: cover;\n --blume-foreground: oklch(0.96 0 0);\n --blume-muted: oklch(0.16 0 0);\n --blume-muted-foreground: oklch(0.68 0 0);\n --blume-border: oklch(0.24 0 0 / 0.8);\n --blume-accent: oklch(0.96 0 0);\n --blume-accent-foreground: oklch(0.085 0 0);\n --blume-action: var(--blume-accent);\n --blume-action-foreground: var(--blume-accent-foreground);\n --blume-code-background: oklch(0.12 0 0);\n /* Brighter tints read better over the dark code surface. */\n --blume-code-highlight: oklch(0.7 0.14 255 / 0.16);\n --blume-code-highlight-border: oklch(0.7 0.14 255 / 0.6);\n --blume-code-add: oklch(0.78 0.17 150 / 0.2);\n --blume-code-add-border: oklch(0.72 0.16 150 / 0.7);\n --blume-code-remove: oklch(0.72 0.21 22 / 0.22);\n --blume-code-remove-border: oklch(0.7 0.2 22 / 0.7);\n --blume-code-word: oklch(0.7 0.14 255 / 0.22);\n --blume-code-word-border: oklch(0.7 0.14 255 / 0.55);\n}`;\n\n/**\n * Tailwind theme mapping from `--blume-*` tokens to utility-facing names\n * (`bg-background`, `border-border`, `rounded-blume`, the font stacks).\n * Shared by both sheets so example code written against Blume's utility\n * vocabulary renders identically inside the isolated preview frame.\n */\nconst THEME_MAPPING = `@theme inline {\n --color-background: var(--blume-background);\n --color-foreground: var(--blume-foreground);\n --color-muted: var(--blume-muted);\n --color-muted-foreground: var(--blume-muted-foreground);\n --color-border: var(--blume-border);\n --color-accent: var(--blume-accent);\n --color-accent-foreground: var(--blume-accent-foreground);\n --color-action: var(--blume-action);\n --color-action-foreground: var(--blume-action-foreground);\n --color-code: var(--blume-code-background);\n --radius-blume: var(--blume-radius);\n --container-content: var(--blume-content-width);\n --font-sans: var(--blume-font-body);\n --font-mono: var(--blume-font-mono);\n --font-display: var(--blume-font-display);\n}`;\n\n/**\n * Build the single Tailwind v4 entry stylesheet for the generated runtime.\n *\n * Everything flows through one Tailwind-processed file so utilities are\n * generated and design tokens cascade deterministically:\n * base defaults -> config tokens -> user theme.css.\n */\nexport const tailwindEntryTemplate = (options: TailwindEntryOptions): string =>\n `/* Generated by Blume. Do not edit. */\n@import \"tailwindcss\";\n@plugin \"@tailwindcss/typography\";\n\n/* Scan Blume's components and the user's project for utility classes. */\n${options.sources.map((source) => `@source \"${source}\";`).join(\"\\n\")}\n\n${DARK_VARIANT}\n\n${COLOR_SCHEME_DEFAULTS}\n\n${TOKEN_DEFAULTS}\n\n${THEME_MAPPING}\n\n@layer base {\n /* Nothing refuses to shrink below its intrinsic content width. This global\n min-width reset defuses the classic flex/grid overflow — a long or\n truncating child forcing its container (and the page) past the viewport\n edge — so components don't need per-element min-w-0 overrides. */\n * {\n min-width: 0;\n }\n /* Interactive controls get a pointer cursor unless disabled. */\n button:not(:disabled),\n [role=\"button\"]:not(:disabled) {\n cursor: pointer;\n }\n html {\n scroll-behavior: smooth;\n scroll-padding-top: 4.5rem;\n text-rendering: optimizeLegibility;\n }\n /* Modal surfaces coordinate through independent root attributes. The lock\n remains until every owner releases its attribute, while !important lets it\n temporarily override (and therefore preserve) an authored inline value.\n Classic (non-overlay) scrollbars would otherwise vanish while locked and\n shift the page and the centered dialog sideways, so keep their gutter. */\n html:where([data-blume-nav-open], [data-blume-search-dialog-open]) {\n overflow: hidden !important;\n scrollbar-gutter: stable;\n }\n /* Headings use the display font (defaults to the body font when unset).\n The tightened tracking is part of the theme, not the font: display-tuned\n families bake it into their metrics, but a text family promoted to\n headings (including the Inter default) reads loose without it. -0.05em\n was matched visually against Inter Tight, the previous display default. */\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: var(--font-display);\n letter-spacing: -0.05em;\n }\n :focus-visible {\n outline: 2px solid var(--blume-accent);\n outline-offset: 2px;\n border-radius: 2px;\n }\n body {\n background-attachment: fixed;\n background-image: var(--blume-background-image);\n background-position: center top;\n background-repeat: var(--blume-background-image-repeat);\n background-size: var(--blume-background-image-size);\n }\n @media (prefers-reduced-motion: reduce) {\n html {\n scroll-behavior: auto;\n }\n }\n}\n\n/* Same-origin navigations ride Astro's client router (the layouts render\n ClientRouter), which owns the page-transition styling — including its own\n prefers-reduced-motion guard — so the theme declares nothing about it. The\n cross-document view-transition opt-in that briefly lived here is\n deliberately gone: mixing it with the client router double-animates the\n full-load navigations the router hands back to the browser. */\n\n/* Code reads left-to-right regardless of page direction; only the surrounding\n chrome mirrors for RTL. Inline code is isolated so LTR identifiers don't\n disturb the bidi flow of right-to-left prose. */\n[dir=\"rtl\"] pre,\n[dir=\"rtl\"] .prose pre {\n direction: ltr;\n text-align: left;\n}\n[dir=\"rtl\"] :not(pre) > code {\n unicode-bidi: isolate;\n}\n\n/* The sidebar's rows. A docs site renders every sidebar row on every page,\n so a large site's HTML is mostly this markup — one utility per row kind\n instead of the dozen classes each expands to keeps every page (and the\n build's HTML output) small. Kept in sync with NavTree.astro: a page row,\n a page-mode group's drill-in button, a collapsible group's summary and\n the link inside it, and a flat group's heading and the link inside it. */\n@utility blume-nav-link {\n @apply block rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:font-medium aria-[current=page]:text-foreground;\n}\n@utility blume-nav-drill {\n @apply flex w-full items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-left font-medium text-foreground text-sm transition-colors hover:bg-muted;\n}\n@utility blume-nav-summary {\n @apply flex cursor-pointer list-none items-center gap-1.5 rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground [&::-webkit-details-marker]:hidden;\n}\n@utility blume-nav-summary-link {\n @apply -my-1 flex flex-1 items-center gap-1.5 rounded py-1 transition-colors aria-[current=page]:text-foreground aria-[current=page]:font-semibold;\n}\n@utility blume-nav-heading {\n @apply mb-2 flex items-center gap-1.5 px-2.5 font-medium text-foreground text-sm;\n}\n@utility blume-nav-heading-link {\n @apply -ml-1 flex flex-1 items-center gap-1.5 rounded-[0.65rem] px-1 py-0.5 text-foreground transition-colors hover:bg-muted aria-[current=page]:bg-muted;\n}\n\n/* Theme Tailwind Typography (prose) with Blume tokens. */\n.prose {\n --tw-prose-body: var(--blume-foreground);\n --tw-prose-headings: var(--blume-foreground);\n --tw-prose-lead: var(--blume-muted-foreground);\n --tw-prose-links: var(--blume-foreground);\n --tw-prose-bold: var(--blume-foreground);\n --tw-prose-counters: var(--blume-muted-foreground);\n --tw-prose-bullets: var(--blume-muted-foreground);\n --tw-prose-hr: var(--blume-border);\n --tw-prose-quotes: var(--blume-muted-foreground);\n --tw-prose-quote-borders: var(--blume-border);\n --tw-prose-captions: var(--blume-muted-foreground);\n --tw-prose-code: var(--blume-foreground);\n --tw-prose-pre-code: var(--blume-foreground);\n --tw-prose-pre-bg: var(--blume-code-background);\n --tw-prose-th-borders: var(--blume-border);\n --tw-prose-td-borders: var(--blume-border);\n color: var(--blume-muted-foreground);\n font-size: 0.875rem;\n line-height: 1.7;\n /* An unbreakable run — an API permission, a broker list, a bare URL used as\n its own link text, an OpenAPI operation title of the form\n \\`METHOD /very/long/{path}\\`, a module-qualified name in a generated\n reference — paints past the content column, and nothing between the\n paragraph and the viewport clips it, so it lands in the document's scroll\n width and drags the page sideways on a phone. Inherited, so headings and\n inline code are covered too; the only re-declarations below are the\n opt-in code-wrap mode and Twoslash, which want different values.\n \\`break-word\\` and not \\`anywhere\\`: only \\`anywhere\\` reduces min-content,\n which is what sizes \\`table-layout: auto\\` columns, so it would resize\n every table on the site. The flip side is that a token in a table cell\n still never breaks — the column grows to fit it — so wide tables rely on\n the .blume-table-scroll wrapper, not on this. */\n overflow-wrap: break-word;\n}\n\n/* No letter-spacing here: prose headings inherit the base h1-h6 rule's\n display tracking, same as headings outside the prose column. */\n.prose :where(h1, h2, h3, h4) {\n font-weight: 500;\n}\n\n.prose :where(h1) {\n font-size: 3rem;\n line-height: 1.1;\n margin: 0 0 1rem;\n}\n\n.prose :where(h2) {\n font-size: 1.875rem;\n line-height: 1.2;\n margin-top: 3rem;\n}\n\n.prose :where(h3) {\n font-size: 1.25rem;\n line-height: 1.35;\n}\n\n.prose :where(h4) {\n color: var(--blume-muted-foreground);\n font-size: 0.875rem;\n line-height: 1.4;\n}\n\n.prose :where(h1, h2, h3, h4, h5, h6) a {\n color: inherit;\n font-weight: inherit;\n text-decoration: none;\n}\n\n/* Auto-generated heading permalinks (markdown.headingAnchors): the whole\n heading links to its own id, with a muted “#” revealed on hover or keyboard\n focus so the link is discoverable without cluttering the heading at rest. */\n.prose :where(h2, h3, h4, h5, h6) a.blume-heading-anchor::after {\n content: \"#\";\n color: var(--blume-muted-foreground);\n margin-inline-start: 0.35em;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n.prose :where(h2, h3, h4, h5, h6) a.blume-heading-anchor:hover::after,\n.prose :where(h2, h3, h4, h5, h6) a.blume-heading-anchor:focus-visible::after {\n opacity: 1;\n}\n\n/* A [toc]-marked heading exists only for the table of contents: it stays in\n the flow as a zero-height, invisible anchor target so its TOC entry (and any\n deep link) still has somewhere to scroll to, without rendering on the page. */\n.prose :where(.blume-toc-only) {\n border: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n padding: 0;\n visibility: hidden;\n}\n\n.prose :where(h2:first-child) {\n border-top: 0;\n padding-top: 0;\n}\n\n.prose :where(p, ul, ol) {\n margin-top: 1rem;\n margin-bottom: 1rem;\n}\n\n.prose :where(strong) {\n font-weight: 600;\n}\n\n.prose :where(a) {\n color: var(--blume-foreground);\n font-weight: 500;\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: 1px;\n text-underline-offset: 0.2em;\n}\n\n.prose :where(a[data-blume-card]) {\n color: inherit;\n font-weight: inherit;\n text-decoration: none;\n}\n\n.prose :where(hr) {\n margin: 2.5rem 0;\n}\n\n.prose :where(pre) {\n background: transparent;\n border: 1px solid var(--blume-border);\n border-radius: var(--blume-radius);\n color: var(--blume-foreground);\n font-family: var(--font-mono);\n font-size: 0.8125rem;\n line-height: 1.55;\n margin: 1.5rem 0;\n overflow-x: auto;\n padding: ${CODE_PADDING_BLOCK_REM}rem 0;\n position: relative;\n}\n\n.prose :where(pre.astro-code) {\n background: transparent !important;\n color: var(--shiki-light, var(--blume-foreground)) !important;\n}\n\n:root[data-theme=\"dark\"] .prose :where(pre.astro-code) {\n color: var(--shiki-dark, var(--blume-foreground)) !important;\n}\n\n.prose :where(pre.astro-code span) {\n background: transparent !important;\n color: var(--shiki-light, inherit);\n font-style: var(--shiki-light-font-style, inherit);\n font-weight: var(--shiki-light-font-weight, inherit);\n text-decoration: var(--shiki-light-text-decoration, inherit);\n}\n\n:root[data-theme=\"dark\"] .prose :where(pre.astro-code span) {\n color: var(--shiki-dark, inherit);\n font-style: var(--shiki-dark-font-style, inherit);\n font-weight: var(--shiki-dark-font-weight, inherit);\n text-decoration: var(--shiki-dark-text-decoration, inherit);\n}\n\n/* The Diff component (@pierre/diffs) renders into a declarative shadow root and\n themes itself with light-dark(). Drive that from Blume's data-theme instead\n of the OS, scoped to the diff host: the custom property pierces the shadow\n boundary, where the appended host color-scheme rule consumes it. */\nblume-diff {\n --blume-diff-color-scheme: light;\n display: block;\n}\n\n:root[data-theme=\"dark\"] blume-diff {\n --blume-diff-color-scheme: dark;\n}\n\n.prose :where(pre[data-language]) {\n padding-top: 3.75rem;\n}\n\n.prose :where(pre[data-language])::before {\n align-items: center;\n border-bottom: 1px solid var(--blume-border);\n color: var(--blume-muted-foreground);\n content: attr(data-language);\n display: flex;\n font-family: var(--font-sans);\n font-size: 0.75rem;\n font-weight: 500;\n height: 2.75rem;\n left: 0;\n padding: 0 3.25rem 0 1rem;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.prose :where(pre[data-title])::before {\n content: attr(data-title);\n}\n\n/* Language icon (simple-icons) sits at the header's left edge; the label shifts\n right to make room. Injected at build time by the language-icon transformer.\n The icon is gated on data-language (the header bar), not just data-icon: the\n transformer runs whenever icons are on, but a header-less standalone\n CodeBlock (no title) never gets data-language, so without this gate the\n absolutely-positioned icon would overlap the first code line. Fenced code\n and titled blocks always have a header, so the icon shows there. */\n.prose > :where(pre[data-language][data-icon])::after {\n content: \"\";\n height: 0.875rem;\n left: 1rem;\n -webkit-mask-position: center;\n -webkit-mask-repeat: no-repeat;\n -webkit-mask-size: contain;\n mask-position: center;\n mask-repeat: no-repeat;\n mask-size: contain;\n pointer-events: none;\n position: absolute;\n top: 0.875rem;\n width: 0.875rem;\n}\n\n.prose > :where(pre[data-language][data-icon])::before {\n padding-left: 2.5rem;\n}\n\n/* One mask rule per language the site's Markdown uses (see\n markdown/language-icon.ts); the ::after above only gets a color and a mask\n from these, so a block whose language has no rule paints nothing. */\n${options.languageIcons ?? \"\"}\n\n.prose :where(pre code) {\n background: transparent;\n border-radius: 0;\n color: inherit;\n font-size: inherit;\n font-weight: 400;\n padding: 0;\n}\n\n/* Long lines scroll inside the code element, not the pre: the pre stays static\n so its absolute header bar (::before) and copy button don't drift with the\n scroll. The pre's horizontal padding lives here so content still scrolls\n edge-to-edge past it. Two contexts opt out: twoslash blocks (popups must\n escape any scroll container — see theme/twoslash.ts), and the API request\n panel, which owns its code layout and keeps the copy control in the panel\n header. Every other component that hosts a code block — Tabs, CodeGroup,\n Steps, Callout, Card, Accordion — is real prose content and keeps the inset,\n even though its chrome wrapper is not-prose. */\n.prose :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *) > code) {\n display: block;\n /* Tall blocks scroll vertically in place instead of taking the page. Both\n axes live on the code element for the same reason: the pre stays static\n so the header bar and copy button never drift with the scroll. */\n max-height: 24rem;\n overflow: auto;\n /* The small bottom inset keeps the horizontal thumb off the last line's\n descenders now that scrollbars are visible. The pre gives up the same\n amount below (next rule), so the inset adds no height to the block. */\n padding: 0 1.25rem ${CODE_SCROLL_INSET_REM}rem;\n /* Thin theme-colored scrollbars, matching the sidebar treatment, so a\n height-capped block reads as scrollable instead of simply ending.\n Safari before 18.2 supports neither property and falls back to the\n platform-default scrollbar — acceptable, since macOS overlays it. */\n scrollbar-color: var(--blume-border) transparent;\n scrollbar-width: thin;\n}\n\n/* The scroller's bottom inset comes out of the pre's own block padding: the\n text still sits one full inset above the frame's bottom edge, the thumb sits\n in the gap, and a one-line command is no taller than it was before the\n scroller existed. */\n.prose :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *):has(> code)) {\n padding-bottom: calc(${CODE_PADDING_BLOCK_REM}rem - ${CODE_SCROLL_INSET_REM}rem);\n}\n\n/* The dark border token is too close to the page background to read as a\n scrollbar thumb; derive a brighter one from the muted foreground instead. */\n:root[data-theme=\"dark\"]\n .prose\n :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *) > code) {\n scrollbar-color: color-mix(in oklab, var(--blume-muted-foreground) 55%, transparent)\n transparent;\n}\n\n/* Word wrap (markdown.code.wrap): long lines wrap instead of scrolling. The\n attribute is set on <body> from config; default code keeps \\`white-space: pre\\`. */\n[data-blume-code-wrap] pre,\n[data-blume-code-wrap] pre code {\n overflow-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.prose :where(table) {\n font-size: 0.8125rem;\n}\n\n/* Scroll wide tables in place; the wrapper is added by the blume:table-wrap hast\n plugin. The border+radius frames the scroll viewport so a clipped wide table\n reads as scrollable rather than cut off, and carries the table's vertical\n rhythm (the inner table's own margin is zeroed so it fills the frame). */\n.blume-table-scroll {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n margin: 1.5rem 0;\n border: 1px solid var(--blume-border);\n border-radius: var(--blume-radius);\n}\n.blume-table-scroll > table {\n margin: 0;\n}\n/* Restore inner padding on every cell. Typography zeroes the first/last cell's\n inline padding so a borderless table aligns to the prose margin; inside the\n framed wrapper that leaves edge text touching the border. The :is() selector\n outweighs Typography's :where()-scoped rules so the outer columns get it too.\n\n The block padding is 0.75rem against a table line-height near 1.7: at 0.5rem a\n cell whose content wrapped put MORE space between its own two lines than\n between itself and the next row, so a table of wrapping cells read as one\n block rather than as rows. The inline padding stays where it was, deliberately\n — widening it comes out of column width in a capped article, and on one corpus\n that pushed cells fitting on two lines onto three. */\n.blume-table-scroll :is(th, td) {\n padding: 0.75rem;\n}\n/* Keep column labels on one line so a two-word header does not wrap into a\n ragged stack; the table just scrolls a little wider instead. Body cells keep\n wrapping so a wide table stays a scroll away, not an endless horizontal run. */\n.blume-table-scroll th {\n white-space: nowrap;\n}\n\n/* GFM renders cells as <td><code> directly, which the descendant form alone\n never matches (a cell is not its own descendant). */\n.prose :where(td, th) > code,\n.prose :where(td, th) :not(pre) > code {\n white-space: normal;\n}\n\nblume-tabs pre,\n.not-prose > div > pre {\n background: var(--blume-code-background);\n}\n\n/* The Component source pane fills its tab's fixed height (set inline to match the\n preview tab) and scrolls the inner code element, leaving the pre static so the\n copy button — absolute, pinned to the pre — doesn't drift while it scrolls. */\npre.blume-source {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\npre.blume-source > code {\n flex: 1;\n /* The pane's measured height is authoritative (it can exceed the prose\n 24rem cap), so undo the generic prose max-height: the code must fill\n whatever height the tab was given. */\n max-height: none;\n min-height: 0;\n overflow: auto;\n}\n\n/* Code blocks inside tabs sit flush; the tab container owns the frame. These\n rules are unlayered like the base \\`pre\\` styles, so they win over Tailwind's\n layered utilities (which a class on the panel cannot). The second selector\n covers <CodeGroup>, where each code block IS the panel (a direct child of the\n tab content wrapper) rather than a <pre> nested inside a <Tab>. */\nblume-tabs [data-blume-tab-panel] > pre,\nblume-tabs [data-blume-tab-content] > pre {\n /* Important to beat the astro-code background rule above; the tab container\n owns the surface, so the code sits directly on it. */\n background: transparent !important;\n border: 0;\n border-radius: 0;\n margin: 0;\n}\n\n/* These contexts drop the language bar (\\`::before\\` is cleared below), so the\n bar's padding goes with it and the block keeps the plain inset. Unscoped on\n purpose: <CodeBlock> wraps its pre in its own \\`.prose\\` below the component\n chrome, so without this a titled block on a page with no prose column\n (PageLayout) would keep the 3.75rem bar padding under a cleared bar. */\nblume-tabs pre[data-language],\n.not-prose pre[data-language] {\n padding-top: ${CODE_PADDING_BLOCK_REM}rem;\n}\n\n/* Where no language bar holds the copy button — a flush block in tabs or a\n not-prose component, a bar-less block in prose — the docs layout still pins\n one over the block's top-right corner, so a first line long enough to reach\n it would end underneath. A code switcher (CodeGroup, ts2js) hosts the button\n in its tab strip instead and needs nothing here; for every block that keeps\n an overlay button, give the scrolling code element enough end padding that\n the line's tail clears the button at the end of its scroll. Keyed on the\n injected button itself (which the playground's client-created response pre\n never gets), and \\`.prose\\`-scoped to outrank the base \\`:where(pre code)\\`\n inset. Not a vertical inset — that reserved a strip above every one-line\n command and read as a rendering bug. */\n.prose :is(blume-tabs pre, .not-prose pre, pre:not([data-language])):not(.twoslash, .twoslash pre, blume-panel-tabs *):has(> [data-blume-copy]) > code {\n padding-inline-end: 3.5rem;\n}\n\nblume-tabs pre[data-language]::before,\n.not-prose pre[data-language]::before {\n content: none;\n}\n\n/* Pre-hydration layout-shift guard. The horizontal trigger row and\n single-panel visibility are built by the <blume-tabs> custom element's JS:\n until it upgrades, the trigger row is empty and every panel is in normal flow,\n so the browser paints all panels stacked vertically (e.g. all four\n package-manager commands at once) before JS hides them. While the element is\n :not(:defined), show only the first panel and reserve the trigger row's height\n so nothing jumps when JS takes over. The child selector covers both <Tab>\n panels and <CodeGroup> raw code blocks (which only gain\n [data-blume-tab-panel] from JS). */\nblume-tabs:not(:defined) [data-blume-tab-content] > *:nth-child(n + 2) {\n display: none;\n}\n\nblume-tabs:not(:defined) [data-blume-tablist] {\n /* Matches a trigger's height: py-2.5 + text-xs line-height + border-b-2. */\n min-height: 2.375rem;\n}\n\nblume-tabs:not(:defined)[data-dropdown=\"true\"] [data-blume-tablist] {\n /* Dropdown variant: p-3 padding around a select (py-2 + text-sm + border). */\n min-height: 3.875rem;\n}\n\n/* Code blocks inside request/response example panels sit flush; the panel owns\n the frame. Unlayered (like the tab rules) so they beat the base \\`pre\\` styles\n that a class on the panel cannot. */\n[data-blume-code-panel] pre {\n background: transparent !important;\n border: 0;\n border-radius: 0;\n margin: 0;\n}\n\n/* Opt-in line numbers (\\`\\`\\`ts file.ts lineNumbers): a counter-driven gutter that\n works in prose and flush (tab / API panel) code blocks alike. */\npre[data-line-numbers] code {\n counter-reset: line;\n}\n\npre[data-line-numbers] .line::before {\n color: var(--blume-muted-foreground);\n content: counter(line);\n counter-increment: line;\n display: inline-block;\n margin-right: 1.25rem;\n text-align: right;\n user-select: none;\n width: 1.25rem;\n}\n\n/* Shiki notation transformers (on by default). The notation comments are\n stripped from the output; these style the classes they leave behind. A styled\n line becomes a full-width inline-block so its background fills the row; plain\n lines are left untouched, so blocks without notations render as before. */\n.line.highlighted,\n.line.diff {\n display: inline-block;\n width: 100%;\n}\n\n/* The backgrounds need !important to beat the \\`pre.astro-code span\\` rule above,\n which forces token spans transparent; these line/word spans are exceptions. */\n.line.highlighted {\n background-color: var(--blume-code-highlight) !important;\n box-shadow: inset 2px 0 0 0 var(--blume-code-highlight-border);\n}\n\n.line.diff.add {\n background-color: var(--blume-code-add) !important;\n box-shadow: inset 2px 0 0 0 var(--blume-code-add-border);\n}\n\n.line.diff.remove {\n background-color: var(--blume-code-remove) !important;\n box-shadow: inset 2px 0 0 0 var(--blume-code-remove-border);\n}\n\n/* Word highlight (\\`// [!code word:x]\\`) wraps matches in an inline span. The\n element selector keeps it ahead of the transparent token-span rule. */\nspan.highlighted-word {\n background-color: var(--blume-code-word) !important;\n border-radius: 0.25rem;\n box-shadow: 0 0 0 1px var(--blume-code-word-border);\n padding: 0.1em 0.2em;\n}\n\n/* Focus (\\`// [!code focus]\\`): dim and blur the rest; reveal on hover. */\npre:has(.line.focused) .line:not(.focused) {\n filter: blur(0.085rem);\n opacity: 0.5;\n transition:\n filter 0.2s ease,\n opacity 0.2s ease;\n}\n\npre:has(.line.focused):hover .line:not(.focused) {\n filter: none;\n opacity: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n pre:has(.line.focused) .line:not(.focused) {\n transition: none;\n }\n}\n\n@media (max-width: 640px) {\n .prose :where(h1) {\n font-size: 2.25rem;\n }\n\n .prose :where(h2) {\n font-size: 1.625rem;\n }\n}\n\n.prose :not(pre) > code:not(:where([class~=\"not-prose\"] *)) {\n background: var(--blume-code-background);\n padding: 0.15em 0.35em;\n border-radius: 0.3rem;\n font-family: var(--font-mono);\n font-weight: 500;\n}\n\n.prose :not(pre) > code::before,\n.prose :not(pre) > code::after {\n content: none;\n}\n\n/* Inline code highlighting: Shiki colors the tokens of a \\`code\\`{:lang} snippet\n via the same dual-theme CSS variables as fenced blocks, keeping the inline\n pill background. Always on — it only fires on the trailing {:lang} marker. */\n.prose code.blume-inline-code span {\n color: var(--shiki-light);\n}\n\n:root[data-theme=\"dark\"] .prose code.blume-inline-code span {\n color: var(--shiki-dark);\n}\n\n/* Print / \"Save as PDF\" (the page-actions Export → PDF runs window.print()).\n Strip the surrounding chrome so the printout is just the article. */\n@media print {\n [data-blume-banner],\n header,\n aside,\n [data-blume-page-actions],\n #blume-content > nav,\n #blume-content > details {\n display: none !important;\n }\n\n /* Paper can't scroll: uncap the code scroller so long blocks print in\n full, same as tab panels are force-expanded below. */\n .prose :where(pre:not(.twoslash, .twoslash pre, blume-panel-tabs *) > code) {\n max-height: none;\n overflow: visible;\n }\n\n #blume-content {\n padding: 0 !important;\n }\n\n .prose {\n margin: 0 !important;\n max-width: none !important;\n }\n\n /* Reveal collapsed tab panels so their content isn't dropped from the print. */\n blume-tabs [data-blume-tab-panel] {\n display: block !important;\n }\n\n /* Keep code/callout backgrounds (subject to the dialog's \"Background graphics\"\n toggle). */\n pre,\n .prose :not(pre) > code {\n -webkit-print-color-adjust: exact;\n print-color-adjust: exact;\n }\n}\n\n/* Twoslash rich-renderer styles (used by fences with the \\`twoslash\\` meta). */\n${options.twoslashCss ?? \"\"}\n\n/* Token overrides: config first, then the user's theme.css (highest priority). */\n${options.configTokens}\n${options.userTheme}\n`;\n\ninterface ExamplesEntryOptions {\n /** Config-derived token overrides (`:root { --blume-accent: ... }`). */\n configTokens: string;\n /** Globs to scan for utility classes (the project and examples directory). */\n sources: string[];\n /** Raw contents of the configured `examples.css`, if any. */\n userCss: string;\n}\n\n/**\n * Build the Tailwind entry for `<Component />` preview frames. Each example\n * renders in its own iframe so none of the app sheet above — prose typography,\n * component chrome, base overrides — can reach it. This sheet provides only\n * what an example needs to look like it does in an app: Tailwind (preflight +\n * utilities scanned from the example sources), the `--blume-*` tokens and\n * their utility mapping (so `bg-background`-style classes keep working and\n * previews follow the site palette by default), and the user's example CSS\n * (shadcn variables, `@theme` mappings, custom styles) last so it wins.\n */\nexport const examplesEntryTemplate = (options: ExamplesEntryOptions): string =>\n `/* Generated by Blume. Do not edit. */\n@import \"tailwindcss\";\n\n/* Scan the project (and an out-of-root examples directory) for utility classes. */\n${options.sources.map((source) => `@source \"${source}\";`).join(\"\\n\")}\n\n${DARK_VARIANT}\n\n${COLOR_SCHEME_DEFAULTS}\n\n${TOKEN_DEFAULTS}\n\n${THEME_MAPPING}\n\n/* Frame defaults: readable text in both modes, transparent so the docs pane's\n surface shows through. Base layer, so any user/example CSS wins. */\n@layer base {\n body {\n background: transparent;\n color: var(--blume-foreground);\n }\n}\n\n/* Token overrides: config first, then the configured examples css (highest\n priority) — the place for shadcn variables and other component tokens. */\n${options.configTokens}\n${options.userCss}\n`;\n",
|
|
31
31
|
"import { dirname, isAbsolute, relative, resolve } from \"pathe\";\n\n/**\n * A Tailwind `@source \"…\"` / `@source not \"…\"` directive with a quoted path.\n * `@source inline(\"…\")` never matches: the quote must directly follow the\n * keyword (or `not`), and `inline(` sits in between.\n */\nconst SOURCE_DIRECTIVE =\n /@source(?<not>\\s+not)?\\s+(?<quote>[\"'])(?<path>[^\"']+)\\k<quote>/gu;\n\n/**\n * Rewrite the relative `@source` paths in a user stylesheet so they still\n * point where the author meant once the sheet is inlined into a generated\n * Tailwind entry. Tailwind resolves `@source` relative to the stylesheet that\n * declares it, and Blume splices `theme.css` / `examples.css` verbatim into\n * `.blume/src/generated/*.css` (or `src/generated/*.css` after eject), which\n * would silently re-root them there. Resolving each path against the user's\n * file and re-expressing it relative to the generated directory keeps the\n * standard contract — write `@source \"../../packages/ui\"` next to the file\n * that says it — and lets a monorepo scan sibling workspace packages for\n * utility classes without any knowledge of Blume's internal layout. Absolute\n * paths pass through untouched.\n */\nexport const rebaseSourceDirectives = (\n css: string,\n options: {\n /** The user's stylesheet the CSS was read from. */\n from: string;\n /** The directory of the generated entry the CSS is inlined into. */\n to: string;\n }\n): string => {\n const base = dirname(options.from);\n return css.replace(\n SOURCE_DIRECTIVE,\n (\n directive: string,\n not: string | undefined,\n quote: string,\n path: string\n ): string => {\n if (isAbsolute(path)) {\n return directive;\n }\n const rebased = relative(options.to, resolve(base, path));\n return `@source${not ?? \"\"} ${quote}${rebased}${quote}`;\n }\n );\n};\n",
|
|
32
32
|
"/**\n * CSS for Twoslash's rich renderer, emitted into the Tailwind entry (Twoslash\n * runs on any fence with the `twoslash` meta). It is the shipped\n * `@shikijs/twoslash` stylesheet plus a Blume-themed override layer:\n *\n * - maps the renderer's `--twoslash-*` variables onto Blume tokens so popups\n * match the active theme (light/dark);\n * - lets popups escape the code block's horizontal scroll container; and\n * - restores backgrounds the theme's `pre.astro-code span { background:\n * transparent !important }` rule would otherwise clear from popup chrome.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\n/** Blume-token theming layered over the shipped rich renderer styles. */\nconst OVERRIDES = `\n/* Twoslash: theme the rich renderer with Blume tokens. */\n:root {\n --twoslash-border-color: var(--blume-border);\n --twoslash-popup-bg: var(--blume-code-background);\n --twoslash-popup-color: var(--blume-foreground);\n --twoslash-popup-shadow: 0 6px 24px oklch(0 0 0 / 0.18);\n --twoslash-docs-color: var(--blume-muted-foreground);\n --twoslash-docs-font: var(--font-sans);\n --twoslash-code-font: var(--font-mono);\n --twoslash-matched-color: var(--blume-foreground);\n --twoslash-unmatched-color: var(--blume-muted-foreground);\n --twoslash-cursor-color: var(--blume-muted-foreground);\n}\n\n/* Popups are absolutely positioned and must escape the pre's scroll container.\n The base prose pre rule (from the typography layer) wins the cascade here\n despite lower specificity, so !important is needed to force visibility.\n Regular code blocks scroll their inner code element and carry the horizontal\n padding there; twoslash code opts out of that scroller (popups again), so the\n padding is restored on the pre. */\n.prose pre.twoslash {\n overflow: visible !important;\n padding-left: 1.25rem;\n padding-right: 1.25rem;\n}\n\n/* Twoslash blocks keep \\`overflow: visible\\` so popups can escape, which means\n long lines can't scroll — they'd push past the viewport on narrow screens.\n Wrap them on mobile instead; hover popups still position against the token. */\n@media (max-width: 640px) {\n .prose pre.twoslash code {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n}\n\n/* The rich renderer renders each popup's type signature as a nested Shiki\n pre. Strip the code-block chrome (border, radius, padding, background) so it\n sits flush inside the popup, which owns the frame. */\n.prose pre.twoslash .twoslash-popup-container pre {\n background: transparent !important;\n border: 0 !important;\n border-radius: 0 !important;\n margin: 0 !important;\n padding: 0 !important;\n}\n\n/* Re-assert chrome backgrounds the transparent token-span rule would clear. */\n.twoslash .twoslash-popup-container,\n.twoslash .twoslash-popup-arrow,\n.twoslash .twoslash-completion-cursor .twoslash-completion-list {\n background: var(--twoslash-popup-bg) !important;\n}\n.twoslash .twoslash-popup-error {\n background: var(--twoslash-error-bg) !important;\n}\n.twoslash .twoslash-highlighted {\n background: var(--twoslash-highlighted-bg) !important;\n}\n\n/* The error squiggle uses a background image the transparent rule clears, so\n draw it as a wavy underline instead. */\n.twoslash .twoslash-error {\n text-decoration: underline wavy var(--twoslash-error-color);\n text-underline-offset: 0.25em;\n}\n\n.twoslash-popup-container {\n max-width: min(90vw, 36rem);\n}\n`;\n\n/** The full Twoslash stylesheet (shipped rich styles + Blume overrides). */\nexport const twoslashCss = (): string => {\n const file = require.resolve(\"@shikijs/twoslash/style-rich.css\");\n return `${readFileSync(file, \"utf-8\")}\\n${OVERRIDES}`;\n};\n",
|
|
33
33
|
"import type {\n ComponentOverrideAnalysis,\n NormalizedOverride,\n OverrideFramework,\n} from \"../core/component-overrides.ts\";\n\n/**\n * Turn analyzed `components.ts` overrides into the generated `components.ts`\n * module plus per-override hydration wrappers.\n *\n * The runtime overrides object already holds bare imported identifiers, so those\n * (when not hydrated) ride through a plain spread. Everything else needs a static\n * import Vite can see: path-string overrides import the file directly, while\n * hydrated overrides get a wrapper `.astro` that applies the `client:*` directive\n * (Astro directives must be written statically). The `islands` group is folded\n * into the MDX component map — it is just `mdx` with a default `client: \"visible\"`.\n */\n\nexport interface ComponentSlotWrapper {\n content: string;\n /** File name (no extension) under `.blume/src/generated/component-slots/`. */\n name: string;\n}\n\nexport interface ComponentSlotPlan {\n /** Frameworks used by resolved overrides; enable the matching Astro renderer. */\n frameworks: Set<OverrideFramework>;\n /** Contents of `.blume/src/generated/components.ts`. */\n module: string;\n wrappers: ComponentSlotWrapper[];\n}\n\nconst EMPTY_MODULE = `// Generated by Blume. Do not edit.\nimport type { ComponentOverride } from \"blume/core/define-components.ts\";\nexport const mdxComponents: Record<string, ComponentOverride> = {};\nexport const layoutOverrides: Record<string, ComponentOverride> = {};\n`;\n\n// A user-supplied attribute value interpolated into a generated .astro tag: a\n// stray quote or newline would produce a malformed component and an opaque\n// Astro parse error pointing at the generated file, not the user's config.\nconst attributeValue = (value: string): string =>\n value.replaceAll(/[\"\\n\\r]/gu, \" \").trim();\n\nconst CLIENT_LOAD = \"client:load\";\n\n/** Astro client directive for a hydrated override. */\nconst directiveFor = (override: NormalizedOverride): string => {\n const framework = override.source?.framework;\n switch (override.client) {\n case \"idle\": {\n return \"client:idle\";\n }\n case \"visible\": {\n return \"client:visible\";\n }\n case \"media\": {\n return override.media\n ? `client:media=\"${attributeValue(override.media)}\"`\n : CLIENT_LOAD;\n }\n case \"only\": {\n return framework\n ? `client:only=\"${attributeValue(framework)}\"`\n : CLIENT_LOAD;\n }\n default: {\n return CLIENT_LOAD;\n }\n }\n};\n\nconst importClause = (variable: string, name: string, path: string): string =>\n name === \"default\"\n ? `import ${variable} from ${JSON.stringify(path)};`\n : `import { ${name} as ${variable} } from ${JSON.stringify(path)};`;\n\n/** A wrapper `.astro` that statically imports a component and hydrates it. */\nconst wrapperContent = (override: NormalizedOverride): string => {\n // SAFETY: the only caller guards `if (!source)` and bails before invoking\n // this, so the override always carries a resolved source here.\n const { name, path } = override.source as NonNullable<\n NormalizedOverride[\"source\"]\n >;\n const clause =\n name === \"default\"\n ? `import Component from ${JSON.stringify(path)};`\n : `import { ${name} as Component } from ${JSON.stringify(path)};`;\n return `---\n// Generated by Blume. Do not edit.\n${clause}\n---\n<Component ${directiveFor(override)} {...Astro.props}><slot /></Component>\n`;\n};\n\n/**\n * A filesystem-safe, injective token for an override key. Distinct keys must\n * never share a wrapper file (\"Foo.Bar\" vs \"Foo_Bar\" used to collide, racing\n * the same temp file and silently rendering the wrong component), so every\n * non-alphanumeric character is hex-escaped rather than collapsed — the same\n * hardening as `exampleSlug` in templates.ts.\n */\nconst sanitize = (value: string): string =>\n value.replaceAll(\n /[^A-Za-z0-9]/gu,\n (char) => `_${(char.codePointAt(0) ?? 0).toString(16)}_`\n );\n\nexport const planComponentSlots = (\n componentsFile: string | null,\n analysis: ComponentOverrideAnalysis | null\n): ComponentSlotPlan => {\n const frameworks = new Set<OverrideFramework>();\n if (!componentsFile) {\n return { frameworks, module: EMPTY_MODULE, wrappers: [] };\n }\n if (!analysis) {\n return {\n frameworks,\n module: `// Generated by Blume. Do not edit.\nimport overrides from ${JSON.stringify(componentsFile)};\nexport const mdxComponents = overrides.mdx ?? {};\nexport const layoutOverrides = overrides.layout ?? {};\n`,\n wrappers: [],\n };\n }\n\n const wrappers: ComponentSlotWrapper[] = [];\n const importLines: string[] = [];\n // Explicit `key: Variable` map entries, per surface.\n const mdxEntries: string[] = [];\n const layoutEntries: string[] = [];\n let counter = 0;\n\n // Islands are MDX components hydrated by default, so plan them alongside `mdx`.\n const mdxOverrides = [...analysis.mdx, ...analysis.islands];\n\n const plan = (\n override: NormalizedOverride,\n group: \"mdx\" | \"layout\",\n entries: string[]\n ): void => {\n const { source } = override;\n if (source?.framework) {\n frameworks.add(source.framework);\n }\n // Bare identifier, not hydrated: the runtime object already has it.\n if (override.identifier && !override.client) {\n return;\n }\n if (!source) {\n // Unresolved (already warned): leave it on the runtime object.\n return;\n }\n const variable = `__blumeSlot${counter}`;\n counter += 1;\n if (override.client) {\n const name = `${group}-${sanitize(override.key)}`;\n wrappers.push({ content: wrapperContent(override), name });\n importLines.push(\n importClause(variable, \"default\", `./component-slots/${name}.astro`)\n );\n } else {\n importLines.push(importClause(variable, source.name, source.path));\n }\n entries.push(`${JSON.stringify(override.key)}: ${variable}`);\n };\n\n for (const override of mdxOverrides) {\n plan(override, \"mdx\", mdxEntries);\n }\n for (const override of analysis.layout) {\n plan(override, \"layout\", layoutEntries);\n }\n\n // `overrides.islands` is not spread: every valid island is hydrated, so it is\n // emitted as an explicit wrapper entry above (raw spreads only carry bare,\n // non-hydrated identifiers from `mdx`/`layout`).\n const moduleSource = `// Generated by Blume. Do not edit.\nimport overrides from ${JSON.stringify(componentsFile)};\n${importLines.join(\"\\n\")}${importLines.length ? \"\\n\" : \"\"}export const mdxComponents = { ...(overrides.mdx ?? {})${mdxEntries.length ? `, ${mdxEntries.join(\", \")}` : \"\"} };\nexport const layoutOverrides = { ...(overrides.layout ?? {})${layoutEntries.length ? `, ${layoutEntries.join(\", \")}` : \"\"} };\n`;\n\n return { frameworks, module: moduleSource, wrappers };\n};\n",
|
|
34
34
|
"import { readFile } from \"node:fs/promises\";\n\nimport pMap from \"p-map\";\nimport { isAbsolute, join, relative } from \"pathe\";\nimport { glob } from \"tinyglobby\";\n\nimport type { ExampleLookup } from \"../core/types.ts\";\nimport type { IslandClientMode } from \"./islands.ts\";\nimport { readClientMode } from \"./islands.ts\";\n\n/** Framework an example is authored in, inferred from its extension. */\nexport type ExampleFramework = \"astro\" | \"react\" | \"svelte\" | \"vue\";\n\n/** A discovered `examples/` file, ready to wrap (live) and show (source). */\nexport interface ExampleSpec {\n /** Hydration directive for a framework example; `undefined` for `.astro`. */\n client?: IslandClientMode;\n /** Absolute path to the example source file. */\n file: string;\n /** Framework, or `astro` for a server-rendered (static) example. */\n framework: ExampleFramework;\n /** Shiki language for the source pane — the file extension. */\n lang: string;\n /** MDX-facing key: the path under `examples/`, sans extension, `/`-joined. */\n path: string;\n /** Raw source text shown in the code tab. */\n source: string;\n}\n\nexport interface ExampleDiscovery {\n /**\n * Absolute directory the examples were discovered under: the configured\n * `examples.source` (or a glob's static prefix) resolved against the root.\n */\n dir: string;\n examples: ExampleSpec[];\n warnings: string[];\n}\n\n/** Example extensions mapped to the framework that renders them. */\ninterface FrameworkByExtension {\n [extension: string]: ExampleFramework;\n}\n\nconst FRAMEWORK_BY_EXT: FrameworkByExtension = {\n astro: \"astro\",\n jsx: \"react\",\n svelte: \"svelte\",\n tsx: \"react\",\n vue: \"vue\",\n};\n\n// Captures the extension so we can strip it from the path key and pick the\n// framework. Kept in sync with the glob below — non-matching files a user glob\n// happens to sweep in (e.g. a registry's `.ts` sources) are dropped here.\nconst EXAMPLE_FILE = /\\.(?<ext>astro|jsx|svelte|tsx|vue)$/u;\n\n// Renderable example files when `examples` names a plain directory.\nconst DEFAULT_EXAMPLE_GLOB = \"**/*.{astro,jsx,svelte,tsx,vue}\";\n\n/** Ceiling on concurrent example-file reads; unbounded fan-out risks EMFILE. */\nconst READ_CONCURRENCY = 16;\n\n/**\n * Files the preview-frame Tailwind entry scans for utility classes, appended\n * to each directory from `exampleScanRoots`.\n */\nexport const EXAMPLE_SCAN_GLOB = \"**/*.{astro,jsx,svelte,ts,tsx,vue}\";\n\n/**\n * Directories the `<Component />` preview sheet scans for utility classes:\n * the project root, plus the examples directory when it lives outside the\n * root (a sibling workspace package, say). Tailwind's `@source` is a file\n * glob, not an import graph, so an out-of-root examples directory would\n * otherwise contribute no utilities and previews would render half-styled.\n */\nexport const exampleScanRoots = (\n root: string,\n examplesDir: string\n): string[] => {\n const path = relative(root, examplesDir);\n const outside = path.startsWith(\"..\") || isAbsolute(path);\n return outside ? [root, examplesDir] : [root];\n};\n\n// Glob magic that turns `examples` from a plain directory into a pattern. `()`,\n// `@`, and `+` are excluded so literal path segments (npm scopes, parens) keep\n// resolving as directories; the extglob leads `*?!` still trigger here.\nconst GLOB_MAGIC = /[!*?[\\]{}]/u;\n\n/**\n * Split a glob into its static directory prefix and the remaining pattern, so\n * discovered files can be keyed relative to that prefix (e.g.\n * `registry/x/**\\/examples/*` → `{ base: \"registry/x\", rest: \"**\\/examples/*\" }`).\n */\nconst splitGlobBase = (pattern: string) => {\n const segments = pattern.split(\"/\");\n // Only called when the pattern contains glob magic (see the caller), and `/`\n // is never magic, so the magic char always lands in a segment — `findIndex`\n // is never -1 here.\n const firstMagic = segments.findIndex((segment) => GLOB_MAGIC.test(segment));\n return {\n base: segments.slice(0, firstMagic).join(\"/\"),\n rest: segments.slice(firstMagic).join(\"/\"),\n };\n};\n\n/**\n * Discover preview examples for the `examples` config (default `examples`).\n * Every `.astro`/`.tsx`/`.jsx`/`.vue`/`.svelte` file becomes addressable by\n * `<Component path=\"...\">`, where the path is the file's location without its\n * extension (e.g. `forms/login.tsx` → `forms/login`).\n *\n * `pattern` is a directory by default, but may be a glob (anything with\n * `*`/`?`/`[]`/`{}`/`!`) — then only matching files are discovered and each\n * `<Component path>` key is relative to the glob's static prefix. This lets a\n * registry layout that colocates component sources with their examples be\n * targeted directly (e.g. `registry/<pkg>/**\\/examples/*`) without the sources —\n * which have no default export and so can't be wrapped — being swept in.\n *\n * Discovery is path-based (a glob), so no example code is executed. Framework\n * examples carry a hydration mode (default `client:visible`, overridable via\n * `export const client`); `.astro` examples render statically with no client\n * directive.\n */\nexport const discoverExamples = async (\n root: string,\n pattern = \"examples\"\n): Promise<ExampleDiscovery> => {\n const { base, rest } = GLOB_MAGIC.test(pattern)\n ? splitGlobBase(pattern)\n : { base: pattern, rest: DEFAULT_EXAMPLE_GLOB };\n const dir = join(root, base);\n const matches = await glob([rest], {\n absolute: true,\n cwd: dir,\n onlyFiles: true,\n });\n const files = matches.toSorted();\n const sources = await pMap(files, (file) => readFile(file, \"utf-8\"), {\n concurrency: READ_CONCURRENCY,\n });\n\n const examples: ExampleSpec[] = [];\n const warnings: string[] = [];\n const seen = new Map<string, string>();\n\n // Extracted so the two skip paths become early `return`s (one `continue`\n // budget per loop under the lint rule) instead of `continue` statements.\n const collectExample = (file: string, source: string): void => {\n const ext = file.match(EXAMPLE_FILE)?.groups?.ext;\n const framework = ext ? FRAMEWORK_BY_EXT[ext] : undefined;\n if (!(ext && framework)) {\n return;\n }\n // Strip the trailing `.<ext>` to form the `<Component path>` key.\n const path = relative(dir, file).slice(0, -(ext.length + 1));\n const existing = seen.get(path);\n if (existing) {\n warnings.push(\n `Two examples both resolve to \"${path}\" (\"${existing}\" and \"${file}\"); ignoring the second. Give them distinct paths.`\n );\n return;\n }\n seen.set(path, file);\n examples.push({\n client:\n framework === \"astro\"\n ? undefined\n : readClientMode(source, file, warnings),\n file,\n framework,\n lang: ext,\n path,\n source,\n });\n };\n\n for (const [index, file] of files.entries()) {\n collectExample(file, sources[index] ?? \"\");\n }\n\n return { dir, examples, warnings };\n};\n\n/**\n * Reduce discovered examples to the `<Component path>` → source lookup the\n * agent-facing Markdown downleveler needs (see {@link BlumeProject.examples}).\n */\nexport const exampleMarkdownLookup = (examples: ExampleSpec[]): ExampleLookup =>\n Object.fromEntries(\n examples.map((example) => [\n example.path,\n { lang: example.lang, source: example.source },\n ])\n );\n",
|
|
35
35
|
"import { readFile } from \"node:fs/promises\";\n\nimport pMap from \"p-map\";\nimport { basename, join } from \"pathe\";\nimport { glob } from \"tinyglobby\";\n\n/** Astro hydration directives Blume applies to a convention island. */\nexport type IslandClientMode = \"idle\" | \"load\" | \"only\" | \"visible\";\n\n/** Client framework an island is authored in, inferred from its extension. */\nexport type IslandFramework = \"react\" | \"svelte\" | \"vue\";\n\n/** A discovered `islands/` component, ready to wrap and expose to MDX. */\nexport interface IslandSpec {\n /** Hydration directive, from `export const client` or the default. */\n client: IslandClientMode;\n /** Absolute path to the island source file. */\n file: string;\n /** Astro client framework, used to enable the renderer and for `client:only`. */\n framework: IslandFramework;\n /** Component name used in MDX — the file's basename without extension. */\n name: string;\n}\n\nexport interface IslandDiscovery {\n islands: IslandSpec[];\n warnings: string[];\n}\n\n/** Hydration mode used when an island doesn't declare one. */\nconst DEFAULT_CLIENT: IslandClientMode = \"visible\";\n\n/** Ceiling on concurrent island-file reads; unbounded fan-out risks EMFILE. */\nconst READ_CONCURRENCY = 16;\n\nconst VALID_MODES = new Set<IslandClientMode>([\n \"idle\",\n \"load\",\n \"only\",\n \"visible\",\n]);\n\n/** Whether a declared client mode is one Astro's directives support. */\nconst isClientMode = (mode: string): mode is IslandClientMode =>\n // SAFETY: `Set.has` only compares identity at runtime; the assertion widens\n // the lookup key so the narrower-typed set accepts it, and the `has` result\n // is exactly the predicate being claimed.\n VALID_MODES.has(mode as IslandClientMode);\n\n/** Island extensions mapped to the Astro renderer that handles them. */\nconst FRAMEWORK_BY_EXT = new Map<string, IslandFramework>([\n [\"jsx\", \"react\"],\n [\"svelte\", \"svelte\"],\n [\"tsx\", \"react\"],\n [\"vue\", \"vue\"],\n]);\n\n// Captures the extension so we can both strip it from the name and pick the\n// framework. Kept in sync with the glob below.\nconst ISLAND_FILE = /\\.(?<ext>jsx|svelte|tsx|vue)$/u;\n\n// Matches `export const client = \"load\"` (with optional type annotation and\n// either quote style). Read statically so we never execute island code in Node.\nconst CLIENT_EXPORT =\n /export\\s+const\\s+client\\s*(?::[^=]+)?=\\s*[\"'](?<mode>\\w+)[\"']/u;\n\nexport const readClientMode = (\n source: string,\n file: string,\n warnings: string[]\n): IslandClientMode => {\n const mode = source.match(CLIENT_EXPORT)?.groups?.mode;\n if (!mode) {\n return DEFAULT_CLIENT;\n }\n if (!isClientMode(mode)) {\n warnings.push(\n `Island \"${file}\" declares an unknown client mode \"${mode}\"; defaulting to \"${DEFAULT_CLIENT}\". Use \"load\", \"idle\", \"visible\", or \"only\".`\n );\n return DEFAULT_CLIENT;\n }\n return mode;\n};\n\n/**\n * Discover convention islands under `<root>/islands`. Every `.tsx`/`.jsx`/\n * `.vue`/`.svelte` file becomes a globally-available, hydrated MDX component\n * named after the file (which must be PascalCase to be usable as a JSX tag).\n * Hydration defaults to `client:visible`; a file opts out with `export const\n * client = \"load\" | \"idle\" | \"only\"`. Discovery is path-based (a glob), so no\n * user code is executed.\n */\nexport const discoverIslands = async (\n root: string\n): Promise<IslandDiscovery> => {\n const dir = join(root, \"islands\");\n // Enumerate everything and let ISLAND_FILE do the filtering below, so\n // unknown extensions take the skip guard instead of relying on a glob\n // pattern staying in sync with the regex and framework map.\n const matches = await glob([\"**/*\"], {\n absolute: true,\n cwd: dir,\n onlyFiles: true,\n });\n const files = matches.toSorted();\n const sources = await pMap(files, (file) => readFile(file, \"utf-8\"), {\n concurrency: READ_CONCURRENCY,\n });\n\n const islands: IslandSpec[] = [];\n const warnings: string[] = [];\n const seen = new Map<string, string>();\n\n // Extracted so the skip paths become early `return`s (one `continue` budget\n // per loop under the lint rule) instead of `continue` statements.\n const collectIsland = (file: string, source: string): void => {\n const base = basename(file);\n const ext = base.match(ISLAND_FILE)?.groups?.ext;\n const framework = ext ? FRAMEWORK_BY_EXT.get(ext) : undefined;\n if (!framework) {\n return;\n }\n const name = base.replace(ISLAND_FILE, \"\");\n // The name is used verbatim as both an MDX tag and an unquoted object key\n // in the generated island map, so it must be a plain PascalCase identifier\n // — a `-`, `.`, or space (e.g. `Time-Picker.tsx`) would otherwise emit a\n // syntax-error module and fail the whole build with no pointer to the file.\n if (!/^[A-Z][A-Za-z0-9_]*$/u.test(name)) {\n warnings.push(\n `Island \"${file}\" must have a PascalCase identifier filename to be used in MDX (letters, digits, and underscores only, e.g. Counter.tsx → <Counter />); skipping it.`\n );\n return;\n }\n const existing = seen.get(name);\n if (existing) {\n warnings.push(\n `Two islands both resolve to <${name}> (\"${existing}\" and \"${file}\"); ignoring the second. Give them distinct filenames.`\n );\n return;\n }\n seen.set(name, file);\n islands.push({\n client: readClientMode(source, file, warnings),\n file,\n framework,\n name,\n });\n };\n\n for (const [index, file] of files.entries()) {\n collectIsland(file, sources[index] ?? \"\");\n }\n\n return { islands, warnings };\n};\n"
|
|
36
36
|
],
|
|
37
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWO,IAAM,4BACX;AAKK,IAAM,4BACX;;;ACdF,iBAAS,4BAAgB;;;ACDzB,0BAAkB;;;ACHlB;;;ACCA,mBAAS;AAkBT,IAAM,eAAe,IAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;;;AH4D7C,IAAM,eAAe,OAAO,IAAI,mBAAmB;AAMnD,IAAM,YAAW,MAAyB;AAAA,EAIxC,MAAM,OAAO;AAAA,EACb,KAAK,kBAAkB;AAAA,IACrB,cAAc;AAAA,IACd,aAAa;AAAA,IACb,SAAS;AAAA,IACT,gBAAgB;AAAA,EAClB;AAAA,EACA,OAAO,KAAK;AAAA;AASP,IAAM,sBAAsB,CAAC,YAAuC;AAAA,EACzE,UAAS,EAAE,eAAe;AAAA;AAoCrB,IAAM,wBAAwB,CACnC,gBAIS;AAAA,EACT,UAAS,EAAE,cAAc,cACrB;AAAA,IACE,eAAe,IAAI,IAAI,YAAY,aAAa;AAAA,IAChD,gBAAgB,YAAY;AAAA,EAC9B,IACA;AAAA;AAYC,IAAM,sBAAsB,YAA8B;AAAA,EAC/D,QAAQ,mBAAmB,UAAS;AAAA,EACpC,IAAI,CAAC,gBAAgB;AAAA,IACnB,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,eAAe,CAAC,CAAC;AAAA,EACvB,OAAO;AAAA;AAGT,IAAM,iBAAiB,MAAkC;AAAA,EACvD,QAAQ,YAAY,UAAS;AAAA,EAC7B,OAAO,SAAS,MAAM,SAAS;AAAA;AAS1B,IAAM,wBAAwB,CAAC,gBAAoC;AAAA,EACxE,MAAM,SAAuB,CAAC;AAAA,EAC9B,WAAW,cAAc,aAAa;AAAA,IACpC,IAAI,WAAW,aAAa,SAAS;AAAA,MACnC,OAAO,KAAK,iBAAiB,UAAU,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EACA,MAAM,UAAU,eAAe;AAAA,EAC/B,IAAI,OAAO,WAAW,KAAK,CAAC,SAAS;AAAA,IACnC;AAAA,EACF;AAAA,EACA,MAAM,OAAO,OACV,IAAI,CAAC,eAAe;AAAA,IACnB,MAAM,aAAa,WAAW,OAAO,IAAI,WAAW,SAAS;AAAA,IAC7D,MAAM,QAAQ,WAAW,OACrB;AAAA,OAAU,WAAW,OAAO,eAC5B;AAAA,IACJ,MAAM,MAAM,WAAW,aACnB;AAAA,SAAY,WAAW,eACvB;AAAA,IACJ,MAAM,OAAO,WAAW,UAAU;AAAA,UAAa,WAAW,YAAY;AAAA,IACtE,OAAO,IAAI,WAAW,SAAS,WAAW,UAAU,QAAQ,MAAM;AAAA,GACnE,EACA,KAAK;AAAA;AAAA,CAAM;AAAA,EACd,QAAQ,KAAK;AAAA,IACX,KAAK;AAAA,MACH,IAAI,OAAO,IAAI;AAAA,MACf,SAAS,eAAe,OAAO;AAAA;AAAA,EAAuB;AAAA,MACtD,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAAA;;;AI1NH;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,oBAAS,kBAAS;AA2BX,IAAM,aAAa,CACxB,YAEA,WAAW,MAAK,QAAQ,MAAM,cAAc,CAAC,IACzC,MAAK,QAAQ,MAAM,gBAAgB,UAAU,SAAS,IAAI,IAC1D,MAAK,QAAQ,QAAQ,UAAU,IAAI;AAezC,IAAM,gBAAe,OAAO,IAAI,gBAAgB;AAIhD,IAAM,YAAW,MAAuB;AAAA,EAItC,MAAM,OAAO;AAAA,EACb,KAAK,mBAAkB,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,IAAI,IAAM;AAAA,EAC7D,OAAO,KAAK;AAAA;AAYd,IAAM,mBAAmB,IAAI;AAgE7B,IAAM,WAAW,IAAI;AA0Dd,IAAM,iBAAiB,OAAO,QAAiC;AAAA,EACpE,QAAQ,SAAS,UAAS;AAAA,EAC1B,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,UAAU,MAAM,QAAQ,GAAG;AAAA,IAC3B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,EAET,MAAM,QAAQ,QAAQ,OACpB,CAAC,SACC,KAAK,SAAS,MAAM,KACnB,KAAK,SAAS,MAAM,KAAK,CAAC,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC,OAAO,MAAM,CAAC,CACrE;AAAA,EACA,MAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS,GAAG,MAAK,KAAK,IAAI,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC;AAAA,EAC3E,OAAO,MAAM;AAAA;AAQR,IAAM,iBAAiB,MAA+C;AAAA,EAC3E,QAAQ,MAAM,WAAW,UAAS;AAAA,EAClC,OAAO,OAAO,WAAW,IAAI,OAAO,EAAE,MAAM,OAAO;AAAA;;;AClOrD;AACA,uBAAS,6BAAY;AACrB;AAAA;AAAA,WAEE;AAAA,cACA;AAAA;AAAA;AAAA,QAGA;AAAA;AAAA;AAGF,0BAAS;AACT;AAEA;AACA;AAAA,cACE;AAAA,aACA;AAAA,gBACA;AAAA,UACA;AAAA;AAAA,cAEA;AAAA,aACA;AAAA;AAEF,iBAAS;;;ACjBF,IAAM,eAAe;;;AC2G5B,IAAM,YAAY;AAClB,IAAM,gBAAgB;AACtB,IAAM,YAAY;AAElB,IAAM,MAAM,CAAC,UAA6B;AAAA,EACxC,MAAM,wBAAwB;AAChC;AAEA,IAAM,eAAe,CAAC,aAAqB,YAAoC;AAAA,EAC7E,SAAS,GAAG,YAAY,EAAE,QAAQ,IAAI,MAAM,EAAE,EAAE;AAAA,EAChD;AACF;AAEA,IAAM,kBAAkB,CAAC,iBAAyC;AAAA,EAChE,SAAS,GAAG,eAAe,EAAE,QAAQ,IAAI,SAAS,EAAE,EAAE;AAAA,EACtD;AACF;AAEA,IAAM,eAAe,CAAC,aAAqB,UAAkC;AAAA,EAC3E,SAAS,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,EAAE,EAAE;AAAA,EAClD;AACF;AAEA,IAAM,SAAS,CAAC,iBAAyB,EAAE,aAAa,MAAM,SAAS;AAEvE,IAAM,eAAe;AAAA,EACnB,sBAAsB,EAAE,MAAM,SAAS;AAAA,EACvC,aACE;AAAA,EACF,MAAM;AACR;AAEA,IAAM,kBAAkB;AAAA,EACtB,aACE;AAAA,EACF,MAAM;AACR;AAGA,IAAM,mBAAgC;AAAA,EACpC;AAAA,IACE,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,WAAW,GAAG,MAAM,SAAS;AAAA,EACzC;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,SAAS,GAAG,SAAS,IAAI,SAAS,GAAG,MAAM,UAAU;AAAA,EACjE;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,GAAG,MAAM,QAAQ;AAAA,IACnD,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,SAAS;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,SAAS;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,sBAAsB,EAAE,MAAM,SAAS,GAAG,MAAM,SAAS;AAAA,IACnE,OAAO;AAAA,EACT;AACF;AAEA,IAAM,UAAU;AAAA,EACd,gBAAgB;AAAA,IACd,aAAa;AAAA,IACb,YAAY;AAAA,MACV,IAAI,EAAE,aAAa,wCAAwC;AAAA,MAC3D,SAAS,EAAE,OAAO,OAAO,MAAM,SAAS;AAAA,MACxC,QAAQ,OAAO,oDAAoD;AAAA,MACnE,QAAQ,EAAE,aAAa,sBAAsB,MAAM,SAAS;AAAA,IAC9D;AAAA,IACA,UAAU,CAAC,WAAW,QAAQ;AAAA,IAC9B,MAAM;AAAA,EACR;AAAA,EACA,iBAAiB;AAAA,IACf,aAAa;AAAA,IACb,YAAY;AAAA,MACV,OAAO;AAAA,QACL,YAAY;AAAA,UACV,MAAM,EAAE,MAAM,UAAU;AAAA,UACxB,MAAM,CAAC;AAAA,UACP,SAAS,EAAE,MAAM,SAAS;AAAA,QAC5B;AAAA,QACA,UAAU,CAAC,QAAQ,SAAS;AAAA,QAC5B,MAAM;AAAA,MACR;AAAA,MACA,IAAI,CAAC;AAAA,MACL,SAAS,EAAE,OAAO,OAAO,MAAM,SAAS;AAAA,MACxC,QAAQ,EAAE,MAAM,SAAS;AAAA,IAC3B;AAAA,IACA,UAAU,CAAC,SAAS;AAAA,IACpB,MAAM;AAAA,EACR;AAAA,EACA,SAAS;AAAA,IACP,YAAY;AAAA,MACV,MAAM,OAAO,qDAAqD;AAAA,MAClE,MAAM,OAAO,qBAAqB;AAAA,MAClC,OAAO,EAAE,MAAM,SAAS;AAAA,IAC1B;AAAA,IACA,UAAU,CAAC,QAAQ,OAAO;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA,EACA,SAAS;AAAA,IACP,aACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,YAAY;AAAA,UACV,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,YAAY,EAAE,MAAM,UAAU;AAAA,UAC9B,aAAa,EAAE,MAAM,SAAS;AAAA,UAC9B,MAAM,EAAE,MAAM,SAAS;AAAA,UACvB,MAAM,EAAE,OAAO,QAAQ,MAAM,SAAS;AAAA,UACtC,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,QAAQ,OAAO,+BAA+B;AAAA,UAC9C,OAAO,OAAO,mBAAmB;AAAA,QACnC;AAAA,QACA,UAAU,CAAC,QAAQ,SAAS,UAAU,OAAO;AAAA,QAC7C,MAAM;AAAA,MACR;AAAA,MACA;AAAA,QACE,YAAY;AAAA,UACV,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,UAAU,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,UACjD,WAAW,EAAE,MAAM,UAAU;AAAA,UAC7B,MAAM,EAAE,MAAM,SAAS;AAAA,UACvB,MAAM,EAAE,OAAO,SAAS,MAAM,SAAS;AAAA,UACvC,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,MAAM,OAAO,oDAAoD;AAAA,UACjE,OAAO,OAAO,gDAAgD;AAAA,QAChE;AAAA,QACA,UAAU,CAAC,YAAY,QAAQ,OAAO;AAAA,QACtC,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX,aACE;AAAA,IACF,YAAY;AAAA,MACV,OAAO;AAAA,QACL,OAAO;AAAA,UACL,YAAY;AAAA,YACV,aAAa,EAAE,MAAM,SAAS;AAAA,YAC9B,OAAO,EAAE,MAAM,SAAS;AAAA,YACxB,MAAM,EAAE,MAAM,SAAS;AAAA,YACvB,KAAK,EAAE,MAAM,SAAS;AAAA,UACxB;AAAA,UACA,UAAU,CAAC,SAAS,MAAM;AAAA,UAC1B,MAAM;AAAA,QACR;AAAA,QACA,MAAM;AAAA,MACR;AAAA,MACA,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,OAAO,EAAE,MAAM,SAAS;AAAA,IAC1B;AAAA,IACA,UAAU,CAAC,SAAS,QAAQ,OAAO;AAAA,IACnC,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,YAAY;AAAA,MACV,MAAM,OACJ,8EACF;AAAA,MACA,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,MAAM,OAAO,2BAA2B;AAAA,IAC1C;AAAA,IACA,UAAU,CAAC,SAAS,MAAM;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,aACE;AAAA,IACF,YAAY;AAAA,MACV,SAAS,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,MAChD,KAAK,EAAE,OAAO,CAAC,IAAI,SAAS,GAAG,EAAE,MAAM,OAAO,CAAC,EAAE;AAAA,MACjD,UAAU,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,MACjD,SAAS,EAAE,MAAM,CAAC,UAAU,MAAM,EAAE;AAAA,MACpC,MAAM,OAAO,0DAA0D;AAAA,MACvE,WAAW,EAAE,OAAO,IAAI,aAAa,GAAG,MAAM,QAAQ;AAAA,MACtD,SAAS,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,MAChD,MAAM,EAAE,OAAO,IAAI,QAAQ,GAAG,MAAM,QAAQ;AAAA,IAC9C;AAAA,IACA,UAAU,CAAC,YAAY,aAAa,WAAW,MAAM;AAAA,IACrD,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,IACJ,OAAO;AAAA,MACL,IAAI,aAAa;AAAA,MACjB;AAAA,QACE,YAAY;AAAA,UACV,UAAU,OACR,6FACF;AAAA,QACF;AAAA,QACA,UAAU,CAAC,UAAU;AAAA,QACrB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,aAAa;AAAA,EACf;AAAA,EACA,aAAa;AAAA,IACX,YAAY;AAAA,MACV,aAAa,OAAO,+CAA+C;AAAA,MACnE,aAAa,EAAE,MAAM,SAAS;AAAA,MAC9B,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,aACE;AAAA,QACF,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,cAAc;AAAA,QACZ,aAAa;AAAA,QACb,MAAM,CAAC,UAAU,MAAM;AAAA,MACzB;AAAA,MACA,QAAQ,OAAO,yBAAyB;AAAA,MACxC,aAAa;AAAA,QACX,aACE;AAAA,QACF,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,OAAO,OACL,4EACF;AAAA,MACA,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,KAAK;AAAA,QACH,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,SAAS;AAAA,IACX;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,MACV,OAAO,EAAE,MAAM,UAAU;AAAA,MACzB,WAAW,OAAO,wCAAwC;AAAA,MAC1D,OAAO,EAAE,OAAO,IAAI,aAAa,GAAG,MAAM,QAAQ;AAAA,MAClD,MAAM,EAAE,MAAM,CAAC,UAAU,MAAM,EAAE;AAAA,IACnC;AAAA,IACA,UAAU,CAAC,SAAS,aAAa,SAAS,MAAM;AAAA,IAChD,MAAM;AAAA,EACR;AAAA,EACA,SAAS;AAAA,IACP,aACE;AAAA,IACF,YAAY;AAAA,MACV,MAAM,OAAO,4CAA4C;AAAA,MACzD,QAAQ,OAAO,gDAAgD;AAAA,MAC/D,UAAU,OAAO,2CAA2C;AAAA,MAC5D,OAAO;AAAA,QACL,aAAa;AAAA,QACb,OAAO;AAAA,UACL,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,GAAG,OAAO,EAAE,MAAM,SAAS,EAAE;AAAA,UAClE,UAAU,CAAC,QAAQ,OAAO;AAAA,UAC1B,MAAM;AAAA,QACR;AAAA,QACA,MAAM;AAAA,MACR;AAAA,MACA,YAAY,OAAO,kBAAkB;AAAA,MACrC,QAAQ,EAAE,MAAM,UAAU;AAAA,MAC1B,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,MAAM,OAAO,6CAA6C;AAAA,IAC5D;AAAA,IACA,UAAU,CAAC,QAAQ,UAAU,cAAc,UAAU,SAAS,MAAM;AAAA,IACpE,MAAM;AAAA,EACR;AAAA,EACA,WAAW;AAAA,IACT,YAAY;AAAA,MACV,aAAa,EAAE,MAAM,SAAS;AAAA,MAC9B,SAAS,OAAO,sDAAsD;AAAA,MACtE,QAAQ;AAAA,MACR,OAAO,OAAO,yCAAyC;AAAA,MACvD,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,KAAK,EAAE,QAAQ,iBAAiB,MAAM,SAAS;AAAA,MAC/C,SAAS;AAAA,IACX;AAAA,IACA,UAAU,CAAC,WAAW,SAAS,SAAS,KAAK;AAAA,IAC7C,MAAM;AAAA,EACR;AAAA,EACA,gBAAgB;AAAA,IACd,YAAY;AAAA,MACV,OAAO,EAAE,MAAM,UAAU;AAAA,MACzB,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,SAAS,EAAE,OAAO,IAAI,WAAW,GAAG,MAAM,QAAQ;AAAA,IACpD;AAAA,IACA,UAAU,CAAC,SAAS,SAAS,SAAS;AAAA,IACtC,MAAM;AAAA,EACR;AACF;AAEA,IAAM,cAAyB;AAAA,EAC7B,aACE;AAAA,EACF,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ,EAAE,MAAM,SAAS;AAC3B;AAGA,IAAM,YAAY,CAAC,UAAgC;AAAA,EACjD,IAAI,MAAM,MAAM;AAAA,IACd,OAAO,MAAM,OACT,YAAY,MAAM,MAAM,MAAM,IAAI,IAClC,SAAS,MAAM,IAAI;AAAA,EACzB;AAAA,EACA,OAAO,MAAM,QAAQ;AAAA;AAIhB,IAAM,eAAe,CAAC,UAAyC;AAAA,EACpE,MAAM,cAAoC;AAAA,IACxC;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,mBAAmB,YAAY;AAAA,YACnD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,OAAO;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,YAAY,CAAC,WAAW;AAAA,UACxB,WAAW;AAAA,YACT,OAAO,aAAa,aAAa,MAAM;AAAA,YACvC,OAAO,gBAAgB,yBAAyB;AAAA,YAChD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,OAAO;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,wBAAwB,YAAY;AAAA,YACxD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,YAAY;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,MAAM,QAAQ;AAAA,IAChB,YAAY,KAAK;AAAA,MACf;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,WAAW;AAAA,YACT,OAAO,aACL,mCACA,gBACF;AAAA,YACA,OAAO,gBAAgB,iCAAiC;AAAA,YACxD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,QAAQ;AAAA,QACjB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,YAAY,KAAK;AAAA,IACf;AAAA,IACA;AAAA,MACE,KAAK;AAAA,QACH,aACE;AAAA,QACF,aAAa;AAAA,QACb,YAAY,CAAC,WAAW;AAAA,QACxB,WAAW;AAAA,UACT,OAAO,aAAa,yBAAyB,aAAa;AAAA,UAC1D,OAAO,aACL,8DACA,aACF;AAAA,QACF;AAAA,QACA,SAAS;AAAA,QACT,MAAM,CAAC,UAAU;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EACD,IAAI,MAAM,SAAS;AAAA,IACjB,YAAY,KACV;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,cAAc,SAAS;AAAA,UAC7C;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,UAAU;AAAA,QACnB;AAAA,MACF;AAAA,IACF,GACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,0BAA0B,SAAS;AAAA,UACzD;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,UAAU;AAAA,QACnB;AAAA,MACF;AAAA,IACF,CACF;AAAA,EACF;AAAA,EACA,IAAI,MAAM,kBAAkB;AAAA,IAC1B,YAAY,KAAK;AAAA,MACf;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO;AAAA,cACL,SAAS,GAAG,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,EAAE,EAAE;AAAA,cACvD,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,WAAW;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,IAAI,MAAM,UAAU;AAAA,IAClB,YAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN;AAAA,QACE,MAAM;AAAA,UACJ,aACE;AAAA,UACF,aAAa;AAAA,UACb,aAAa;AAAA,YACX,SAAS,GAAG,YAAY,EAAE,QAAQ,IAAI,gBAAgB,EAAE,EAAE;AAAA,YAC1D,UAAU;AAAA,UACZ;AAAA,UACA,WAAW;AAAA,YACT,OAAO,aAAa,0BAA0B,iBAAiB;AAAA,UACjE;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,KAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAc;AAAA,IAClB,EAAE,aAAa,2CAA2C,MAAM,QAAQ;AAAA,IACxE,GAAI,MAAM,SACN,CAAC,EAAE,aAAa,mCAAmC,MAAM,SAAS,CAAC,IACnE,CAAC;AAAA,IACL,EAAE,aAAa,+BAA+B,MAAM,aAAa;AAAA,IACjE,EAAE,aAAa,qCAAqC,MAAM,WAAW;AAAA,IACrE,GAAI,MAAM,mBACN,CAAC,EAAE,aAAa,8BAA8B,MAAM,YAAY,CAAC,IACjE,CAAC;AAAA,IACL,GAAI,MAAM,WACN,CAAC,EAAE,aAAa,wCAAwC,MAAM,MAAM,CAAC,IACrE,CAAC;AAAA,EACP;AAAA,EAEA,MAAM,OAAa;AAAA,IACjB,aAAa;AAAA,MACX,+BAA+B,MAAM,qBAAqB,MAAM,cAAc,KAAK,MAAM,gBAAgB;AAAA,MACzG;AAAA,IACF,EAAE,KAAK;AAAA;AAAA,CAAM;AAAA,IACb,OAAO,cAAc,MAAM,IAAI;AAAA,IAC/B,SAAS,MAAM;AAAA,IACf,eAAe,SAAS,MAAM;AAAA,EAChC;AAAA,EACA,MAAM,WAA4B;AAAA,IAChC,YAAY,EAAE,QAAQ;AAAA,IACtB;AAAA,IACA,SAAS;AAAA,IACT,OAAO,OAAO,YAAY,WAAW;AAAA,IACrC,UAAU,CAAC;AAAA,IACX,SAAS,CAAC,EAAE,aAAa,MAAM,MAAM,KAAK,UAAU,KAAK,EAAE,CAAC;AAAA,IAC5D;AAAA,EACF;AAAA,EACA,IAAI,MAAM,MAAM;AAAA,IACd,SAAS,eAAe;AAAA,MACtB,aAAa,GAAG,MAAM;AAAA,MACtB,KAAK,YAAY,MAAM,MAAM,aAAa,MAAM,MAAM,GAAG,CAAC;AAAA,IAC5D;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;;ACzpBF,IAAM,eAAe,OAAO,YAA4C;AAAA,EAC7E,MAAM,YAAY,MAAM,qBAAqB,SAAS;AAAA,IACpD,UAAU;AAAA,IACV,SAAS;AAAA,IACT,qBAAqB;AAAA,EACvB,CAAC;AAAA,EACD,OAAO;AAAA,IACL,eAAe,QAAQ,OAAO,MAAM;AAAA,IACpC,WAAW,UAAU,IAAI,CAAC,SAAS;AAAA,MACjC,SAAS,IAAI;AAAA,MACb,aAAa,IAAI;AAAA,MACjB,QAAQ,IAAI;AAAA,MACZ,OAAO,IAAI;AAAA,MACX,OAAO,IAAI;AAAA,IACb,EAAE;AAAA,IACF,MAAM,QAAQ,OAAO,WAAW,QAAQ;AAAA,EAC1C;AAAA;;;ACdF,IAAM,aAAY,CAAC,UAAqC;AAAA,EAGtD,MAAM,OAAO,aAAa,MAAM,MAAM,MAAM,KAAK;AAAA,EAGjD,OAAO,MAAM,OAAO,YAAY,MAAM,MAAM,IAAI,IAAI;AAAA;AAO/C,IAAM,oBAAoB,CAAC,WAA8B;AAAA,EAC9D,SAAS;AAAA,IACP;AAAA,MACE,MAAM,MAAM;AAAA,MACZ,WAAW;AAAA,MACX,KAAK,WAAU,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAGA,IAAM,qBACJ;AAGF,IAAM,gBAAgB;AAEtB,IAAM,WAAW,CAAC,SAChB,KAAK,SAAS,gBAAgB,GAAG,KAAK,MAAM,GAAG,gBAAgB,CAAC,OAAO;AAOzE,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAExB,IAAM,eAAe,CAAC,SACpB,SACE,KACG,UAAU,MAAM,EAChB,QAAQ,iBAAiB,EAAE,EAC3B,YAAY,EACZ,QAAQ,gBAAgB,GAAG,GAC9B,GACF;AAQF,IAAM,iBAAiB,CAAC,UAAqC;AAAA,EAC3D,IAAI,YAAY;AAAA,EAChB,IAAI,MAAM,MAAM;AAAA,IACd,IAAI;AAAA,MACF,YAAY,IAAI,IAAI,MAAM,IAAI,EAAE,SAC7B,MAAM,GAAG,EACT,WAAW,EACX,KAAK,GAAG;AAAA,MACX,MAAM;AAAA,EAGV;AAAA,EACA,OAAO,GAAG,aAAa,aAAa,MAAM,IAAI,KAAK;AAAA;AAGrD,IAAM,WAAW;AAkCV,IAAM,qBAAqB,CAAC,UAA4C;AAAA,EAC7E,MAAM,MAAM,WAAU,KAAK;AAAA,EAC3B,MAAM,OAAsB;AAAA,IAC1B,SAAS;AAAA,IAGT,cAAc;AAAA,MACZ,WAAW,EAAE,aAAa,OAAO,WAAW,MAAM;AAAA,MAClD,OAAO,EAAE,aAAa,MAAM;AAAA,IAC9B;AAAA,IACA,aAAa,SACX,yCAAyC,MAAM,qBACjD;AAAA,IACA,MAAM,eAAe,KAAK;AAAA,IAC1B,YAAY,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,QAAQ;AAAA,IACvD,OAAO,SAAS,MAAM,IAAI;AAAA,IAC1B,OAAO,UAAU,IAAI,CAAC,UAAU;AAAA,MAC9B,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,IACd,EAAE;AAAA,IACF,WAAW;AAAA,IACX,YAAY,CAAC,EAAE,UAAU,KAAK,MAAM,kBAAkB,CAAC;AAAA,IACvD;AAAA,IACA,SAAS,MAAM;AAAA,EACjB;AAAA,EACA,IAAI,SAAS,KAAK,GAAG,GAAG;AAAA,IACtB,KAAK,UAAU,CAAC,EAAE,MAAM,mBAAmB,IAAI,CAAC;AAAA,EAClD;AAAA,EACA,IAAI,MAAM,MAAM;AAAA,IACd,KAAK,aAAa,SAAS,MAAM,IAAI;AAAA,EACvC;AAAA,EACA,OAAO;AAAA;;;AC6GF,IAAM,sBAAsB,CAAC,YAClC,QAAQ,KACN,CAAC,SACC,KAAK,SAAS,aACZ,KAAK,WAAW,YAAY,UAC5B,oBAAoB,KAAK,QAAQ,EACvC;AAkBK,IAAM,cAAc,CAAC,SAIR;AAAA,EAClB,EAAE,QAAQ,WAAW,YAAY,KAAK,YAAY,SAAS,UAAU;AAAA,EACrE,GAAG,OAAO,QAAQ,KAAK,kBAAkB,EAAE,IAAI,EAAE,QAAQ,iBAAiB;AAAA,IACxE;AAAA,IACA;AAAA,IACA,SAAS;AAAA,EACX,EAAE;AAAA,EACF,GAAG,OAAO,QAAQ,KAAK,mBAAmB,EAAE,QAAQ,EAAE,SAAS,cAC7D,OAAO,QAAQ,QAAQ,EAAE,IAAI,EAAE,QAAQ,iBAAiB;AAAA,IACtD,QAAQ,UAAU;AAAA,IAClB;AAAA,IACA;AAAA,EACF,EAAE,CACJ;AACF;;;AC7SO,IAAM,mBAAmB,IAAI,IAAY;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EACA;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,CAAC;;;ACxCD,IAAM,UAAU,CAAC,QACf,IACG,WAAW,uCAAuC,mBAAmB,EACrE,YAAY;AASV,IAAM,yBAAyB,CACpC,OACA,WACA,kBACiB;AAAA,EACjB,MAAM,cAA4B,CAAC;AAAA,EACnC,MAAM,OAAO,IAAI;AAAA,EACjB,WAAW,QAAQ,OAAO;AAAA,IACxB,WAAW,OAAO,KAAK,kBAAkB,CAAC,GAAG;AAAA,MAC3C,IAAI,iBAAiB,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,GAAG;AAAA,QACpE;AAAA,MACF;AAAA,MACA,KAAK,IAAI,GAAG;AAAA,MACZ,MAAM,OAAO,QAAQ,GAAG;AAAA,MACxB,MAAM,aAAa,cAAc,IAAI,IAAI,IACrC,mBAAmB,sCAAsC,iCACzD,aAAa,kDAAkD;AAAA,MACnE,YAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,MAAM,KAAK,cAAc,KAAK;AAAA,QAC9B,SAAS,IAAI,mBAAmB,KAAK;AAAA,QACrC,UAAU;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;;AC1CT,uBAAS;AAET,oBAAS,0CAA8B;AACvC;AA4DA,IAAM,SAAS,CAAC,OAAO,UAAU,SAAS;AAC1C,IAAM,YAAY,IAAI,IAAY,MAAM;AAGxC,IAAM,UAAU,CAAC,SAAgC,UAAU,IAAI,IAAI;AAEnE,IAAM,mBAAmB,IAAI,IAA+B;AAAA,EAC1D,CAAC,OAAO,OAAO;AAAA,EACf,CAAC,UAAU,QAAQ;AAAA,EACnB,CAAC,OAAO,OAAO;AAAA,EACf,CAAC,OAAO,KAAK;AACf,CAAC;AAED,IAAM,kBAAkB;AAAA,EACtB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AACP;AAGA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,kBAAuC,IAAI,IAAmB;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,kBAAkB,CAAC,UACvB,gBAAgB,IAAI,KAAK;AAgB3B,IAAM,gBAAgB,OAAkC;AAAA,EACtD,SAAS,CAAC;AAAA,EACV,QAAQ,CAAC;AAAA,EACT,KAAK,CAAC;AAAA,EACN,UAAU,CAAC;AACb;AAEA,IAAM,WAAW,CAAC,SAChB,GAAG,aAAa,IAAI,KAAK,GAAG,gBAAgB,IAAI,IAAI,KAAK,OAAO;AAGlE,IAAM,oBAAoB,CACxB,KACA,cACS;AAAA,EACT,IACE,CAAC,GAAG,oBAAoB,SAAS,KACjC,CAAC,GAAG,gBAAgB,UAAU,eAAe,GAC7C;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAM,YAAY,UAAU,gBAAgB;AAAA,EAC5C,MAAM,SAAS,UAAU;AAAA,EACzB,IAAI,CAAC,QAAQ;AAAA,IACX;AAAA,EACF;AAAA,EACA,IAAI,OAAO,MAAM;AAAA,IACf,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,UAAU,WAAW,UAAU,CAAC;AAAA,EAC9D;AAAA,EACA,MAAM,QAAQ,OAAO;AAAA,EACrB,IAAI,SAAS,GAAG,eAAe,KAAK,GAAG;AAAA,IACrC,WAAW,WAAW,MAAM,UAAU;AAAA,MACpC,IAAI,IAAI,QAAQ,KAAK,MAAM;AAAA,QACzB,WAAW,QAAQ,gBAAgB,QAAQ,MAAM;AAAA,QACjD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAIF,IAAM,iBAAiB,CACrB,eAC+B;AAAA,EAC/B,MAAM,MAAM,IAAI;AAAA,EAChB,WAAW,aAAa,WAAW,YAAY;AAAA,IAC7C,kBAAkB,KAAK,SAAS;AAAA,EAClC;AAAA,EACA,OAAO;AAAA;AAIT,IAAM,eAAe,CACnB,eAC2C;AAAA,EAC3C,IAAI,GAAG,0BAA0B,UAAU,GAAG;AAAA,IAC5C,OAAO;AAAA,EACT;AAAA,EACA,IAAI,GAAG,iBAAiB,UAAU,GAAG;AAAA,IACnC,OAAO,OAAO,WAAW;AAAA,IACzB,OAAO,OAAO,GAAG,0BAA0B,GAAG,IAAI,MAAM;AAAA,EAC1D;AAAA,EACA,IACE,GAAG,eAAe,UAAU,KAC5B,GAAG,0BAA0B,UAAU,GACvC;AAAA,IACA,OAAO,aAAa,WAAW,UAAU;AAAA,EAC3C;AAAA,EACA;AAAA;AAGF,IAAM,0BAA0B,CAC9B,eAC2C;AAAA,EAC3C,WAAW,aAAa,WAAW,YAAY;AAAA,IAC7C,IAAI,GAAG,mBAAmB,SAAS,KAAK,CAAC,UAAU,gBAAgB;AAAA,MACjE,OAAO,aAAa,UAAU,UAAU;AAAA,IAC1C;AAAA,EACF;AAAA,EACA;AAAA;AAGF,IAAM,iBAAiB,CAAC,SAAgC;AAAA,EACtD,WAAW,aAAa,gBAAgB;AAAA,IACtC,MAAM,YAAY,GAAG,QAAQ;AAAA,IAC7B,IAAI,YAAW,SAAS,GAAG;AAAA,MACzB,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAIT,IAAM,WAAW,CACf,WACA,UACA,QACmB;AAAA,EACnB,MAAM,YAAW,UAAU,WAAW,GAAG,KAAK,WAAW,SAAS;AAAA,EAClE,IAAI,OAAO;AAAA,EACX,IAAI,YAAY,QAAQ,SAAS,EAAE,MAAM,CAAC,EAAE,YAAY;AAAA,EACxD,IAAI,WAAU;AAAA,IACZ,MAAM,WAAW,WAAW,SAAS,IACjC,YACA,SAAQ,KAAK,SAAS;AAAA,IAC1B,IAAI,WAAW;AAAA,MACb,OAAO;AAAA,IACT,EAAO;AAAA,MACL,MAAM,SAAS,eAAe,QAAQ;AAAA,MACtC,OAAO,UAAU;AAAA,MACjB,YAAY,SAAS,QAAQ,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,IAAI;AAAA;AAAA,EAElE;AAAA,EACA,OAAO;AAAA,IACL,WAAW,iBAAiB,IAAI,SAAS,KAAK;AAAA,IAC9C,MAAM;AAAA,IACN;AAAA,EACF;AAAA;AAGF,IAAM,oBAAoB,CACxB,MACA,SACA,QAC0B;AAAA,EAC1B,MAAM,UAAU,QAAQ,IAAI,IAAI;AAAA,EAChC,OAAO,UAAU,SAAS,QAAQ,WAAW,QAAQ,UAAU,GAAG,IAAI;AAAA;AAIxE,IAAM,0BAA0B,CAC9B,YACA,UACA,SACA,QACS;AAAA,EACT,IAAI,GAAG,8BAA8B,QAAQ,GAAG;AAAA,IAC9C,IAAI,SAAS,KAAK,SAAS,aAAa;AAAA,MACtC,WAAW,eAAe;AAAA,MAC1B,WAAW,SAAS,kBAAkB,SAAS,KAAK,MAAM,SAAS,GAAG;AAAA,IACxE;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,CAAC,GAAG,qBAAqB,QAAQ,GAAG;AAAA,IACtC;AAAA,EACF;AAAA,EACA,MAAM,OAAO,SAAS,SAAS,IAAI;AAAA,EACnC,MAAM,OAAO,SAAS;AAAA,EACtB,IAAI,SAAS,aAAa;AAAA,IACxB,WAAW,eAAe;AAAA,IAC1B,IAAI,GAAG,gBAAgB,IAAI,GAAG;AAAA,MAC5B,WAAW,SAAS,SAAS,KAAK,MAAM,WAAW,GAAG;AAAA,IACxD,EAAO,SAAI,GAAG,aAAa,IAAI,GAAG;AAAA,MAChC,WAAW,SAAS,kBAAkB,KAAK,MAAM,SAAS,GAAG;AAAA,IAC/D;AAAA,EACF,EAAO,SACL,SAAS,YACT,GAAG,gBAAgB,IAAI,KACvB,gBAAgB,KAAK,IAAI,GACzB;AAAA,IACA,WAAW,SAAS,KAAK;AAAA,EAC3B,EAAO,SAAI,SAAS,WAAW,GAAG,gBAAgB,IAAI,GAAG;AAAA,IACvD,WAAW,QAAQ,KAAK;AAAA,EAC1B;AAAA;AAGF,IAAM,iBAAiB,CACrB,QACA,SACA,QACkB;AAAA,EAClB,MAAM,aAA4B,EAAE,cAAc,OAAO,QAAQ,KAAK;AAAA,EACtE,WAAW,YAAY,OAAO,YAAY;AAAA,IACxC,wBAAwB,YAAY,UAAU,SAAS,GAAG;AAAA,EAC5D;AAAA,EACA,OAAO;AAAA;AAIT,IAAM,WAAW,CACf,KACA,OACA,YACA,OACA,YACA,aAC8B;AAAA,EAC9B,QAAQ,QAAQ,OAAO,WAAW;AAAA,EAElC,IAAI,UAAU,WAAW;AAAA,IACvB,IAAI,CAAC,QAAQ;AAAA,MACX,SAAS,KACP,oBAAoB,gHACtB;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,IAAI,CAAC,OAAO,WAAW;AAAA,MACrB,SAAS,KACP,oBAAoB,SAAS,4FAC/B;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,IAAI,WAAW,WAAW,CAAC,OAAO;AAAA,IAChC,SAAS,KACP,aAAa,uGACf;AAAA,EACF;AAAA,EAEA,IAAI,WAAW,UAAU,UAAU,CAAC,OAAO,WAAW;AAAA,IACpD,SAAS,KACP,aAAa,2GACf;AAAA,EACF;AAAA,EAEA,IAAI,CAAC,UAAU,QAAQ,WAAW;AAAA,IAChC,SAAS,KACP,aAAa,oBAAoB,gBAAgB,OAAO,yBAAyB,yGAAyG,qBAAqB,KAAK,UAAU,KAAK,wBACrO;AAAA,EACF;AAAA,EAEA,MAAM,aAAiC,EAAE,YAAY,KAAK,OAAO;AAAA,EACjE,IAAI,QAAQ;AAAA,IACV,WAAW,SAAS;AAAA,EACtB;AAAA,EACA,IAAI,OAAO;AAAA,IACT,WAAW,QAAQ;AAAA,EACrB;AAAA,EACA,OAAO;AAAA;AAGT,IAAM,iBAAiB,CACrB,OACA,OACA,SACA,KACA,aAC8B;AAAA,EAC9B,MAAM,gBACJ,UAAU,YAAY,YAAY;AAAA,EAEpC,IAAI,GAAG,8BAA8B,KAAK,GAAG;AAAA,IAC3C,MAAM,OAAO,MAAM,KAAK;AAAA,IACxB,OAAO,SACL,MACA,OACA;AAAA,MACE,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAAA,IAC9C,GACA,MACA,MACA,QACF;AAAA,EACF;AAAA,EAEA,IAAI,CAAC,GAAG,qBAAqB,KAAK,GAAG;AAAA,IACnC,OAAO;AAAA,EACT;AAAA,EACA,MAAM,MAAM,SAAS,MAAM,IAAI;AAAA,EAC/B,IAAI,CAAC,KAAK;AAAA,IACR,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,MAAM;AAAA,EAEpB,IAAI,GAAG,aAAa,KAAK,GAAG;AAAA,IAC1B,OAAO,SACL,KACA,OACA;AAAA,MACE,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,QAAQ,kBAAkB,MAAM,MAAM,SAAS,GAAG;AAAA,IACpD,GACA,MAAM,MACN,MACA,QACF;AAAA,EACF;AAAA,EACA,IAAI,GAAG,gBAAgB,KAAK,GAAG;AAAA,IAC7B,OAAO,SACL,KACA,OACA;AAAA,MACE,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,QAAQ,SAAS,MAAM,MAAM,WAAW,GAAG;AAAA,IAC7C,GACA,MAAM,MACN,OACA,QACF;AAAA,EACF;AAAA,EACA,IAAI,GAAG,0BAA0B,KAAK,GAAG;AAAA,IACvC,MAAM,aAAa,eAAe,OAAO,SAAS,GAAG;AAAA,IACrD,IAAI,CAAC,WAAW,cAAc;AAAA,MAC5B,SAAS,KACP,aAAa,sFACf;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,IAAI,CAAC,WAAW,QAAQ;AAAA,MACtB,SAAS,KACP,aAAa,0HACf;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,OAAO,SACL,KACA,OACA,KAAK,YAAY,QAAQ,WAAW,UAAU,cAAc,GAC5D,KACA,OACA,QACF;AAAA,EACF;AAAA,EAGA,OAAO,EAAE,YAAY,OAAO,KAAK,QAAQ,KAAK;AAAA;AAIhD,IAAM,wBAAwB,CAC5B,UACA,SACA,KACA,WACS;AAAA,EACT,IAAI,CAAC,GAAG,qBAAqB,QAAQ,GAAG;AAAA,IACtC;AAAA,EACF;AAAA,EACA,MAAM,OAAO,SAAS,SAAS,IAAI;AAAA,EACnC,IACE,EAAE,QAAQ,QAAQ,IAAI,MACtB,CAAC,GAAG,0BAA0B,SAAS,WAAW,GAClD;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW,SAAS,SAAS,YAAY,YAAY;AAAA,IACnD,MAAM,aAAa,eACjB,OACA,MACA,SACA,KACA,OAAO,QACT;AAAA,IACA,IAAI,YAAY;AAAA,MACd,OAAO,MAAM,KAAK,UAAU;AAAA,IAC9B;AAAA,EACF;AAAA;AAQK,IAAM,4BAA4B,CACvC,QACA,aAC8B;AAAA,EAC9B,MAAM,SAAS,cAAc;AAAA,EAC7B,MAAM,aAAa,GAAG,iBACpB,UACA,QACA,GAAG,aAAa,QAChB,MACA,SAAS,SAAS,KAAK,IAAI,GAAG,WAAW,MAAM,GAAG,WAAW,EAC/D;AAAA,EAEA,MAAM,SAAS,wBAAwB,UAAU;AAAA,EACjD,IAAI,CAAC,QAAQ;AAAA,IACX,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,eAAe,UAAU;AAAA,EACzC,MAAM,MAAM,SAAQ,QAAQ;AAAA,EAE5B,WAAW,YAAY,OAAO,YAAY;AAAA,IACxC,sBAAsB,UAAU,SAAS,KAAK,MAAM;AAAA,EACtD;AAAA,EAEA,OAAO;AAAA;;;ACreT,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,SAAS;AACf,IAAM,UAAU;AAGhB,IAAM,UAAU;AAChB,IAAM,QAAQ,IAAI,IAAI;AAAA,EACpB,CAAC,MAAM,KAAK,OAAO;AAAA,EACnB,CAAC,MAAM,EAAE;AAAA,EACT,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,MAAM,EAAE;AAAA,EACT,CAAC,KAAM,KAAK,UAAW,GAAG;AAAA,EAC1B,CAAC,MAAM,KAAK,UAAU,EAAE;AAAA,EACxB,CAAC,MAAO,KAAK,KAAM,EAAE;AAAA,EACrB,CAAC,MAAM,KAAK,EAAE;AAAA,EACd,CAAC,MAAM,CAAC;AACV,CAAC;AACD,IAAM,SACJ;AAGF,IAAM,cAAc,CAAC,UAAkD;AAAA,EACrE,MAAM,SAAS,UAAU,YAAY,YAAY,OAAO,KAAK,KAAK,GAAG;AAAA,EACrE,IAAI,CAAC,QAAQ;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAM,SAAS,KAAK,MAClB,OAAO,OAAO,MAAM,KAAK,MAAM,IAAI,OAAO,QAAQ,IAAI,KAAK,EAC7D;AAAA,EACA,OAAO,SAAS,IAAI,SAAS;AAAA;AAI/B,IAAM,YAAY,CAAC,MAAc,YAC/B,QAAQ,KAAK,IAAI,GAAG,QAAQ;AAG9B,IAAM,cAAc,CAAC,SAAuC;AAAA,EAC1D,MAAM,MAAM,UAAU,MAAM,OAAO;AAAA,EACnC,IAAI,QAAQ,WAAW;AAAA,IACrB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS,IAAI,MAAM,GAAG;AAAA,EAC5B,MAAM,QAAQ,YAAY,OAAO,EAAE;AAAA,EACnC,MAAM,SAAS,YAAY,OAAO,EAAE;AAAA,EACpC,OAAO,SAAS,SAAS,EAAE,QAAQ,MAAM,IAAI;AAAA;AAQxC,IAAM,gBAAgB,CAAC,QAAsC;AAAA,EAClE,MAAM,OAAO,KAAK,KAAK,GAAG,IAAI;AAAA,EAC9B,IAAI,SAAS,WAAW;AAAA,IACtB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,YAAY,UAAU,MAAM,KAAK,CAAC;AAAA,EAChD,MAAM,SAAS,YAAY,UAAU,MAAM,MAAM,CAAC;AAAA,EAClD,IAAI,SAAS,QAAQ;AAAA,IACnB,OAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AAAA,EACA,MAAM,MAAM,YAAY,IAAI;AAAA,EAC5B,IAAI,CAAC,KAAK;AAAA,IACR,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,IAAI,QAAQ,IAAI;AAAA,EAC9B,IAAI,OAAO;AAAA,IACT,MAAM,SAAS,KAAK,MAAM,QAAQ,KAAK;AAAA,IACvC,OAAO,SAAS,IAAI,EAAE,QAAQ,QAAQ,MAAM,IAAI;AAAA,EAClD;AAAA,EACA,IAAI,QAAQ;AAAA,IACV,MAAM,SAAS,KAAK,MAAM,SAAS,KAAK;AAAA,IACxC,OAAO,SAAS,IAAI,EAAE,QAAQ,OAAO,OAAO,IAAI;AAAA,EAClD;AAAA,EACA,OAAO;AAAA;;;AC/FT,uBAAS;AAET,oBAAS,kBAAS,kBAAM;AACxB;AAiCA,IAAM,aAAiC;AAAA,EACrC,YAAY,IAAG,IAAI;AAAA,EACnB,eAAe,MAAM,CAAC;AAAA,EACtB,UAAU,IAAG,IAAI;AAAA,EACjB,2BAA2B,IAAG,IAAI;AACpC;AAGA,IAAM,eAAe,CAAC,WACpB,OAAO,WAAW;AAGpB,IAAM,UAAU,CACd,KACA,OACA,YACiD;AAAA,EAEjD,OAAO,SAAS;AAAA,EAChB,IAAI,CAAC,aAAa,KAAK,GAAG;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,OAAO,IAAI,SAAS,IAAI,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI;AAAA,EACrD,MAAM,SAAS,MAAM,SAAS,IAAI,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AAAA,EAE3D,IAAI,SAAS,MAAM,SAAS,KAAK;AAAA,IAC/B,OAAO;AAAA,EACT;AAAA,EACA,OAAO,EAAE,MAAM,aAAa,SAAQ,SAAS,MAAM,EAAE;AAAA;AAQhD,IAAM,yBAAyB,CACpC,SAC2B;AAAA,EAC3B,MAAM,QAAQ,CAAC,iBAAiB,eAAe,EAC5C,IAAI,CAAC,SAAS,MAAK,MAAM,IAAI,CAAC,EAC9B,KAAK,CAAC,SAAS,YAAW,IAAI,CAAC;AAAA,EAClC,IAAI,CAAC,OAAO;AAAA,IACV,OAAO,CAAC;AAAA,EACV;AAAA,EACA,QAAQ,QAAQ,UAAU,IAAG,eAAe,OAAO,IAAG,IAAI,QAAQ;AAAA,EAClE,IAAI,OAAO;AAAA,IAET,OAAO,CAAC;AAAA,EACV;AAAA,EACA,MAAM,YAAY,SAAQ,KAAK;AAAA,EAG/B,QAAQ,YAAY,IAAG,2BACrB,QACA,YACA,WACA,WACA,KACF;AAAA,EACA,QAAQ,UAAU;AAAA,EAClB,IAAI,CAAC,OAAO;AAAA,IACV,OAAO,CAAC;AAAA,EACV;AAAA,EAGA,QAAQ,kBAAkB;AAAA,EAE1B,MAAM,UAAU,QAAQ,WAAW,iBAAiB;AAAA,EACpD,MAAM,UAA8B,CAAC;AAAA,EACrC,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IAChD,MAAM,QAAQ,QAAQ,KAAK,OAAO,OAAO;AAAA,IACzC,IAAI,OAAO;AAAA,MACT,QAAQ,KAAK,CAAC,MAAM,MAAM,MAAM,WAAW,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EACA,OAAO,OAAO,YAAY,OAAO;AAAA;;;ACnGnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDA,IAAM,iBAAgC;AAAA,EACpC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,OAAO;AAAA,EACP,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AACP;AA6CO,IAAM,mBAAmB,CAAC,aAC/B,eAAe,SAAS,YAAY,IAAI,QAAQ;AAKlD,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAMf,IAAM,sBAAsB,CAAC,aAA+B;AAAA,EACjE,MAAM,QAAQ,IAAI;AAAA,EAClB,WAAW,WAAW,CAAC,gBAAgB,aAAa,GAAG;AAAA,IACrD,WAAW,SAAS,SAAS,SAAS,OAAO,GAAG;AAAA,MAC9C,MAAM,OAAO,iBAAiB,MAAM,QAAQ,QAAQ,EAAE;AAAA,MACtD,IAAI,MAAM;AAAA,QACR,MAAM,IAAI,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO,CAAC,GAAG,KAAK,EAAE,SAAS;AAAA;AAG7B,IAAM,aAAa,CAAC,SAClB,OAAO,OAAO,cAAc,EAAE,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI;AAGjE,IAAM,UAAU,CAAC,SACf,2BAA2B,mBAAmB,wEAAwE,eAAe;AAQhI,IAAM,kBAAkB,CAAC,UAC9B,MACG,IAAI,CAAC,SAAS;AAAA,EACb,MAAM,OAAO,WAAW,IAAI;AAAA,EAC5B,IAAI,CAAC,MAAM;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,MAAM,OAAO,QAAQ,KAAK,IAAI;AAAA,EAC9B,OAAO,iDAAiD;AAAA;AAAA,wBAEtC;AAAA,gBACR;AAAA;AAAA,CAEX,EACA,OAAO,CAAC,SAAS,SAAS,EAAE,EAC5B,KAAK;AAAA,CAAI;;;ACxMd,IAAM,gBAAgB;AAGf,IAAM,kBAAkB,CAAC,SAC9B,cAAc,KAAK,IAAI;;;ACjBzB,uBAAS;AAET,uBAAS,qBAAY;AAiBrB,IAAM,eAAe,CAAC,KAAK,GAAG;AAG9B,IAAM,cAAc,CAAC,MAAc,QACjC,YAAW,GAAG,IAAI,MAAM,MAAK,MAAM,GAAG;AAGxC,IAAM,kBAAkB,CACtB,WACqB,OAAO,WAAW;AAGzC,IAAM,gBAAgB,CAAC,WACrB,OAAO,WAAW;AAGpB,IAAM,aAAa,CAAC,UAClB,OAAO,UAAU;AAGnB,IAAM,gBAAgB,CAAC,SACrB,OAAO,SAAS,aAAY,SAAS;AAOvC,IAAM,gBAAgB,CACpB,YACkC;AAAA,EAClC,MAAM,UAAU,QAAQ,OAAO,eAAe;AAAA,EAC9C,MAAM,OAAO,QAAQ,OAAO,CAAC,WAAW,aAAa,SAAS,MAAM,CAAC;AAAA,EACrE,IAAI,KAAK,SAAS,GAAG;AAAA,IACnB,OAAO;AAAA,EACT;AAAA,EACA,IAAI,QAAQ,SAAS,GAAG;AAAA,IACtB,OAAO;AAAA,EACT;AAAA,EACA,OAAO,SAAS;AAAA,EAChB,OAAO,QAAQ,WAAW,KAAK,cAAc,KAAK,IAAI,QAAQ;AAAA;AAGhE,IAAM,eAAe,CAAC,MAAc,YAAyC;AAAA,EAC3E,MAAM,SAAS,cAAc,OAAO;AAAA,EACpC,OAAO,WAAW,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,OAAO;AAAA;AAI1D,IAAM,eAAe,CAAC,MAAuB,SAC3C,KAAK,SAAS,IAAI,CAAC,YAAY;AAAA,EAC7B,MAAM,QAAqB;AAAA,IACzB,MAAM,KAAK;AAAA,IACX,KAAK,YAAY,MAAM,QAAQ,GAAG;AAAA,EACpC;AAAA,EACA,MAAM,aAA0B,gBAAgB,QAAQ,MAAM,IAC1D,KAAK,OAAO,QAAQ,QAAQ,OAAO,IACnC;AAAA,EAEJ,OAAO,QAAQ,UAAU,YAAY,QAAQ,UAAU,WACnD,KAAK,YAAY,OAAO,QAAQ,MAAM,IACtC;AAAA,CACL;AAOH,IAAM,YAAY,CAAC,OAAkB,SAAkC;AAAA,EACrE,IAAI,WAAW,KAAK,GAAG;AAAA,IACrB,IAAI,CAAC,WAAW,KAAK,GAAG;AAAA,MACtB,OAAO;AAAA,IACT;AAAA,IACA,MAAM,MAAM,aAAa;AAAA,IACzB,OAAO,CAAC,aAAa,IAAI,QAAQ,IAAI,OAAO,CAAC;AAAA,EAC/C;AAAA,EACA,IAAI,cAAc,OAAO;AAAA,IACvB,OAAO,aAAa,OAAO,IAAI;AAAA,EACjC;AAAA,EACA,KAAK,MAAM,YAAY,cAAc,UAAU;AAAA,IAC7C,OAAO;AAAA,EACT;AAAA,EACA,OAAO,CAAC,aAAa,MAAM,MAAM,MAAM,WAAW,YAAY,CAAC;AAAA;AAIjE,IAAM,aAAa,CAAC,UAAoC;AAAA,EACtD,IAAI,WAAW,KAAK,GAAG;AAAA,IACrB,OAAO,WAAW,KAAK,IAAI,aAAa,OAAO,SAAS;AAAA,EAC1D;AAAA,EACA,OAAO,MAAM;AAAA;AAQR,IAAM,gBAAgB,CAC3B,OACA,SACmB;AAAA,EACnB,MAAM,UAAoB,CAAC;AAAA,EAC3B,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,WAA2B,CAAC;AAAA,EAElC,MAAM,QAAQ;AAAA,IACZ,CAAC,SAAS,OAAO,OAAO;AAAA,IACxB,CAAC,QAAQ,OAAO,IAAI;AAAA,EACtB;AAAA,EACA,YAAY,MAAM,UAAU,OAAO;AAAA,IACjC,IAAI,UAAU,WAAW;AAAA,MACvB;AAAA,IACF;AAAA,IACA,MAAM,cAAc,UAAU,OAAO,IAAI;AAAA,IACzC,IAAI,CAAC,aAAa;AAAA,MAChB;AAAA,IACF;AAAA,IACA,SAAS,QAAQ,WAAW,KAAK,KAAK;AAAA,IACtC,WAAW,SAAS,aAAa;AAAA,MAC/B,MAAM,MAAM,KAAK,UAAU,KAAK;AAAA,MAChC,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAAA,QAClB,KAAK,IAAI,GAAG;AAAA,QACZ,QAAQ,KAAK,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAyB,EAAE,OAAO,QAAQ;AAAA,EAChD,IAAI,SAAS,SAAS,SAAS,MAAM;AAAA,IACnC,OAAO,WAAW;AAAA,EACpB;AAAA,EACA,OAAO;AAAA;AAIF,IAAM,uBAAuB,CAAC,OAAiB,SACpD,MAAM,IAAI,CAAC,SACT,cAAc,IAAI,IAAI,KAAK,MAAM,KAAK,YAAY,MAAM,KAAK,GAAG,EAAE,IAAI,IACxE;AAQK,IAAM,iBAAiB,CAC5B,SAOA,SACmB;AAAA,EACnB,IAAI,QAAQ,SAAS;AAAA,IACnB,OAAO,EAAE,OAAO,qBAAqB,QAAQ,SAAS,IAAI,EAAE;AAAA,EAC9D;AAAA,EACA,OAAO,QAAQ,uBACX,cAAc,QAAQ,YAAY,IAAI,IACtC,EAAE,OAAO,CAAC,EAAE;AAAA;AAQX,IAAM,mBAAmB,CAC9B,SACA,SACa;AAAA,EACb,MAAM,UAAoB,CAAC;AAAA,EAC3B,WAAW,SAAS,OAAO,OAAO,QAAQ,cAAc,CAAC,CAAC,GAAG;AAAA,IAC3D,IAAI,CAAC,WAAW,KAAK,KAAK,cAAc,OAAO;AAAA,MAC7C,QAAQ,KACN,GAAG,MAAM,SAAS,IAAI,CAAC,YAAY,YAAY,MAAM,QAAQ,GAAG,CAAC,CACnE;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW,QAAQ,QAAQ,SAAS;AAAA,IAClC,IAAI,cAAc,IAAI,GAAG;AAAA,MACvB,QAAQ,KAAK,YAAY,MAAM,KAAK,GAAG,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EACA,OAAO,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,YAAW,IAAI,CAAC;AAAA;;;ACtNjE,uBAAS;AAET,iBAAS;AAKF,IAAM,gBAAgB,CAC3B,SACA,WACuB;AAAA,EACvB,IAAI,CAAC,QAAQ,YAAY,EAAE,SAAS,MAAM,GAAG;AAAA,IAC3C;AAAA,EACF;AAAA,EACA,MAAM,YAAW,OAAO,QAAQ,QAAQ,EAAE;AAAA,EAC1C,MAAM,OAAO;AAAA,IACX,MAAK,QAAQ,QAAQ,MAAM,UAAU,SAAQ;AAAA,IAC7C,MAAK,QAAQ,QAAQ,MAAM,SAAQ;AAAA,EACrC,EAAE,KAAK,CAAC,SAAS,YAAW,IAAI,CAAC;AAAA,EACjC,OAAO,OAAO,aAAa,MAAM,OAAO,IAAI;AAAA;;;ACnB9C,qBAAS;AAET,uBAAS,qBAAY;;;ACArB,IAAM,kBAAkB;AAOjB,IAAM,UAAU;AAAA,EACrB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AACR;AAQO,IAAM,iBAAiB,CAAC,UAC7B,OAAO,OAAO,SAAS,KAAK;AAK9B,IAAM,YAAY;AAGlB,IAAM,YAAY,CAAC,OAAe,aAChC,UAAU,KAAK,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,IAAI;AAGhD,IAAM,gBAAgB,CAAC,UACrB,eAAe,KAAK,IAAI,QAAQ,SAAS,UAAU,OAAO,eAAe;AAG3E,IAAM,kBAAkB,CAAC,UACvB,SAAS,UAAU,KAAK,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,IAAI;AAEzD,IAAM,QAAQ;AAAA,EACZ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AACN;AAEA,IAAM,YAAY,CAAC,UAA0B,KAAK,UAAU,KAAK;AAEjE,IAAM,qBAAqB,CAAC,UAC1B,OAAO,UAAU,KAAK;AAExB,IAAM,WAAW,CAAC,MAAc,UAC9B,QAAQ,CAAC,KAAK,SAAS,QAAQ,IAAI,CAAC;AAEtC,IAAM,eAAe,CACnB,OACA,YAMA;AAAA,EACE,qBAAqB,QAAQ;AAAA,EAC7B,GAAG,SAAS,kBAAkB,QAAQ,MAAM;AAAA,EAC5C,GAAG,SACD,6BACA,QAAQ,SAAS,iBAAiB,IACpC;AAAA,EACA,GAAG,SAAS,sBAAsB,gBAAgB,MAAM,YAAY,KAAK,CAAC;AAAA,EAC1E,GAAG,SACD,4BACA,MAAM,iBAAiB,QACnB,mBAAmB,MAAM,gBAAgB,KAAK,IAC9C,IACN;AAAA,EACA,qBAAqB,QAAQ;AAC/B,EACG,OAAO,OAAO,EACd,KAAK;AAAA,CAAI;AAEd,IAAM,eAAe,CACnB,OACA,YAIW;AAAA,EAKX,MAAM,SAAS;AAAA,IACb,qBAAqB,QAAQ;AAAA,IAC7B;AAAA,IACA,GAAG,SAAS,kBAAkB,QAAQ,MAAM;AAAA,IAC5C,GAAG,SACD,6BACA,QAAQ,SAAS,iBAAiB,IACpC;AAAA,IACA,GAAG,SAAS,sBAAsB,gBAAgB,MAAM,YAAY,IAAI,CAAC;AAAA,IACzE,GAAG,SACD,4BACA,MAAM,iBAAiB,OACnB,mBAAmB,MAAM,gBAAgB,IAAI,IAC7C,IACN;AAAA,EACF,EAAE,OAAO,OAAO;AAAA,EAChB,OAAO;AAAA,EACP,OAAO,KAAK;AAAA,CAAI;AAAA;AAAA;AAAA;AAkBX,IAAM,gBAAgB,CAC3B,WACkB;AAAA,EAClB,MAAM,cAAc,MAAM,OAAO,IAAI;AAAA,EACrC,OAAO,cAAc,MAAM,OAAO,KAAK;AACzC;AAGO,IAAM,gBAAgB,CAAC,UAC5B,MAAM,MAAM;AAOP,IAAM,gBAAgB,CAAC,UAA2C;AAAA,EACvE,MAAM,SAAS,cAAc,KAAK;AAAA,EAClC,MAAM,SAAS,MAAM,SAAS,cAAc,MAAM,MAAM,IAAI;AAAA,EAC5D,MAAM,SAAS,MAAM,MAAM;AAAA,EAC3B,MAAM,OAAO,aAAa,OAAO;AAAA,IAC/B,QAAQ,OAAO;AAAA,IACf;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACD,MAAM,OAAO,aAAa,OAAO;AAAA,IAC/B,QAAQ,OAAO;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EAED,OAAO;AAAA;AAAA,EAEP;AAAA;AAAA,EAEA;AAAA;;;AD7IF,IAAM,WAAW;AAGjB,IAAM,oBAAoB,CAAC,UAA0B;AAAA,EACnD,MAAM,WAAW,SAAS,OAAO,GAAG;AAAA,EACpC,OAAO,GAAG,aAAa,KAAK,UAAU;AAAA;AAcxC,IAAM,qBAAqB,CAAC,QAAwB,aAAsB;AAAA,EACxE,IAAI,UAAU;AAAA,IACZ,OAAO,EAAE,OAAO,SAAS;AAAA,EAC3B;AAAA,EACA,MAAM,SAAS,cAAc,OAAO,KAAK;AAAA,EACzC,MAAM,SAAS,cAAc,OAAO,KAAK;AAAA,EACzC,OAAO;AAAA,IACL,WAAW,sDAAsD,OAAO,yBAAyB,4CAA4C,OAAO;AAAA,EACtJ;AAAA;AAIF,IAAM,oBAAoB,OACxB,MACA,SAII;AAAA,EACJ,IAAI,SAAS,KAAK,IAAI,GAAG;AAAA,IACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE;AAAA,EACjC;AAAA,EAGA,MAAM,WAAW,YAAW,IAAI,IAAI,OAAO,MAAK,MAAM,IAAI;AAAA,EAC1D,IAAI;AAAA,IACF,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,UAAS,UAAU,OAAO,EAAE,EAAE;AAAA,IAChE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,QAAQ,EAAE,KAAK,KAAK;AAAA,MACpB,SAAS,kCAAkC,oBAAoB;AAAA,IACjE;AAAA;AAAA;AAQJ,IAAM,wBAAwB,CAC5B,MACA,MACA,eACA,aAC2B;AAAA,EAC3B,IAAI,KAAI,aAAa,UAAU;AAAA,IAC7B,OAAO;AAAA,EACT;AAAA,EACA,IAAI,KAAK,IAAI,KAAI,KAAK,GAAG;AAAA,IACvB,SAAS,KACP,wCAAwC,KAAI,2BAC9C;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EACA,IAAI,cAAc,IAAI,KAAI,KAAK,GAAG;AAAA,IAChC,SAAS,KACP,uBAAuB,KAAI,mEAC7B;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EACA,KAAK,IAAI,KAAI,KAAK;AAAA,EAClB,OAAO;AAAA;AASF,IAAM,sBAAsB,OAAO,YAIqB;AAAA,EAC7D,QAAQ,QAAQ,MAAM,kBAAkB;AAAA,EACxC,MAAM,WAAqB,CAAC;AAAA,EAG5B,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,WAA8B,CAAC;AAAA,EACrC,WAAW,QAAO,kBAAkB,MAAM,GAAG;AAAA,IAC3C,MAAM,OAAO,sBAAsB,MAAK,MAAM,eAAe,QAAQ;AAAA,IACrE,IAAI,MAAM;AAAA,MACR,SAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,MAAM,QAAQ,IAC1B,SAAS,IAAI,OAAO,UAAS;AAAA,IAC3B;AAAA,IACA,MAAM,MAAM,kBAAkB,KAAI,MAAM,IAAI;AAAA,EAC9C,EAAE,CACJ;AAAA,EAEA,MAAM,QAAyB,CAAC;AAAA,EAChC,aAAa,WAAK,UAAU,OAAO;AAAA,IACjC,IAAI,KAAK,SAAS;AAAA,MAChB,SAAS,KAAK,KAAK,OAAO;AAAA,IAC5B;AAAA,IACA,MAAM,WAAW,kBAAkB,KAAI,KAAK;AAAA,IAC5C,MAAM,KAAK;AAAA,MACT,SAAS,wBAAwB;AAAA,QAC/B,eAAe;AAAA,aACV,KAAK;AAAA,aACL,mBAAmB,QAAQ,KAAI,KAAK;AAAA,aAIpC,KAAI;AAAA,QACT;AAAA,QACA,SAAS,KAAI;AAAA,QACb,OAAO,KAAI;AAAA,QACX,OAAO,KAAI;AAAA,MACb,CAAC;AAAA,MACD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,EAAE,OAAO,SAAS;AAAA;;;AE5IpB,IAAM,uBAAuB,CAClC,SACA,aAEA,QAAQ,IAAI,GAAG,MAAM,MAAM,YAAY;AAAA,EACrC,MAAM,OAA0B;AAAA,IAC9B;AAAA,IACA,OAAO,aAAa,UAAU,IAAI;AAAA,EACpC;AAAA,EACA,IAAI,MAAM;AAAA,IACR,KAAK,OAAO;AAAA,EACd;AAAA,EACA,OAAO;AAAA,CACR;;;AC9BI,IAAM,yBAAyB;;;ACCtC,IAAM,wBAAwB;AAmB9B,IAAM,eAAe;AAAA;AAIrB,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa9B,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6FvB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBf,IAAM,wBAAwB,CAAC,YACpC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,QAAQ,IAAI,CAAC,WAAW,YAAY,UAAU,EAAE,KAAK;AAAA,CAAI;AAAA;AAAA,EAEjE;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aA+OW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgGX,QAAQ,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBA8BJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAcE,+BAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAiHvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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",
|
|
38
|
-
"debugId": "
|
|
37
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWO,IAAM,4BACX;AAKK,IAAM,4BACX;;;ACdF,iBAAS,4BAAgB;;;ACDzB,0BAAkB;;;ACHlB;;;ACCA,mBAAS;AAkBT,IAAM,eAAe,IAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;;;AH4D7C,IAAM,eAAe,OAAO,IAAI,mBAAmB;AAMnD,IAAM,YAAW,MAAyB;AAAA,EAIxC,MAAM,OAAO;AAAA,EACb,KAAK,kBAAkB;AAAA,IACrB,cAAc;AAAA,IACd,aAAa;AAAA,IACb,SAAS;AAAA,IACT,gBAAgB;AAAA,EAClB;AAAA,EACA,OAAO,KAAK;AAAA;AASP,IAAM,sBAAsB,CAAC,YAAuC;AAAA,EACzE,UAAS,EAAE,eAAe;AAAA;AAoCrB,IAAM,wBAAwB,CACnC,gBAIS;AAAA,EACT,UAAS,EAAE,cAAc,cACrB;AAAA,IACE,eAAe,IAAI,IAAI,YAAY,aAAa;AAAA,IAChD,gBAAgB,YAAY;AAAA,EAC9B,IACA;AAAA;AAYC,IAAM,sBAAsB,YAA8B;AAAA,EAC/D,QAAQ,mBAAmB,UAAS;AAAA,EACpC,IAAI,CAAC,gBAAgB;AAAA,IACnB,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,eAAe,CAAC,CAAC;AAAA,EACvB,OAAO;AAAA;AAGT,IAAM,iBAAiB,MAAkC;AAAA,EACvD,QAAQ,YAAY,UAAS;AAAA,EAC7B,OAAO,SAAS,MAAM,SAAS;AAAA;AAS1B,IAAM,wBAAwB,CAAC,gBAAoC;AAAA,EACxE,MAAM,SAAuB,CAAC;AAAA,EAC9B,WAAW,cAAc,aAAa;AAAA,IACpC,IAAI,WAAW,aAAa,SAAS;AAAA,MACnC,OAAO,KAAK,iBAAiB,UAAU,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EACA,MAAM,UAAU,eAAe;AAAA,EAC/B,IAAI,OAAO,WAAW,KAAK,CAAC,SAAS;AAAA,IACnC;AAAA,EACF;AAAA,EACA,MAAM,OAAO,OACV,IAAI,CAAC,eAAe;AAAA,IACnB,MAAM,aAAa,WAAW,OAAO,IAAI,WAAW,SAAS;AAAA,IAC7D,MAAM,QAAQ,WAAW,OACrB;AAAA,OAAU,WAAW,OAAO,eAC5B;AAAA,IACJ,MAAM,MAAM,WAAW,aACnB;AAAA,SAAY,WAAW,eACvB;AAAA,IACJ,MAAM,OAAO,WAAW,UAAU;AAAA,UAAa,WAAW,YAAY;AAAA,IACtE,OAAO,IAAI,WAAW,SAAS,WAAW,UAAU,QAAQ,MAAM;AAAA,GACnE,EACA,KAAK;AAAA;AAAA,CAAM;AAAA,EACd,QAAQ,KAAK;AAAA,IACX,KAAK;AAAA,MACH,IAAI,OAAO,IAAI;AAAA,MACf,SAAS,eAAe,OAAO;AAAA;AAAA,EAAuB;AAAA,MACtD,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAAA;;;AI1NH;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,oBAAS,kBAAS;AA2BX,IAAM,aAAa,CACxB,YAEA,WAAW,MAAK,QAAQ,MAAM,cAAc,CAAC,IACzC,MAAK,QAAQ,MAAM,gBAAgB,UAAU,SAAS,IAAI,IAC1D,MAAK,QAAQ,QAAQ,UAAU,IAAI;AAezC,IAAM,gBAAe,OAAO,IAAI,gBAAgB;AAIhD,IAAM,YAAW,MAAuB;AAAA,EAItC,MAAM,OAAO;AAAA,EACb,KAAK,mBAAkB,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,IAAI,IAAM;AAAA,EAC7D,OAAO,KAAK;AAAA;AAYd,IAAM,mBAAmB,IAAI;AAgE7B,IAAM,WAAW,IAAI;AA0Dd,IAAM,iBAAiB,OAAO,QAAiC;AAAA,EACpE,QAAQ,SAAS,UAAS;AAAA,EAC1B,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,UAAU,MAAM,QAAQ,GAAG;AAAA,IAC3B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,EAET,MAAM,QAAQ,QAAQ,OACpB,CAAC,SACC,KAAK,SAAS,MAAM,KACnB,KAAK,SAAS,MAAM,KAAK,CAAC,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC,OAAO,MAAM,CAAC,CACrE;AAAA,EACA,MAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS,GAAG,MAAK,KAAK,IAAI,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC;AAAA,EAC3E,OAAO,MAAM;AAAA;AAQR,IAAM,iBAAiB,MAA+C;AAAA,EAC3E,QAAQ,MAAM,WAAW,UAAS;AAAA,EAClC,OAAO,OAAO,WAAW,IAAI,OAAO,EAAE,MAAM,OAAO;AAAA;;;AClOrD;AACA,uBAAS,6BAAY;AACrB;AAAA;AAAA,WAEE;AAAA,cACA;AAAA;AAAA;AAAA,QAGA;AAAA;AAAA;AAGF,0BAAS;AACT;AAEA;AACA;AAAA,cACE;AAAA,aACA;AAAA,gBACA;AAAA,UACA;AAAA;AAAA,cAEA;AAAA,aACA;AAAA;AAEF,iBAAS;;;ACjBF,IAAM,eAAe;;;AC2G5B,IAAM,YAAY;AAClB,IAAM,gBAAgB;AACtB,IAAM,YAAY;AAElB,IAAM,MAAM,CAAC,UAA6B;AAAA,EACxC,MAAM,wBAAwB;AAChC;AAEA,IAAM,eAAe,CAAC,aAAqB,YAAoC;AAAA,EAC7E,SAAS,GAAG,YAAY,EAAE,QAAQ,IAAI,MAAM,EAAE,EAAE;AAAA,EAChD;AACF;AAEA,IAAM,kBAAkB,CAAC,iBAAyC;AAAA,EAChE,SAAS,GAAG,eAAe,EAAE,QAAQ,IAAI,SAAS,EAAE,EAAE;AAAA,EACtD;AACF;AAEA,IAAM,eAAe,CAAC,aAAqB,UAAkC;AAAA,EAC3E,SAAS,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,EAAE,EAAE;AAAA,EAClD;AACF;AAEA,IAAM,SAAS,CAAC,iBAAyB,EAAE,aAAa,MAAM,SAAS;AAEvE,IAAM,eAAe;AAAA,EACnB,sBAAsB,EAAE,MAAM,SAAS;AAAA,EACvC,aACE;AAAA,EACF,MAAM;AACR;AAEA,IAAM,kBAAkB;AAAA,EACtB,aACE;AAAA,EACF,MAAM;AACR;AAGA,IAAM,mBAAgC;AAAA,EACpC;AAAA,IACE,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,WAAW,GAAG,MAAM,SAAS;AAAA,EACzC;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,SAAS,GAAG,SAAS,IAAI,SAAS,GAAG,MAAM,UAAU;AAAA,EACjE;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,GAAG,MAAM,QAAQ;AAAA,IACnD,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,SAAS;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,SAAS;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,aACE;AAAA,IACF,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,sBAAsB,EAAE,MAAM,SAAS,GAAG,MAAM,SAAS;AAAA,IACnE,OAAO;AAAA,EACT;AACF;AAEA,IAAM,UAAU;AAAA,EACd,gBAAgB;AAAA,IACd,aAAa;AAAA,IACb,YAAY;AAAA,MACV,IAAI,EAAE,aAAa,wCAAwC;AAAA,MAC3D,SAAS,EAAE,OAAO,OAAO,MAAM,SAAS;AAAA,MACxC,QAAQ,OAAO,oDAAoD;AAAA,MACnE,QAAQ,EAAE,aAAa,sBAAsB,MAAM,SAAS;AAAA,IAC9D;AAAA,IACA,UAAU,CAAC,WAAW,QAAQ;AAAA,IAC9B,MAAM;AAAA,EACR;AAAA,EACA,iBAAiB;AAAA,IACf,aAAa;AAAA,IACb,YAAY;AAAA,MACV,OAAO;AAAA,QACL,YAAY;AAAA,UACV,MAAM,EAAE,MAAM,UAAU;AAAA,UACxB,MAAM,CAAC;AAAA,UACP,SAAS,EAAE,MAAM,SAAS;AAAA,QAC5B;AAAA,QACA,UAAU,CAAC,QAAQ,SAAS;AAAA,QAC5B,MAAM;AAAA,MACR;AAAA,MACA,IAAI,CAAC;AAAA,MACL,SAAS,EAAE,OAAO,OAAO,MAAM,SAAS;AAAA,MACxC,QAAQ,EAAE,MAAM,SAAS;AAAA,IAC3B;AAAA,IACA,UAAU,CAAC,SAAS;AAAA,IACpB,MAAM;AAAA,EACR;AAAA,EACA,SAAS;AAAA,IACP,YAAY;AAAA,MACV,MAAM,OAAO,qDAAqD;AAAA,MAClE,MAAM,OAAO,qBAAqB;AAAA,MAClC,OAAO,EAAE,MAAM,SAAS;AAAA,IAC1B;AAAA,IACA,UAAU,CAAC,QAAQ,OAAO;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA,EACA,SAAS;AAAA,IACP,aACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,YAAY;AAAA,UACV,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,YAAY,EAAE,MAAM,UAAU;AAAA,UAC9B,aAAa,EAAE,MAAM,SAAS;AAAA,UAC9B,MAAM,EAAE,MAAM,SAAS;AAAA,UACvB,MAAM,EAAE,OAAO,QAAQ,MAAM,SAAS;AAAA,UACtC,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,QAAQ,OAAO,+BAA+B;AAAA,UAC9C,OAAO,OAAO,mBAAmB;AAAA,QACnC;AAAA,QACA,UAAU,CAAC,QAAQ,SAAS,UAAU,OAAO;AAAA,QAC7C,MAAM;AAAA,MACR;AAAA,MACA;AAAA,QACE,YAAY;AAAA,UACV,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,UAAU,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,UACjD,WAAW,EAAE,MAAM,UAAU;AAAA,UAC7B,MAAM,EAAE,MAAM,SAAS;AAAA,UACvB,MAAM,EAAE,OAAO,SAAS,MAAM,SAAS;AAAA,UACvC,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,MAAM,OAAO,oDAAoD;AAAA,UACjE,OAAO,OAAO,gDAAgD;AAAA,QAChE;AAAA,QACA,UAAU,CAAC,YAAY,QAAQ,OAAO;AAAA,QACtC,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX,aACE;AAAA,IACF,YAAY;AAAA,MACV,OAAO;AAAA,QACL,OAAO;AAAA,UACL,YAAY;AAAA,YACV,aAAa,EAAE,MAAM,SAAS;AAAA,YAC9B,OAAO,EAAE,MAAM,SAAS;AAAA,YACxB,MAAM,EAAE,MAAM,SAAS;AAAA,YACvB,KAAK,EAAE,MAAM,SAAS;AAAA,UACxB;AAAA,UACA,UAAU,CAAC,SAAS,MAAM;AAAA,UAC1B,MAAM;AAAA,QACR;AAAA,QACA,MAAM;AAAA,MACR;AAAA,MACA,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,OAAO,EAAE,MAAM,SAAS;AAAA,IAC1B;AAAA,IACA,UAAU,CAAC,SAAS,QAAQ,OAAO;AAAA,IACnC,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,YAAY;AAAA,MACV,MAAM,OACJ,8EACF;AAAA,MACA,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,MAAM,OAAO,2BAA2B;AAAA,IAC1C;AAAA,IACA,UAAU,CAAC,SAAS,MAAM;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,aACE;AAAA,IACF,YAAY;AAAA,MACV,SAAS,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,MAChD,KAAK,EAAE,OAAO,CAAC,IAAI,SAAS,GAAG,EAAE,MAAM,OAAO,CAAC,EAAE;AAAA,MACjD,UAAU,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,MACjD,SAAS,EAAE,MAAM,CAAC,UAAU,MAAM,EAAE;AAAA,MACpC,MAAM,OAAO,0DAA0D;AAAA,MACvE,WAAW,EAAE,OAAO,IAAI,aAAa,GAAG,MAAM,QAAQ;AAAA,MACtD,SAAS,EAAE,OAAO,IAAI,SAAS,GAAG,MAAM,QAAQ;AAAA,MAChD,MAAM,EAAE,OAAO,IAAI,QAAQ,GAAG,MAAM,QAAQ;AAAA,IAC9C;AAAA,IACA,UAAU,CAAC,YAAY,aAAa,WAAW,MAAM;AAAA,IACrD,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,IACJ,OAAO;AAAA,MACL,IAAI,aAAa;AAAA,MACjB;AAAA,QACE,YAAY;AAAA,UACV,UAAU,OACR,6FACF;AAAA,QACF;AAAA,QACA,UAAU,CAAC,UAAU;AAAA,QACrB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,aAAa;AAAA,EACf;AAAA,EACA,aAAa;AAAA,IACX,YAAY;AAAA,MACV,aAAa,OAAO,+CAA+C;AAAA,MACnE,aAAa,EAAE,MAAM,SAAS;AAAA,MAC9B,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,aACE;AAAA,QACF,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,cAAc;AAAA,QACZ,aAAa;AAAA,QACb,MAAM,CAAC,UAAU,MAAM;AAAA,MACzB;AAAA,MACA,QAAQ,OAAO,yBAAyB;AAAA,MACxC,aAAa;AAAA,QACX,aACE;AAAA,QACF,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,OAAO,OACL,4EACF;AAAA,MACA,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,KAAK;AAAA,QACH,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,SAAS;AAAA,IACX;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,MACV,OAAO,EAAE,MAAM,UAAU;AAAA,MACzB,WAAW,OAAO,wCAAwC;AAAA,MAC1D,OAAO,EAAE,OAAO,IAAI,aAAa,GAAG,MAAM,QAAQ;AAAA,MAClD,MAAM,EAAE,MAAM,CAAC,UAAU,MAAM,EAAE;AAAA,IACnC;AAAA,IACA,UAAU,CAAC,SAAS,aAAa,SAAS,MAAM;AAAA,IAChD,MAAM;AAAA,EACR;AAAA,EACA,SAAS;AAAA,IACP,aACE;AAAA,IACF,YAAY;AAAA,MACV,MAAM,OAAO,4CAA4C;AAAA,MACzD,QAAQ,OAAO,gDAAgD;AAAA,MAC/D,UAAU,OAAO,2CAA2C;AAAA,MAC5D,OAAO;AAAA,QACL,aAAa;AAAA,QACb,OAAO;AAAA,UACL,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,GAAG,OAAO,EAAE,MAAM,SAAS,EAAE;AAAA,UAClE,UAAU,CAAC,QAAQ,OAAO;AAAA,UAC1B,MAAM;AAAA,QACR;AAAA,QACA,MAAM;AAAA,MACR;AAAA,MACA,YAAY,OAAO,kBAAkB;AAAA,MACrC,QAAQ,EAAE,MAAM,UAAU;AAAA,MAC1B,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,MAAM,OAAO,6CAA6C;AAAA,IAC5D;AAAA,IACA,UAAU,CAAC,QAAQ,UAAU,cAAc,UAAU,SAAS,MAAM;AAAA,IACpE,MAAM;AAAA,EACR;AAAA,EACA,WAAW;AAAA,IACT,YAAY;AAAA,MACV,aAAa,EAAE,MAAM,SAAS;AAAA,MAC9B,SAAS,OAAO,sDAAsD;AAAA,MACtE,QAAQ;AAAA,MACR,OAAO,OAAO,yCAAyC;AAAA,MACvD,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,KAAK,EAAE,QAAQ,iBAAiB,MAAM,SAAS;AAAA,MAC/C,SAAS;AAAA,IACX;AAAA,IACA,UAAU,CAAC,WAAW,SAAS,SAAS,KAAK;AAAA,IAC7C,MAAM;AAAA,EACR;AAAA,EACA,gBAAgB;AAAA,IACd,YAAY;AAAA,MACV,OAAO,EAAE,MAAM,UAAU;AAAA,MACzB,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,SAAS,EAAE,OAAO,IAAI,WAAW,GAAG,MAAM,QAAQ;AAAA,IACpD;AAAA,IACA,UAAU,CAAC,SAAS,SAAS,SAAS;AAAA,IACtC,MAAM;AAAA,EACR;AACF;AAEA,IAAM,cAAyB;AAAA,EAC7B,aACE;AAAA,EACF,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ,EAAE,MAAM,SAAS;AAC3B;AAGA,IAAM,YAAY,CAAC,UAAgC;AAAA,EACjD,IAAI,MAAM,MAAM;AAAA,IACd,OAAO,MAAM,OACT,YAAY,MAAM,MAAM,MAAM,IAAI,IAClC,SAAS,MAAM,IAAI;AAAA,EACzB;AAAA,EACA,OAAO,MAAM,QAAQ;AAAA;AAIhB,IAAM,eAAe,CAAC,UAAyC;AAAA,EACpE,MAAM,cAAoC;AAAA,IACxC;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,mBAAmB,YAAY;AAAA,YACnD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,OAAO;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,YAAY,CAAC,WAAW;AAAA,UACxB,WAAW;AAAA,YACT,OAAO,aAAa,aAAa,MAAM;AAAA,YACvC,OAAO,gBAAgB,yBAAyB;AAAA,YAChD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,OAAO;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,wBAAwB,YAAY;AAAA,YACxD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,YAAY;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,MAAM,QAAQ;AAAA,IAChB,YAAY,KAAK;AAAA,MACf;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,WAAW;AAAA,YACT,OAAO,aACL,mCACA,gBACF;AAAA,YACA,OAAO,gBAAgB,iCAAiC;AAAA,YACxD,SAAS,gBAAgB,+BAA+B;AAAA,UAC1D;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,QAAQ;AAAA,QACjB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,YAAY,KAAK;AAAA,IACf;AAAA,IACA;AAAA,MACE,KAAK;AAAA,QACH,aACE;AAAA,QACF,aAAa;AAAA,QACb,YAAY,CAAC,WAAW;AAAA,QACxB,WAAW;AAAA,UACT,OAAO,aAAa,yBAAyB,aAAa;AAAA,UAC1D,OAAO,aACL,8DACA,aACF;AAAA,QACF;AAAA,QACA,SAAS;AAAA,QACT,MAAM,CAAC,UAAU;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EACD,IAAI,MAAM,SAAS;AAAA,IACjB,YAAY,KACV;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,cAAc,SAAS;AAAA,UAC7C;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,UAAU;AAAA,QACnB;AAAA,MACF;AAAA,IACF,GACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO,aAAa,0BAA0B,SAAS;AAAA,UACzD;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,UAAU;AAAA,QACnB;AAAA,MACF;AAAA,IACF,CACF;AAAA,EACF;AAAA,EACA,IAAI,MAAM,kBAAkB;AAAA,IAC1B,YAAY,KAAK;AAAA,MACf;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,aACE;AAAA,UACF,aAAa;AAAA,UACb,WAAW;AAAA,YACT,OAAO;AAAA,cACL,SAAS,GAAG,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,EAAE,EAAE;AAAA,cACvD,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,WAAW;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,IAAI,MAAM,UAAU;AAAA,IAClB,YAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN;AAAA,QACE,MAAM;AAAA,UACJ,aACE;AAAA,UACF,aAAa;AAAA,UACb,aAAa;AAAA,YACX,SAAS,GAAG,YAAY,EAAE,QAAQ,IAAI,gBAAgB,EAAE,EAAE;AAAA,YAC1D,UAAU;AAAA,UACZ;AAAA,UACA,WAAW;AAAA,YACT,OAAO,aAAa,0BAA0B,iBAAiB;AAAA,UACjE;AAAA,UACA,SAAS;AAAA,UACT,MAAM,CAAC,KAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAc;AAAA,IAClB,EAAE,aAAa,2CAA2C,MAAM,QAAQ;AAAA,IACxE,GAAI,MAAM,SACN,CAAC,EAAE,aAAa,mCAAmC,MAAM,SAAS,CAAC,IACnE,CAAC;AAAA,IACL,EAAE,aAAa,+BAA+B,MAAM,aAAa;AAAA,IACjE,EAAE,aAAa,qCAAqC,MAAM,WAAW;AAAA,IACrE,GAAI,MAAM,mBACN,CAAC,EAAE,aAAa,8BAA8B,MAAM,YAAY,CAAC,IACjE,CAAC;AAAA,IACL,GAAI,MAAM,WACN,CAAC,EAAE,aAAa,wCAAwC,MAAM,MAAM,CAAC,IACrE,CAAC;AAAA,EACP;AAAA,EAEA,MAAM,OAAa;AAAA,IACjB,aAAa;AAAA,MACX,+BAA+B,MAAM,qBAAqB,MAAM,cAAc,KAAK,MAAM,gBAAgB;AAAA,MACzG;AAAA,IACF,EAAE,KAAK;AAAA;AAAA,CAAM;AAAA,IACb,OAAO,cAAc,MAAM,IAAI;AAAA,IAC/B,SAAS,MAAM;AAAA,IACf,eAAe,SAAS,MAAM;AAAA,EAChC;AAAA,EACA,MAAM,WAA4B;AAAA,IAChC,YAAY,EAAE,QAAQ;AAAA,IACtB;AAAA,IACA,SAAS;AAAA,IACT,OAAO,OAAO,YAAY,WAAW;AAAA,IACrC,UAAU,CAAC;AAAA,IACX,SAAS,CAAC,EAAE,aAAa,MAAM,MAAM,KAAK,UAAU,KAAK,EAAE,CAAC;AAAA,IAC5D;AAAA,EACF;AAAA,EACA,IAAI,MAAM,MAAM;AAAA,IACd,SAAS,eAAe;AAAA,MACtB,aAAa,GAAG,MAAM;AAAA,MACtB,KAAK,YAAY,MAAM,MAAM,aAAa,MAAM,MAAM,GAAG,CAAC;AAAA,IAC5D;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;;ACzpBF,IAAM,eAAe,OAAO,YAA4C;AAAA,EAC7E,MAAM,YAAY,MAAM,qBAAqB,SAAS;AAAA,IACpD,UAAU;AAAA,IACV,SAAS;AAAA,IACT,qBAAqB;AAAA,EACvB,CAAC;AAAA,EACD,OAAO;AAAA,IACL,eAAe,QAAQ,OAAO,MAAM;AAAA,IACpC,WAAW,UAAU,IAAI,CAAC,SAAS;AAAA,MACjC,SAAS,IAAI;AAAA,MACb,aAAa,IAAI;AAAA,MACjB,QAAQ,IAAI;AAAA,MACZ,OAAO,IAAI;AAAA,MACX,OAAO,IAAI;AAAA,IACb,EAAE;AAAA,IACF,MAAM,QAAQ,OAAO,WAAW,QAAQ;AAAA,EAC1C;AAAA;;;ACdF,IAAM,aAAY,CAAC,UAAqC;AAAA,EAGtD,MAAM,OAAO,aAAa,MAAM,MAAM,MAAM,KAAK;AAAA,EAGjD,OAAO,MAAM,OAAO,YAAY,MAAM,MAAM,IAAI,IAAI;AAAA;AAO/C,IAAM,oBAAoB,CAAC,WAA8B;AAAA,EAC9D,SAAS;AAAA,IACP;AAAA,MACE,MAAM,MAAM;AAAA,MACZ,WAAW;AAAA,MACX,KAAK,WAAU,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAGA,IAAM,qBACJ;AAGF,IAAM,gBAAgB;AAEtB,IAAM,WAAW,CAAC,SAChB,KAAK,SAAS,gBAAgB,GAAG,KAAK,MAAM,GAAG,gBAAgB,CAAC,OAAO;AAOzE,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAExB,IAAM,eAAe,CAAC,SACpB,SACE,KACG,UAAU,MAAM,EAChB,QAAQ,iBAAiB,EAAE,EAC3B,YAAY,EACZ,QAAQ,gBAAgB,GAAG,GAC9B,GACF;AAQF,IAAM,iBAAiB,CAAC,UAAqC;AAAA,EAC3D,IAAI,YAAY;AAAA,EAChB,IAAI,MAAM,MAAM;AAAA,IACd,IAAI;AAAA,MACF,YAAY,IAAI,IAAI,MAAM,IAAI,EAAE,SAC7B,MAAM,GAAG,EACT,WAAW,EACX,KAAK,GAAG;AAAA,MACX,MAAM;AAAA,EAGV;AAAA,EACA,OAAO,GAAG,aAAa,aAAa,MAAM,IAAI,KAAK;AAAA;AAGrD,IAAM,WAAW;AAkCV,IAAM,qBAAqB,CAAC,UAA4C;AAAA,EAC7E,MAAM,MAAM,WAAU,KAAK;AAAA,EAC3B,MAAM,OAAsB;AAAA,IAC1B,SAAS;AAAA,IAGT,cAAc;AAAA,MACZ,WAAW,EAAE,aAAa,OAAO,WAAW,MAAM;AAAA,MAClD,OAAO,EAAE,aAAa,MAAM;AAAA,IAC9B;AAAA,IACA,aAAa,SACX,yCAAyC,MAAM,qBACjD;AAAA,IACA,MAAM,eAAe,KAAK;AAAA,IAC1B,YAAY,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,QAAQ;AAAA,IACvD,OAAO,SAAS,MAAM,IAAI;AAAA,IAC1B,OAAO,UAAU,IAAI,CAAC,UAAU;AAAA,MAC9B,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,IACd,EAAE;AAAA,IACF,WAAW;AAAA,IACX,YAAY,CAAC,EAAE,UAAU,KAAK,MAAM,kBAAkB,CAAC;AAAA,IACvD;AAAA,IACA,SAAS,MAAM;AAAA,EACjB;AAAA,EACA,IAAI,SAAS,KAAK,GAAG,GAAG;AAAA,IACtB,KAAK,UAAU,CAAC,EAAE,MAAM,mBAAmB,IAAI,CAAC;AAAA,EAClD;AAAA,EACA,IAAI,MAAM,MAAM;AAAA,IACd,KAAK,aAAa,SAAS,MAAM,IAAI;AAAA,EACvC;AAAA,EACA,OAAO;AAAA;;;AC2HF,IAAM,sBAAsB,CAAC,YAClC,QAAQ,KACN,CAAC,SACC,KAAK,SAAS,aACZ,KAAK,WAAW,YAAY,UAC5B,oBAAoB,KAAK,QAAQ,EACvC;AA+BK,IAAM,cAAc,CACzB,MAKA,gBAA+B,SACd;AAAA,EACjB,EAAE,QAAQ,WAAW,YAAY,KAAK,YAAY,SAAS,UAAU;AAAA,EACrE,GAAG,OAAO,QAAQ,KAAK,kBAAkB,EACtC,OAAO,EAAE,YAAY,WAAW,aAAa,EAC7C,IAAI,EAAE,QAAQ,iBAAiB;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,SAAS;AAAA,EACX,EAAE;AAAA,EACJ,GAAG,OAAO,QAAQ,KAAK,mBAAmB,EAAE,QAAQ,EAAE,SAAS,cAC7D,OAAO,QAAQ,QAAQ,EAAE,IAAI,EAAE,QAAQ,iBAAiB;AAAA,IACtD,QAAQ,UAAU,WAAW,gBAAgB,SAAS;AAAA,IACtD;AAAA,IACA;AAAA,EACF,EAAE,CACJ;AACF;;;AC7UO,IAAM,mBAAmB,IAAI,IAAY;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EACA;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,CAAC;;;ACxCD,IAAM,UAAU,CAAC,QACf,IACG,WAAW,uCAAuC,mBAAmB,EACrE,YAAY;AASV,IAAM,yBAAyB,CACpC,OACA,WACA,kBACiB;AAAA,EACjB,MAAM,cAA4B,CAAC;AAAA,EACnC,MAAM,OAAO,IAAI;AAAA,EACjB,WAAW,QAAQ,OAAO;AAAA,IACxB,WAAW,OAAO,KAAK,kBAAkB,CAAC,GAAG;AAAA,MAC3C,IAAI,iBAAiB,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,GAAG;AAAA,QACpE;AAAA,MACF;AAAA,MACA,KAAK,IAAI,GAAG;AAAA,MACZ,MAAM,OAAO,QAAQ,GAAG;AAAA,MACxB,MAAM,aAAa,cAAc,IAAI,IAAI,IACrC,mBAAmB,sCAAsC,iCACzD,aAAa,kDAAkD;AAAA,MACnE,YAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,MAAM,KAAK,cAAc,KAAK;AAAA,QAC9B,SAAS,IAAI,mBAAmB,KAAK;AAAA,QACrC,UAAU;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;;AC1CT,uBAAS;AAET,oBAAS,0CAA8B;AACvC;AA4DA,IAAM,SAAS,CAAC,OAAO,UAAU,SAAS;AAC1C,IAAM,YAAY,IAAI,IAAY,MAAM;AAGxC,IAAM,UAAU,CAAC,SAAgC,UAAU,IAAI,IAAI;AAEnE,IAAM,mBAAmB,IAAI,IAA+B;AAAA,EAC1D,CAAC,OAAO,OAAO;AAAA,EACf,CAAC,UAAU,QAAQ;AAAA,EACnB,CAAC,OAAO,OAAO;AAAA,EACf,CAAC,OAAO,KAAK;AACf,CAAC;AAED,IAAM,kBAAkB;AAAA,EACtB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AACP;AAGA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,kBAAuC,IAAI,IAAmB;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,kBAAkB,CAAC,UACvB,gBAAgB,IAAI,KAAK;AAgB3B,IAAM,gBAAgB,OAAkC;AAAA,EACtD,SAAS,CAAC;AAAA,EACV,QAAQ,CAAC;AAAA,EACT,KAAK,CAAC;AAAA,EACN,UAAU,CAAC;AACb;AAEA,IAAM,WAAW,CAAC,SAChB,GAAG,aAAa,IAAI,KAAK,GAAG,gBAAgB,IAAI,IAAI,KAAK,OAAO;AAGlE,IAAM,oBAAoB,CACxB,KACA,cACS;AAAA,EACT,IACE,CAAC,GAAG,oBAAoB,SAAS,KACjC,CAAC,GAAG,gBAAgB,UAAU,eAAe,GAC7C;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAM,YAAY,UAAU,gBAAgB;AAAA,EAC5C,MAAM,SAAS,UAAU;AAAA,EACzB,IAAI,CAAC,QAAQ;AAAA,IACX;AAAA,EACF;AAAA,EACA,IAAI,OAAO,MAAM;AAAA,IACf,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,UAAU,WAAW,UAAU,CAAC;AAAA,EAC9D;AAAA,EACA,MAAM,QAAQ,OAAO;AAAA,EACrB,IAAI,SAAS,GAAG,eAAe,KAAK,GAAG;AAAA,IACrC,WAAW,WAAW,MAAM,UAAU;AAAA,MACpC,IAAI,IAAI,QAAQ,KAAK,MAAM;AAAA,QACzB,WAAW,QAAQ,gBAAgB,QAAQ,MAAM;AAAA,QACjD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAIF,IAAM,iBAAiB,CACrB,eAC+B;AAAA,EAC/B,MAAM,MAAM,IAAI;AAAA,EAChB,WAAW,aAAa,WAAW,YAAY;AAAA,IAC7C,kBAAkB,KAAK,SAAS;AAAA,EAClC;AAAA,EACA,OAAO;AAAA;AAIT,IAAM,eAAe,CACnB,eAC2C;AAAA,EAC3C,IAAI,GAAG,0BAA0B,UAAU,GAAG;AAAA,IAC5C,OAAO;AAAA,EACT;AAAA,EACA,IAAI,GAAG,iBAAiB,UAAU,GAAG;AAAA,IACnC,OAAO,OAAO,WAAW;AAAA,IACzB,OAAO,OAAO,GAAG,0BAA0B,GAAG,IAAI,MAAM;AAAA,EAC1D;AAAA,EACA,IACE,GAAG,eAAe,UAAU,KAC5B,GAAG,0BAA0B,UAAU,GACvC;AAAA,IACA,OAAO,aAAa,WAAW,UAAU;AAAA,EAC3C;AAAA,EACA;AAAA;AAGF,IAAM,0BAA0B,CAC9B,eAC2C;AAAA,EAC3C,WAAW,aAAa,WAAW,YAAY;AAAA,IAC7C,IAAI,GAAG,mBAAmB,SAAS,KAAK,CAAC,UAAU,gBAAgB;AAAA,MACjE,OAAO,aAAa,UAAU,UAAU;AAAA,IAC1C;AAAA,EACF;AAAA,EACA;AAAA;AAGF,IAAM,iBAAiB,CAAC,SAAgC;AAAA,EACtD,WAAW,aAAa,gBAAgB;AAAA,IACtC,MAAM,YAAY,GAAG,QAAQ;AAAA,IAC7B,IAAI,YAAW,SAAS,GAAG;AAAA,MACzB,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAIT,IAAM,WAAW,CACf,WACA,UACA,QACmB;AAAA,EACnB,MAAM,WAAW,UAAU,WAAW,GAAG,KAAK,WAAW,SAAS;AAAA,EAClE,IAAI,OAAO;AAAA,EACX,IAAI,YAAY,QAAQ,SAAS,EAAE,MAAM,CAAC,EAAE,YAAY;AAAA,EACxD,IAAI,UAAU;AAAA,IACZ,MAAM,WAAW,WAAW,SAAS,IACjC,YACA,SAAQ,KAAK,SAAS;AAAA,IAC1B,IAAI,WAAW;AAAA,MACb,OAAO;AAAA,IACT,EAAO;AAAA,MACL,MAAM,SAAS,eAAe,QAAQ;AAAA,MACtC,OAAO,UAAU;AAAA,MACjB,YAAY,SAAS,QAAQ,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,IAAI;AAAA;AAAA,EAElE;AAAA,EACA,OAAO;AAAA,IACL,WAAW,iBAAiB,IAAI,SAAS,KAAK;AAAA,IAC9C,MAAM;AAAA,IACN;AAAA,EACF;AAAA;AAGF,IAAM,oBAAoB,CACxB,MACA,SACA,QAC0B;AAAA,EAC1B,MAAM,UAAU,QAAQ,IAAI,IAAI;AAAA,EAChC,OAAO,UAAU,SAAS,QAAQ,WAAW,QAAQ,UAAU,GAAG,IAAI;AAAA;AAIxE,IAAM,0BAA0B,CAC9B,YACA,UACA,SACA,QACS;AAAA,EACT,IAAI,GAAG,8BAA8B,QAAQ,GAAG;AAAA,IAC9C,IAAI,SAAS,KAAK,SAAS,aAAa;AAAA,MACtC,WAAW,eAAe;AAAA,MAC1B,WAAW,SAAS,kBAAkB,SAAS,KAAK,MAAM,SAAS,GAAG;AAAA,IACxE;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,CAAC,GAAG,qBAAqB,QAAQ,GAAG;AAAA,IACtC;AAAA,EACF;AAAA,EACA,MAAM,OAAO,SAAS,SAAS,IAAI;AAAA,EACnC,MAAM,OAAO,SAAS;AAAA,EACtB,IAAI,SAAS,aAAa;AAAA,IACxB,WAAW,eAAe;AAAA,IAC1B,IAAI,GAAG,gBAAgB,IAAI,GAAG;AAAA,MAC5B,WAAW,SAAS,SAAS,KAAK,MAAM,WAAW,GAAG;AAAA,IACxD,EAAO,SAAI,GAAG,aAAa,IAAI,GAAG;AAAA,MAChC,WAAW,SAAS,kBAAkB,KAAK,MAAM,SAAS,GAAG;AAAA,IAC/D;AAAA,EACF,EAAO,SACL,SAAS,YACT,GAAG,gBAAgB,IAAI,KACvB,gBAAgB,KAAK,IAAI,GACzB;AAAA,IACA,WAAW,SAAS,KAAK;AAAA,EAC3B,EAAO,SAAI,SAAS,WAAW,GAAG,gBAAgB,IAAI,GAAG;AAAA,IACvD,WAAW,QAAQ,KAAK;AAAA,EAC1B;AAAA;AAGF,IAAM,iBAAiB,CACrB,QACA,SACA,QACkB;AAAA,EAClB,MAAM,aAA4B,EAAE,cAAc,OAAO,QAAQ,KAAK;AAAA,EACtE,WAAW,YAAY,OAAO,YAAY;AAAA,IACxC,wBAAwB,YAAY,UAAU,SAAS,GAAG;AAAA,EAC5D;AAAA,EACA,OAAO;AAAA;AAIT,IAAM,WAAW,CACf,KACA,OACA,YACA,OACA,YACA,aAC8B;AAAA,EAC9B,QAAQ,QAAQ,OAAO,WAAW;AAAA,EAElC,IAAI,UAAU,WAAW;AAAA,IACvB,IAAI,CAAC,QAAQ;AAAA,MACX,SAAS,KACP,oBAAoB,gHACtB;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,IAAI,CAAC,OAAO,WAAW;AAAA,MACrB,SAAS,KACP,oBAAoB,SAAS,4FAC/B;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,IAAI,WAAW,WAAW,CAAC,OAAO;AAAA,IAChC,SAAS,KACP,aAAa,uGACf;AAAA,EACF;AAAA,EAEA,IAAI,WAAW,UAAU,UAAU,CAAC,OAAO,WAAW;AAAA,IACpD,SAAS,KACP,aAAa,2GACf;AAAA,EACF;AAAA,EAEA,IAAI,CAAC,UAAU,QAAQ,WAAW;AAAA,IAChC,SAAS,KACP,aAAa,oBAAoB,gBAAgB,OAAO,yBAAyB,yGAAyG,qBAAqB,KAAK,UAAU,KAAK,wBACrO;AAAA,EACF;AAAA,EAEA,MAAM,aAAiC,EAAE,YAAY,KAAK,OAAO;AAAA,EACjE,IAAI,QAAQ;AAAA,IACV,WAAW,SAAS;AAAA,EACtB;AAAA,EACA,IAAI,OAAO;AAAA,IACT,WAAW,QAAQ;AAAA,EACrB;AAAA,EACA,OAAO;AAAA;AAGT,IAAM,iBAAiB,CACrB,OACA,OACA,SACA,KACA,aAC8B;AAAA,EAC9B,MAAM,gBACJ,UAAU,YAAY,YAAY;AAAA,EAEpC,IAAI,GAAG,8BAA8B,KAAK,GAAG;AAAA,IAC3C,MAAM,OAAO,MAAM,KAAK;AAAA,IACxB,OAAO,SACL,MACA,OACA;AAAA,MACE,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAAA,IAC9C,GACA,MACA,MACA,QACF;AAAA,EACF;AAAA,EAEA,IAAI,CAAC,GAAG,qBAAqB,KAAK,GAAG;AAAA,IACnC,OAAO;AAAA,EACT;AAAA,EACA,MAAM,MAAM,SAAS,MAAM,IAAI;AAAA,EAC/B,IAAI,CAAC,KAAK;AAAA,IACR,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,MAAM;AAAA,EAEpB,IAAI,GAAG,aAAa,KAAK,GAAG;AAAA,IAC1B,OAAO,SACL,KACA,OACA;AAAA,MACE,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,QAAQ,kBAAkB,MAAM,MAAM,SAAS,GAAG;AAAA,IACpD,GACA,MAAM,MACN,MACA,QACF;AAAA,EACF;AAAA,EACA,IAAI,GAAG,gBAAgB,KAAK,GAAG;AAAA,IAC7B,OAAO,SACL,KACA,OACA;AAAA,MACE,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,QAAQ,SAAS,MAAM,MAAM,WAAW,GAAG;AAAA,IAC7C,GACA,MAAM,MACN,OACA,QACF;AAAA,EACF;AAAA,EACA,IAAI,GAAG,0BAA0B,KAAK,GAAG;AAAA,IACvC,MAAM,aAAa,eAAe,OAAO,SAAS,GAAG;AAAA,IACrD,IAAI,CAAC,WAAW,cAAc;AAAA,MAC5B,SAAS,KACP,aAAa,sFACf;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,IAAI,CAAC,WAAW,QAAQ;AAAA,MACtB,SAAS,KACP,aAAa,0HACf;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,OAAO,SACL,KACA,OACA,KAAK,YAAY,QAAQ,WAAW,UAAU,cAAc,GAC5D,KACA,OACA,QACF;AAAA,EACF;AAAA,EAGA,OAAO,EAAE,YAAY,OAAO,KAAK,QAAQ,KAAK;AAAA;AAIhD,IAAM,wBAAwB,CAC5B,UACA,SACA,KACA,WACS;AAAA,EACT,IAAI,CAAC,GAAG,qBAAqB,QAAQ,GAAG;AAAA,IACtC;AAAA,EACF;AAAA,EACA,MAAM,OAAO,SAAS,SAAS,IAAI;AAAA,EACnC,IACE,EAAE,QAAQ,QAAQ,IAAI,MACtB,CAAC,GAAG,0BAA0B,SAAS,WAAW,GAClD;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW,SAAS,SAAS,YAAY,YAAY;AAAA,IACnD,MAAM,aAAa,eACjB,OACA,MACA,SACA,KACA,OAAO,QACT;AAAA,IACA,IAAI,YAAY;AAAA,MACd,OAAO,MAAM,KAAK,UAAU;AAAA,IAC9B;AAAA,EACF;AAAA;AAQK,IAAM,4BAA4B,CACvC,QACA,aAC8B;AAAA,EAC9B,MAAM,SAAS,cAAc;AAAA,EAC7B,MAAM,aAAa,GAAG,iBACpB,UACA,QACA,GAAG,aAAa,QAChB,MACA,SAAS,SAAS,KAAK,IAAI,GAAG,WAAW,MAAM,GAAG,WAAW,EAC/D;AAAA,EAEA,MAAM,SAAS,wBAAwB,UAAU;AAAA,EACjD,IAAI,CAAC,QAAQ;AAAA,IACX,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,eAAe,UAAU;AAAA,EACzC,MAAM,MAAM,SAAQ,QAAQ;AAAA,EAE5B,WAAW,YAAY,OAAO,YAAY;AAAA,IACxC,sBAAsB,UAAU,SAAS,KAAK,MAAM;AAAA,EACtD;AAAA,EAEA,OAAO;AAAA;;;ACreT,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,SAAS;AACf,IAAM,UAAU;AAGhB,IAAM,UAAU;AAChB,IAAM,QAAQ,IAAI,IAAI;AAAA,EACpB,CAAC,MAAM,KAAK,OAAO;AAAA,EACnB,CAAC,MAAM,EAAE;AAAA,EACT,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,MAAM,EAAE;AAAA,EACT,CAAC,KAAM,KAAK,UAAW,GAAG;AAAA,EAC1B,CAAC,MAAM,KAAK,UAAU,EAAE;AAAA,EACxB,CAAC,MAAO,KAAK,KAAM,EAAE;AAAA,EACrB,CAAC,MAAM,KAAK,EAAE;AAAA,EACd,CAAC,MAAM,CAAC;AACV,CAAC;AACD,IAAM,SACJ;AAGF,IAAM,cAAc,CAAC,UAAkD;AAAA,EACrE,MAAM,SAAS,UAAU,YAAY,YAAY,OAAO,KAAK,KAAK,GAAG;AAAA,EACrE,IAAI,CAAC,QAAQ;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAM,SAAS,KAAK,MAClB,OAAO,OAAO,MAAM,KAAK,MAAM,IAAI,OAAO,QAAQ,IAAI,KAAK,EAC7D;AAAA,EACA,OAAO,SAAS,IAAI,SAAS;AAAA;AAI/B,IAAM,YAAY,CAAC,MAAc,YAC/B,QAAQ,KAAK,IAAI,GAAG,QAAQ;AAG9B,IAAM,cAAc,CAAC,SAAuC;AAAA,EAC1D,MAAM,MAAM,UAAU,MAAM,OAAO;AAAA,EACnC,IAAI,QAAQ,WAAW;AAAA,IACrB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS,IAAI,MAAM,GAAG;AAAA,EAC5B,MAAM,QAAQ,YAAY,OAAO,EAAE;AAAA,EACnC,MAAM,SAAS,YAAY,OAAO,EAAE;AAAA,EACpC,OAAO,SAAS,SAAS,EAAE,QAAQ,MAAM,IAAI;AAAA;AAQxC,IAAM,gBAAgB,CAAC,QAAsC;AAAA,EAClE,MAAM,OAAO,KAAK,KAAK,GAAG,IAAI;AAAA,EAC9B,IAAI,SAAS,WAAW;AAAA,IACtB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,YAAY,UAAU,MAAM,KAAK,CAAC;AAAA,EAChD,MAAM,SAAS,YAAY,UAAU,MAAM,MAAM,CAAC;AAAA,EAClD,IAAI,SAAS,QAAQ;AAAA,IACnB,OAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AAAA,EACA,MAAM,MAAM,YAAY,IAAI;AAAA,EAC5B,IAAI,CAAC,KAAK;AAAA,IACR,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,IAAI,QAAQ,IAAI;AAAA,EAC9B,IAAI,OAAO;AAAA,IACT,MAAM,SAAS,KAAK,MAAM,QAAQ,KAAK;AAAA,IACvC,OAAO,SAAS,IAAI,EAAE,QAAQ,QAAQ,MAAM,IAAI;AAAA,EAClD;AAAA,EACA,IAAI,QAAQ;AAAA,IACV,MAAM,SAAS,KAAK,MAAM,SAAS,KAAK;AAAA,IACxC,OAAO,SAAS,IAAI,EAAE,QAAQ,OAAO,OAAO,IAAI;AAAA,EAClD;AAAA,EACA,OAAO;AAAA;;;AC/FT,uBAAS;AAET,oBAAS,kBAAS,kBAAM;AACxB;AAiCA,IAAM,aAAiC;AAAA,EACrC,YAAY,IAAG,IAAI;AAAA,EACnB,eAAe,MAAM,CAAC;AAAA,EACtB,UAAU,IAAG,IAAI;AAAA,EACjB,2BAA2B,IAAG,IAAI;AACpC;AAGA,IAAM,eAAe,CAAC,WACpB,OAAO,WAAW;AAGpB,IAAM,UAAU,CACd,KACA,OACA,YACiD;AAAA,EAEjD,OAAO,SAAS;AAAA,EAChB,IAAI,CAAC,aAAa,KAAK,GAAG;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,OAAO,IAAI,SAAS,IAAI,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI;AAAA,EACrD,MAAM,SAAS,MAAM,SAAS,IAAI,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AAAA,EAE3D,IAAI,SAAS,MAAM,SAAS,KAAK;AAAA,IAC/B,OAAO;AAAA,EACT;AAAA,EACA,OAAO,EAAE,MAAM,aAAa,SAAQ,SAAS,MAAM,EAAE;AAAA;AAQhD,IAAM,yBAAyB,CACpC,SAC2B;AAAA,EAC3B,MAAM,QAAQ,CAAC,iBAAiB,eAAe,EAC5C,IAAI,CAAC,SAAS,MAAK,MAAM,IAAI,CAAC,EAC9B,KAAK,CAAC,SAAS,YAAW,IAAI,CAAC;AAAA,EAClC,IAAI,CAAC,OAAO;AAAA,IACV,OAAO,CAAC;AAAA,EACV;AAAA,EACA,QAAQ,QAAQ,UAAU,IAAG,eAAe,OAAO,IAAG,IAAI,QAAQ;AAAA,EAClE,IAAI,OAAO;AAAA,IAET,OAAO,CAAC;AAAA,EACV;AAAA,EACA,MAAM,YAAY,SAAQ,KAAK;AAAA,EAG/B,QAAQ,YAAY,IAAG,2BACrB,QACA,YACA,WACA,WACA,KACF;AAAA,EACA,QAAQ,UAAU;AAAA,EAClB,IAAI,CAAC,OAAO;AAAA,IACV,OAAO,CAAC;AAAA,EACV;AAAA,EAGA,QAAQ,kBAAkB;AAAA,EAE1B,MAAM,UAAU,QAAQ,WAAW,iBAAiB;AAAA,EACpD,MAAM,UAA8B,CAAC;AAAA,EACrC,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IAChD,MAAM,QAAQ,QAAQ,KAAK,OAAO,OAAO;AAAA,IACzC,IAAI,OAAO;AAAA,MACT,QAAQ,KAAK,CAAC,MAAM,MAAM,MAAM,WAAW,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EACA,OAAO,OAAO,YAAY,OAAO;AAAA;;;ACnGnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDA,IAAM,iBAAgC;AAAA,EACpC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,GAAG;AAAA,EACH,OAAO;AAAA,EACP,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AACP;AA6CO,IAAM,mBAAmB,CAAC,aAC/B,eAAe,SAAS,YAAY,IAAI,QAAQ;AAKlD,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAMf,IAAM,sBAAsB,CAAC,aAA+B;AAAA,EACjE,MAAM,QAAQ,IAAI;AAAA,EAClB,WAAW,WAAW,CAAC,gBAAgB,aAAa,GAAG;AAAA,IACrD,WAAW,SAAS,SAAS,SAAS,OAAO,GAAG;AAAA,MAC9C,MAAM,OAAO,iBAAiB,MAAM,QAAQ,QAAQ,EAAE;AAAA,MACtD,IAAI,MAAM;AAAA,QACR,MAAM,IAAI,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO,CAAC,GAAG,KAAK,EAAE,SAAS;AAAA;AAG7B,IAAM,aAAa,CAAC,SAClB,OAAO,OAAO,cAAc,EAAE,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI;AAGjE,IAAM,UAAU,CAAC,SACf,2BAA2B,mBAAmB,wEAAwE,eAAe;AAQhI,IAAM,kBAAkB,CAAC,UAC9B,MACG,IAAI,CAAC,SAAS;AAAA,EACb,MAAM,OAAO,WAAW,IAAI;AAAA,EAC5B,IAAI,CAAC,MAAM;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,MAAM,OAAO,QAAQ,KAAK,IAAI;AAAA,EAC9B,OAAO,iDAAiD;AAAA;AAAA,wBAEtC;AAAA,gBACR;AAAA;AAAA,CAEX,EACA,OAAO,CAAC,SAAS,SAAS,EAAE,EAC5B,KAAK;AAAA,CAAI;;;ACxMd,IAAM,gBAAgB;AAGf,IAAM,kBAAkB,CAAC,SAC9B,cAAc,KAAK,IAAI;;;ACjBzB,uBAAS;AAET,uBAAS,qBAAY;AAiBrB,IAAM,eAAe,CAAC,KAAK,GAAG;AAG9B,IAAM,cAAc,CAAC,MAAc,QACjC,YAAW,GAAG,IAAI,MAAM,MAAK,MAAM,GAAG;AAGxC,IAAM,kBAAkB,CACtB,WACqB,OAAO,WAAW;AAGzC,IAAM,gBAAgB,CAAC,WACrB,OAAO,WAAW;AAGpB,IAAM,aAAa,CAAC,UAClB,OAAO,UAAU;AAGnB,IAAM,gBAAgB,CAAC,SACrB,OAAO,SAAS,aAAY,SAAS;AAOvC,IAAM,gBAAgB,CACpB,YACkC;AAAA,EAClC,MAAM,UAAU,QAAQ,OAAO,eAAe;AAAA,EAC9C,MAAM,OAAO,QAAQ,OAAO,CAAC,WAAW,aAAa,SAAS,MAAM,CAAC;AAAA,EACrE,IAAI,KAAK,SAAS,GAAG;AAAA,IACnB,OAAO;AAAA,EACT;AAAA,EACA,IAAI,QAAQ,SAAS,GAAG;AAAA,IACtB,OAAO;AAAA,EACT;AAAA,EACA,OAAO,SAAS;AAAA,EAChB,OAAO,QAAQ,WAAW,KAAK,cAAc,KAAK,IAAI,QAAQ;AAAA;AAGhE,IAAM,eAAe,CAAC,MAAc,YAAyC;AAAA,EAC3E,MAAM,SAAS,cAAc,OAAO;AAAA,EACpC,OAAO,WAAW,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,OAAO;AAAA;AAI1D,IAAM,eAAe,CAAC,MAAuB,SAC3C,KAAK,SAAS,IAAI,CAAC,YAAY;AAAA,EAC7B,MAAM,QAAqB;AAAA,IACzB,MAAM,KAAK;AAAA,IACX,KAAK,YAAY,MAAM,QAAQ,GAAG;AAAA,EACpC;AAAA,EACA,MAAM,aAA0B,gBAAgB,QAAQ,MAAM,IAC1D,KAAK,OAAO,QAAQ,QAAQ,OAAO,IACnC;AAAA,EAEJ,OAAO,QAAQ,UAAU,YAAY,QAAQ,UAAU,WACnD,KAAK,YAAY,OAAO,QAAQ,MAAM,IACtC;AAAA,CACL;AAOH,IAAM,YAAY,CAAC,OAAkB,SAAkC;AAAA,EACrE,IAAI,WAAW,KAAK,GAAG;AAAA,IACrB,IAAI,CAAC,WAAW,KAAK,GAAG;AAAA,MACtB,OAAO;AAAA,IACT;AAAA,IACA,MAAM,MAAM,aAAa;AAAA,IACzB,OAAO,CAAC,aAAa,IAAI,QAAQ,IAAI,OAAO,CAAC;AAAA,EAC/C;AAAA,EACA,IAAI,cAAc,OAAO;AAAA,IACvB,OAAO,aAAa,OAAO,IAAI;AAAA,EACjC;AAAA,EACA,KAAK,MAAM,YAAY,cAAc,UAAU;AAAA,IAC7C,OAAO;AAAA,EACT;AAAA,EACA,OAAO,CAAC,aAAa,MAAM,MAAM,MAAM,WAAW,YAAY,CAAC;AAAA;AAIjE,IAAM,aAAa,CAAC,UAAoC;AAAA,EACtD,IAAI,WAAW,KAAK,GAAG;AAAA,IACrB,OAAO,WAAW,KAAK,IAAI,aAAa,OAAO,SAAS;AAAA,EAC1D;AAAA,EACA,OAAO,MAAM;AAAA;AAQR,IAAM,gBAAgB,CAC3B,OACA,SACmB;AAAA,EACnB,MAAM,UAAoB,CAAC;AAAA,EAC3B,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,WAA2B,CAAC;AAAA,EAElC,MAAM,QAAQ;AAAA,IACZ,CAAC,SAAS,OAAO,OAAO;AAAA,IACxB,CAAC,QAAQ,OAAO,IAAI;AAAA,EACtB;AAAA,EACA,YAAY,MAAM,UAAU,OAAO;AAAA,IACjC,IAAI,UAAU,WAAW;AAAA,MACvB;AAAA,IACF;AAAA,IACA,MAAM,cAAc,UAAU,OAAO,IAAI;AAAA,IACzC,IAAI,CAAC,aAAa;AAAA,MAChB;AAAA,IACF;AAAA,IACA,SAAS,QAAQ,WAAW,KAAK,KAAK;AAAA,IACtC,WAAW,SAAS,aAAa;AAAA,MAC/B,MAAM,MAAM,KAAK,UAAU,KAAK;AAAA,MAChC,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAAA,QAClB,KAAK,IAAI,GAAG;AAAA,QACZ,QAAQ,KAAK,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAyB,EAAE,OAAO,QAAQ;AAAA,EAChD,IAAI,SAAS,SAAS,SAAS,MAAM;AAAA,IACnC,OAAO,WAAW;AAAA,EACpB;AAAA,EACA,OAAO;AAAA;AAIF,IAAM,uBAAuB,CAAC,OAAiB,SACpD,MAAM,IAAI,CAAC,SACT,cAAc,IAAI,IAAI,KAAK,MAAM,KAAK,YAAY,MAAM,KAAK,GAAG,EAAE,IAAI,IACxE;AAQK,IAAM,iBAAiB,CAC5B,SAOA,SACmB;AAAA,EACnB,IAAI,QAAQ,SAAS;AAAA,IACnB,OAAO,EAAE,OAAO,qBAAqB,QAAQ,SAAS,IAAI,EAAE;AAAA,EAC9D;AAAA,EACA,OAAO,QAAQ,uBACX,cAAc,QAAQ,YAAY,IAAI,IACtC,EAAE,OAAO,CAAC,EAAE;AAAA;AAQX,IAAM,mBAAmB,CAC9B,SACA,SACa;AAAA,EACb,MAAM,UAAoB,CAAC;AAAA,EAC3B,WAAW,SAAS,OAAO,OAAO,QAAQ,cAAc,CAAC,CAAC,GAAG;AAAA,IAC3D,IAAI,CAAC,WAAW,KAAK,KAAK,cAAc,OAAO;AAAA,MAC7C,QAAQ,KACN,GAAG,MAAM,SAAS,IAAI,CAAC,YAAY,YAAY,MAAM,QAAQ,GAAG,CAAC,CACnE;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW,QAAQ,QAAQ,SAAS;AAAA,IAClC,IAAI,cAAc,IAAI,GAAG;AAAA,MACvB,QAAQ,KAAK,YAAY,MAAM,KAAK,GAAG,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EACA,OAAO,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,YAAW,IAAI,CAAC;AAAA;;;ACtNjE,uBAAS;AAET,iBAAS;AAKF,IAAM,gBAAgB,CAC3B,SACA,WACuB;AAAA,EACvB,IAAI,CAAC,QAAQ,YAAY,EAAE,SAAS,MAAM,GAAG;AAAA,IAC3C;AAAA,EACF;AAAA,EACA,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;AAAA,EAC1C,MAAM,OAAO;AAAA,IACX,MAAK,QAAQ,QAAQ,MAAM,UAAU,QAAQ;AAAA,IAC7C,MAAK,QAAQ,QAAQ,MAAM,QAAQ;AAAA,EACrC,EAAE,KAAK,CAAC,SAAS,YAAW,IAAI,CAAC;AAAA,EACjC,OAAO,OAAO,aAAa,MAAM,OAAO,IAAI;AAAA;;;ACnB9C,qBAAS;AAET,uBAAS,qBAAY;;;ACArB,IAAM,kBAAkB;AAOjB,IAAM,UAAU;AAAA,EACrB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AACR;AAQO,IAAM,iBAAiB,CAAC,UAC7B,OAAO,OAAO,SAAS,KAAK;AAK9B,IAAM,YAAY;AAGlB,IAAM,YAAY,CAAC,OAAe,aAChC,UAAU,KAAK,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,IAAI;AAGhD,IAAM,gBAAgB,CAAC,UACrB,eAAe,KAAK,IAAI,QAAQ,SAAS,UAAU,OAAO,eAAe;AAG3E,IAAM,kBAAkB,CAAC,UACvB,SAAS,UAAU,KAAK,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,IAAI;AAEzD,IAAM,QAAQ;AAAA,EACZ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AACN;AAEA,IAAM,YAAY,CAAC,UAA0B,KAAK,UAAU,KAAK;AAEjE,IAAM,qBAAqB,CAAC,UAC1B,OAAO,UAAU,KAAK;AAExB,IAAM,WAAW,CAAC,MAAc,UAC9B,QAAQ,CAAC,KAAK,SAAS,QAAQ,IAAI,CAAC;AAEtC,IAAM,eAAe,CACnB,OACA,YAMA;AAAA,EACE,qBAAqB,QAAQ;AAAA,EAC7B,GAAG,SAAS,kBAAkB,QAAQ,MAAM;AAAA,EAC5C,GAAG,SACD,6BACA,QAAQ,SAAS,iBAAiB,IACpC;AAAA,EACA,GAAG,SAAS,sBAAsB,gBAAgB,MAAM,YAAY,KAAK,CAAC;AAAA,EAC1E,GAAG,SACD,4BACA,MAAM,iBAAiB,QACnB,mBAAmB,MAAM,gBAAgB,KAAK,IAC9C,IACN;AAAA,EACA,qBAAqB,QAAQ;AAC/B,EACG,OAAO,OAAO,EACd,KAAK;AAAA,CAAI;AAEd,IAAM,eAAe,CACnB,OACA,YAIW;AAAA,EAKX,MAAM,SAAS;AAAA,IACb,qBAAqB,QAAQ;AAAA,IAC7B;AAAA,IACA,GAAG,SAAS,kBAAkB,QAAQ,MAAM;AAAA,IAC5C,GAAG,SACD,6BACA,QAAQ,SAAS,iBAAiB,IACpC;AAAA,IACA,GAAG,SAAS,sBAAsB,gBAAgB,MAAM,YAAY,IAAI,CAAC;AAAA,IACzE,GAAG,SACD,4BACA,MAAM,iBAAiB,OACnB,mBAAmB,MAAM,gBAAgB,IAAI,IAC7C,IACN;AAAA,EACF,EAAE,OAAO,OAAO;AAAA,EAChB,OAAO;AAAA,EACP,OAAO,KAAK;AAAA,CAAI;AAAA;AAAA;AAAA;AAkBX,IAAM,gBAAgB,CAC3B,WACkB;AAAA,EAClB,MAAM,cAAc,MAAM,OAAO,IAAI;AAAA,EACrC,OAAO,cAAc,MAAM,OAAO,KAAK;AACzC;AAGO,IAAM,gBAAgB,CAAC,UAC5B,MAAM,MAAM;AAOP,IAAM,gBAAgB,CAAC,UAA2C;AAAA,EACvE,MAAM,SAAS,cAAc,KAAK;AAAA,EAClC,MAAM,SAAS,MAAM,SAAS,cAAc,MAAM,MAAM,IAAI;AAAA,EAC5D,MAAM,SAAS,MAAM,MAAM;AAAA,EAC3B,MAAM,OAAO,aAAa,OAAO;AAAA,IAC/B,QAAQ,OAAO;AAAA,IACf;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACD,MAAM,OAAO,aAAa,OAAO;AAAA,IAC/B,QAAQ,OAAO;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EAED,OAAO;AAAA;AAAA,EAEP;AAAA;AAAA,EAEA;AAAA;;;AD7IF,IAAM,WAAW;AAGjB,IAAM,oBAAoB,CAAC,UAA0B;AAAA,EACnD,MAAM,WAAW,SAAS,OAAO,GAAG;AAAA,EACpC,OAAO,GAAG,aAAa,KAAK,UAAU;AAAA;AAcxC,IAAM,qBAAqB,CAAC,QAAwB,aAAsB;AAAA,EACxE,IAAI,UAAU;AAAA,IACZ,OAAO,EAAE,OAAO,SAAS;AAAA,EAC3B;AAAA,EACA,MAAM,SAAS,cAAc,OAAO,KAAK;AAAA,EACzC,MAAM,SAAS,cAAc,OAAO,KAAK;AAAA,EACzC,OAAO;AAAA,IACL,WAAW,sDAAsD,OAAO,yBAAyB,4CAA4C,OAAO;AAAA,EACtJ;AAAA;AAIF,IAAM,oBAAoB,OACxB,MACA,SAII;AAAA,EACJ,IAAI,SAAS,KAAK,IAAI,GAAG;AAAA,IACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE;AAAA,EACjC;AAAA,EAGA,MAAM,WAAW,YAAW,IAAI,IAAI,OAAO,MAAK,MAAM,IAAI;AAAA,EAC1D,IAAI;AAAA,IACF,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,UAAS,UAAU,OAAO,EAAE,EAAE;AAAA,IAChE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,QAAQ,EAAE,KAAK,KAAK;AAAA,MACpB,SAAS,kCAAkC,oBAAoB;AAAA,IACjE;AAAA;AAAA;AAQJ,IAAM,wBAAwB,CAC5B,KACA,MACA,eACA,aAC2B;AAAA,EAC3B,IAAI,IAAI,aAAa,UAAU;AAAA,IAC7B,OAAO;AAAA,EACT;AAAA,EACA,IAAI,KAAK,IAAI,IAAI,KAAK,GAAG;AAAA,IACvB,SAAS,KACP,wCAAwC,IAAI,2BAC9C;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EACA,IAAI,cAAc,IAAI,IAAI,KAAK,GAAG;AAAA,IAChC,SAAS,KACP,uBAAuB,IAAI,mEAC7B;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EACA,KAAK,IAAI,IAAI,KAAK;AAAA,EAClB,OAAO;AAAA;AASF,IAAM,sBAAsB,OAAO,YAIqB;AAAA,EAC7D,QAAQ,QAAQ,MAAM,kBAAkB;AAAA,EACxC,MAAM,WAAqB,CAAC;AAAA,EAG5B,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,WAA8B,CAAC;AAAA,EACrC,WAAW,OAAO,kBAAkB,MAAM,GAAG;AAAA,IAC3C,MAAM,OAAO,sBAAsB,KAAK,MAAM,eAAe,QAAQ;AAAA,IACrE,IAAI,MAAM;AAAA,MACR,SAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,MAAM,QAAQ,IAC1B,SAAS,IAAI,OAAO,SAAS;AAAA,IAC3B;AAAA,IACA,MAAM,MAAM,kBAAkB,IAAI,MAAM,IAAI;AAAA,EAC9C,EAAE,CACJ;AAAA,EAEA,MAAM,QAAyB,CAAC;AAAA,EAChC,aAAa,KAAK,UAAU,OAAO;AAAA,IACjC,IAAI,KAAK,SAAS;AAAA,MAChB,SAAS,KAAK,KAAK,OAAO;AAAA,IAC5B;AAAA,IACA,MAAM,WAAW,kBAAkB,IAAI,KAAK;AAAA,IAC5C,MAAM,KAAK;AAAA,MACT,SAAS,wBAAwB;AAAA,QAC/B,eAAe;AAAA,aACV,KAAK;AAAA,aACL,mBAAmB,QAAQ,IAAI,KAAK;AAAA,aAIpC,IAAI;AAAA,QACT;AAAA,QACA,SAAS,IAAI;AAAA,QACb,OAAO,IAAI;AAAA,QACX,OAAO,IAAI;AAAA,MACb,CAAC;AAAA,MACD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,EAAE,OAAO,SAAS;AAAA;;;AE5IpB,IAAM,uBAAuB,CAClC,SACA,aAEA,QAAQ,IAAI,GAAG,MAAM,MAAM,YAAY;AAAA,EACrC,MAAM,OAA0B;AAAA,IAC9B;AAAA,IACA,OAAO,aAAa,UAAU,IAAI;AAAA,EACpC;AAAA,EACA,IAAI,MAAM;AAAA,IACR,KAAK,OAAO;AAAA,EACd;AAAA,EACA,OAAO;AAAA,CACR;;;AC9BI,IAAM,yBAAyB;;;ACCtC,IAAM,wBAAwB;AAmB9B,IAAM,eAAe;AAAA;AAIrB,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAa9B,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6FvB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBf,IAAM,wBAAwB,CAAC,YACpC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,QAAQ,IAAI,CAAC,WAAW,YAAY,UAAU,EAAE,KAAK;AAAA,CAAI;AAAA;AAAA,EAEjE;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAwPW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgGX,QAAQ,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBA8BJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAcE,+BAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAiHvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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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",
|
|
38
|
+
"debugId": "851B0C91E17092DD64756E2164756E21",
|
|
39
39
|
"names": []
|
|
40
40
|
}
|