export declare const mermaidTemplate = "import \"server-only\";\nimport { renderMermaidSVG } from \"beautiful-mermaid\";\n\nconst DIAGRAM_OPTIONS = {\n bg: \"var(--mermaid-bg)\",\n fg: \"var(--mermaid-fg)\",\n line: \"var(--mermaid-line)\",\n accent: \"var(--mermaid-accent)\",\n muted: \"var(--mermaid-muted)\",\n surface: \"var(--mermaid-surface)\",\n border: \"var(--mermaid-border)\",\n transparent: true,\n};\n\nexport type MermaidResult =\n | { ok: true; svg: string; width: number | null }\n | { ok: false; error: string };\n\nfunction parseColor(value: string): [number, number, number] | null {\n const hex = /^#([0-9a-f]{3,8})$/i.exec(value.trim());\n if (hex) {\n let channels = hex[1];\n if (channels.length === 3 || channels.length === 4) {\n channels = channels\n .slice(0, 3)\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n }\n if (channels.length !== 6 && channels.length !== 8) return null;\n return [\n Number.parseInt(channels.slice(0, 2), 16),\n Number.parseInt(channels.slice(2, 4), 16),\n Number.parseInt(channels.slice(4, 6), 16),\n ];\n }\n const rgb = /^rgba?\\(\\s*(\\d+)[\\s,]+(\\d+)[\\s,]+(\\d+)/i.exec(value.trim());\n if (rgb) return [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])];\n return null;\n}\n\n// beautiful-mermaid labels nodes with the theme foreground (white in dark\n// mode) even when the diagram sets an explicit fill via classDef/style, which\n// leaves white text on light colored boxes. The SVG renders once and is shared\n// by both modes, so bake a literal contrast color into the labels of nodes\n// whose shape has a literal fill.\nfunction contrastNodeLabels(svg: string): string {\n return svg.replace(/]*>[\\s\\S]*?<\\/g>/g, (group) => {\n const shapeFill = /fill=\"([^\"]*)\"/.exec(group)?.[1] ?? \"\";\n if (shapeFill.startsWith(\"var(\") || shapeFill === \"none\") return group;\n const rgb = parseColor(shapeFill);\n // YIQ perceived brightness. Unparseable literals (named colors) default\n // to black text \u2014 classDef fills are overwhelmingly light pastels.\n const yiq = rgb ? (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000 : 255;\n const label = yiq >= 128 ? \"#000000\" : \"#ffffff\";\n return group.replace(\n /(]*fill=\")var\\(--_text\\)(\")/g,\n \"$1\" + label + \"$2\",\n );\n });\n}\n\nfunction normalizeSvg(svg: string): {\n ok: true;\n svg: string;\n width: number | null;\n} {\n const openTag = /^]*>/.exec(svg);\n if (!openTag) return { ok: true, svg, width: null };\n\n const widthMatch = /\\swidth=\"([\\d.]+)\"/.exec(openTag[0]);\n const width = widthMatch ? Number.parseFloat(widthMatch[1]) : null;\n\n const stripped = openTag[0].replace(/\\s(?:width|height)=\"[^\"]*\"/g, \"\");\n return {\n ok: true,\n svg: stripped + svg.slice(openTag[0].length),\n width: width !== null && Number.isFinite(width) ? width : null,\n };\n}\n\nexport function renderDiagram(code: string): MermaidResult {\n try {\n return normalizeSvg(\n contrastNodeLabels(renderMermaidSVG(code, DIAGRAM_OPTIONS)),\n );\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n";