@diagrammo/dgmo 0.2.18 → 0.2.20

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fonts.ts","../src/colors.ts","../src/palettes/registry.ts","../src/palettes/color-utils.ts","../src/palettes/nord.ts","../src/palettes/solarized.ts","../src/palettes/catppuccin.ts","../src/palettes/rose-pine.ts","../src/palettes/gruvbox.ts","../src/palettes/tokyo-night.ts","../src/palettes/one-dark.ts","../src/palettes/bold.ts","../src/palettes/mermaid-bridge.ts","../src/palettes/index.ts","../src/sequence/participant-inference.ts","../src/sequence/parser.ts","../src/graph/flowchart-parser.ts","../src/class/parser.ts","../src/er/parser.ts","../src/dgmo-router.ts","../src/org/parser.ts","../src/org/layout.ts","../src/org/collapse.ts","../src/org/renderer.ts","../src/class/layout.ts","../src/class/renderer.ts","../src/er/layout.ts","../src/er/renderer.ts","../src/graph/layout.ts","../src/graph/flowchart-renderer.ts","../src/sequence/renderer.ts","../src/index.ts","../src/d3.ts","../src/branding.ts","../src/echarts.ts","../src/chart.ts","../src/render.ts","../src/dgmo-mermaid.ts","../src/sharing.ts"],"sourcesContent":["export const FONT_FAMILY = 'Inter, system-ui, Avenir, Helvetica, Arial, sans-serif';\nexport const DEFAULT_FONT_NAME = 'Helvetica';\n","// ============================================================\n// Shared Nord Color Palette\n// ============================================================\n\n/** Complete 16-entry Nord palette. */\nexport const nord = {\n // Polar Night (dark)\n nord0: '#2e3440',\n nord1: '#3b4252',\n nord2: '#434c5e',\n nord3: '#4c566a',\n // Snow Storm (light)\n nord4: '#d8dee9',\n nord5: '#e5e9f0',\n nord6: '#eceff4',\n // Frost (accent blues)\n nord7: '#8fbcbb',\n nord8: '#88c0d0',\n nord9: '#81a1c1',\n nord10: '#5e81ac',\n // Aurora (colors)\n nord11: '#bf616a', // red\n nord12: '#d08770', // orange\n nord13: '#ebcb8b', // yellow\n nord14: '#a3be8c', // green\n nord15: '#b48ead', // purple\n};\n\n/** Color name → Nord hex for inline `(color)` annotations. */\nexport const colorNames: Record<string, string> = {\n red: nord.nord11,\n orange: nord.nord12,\n yellow: nord.nord13,\n green: nord.nord14,\n blue: nord.nord10,\n purple: nord.nord15,\n teal: nord.nord7,\n cyan: nord.nord8,\n lightblue: nord.nord8,\n gray: nord.nord3,\n};\n\n/**\n * Resolves a color name or hex code to a valid CSS color.\n * When a palette is provided, named colors resolve against its color map first.\n * Hex codes (e.g. \"#ff0000\") are passed through regardless of palette (FR8).\n * Unknown names are returned as-is.\n */\nexport function resolveColor(\n color: string,\n palette?: { colors: Record<string, string> }\n): string {\n const lower = color.toLowerCase();\n if (lower.startsWith('#')) return lower;\n\n if (palette) {\n const named = palette.colors[lower];\n if (named) return named;\n }\n\n if (colorNames[lower]) return colorNames[lower];\n return color;\n}\n\n/** @deprecated Use getSeriesColors(palette) from '@/lib/palettes' instead. */\nexport const seriesColors = [\n nord.nord10, // blue\n nord.nord14, // green\n nord.nord13, // yellow\n nord.nord12, // orange\n nord.nord15, // purple\n nord.nord11, // red\n nord.nord7, // teal\n nord.nord8, // light blue\n];\n","import type { PaletteConfig, PaletteColors } from './types';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst PALETTE_REGISTRY = new Map<string, PaletteConfig>();\nconst DEFAULT_PALETTE_ID = 'nord';\n\n// ============================================================\n// Validation\n// ============================================================\n\n/** Validate that a hex string is well-formed (#RGB or #RRGGBB). */\nexport function isValidHex(value: string): boolean {\n return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);\n}\n\n/** Named color keys that must be present in PaletteColors.colors. */\nconst COLOR_KEYS: (keyof PaletteColors['colors'])[] = [\n 'red',\n 'orange',\n 'yellow',\n 'green',\n 'blue',\n 'purple',\n 'teal',\n 'cyan',\n 'gray',\n];\n\n/** Semantic color keys that must be present at the top level of PaletteColors. */\nconst SEMANTIC_KEYS: (keyof Omit<PaletteColors, 'colors'>)[] = [\n 'bg',\n 'surface',\n 'overlay',\n 'border',\n 'text',\n 'textMuted',\n 'primary',\n 'secondary',\n 'accent',\n 'destructive',\n];\n\nfunction validatePaletteColors(\n colors: PaletteColors,\n mode: string,\n paletteId: string\n): void {\n for (const key of SEMANTIC_KEYS) {\n const value = colors[key];\n if (typeof value !== 'string' || !isValidHex(value)) {\n throw new Error(\n `Palette \"${paletteId}\" ${mode}.${key}: invalid hex \"${value}\"`\n );\n }\n }\n for (const key of COLOR_KEYS) {\n const value = colors.colors[key];\n if (typeof value !== 'string' || !isValidHex(value)) {\n throw new Error(\n `Palette \"${paletteId}\" ${mode}.colors.${key}: invalid hex \"${value}\"`\n );\n }\n }\n}\n\n// ============================================================\n// Registry Functions\n// ============================================================\n\n/**\n * Register a palette. Called at module initialization.\n * Validates that all 19 color fields per mode are present and valid hex.\n * Throws on malformed palettes to catch errors at startup, not at render time.\n */\nexport function registerPalette(palette: PaletteConfig): void {\n validatePaletteColors(palette.light, 'light', palette.id);\n validatePaletteColors(palette.dark, 'dark', palette.id);\n PALETTE_REGISTRY.set(palette.id, palette);\n}\n\n/** Get palette by id. Returns Nord if id is unrecognized (FR10). */\nexport function getPalette(id: string): PaletteConfig {\n return PALETTE_REGISTRY.get(id) ?? PALETTE_REGISTRY.get(DEFAULT_PALETTE_ID)!;\n}\n\n/** List all registered palettes (for the selector UI). */\nexport function getAvailablePalettes(): PaletteConfig[] {\n return Array.from(PALETTE_REGISTRY.values());\n}\n","import type { PaletteColors } from './types';\n\n// ============================================================\n// HSL Conversion\n// ============================================================\n\n/** Convert hex (#RRGGBB or #RGB) to { h, s, l } with h in degrees, s/l as percentages. */\nexport function hexToHSL(hex: string): { h: number; s: number; l: number } {\n const raw = hex.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n\n const r = parseInt(full.substring(0, 2), 16) / 255;\n const g = parseInt(full.substring(2, 4), 16) / 255;\n const b = parseInt(full.substring(4, 6), 16) / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l: Math.round(l * 100) };\n }\n\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n let h: number;\n if (max === r) {\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n } else if (max === g) {\n h = ((b - r) / d + 2) / 6;\n } else {\n h = ((r - g) / d + 4) / 6;\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/** Convert { h (degrees), s (%), l (%) } back to #RRGGBB hex string. */\nexport function hslToHex(h: number, s: number, l: number): string {\n const sNorm = s / 100;\n const lNorm = l / 100;\n\n if (sNorm === 0) {\n const v = Math.round(lNorm * 255);\n return `#${v.toString(16).padStart(2, '0')}${v.toString(16).padStart(2, '0')}${v.toString(16).padStart(2, '0')}`;\n }\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n let tNorm = t;\n if (tNorm < 0) tNorm += 1;\n if (tNorm > 1) tNorm -= 1;\n if (tNorm < 1 / 6) return p + (q - p) * 6 * tNorm;\n if (tNorm < 1 / 2) return q;\n if (tNorm < 2 / 3) return p + (q - p) * (2 / 3 - tNorm) * 6;\n return p;\n };\n\n const q = lNorm < 0.5 ? lNorm * (1 + sNorm) : lNorm + sNorm - lNorm * sNorm;\n const p = 2 * lNorm - q;\n const hNorm = h / 360;\n\n const r = Math.round(hue2rgb(p, q, hNorm + 1 / 3) * 255);\n const g = Math.round(hue2rgb(p, q, hNorm) * 255);\n const b = Math.round(hue2rgb(p, q, hNorm - 1 / 3) * 255);\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/** Convert hex to \"H S% L%\" string for CSS custom properties. */\nexport function hexToHSLString(hex: string): string {\n const { h, s, l } = hexToHSL(hex);\n return `${h} ${s}% ${l}%`;\n}\n\n// ============================================================\n// Color Manipulation\n// ============================================================\n\n/**\n * Derive a muted (desaturated, darkened) variant of a color.\n * Used by the Mermaid theme generator for dark-mode fills.\n *\n * Algorithm: cap saturation at 35% and lightness at 36%.\n */\nexport function mute(hex: string): string {\n const { h, s, l } = hexToHSL(hex);\n return hslToHex(h, Math.min(s, 35), Math.min(l, 36));\n}\n\n/**\n * Blend a color toward white (light mode quadrant fills).\n * amount: 0 = original, 1 = white\n */\nexport function tint(hex: string, amount: number): string {\n const raw = hex.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n\n const r = parseInt(full.substring(0, 2), 16);\n const g = parseInt(full.substring(2, 4), 16);\n const b = parseInt(full.substring(4, 6), 16);\n\n const tr = Math.round(r + (255 - r) * amount);\n const tg = Math.round(g + (255 - g) * amount);\n const tb = Math.round(b + (255 - b) * amount);\n\n return `#${tr.toString(16).padStart(2, '0')}${tg.toString(16).padStart(2, '0')}${tb.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Blend a color toward a dark base (dark mode quadrant fills).\n * amount: 0 = original, 1 = base\n */\nexport function shade(hex: string, base: string, amount: number): string {\n const parse = (h: string): [number, number, number] => {\n const raw = h.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n return [\n parseInt(full.substring(0, 2), 16),\n parseInt(full.substring(2, 4), 16),\n parseInt(full.substring(4, 6), 16),\n ];\n };\n\n const [r, g, b] = parse(hex);\n const [br, bg, bb] = parse(base);\n\n const sr = Math.round(r + (br - r) * amount);\n const sg = Math.round(g + (bg - g) * amount);\n const sb = Math.round(b + (bb - b) * amount);\n\n return `#${sr.toString(16).padStart(2, '0')}${sg.toString(16).padStart(2, '0')}${sb.toString(16).padStart(2, '0')}`;\n}\n\n// ============================================================\n// Contrast / Accessibility\n// ============================================================\n\n/** WCAG 2.1 relative luminance (0 = black, 1 = white). */\nexport function relativeLuminance(hex: string): number {\n const raw = hex.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n\n const srgb = [\n parseInt(full.substring(0, 2), 16) / 255,\n parseInt(full.substring(2, 4), 16) / 255,\n parseInt(full.substring(4, 6), 16) / 255,\n ].map((c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4));\n\n return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];\n}\n\n/**\n * Pick a text color that contrasts against `bg`.\n * Returns `darkText` when background is light (luminance > 0.179),\n * `lightText` when background is dark.\n * Threshold 0.179 is the standard WCAG midpoint for the contrast flip.\n */\nexport function contrastText(\n bg: string,\n lightText: string,\n darkText: string\n): string {\n return relativeLuminance(bg) > 0.179 ? darkText : lightText;\n}\n\n// ============================================================\n// Series Colors\n// ============================================================\n\n/** Derive the 8-color series rotation from a palette's named colors. */\nexport function getSeriesColors(palette: PaletteColors): string[] {\n const c = palette.colors;\n return [c.blue, c.green, c.yellow, c.orange, c.purple, c.red, c.teal, c.cyan];\n}\n\n/**\n * Generate `count` visually distinct colors for segment-based charts\n * (pie, doughnut, polar-area).\n *\n * Problem: several palettes have duplicate hex values for different named\n * colors (e.g. Solarized teal===cyan, One Dark orange===yellow), and the\n * 8-color modulo cycle repeats when there are more than 8 segments.\n *\n * Solution: generate evenly-spaced hues using the palette's characteristic\n * saturation and lightness, guaranteeing every segment gets a unique,\n * perceptually distinct color regardless of segment count.\n */\nexport function getSegmentColors(palette: PaletteColors, count: number): string[] {\n const base = getSeriesColors(palette);\n const unique = [...new Set(base)];\n const hsls = unique.map(hexToHSL);\n\n const avgS = Math.round(hsls.reduce((s, c) => s + c.s, 0) / hsls.length);\n const avgL = Math.round(hsls.reduce((s, c) => s + c.l, 0) / hsls.length);\n\n // Start from the palette's blue hue (first in series) for consistency\n const startHue = hsls[0].h;\n const step = 360 / count;\n\n return Array.from({ length: count }, (_, i) =>\n hslToHex(Math.round((startHue + i * step) % 360), avgS, avgL)\n );\n}\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Nord Palette Definition\n// ============================================================\n\nexport const nordPalette: PaletteConfig = {\n id: 'nord',\n name: 'Nord',\n light: {\n bg: '#eceff4', // nord6\n surface: '#e5e9f0', // nord5\n overlay: '#d8dee9', // nord4 (muted/secondary backgrounds)\n border: '#d8dee9', // nord4\n text: '#2e3440', // nord0\n textMuted: '#4c566a', // nord3\n primary: '#5e81ac', // nord10\n secondary: '#81a1c1', // nord9\n accent: '#81a1c1', // nord9\n destructive: '#bf616a', // nord11\n colors: {\n red: '#bf616a', // nord11\n orange: '#d08770', // nord12\n yellow: '#ebcb8b', // nord13\n green: '#a3be8c', // nord14\n blue: '#5e81ac', // nord10\n purple: '#b48ead', // nord15\n teal: '#8fbcbb', // nord7\n cyan: '#88c0d0', // nord8\n gray: '#4c566a', // nord3\n },\n },\n dark: {\n bg: '#2e3440', // nord0\n surface: '#3b4252', // nord1\n overlay: '#434c5e', // nord2\n border: '#4c566a', // nord3\n text: '#eceff4', // nord6\n textMuted: '#d8dee9', // nord4\n primary: '#88c0d0', // nord8 (different from light's nord10)\n secondary: '#81a1c1', // nord9\n accent: '#81a1c1', // nord9\n destructive: '#bf616a', // nord11\n colors: {\n red: '#bf616a', // nord11\n orange: '#d08770', // nord12\n yellow: '#ebcb8b', // nord13\n green: '#a3be8c', // nord14\n blue: '#5e81ac', // nord10\n purple: '#b48ead', // nord15\n teal: '#8fbcbb', // nord7\n cyan: '#88c0d0', // nord8\n gray: '#4c566a', // nord3\n },\n },\n};\n\nregisterPalette(nordPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Solarized Palette Definition\n// ============================================================\n\n// Official Solarized colors: https://ethanschoonover.com/solarized/\n//\n// Base tones:\n// base03 #002b36 | base02 #073642 | base01 #586e75 | base00 #657b83\n// base0 #839496 | base1 #93a1a1 | base2 #eee8d5 | base3 #fdf6e3\n//\n// Accent colors:\n// yellow #b58900 | orange #cb4b16 | red #dc322f | magenta #d33682\n// violet #6c71c4 | blue #268bd2 | cyan #2aa198 | green #859900\n\nexport const solarizedPalette: PaletteConfig = {\n id: 'solarized',\n name: 'Solarized',\n light: {\n bg: '#fdf6e3', // base3\n surface: '#eee8d5', // base2\n overlay: '#eee8d5', // base2 (muted/secondary backgrounds)\n border: '#93a1a1', // base1\n text: '#657b83', // base00\n textMuted: '#93a1a1', // base1\n primary: '#268bd2', // blue\n secondary: '#2aa198', // cyan\n accent: '#6c71c4', // violet\n destructive: '#dc322f', // red\n colors: {\n red: '#dc322f',\n orange: '#cb4b16',\n yellow: '#b58900',\n green: '#859900',\n blue: '#268bd2',\n purple: '#6c71c4',\n teal: '#2aa198',\n cyan: '#2aa198', // Solarized has no separate cyan — reuse teal\n gray: '#586e75', // base01\n },\n },\n dark: {\n bg: '#002b36', // base03\n surface: '#073642', // base02\n overlay: '#073642', // base02 (muted/secondary backgrounds)\n border: '#586e75', // base01\n text: '#839496', // base0\n textMuted: '#586e75', // base01\n primary: '#268bd2', // blue\n secondary: '#2aa198', // cyan\n accent: '#6c71c4', // violet\n destructive: '#dc322f', // red\n colors: {\n red: '#dc322f',\n orange: '#cb4b16',\n yellow: '#b58900',\n green: '#859900',\n blue: '#268bd2',\n purple: '#6c71c4',\n teal: '#2aa198',\n cyan: '#2aa198',\n gray: '#586e75', // base01\n },\n },\n};\n\nregisterPalette(solarizedPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Catppuccin Palette Definition\n// ============================================================\n\n// Official Catppuccin colors: https://catppuccin.com/palette\n//\n// Latte (light):\n// Base #eff1f5 | Mantle #e6e9ef | Crust #dce0e8\n// Surface0 #ccd0da | Text #4c4f69 | Subtext1 #5c5f77 | Overlay0 #9ca0b0\n//\n// Mocha (dark):\n// Base #1e1e2e | Mantle #181825 | Surface0 #313244\n// Surface1 #45475a | Overlay0 #6c7086 | Text #cdd6f4 | Subtext1 #bac2de\n//\n// Accents (Latte / Mocha):\n// Red #d20f39 / #f38ba8 | Peach #fe640b / #fab387\n// Yellow #df8e1d / #f9e2af | Green #40a02b / #a6e3a1\n// Blue #1e66f5 / #89b4fa | Mauve #8839ef / #cba6f7\n// Teal #179299 / #94e2d5 | Sapphire #209fb5 / #74c7ec\n// Lavender #7287fd / #b4befe\n\nexport const catppuccinPalette: PaletteConfig = {\n id: 'catppuccin',\n name: 'Catppuccin',\n light: {\n bg: '#eff1f5', // Latte Base\n surface: '#e6e9ef', // Latte Mantle\n overlay: '#ccd0da', // Latte Surface0\n border: '#dce0e8', // Latte Crust\n text: '#4c4f69', // Latte Text\n textMuted: '#5c5f77', // Latte Subtext1\n primary: '#1e66f5', // Latte Blue\n secondary: '#7287fd', // Latte Lavender\n accent: '#8839ef', // Latte Mauve\n destructive: '#d20f39', // Latte Red\n colors: {\n red: '#d20f39',\n orange: '#fe640b',\n yellow: '#df8e1d',\n green: '#40a02b',\n blue: '#1e66f5',\n purple: '#8839ef',\n teal: '#179299',\n cyan: '#209fb5',\n gray: '#9ca0b0', // Latte Overlay0\n },\n },\n dark: {\n bg: '#1e1e2e', // Mocha Base\n surface: '#313244', // Mocha Surface0\n overlay: '#45475a', // Mocha Surface1\n border: '#6c7086', // Mocha Overlay0\n text: '#cdd6f4', // Mocha Text\n textMuted: '#bac2de', // Mocha Subtext1\n primary: '#89b4fa', // Mocha Blue\n secondary: '#b4befe', // Mocha Lavender\n accent: '#cba6f7', // Mocha Mauve\n destructive: '#f38ba8', // Mocha Red\n colors: {\n red: '#f38ba8',\n orange: '#fab387',\n yellow: '#f9e2af',\n green: '#a6e3a1',\n blue: '#89b4fa',\n purple: '#cba6f7',\n teal: '#94e2d5',\n cyan: '#74c7ec',\n gray: '#6c7086', // Mocha Overlay0\n },\n },\n};\n\nregisterPalette(catppuccinPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Rosé Pine Palette Definition\n// ============================================================\n\n// Official Rosé Pine colors: https://rosepinetheme.com/palette\n//\n// Dawn (light):\n// Base #faf4ed | Surface #fffaf3 | Overlay #f2e9e1\n// Muted #9893a5 | Subtle #797593 | Text #575279\n// Highlight Med #dfdad9\n//\n// Moon (dark):\n// Base #232136 | Surface #2a273f | Overlay #393552\n// Muted #6e6a86 | Subtle #908caa | Text #e0def4\n// Highlight Med #44415a\n//\n// Accents (Dawn / Moon):\n// Love #b4637a / #eb6f92 | Gold #ea9d34 / #f6c177\n// Rose #d7827e / #ea9a97 | Pine #286983 / #3e8fb0\n// Foam #56949f / #9ccfd8 | Iris #907aa9 / #c4a7e7\n\nexport const rosePinePalette: PaletteConfig = {\n id: 'rose-pine',\n name: 'Rosé Pine',\n light: {\n bg: '#faf4ed', // Dawn Base\n surface: '#fffaf3', // Dawn Surface\n overlay: '#f2e9e1', // Dawn Overlay\n border: '#dfdad9', // Dawn Highlight Med\n text: '#575279', // Dawn Text\n textMuted: '#9893a5', // Dawn Muted\n primary: '#286983', // Dawn Pine\n secondary: '#56949f', // Dawn Foam\n accent: '#907aa9', // Dawn Iris\n destructive: '#b4637a', // Dawn Love\n colors: {\n red: '#b4637a', // Love\n orange: '#d7827e', // Rose\n yellow: '#ea9d34', // Gold\n green: '#286983', // Pine\n blue: '#56949f', // Foam\n purple: '#907aa9', // Iris\n teal: '#286983', // Pine\n cyan: '#56949f', // Foam\n gray: '#9893a5', // Muted\n },\n },\n dark: {\n bg: '#232136', // Moon Base\n surface: '#2a273f', // Moon Surface\n overlay: '#393552', // Moon Overlay\n border: '#44415a', // Moon Highlight Med\n text: '#e0def4', // Moon Text\n textMuted: '#908caa', // Moon Subtle\n primary: '#3e8fb0', // Moon Pine\n secondary: '#9ccfd8', // Moon Foam\n accent: '#c4a7e7', // Moon Iris\n destructive: '#eb6f92', // Moon Love\n colors: {\n red: '#eb6f92', // Love\n orange: '#ea9a97', // Rose\n yellow: '#f6c177', // Gold\n green: '#3e8fb0', // Pine\n blue: '#9ccfd8', // Foam\n purple: '#c4a7e7', // Iris\n teal: '#3e8fb0', // Pine\n cyan: '#9ccfd8', // Foam\n gray: '#6e6a86', // Muted\n },\n },\n};\n\nregisterPalette(rosePinePalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Gruvbox Palette Definition\n// ============================================================\n\n// Official Gruvbox colors: https://github.com/morhetz/gruvbox\n//\n// Neutrals:\n// dark0 #282828 | dark1 #3c3836 | dark2 #504945 | dark3 #665c54\n// light0 #fbf1c7 | light1 #ebdbb2 | light2 #d5c4a1 | light3 #bdae93\n// gray #928374\n//\n// Accents (bright / neutral / faded):\n// Red #fb4934 / #cc241d / #9d0006\n// Green #b8bb26 / #98971a / #79740e\n// Yellow #fabd2f / #d79921 / #b57614\n// Blue #83a598 / #458588 / #076678\n// Purple #d3869b / #b16286 / #8f3f71\n// Aqua #8ec07c / #689d6a / #427b58\n// Orange #fe8019 / #d65d0e / #af3a03\n//\n// Light mode uses faded accents, dark mode uses bright accents.\n\nexport const gruvboxPalette: PaletteConfig = {\n id: 'gruvbox',\n name: 'Gruvbox',\n light: {\n bg: '#fbf1c7', // light0\n surface: '#ebdbb2', // light1\n overlay: '#d5c4a1', // light2\n border: '#bdae93', // light3\n text: '#3c3836', // dark1\n textMuted: '#7c6f64', // dark4\n primary: '#076678', // faded blue\n secondary: '#427b58', // faded aqua\n accent: '#8f3f71', // faded purple\n destructive: '#9d0006', // faded red\n colors: {\n red: '#9d0006', // faded\n orange: '#af3a03', // faded\n yellow: '#b57614', // faded\n green: '#79740e', // faded\n blue: '#076678', // faded\n purple: '#8f3f71', // faded\n teal: '#427b58', // faded aqua\n cyan: '#427b58', // faded aqua\n gray: '#928374',\n },\n },\n dark: {\n bg: '#282828', // dark0\n surface: '#3c3836', // dark1\n overlay: '#504945', // dark2\n border: '#665c54', // dark3\n text: '#ebdbb2', // light1\n textMuted: '#a89984', // light4\n primary: '#83a598', // bright blue\n secondary: '#8ec07c', // bright aqua\n accent: '#d3869b', // bright purple\n destructive: '#fb4934', // bright red\n colors: {\n red: '#fb4934', // bright\n orange: '#fe8019', // bright\n yellow: '#fabd2f', // bright\n green: '#b8bb26', // bright\n blue: '#83a598', // bright\n purple: '#d3869b', // bright\n teal: '#8ec07c', // bright aqua\n cyan: '#8ec07c', // bright aqua\n gray: '#928374',\n },\n },\n};\n\nregisterPalette(gruvboxPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Tokyo Night Palette Definition\n// ============================================================\n\n// Official Tokyo Night colors: https://github.com/folke/tokyonight.nvim\n//\n// Night (dark):\n// bg #1a1b26 | bg_highlight #292e42 | terminal_black #414868\n// fg_gutter #3b4261 | fg #c0caf5 | fg_dark #a9b1d6\n// comment #565f89\n//\n// Day (light):\n// bg #e1e2e7 | bg_float #d0d5e3 | bg_highlight #c4c8da\n// fg_gutter #a8aecb | fg #3760bf | fg_dark #6172b0\n// dark3 #8990b3\n//\n// Accents (Day / Night):\n// Red #f52a65 / #f7768e | Orange #b15c00 / #ff9e64\n// Yellow #8c6c3e / #e0af68 | Green #587539 / #9ece6a\n// Blue #2e7de9 / #7aa2f7 | Purple #7847bd / #bb9af7\n// Teal #118c74 / #1abc9c | Cyan #007197 / #7dcfff\n// Magenta #9854f1 / #bb9af7\n\nexport const tokyoNightPalette: PaletteConfig = {\n id: 'tokyo-night',\n name: 'Tokyo Night',\n light: {\n bg: '#e1e2e7', // Day bg\n surface: '#d0d5e3', // Day bg_float\n overlay: '#c4c8da', // Day bg_highlight\n border: '#a8aecb', // Day fg_gutter\n text: '#3760bf', // Day fg\n textMuted: '#6172b0', // Day fg_dark\n primary: '#2e7de9', // Day blue\n secondary: '#007197', // Day cyan\n accent: '#9854f1', // Day magenta\n destructive: '#f52a65', // Day red\n colors: {\n red: '#f52a65',\n orange: '#b15c00',\n yellow: '#8c6c3e',\n green: '#587539',\n blue: '#2e7de9',\n purple: '#7847bd',\n teal: '#118c74',\n cyan: '#007197',\n gray: '#8990b3', // Day dark3\n },\n },\n dark: {\n bg: '#1a1b26', // Night bg\n surface: '#292e42', // Night bg_highlight\n overlay: '#414868', // Night terminal_black\n border: '#3b4261', // Night fg_gutter\n text: '#c0caf5', // Night fg\n textMuted: '#a9b1d6', // Night fg_dark\n primary: '#7aa2f7', // Night blue\n secondary: '#7dcfff', // Night cyan\n accent: '#bb9af7', // Night magenta\n destructive: '#f7768e', // Night red\n colors: {\n red: '#f7768e',\n orange: '#ff9e64',\n yellow: '#e0af68',\n green: '#9ece6a',\n blue: '#7aa2f7',\n purple: '#bb9af7',\n teal: '#1abc9c',\n cyan: '#7dcfff',\n gray: '#565f89', // Night comment\n },\n },\n};\n\nregisterPalette(tokyoNightPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// One Dark Palette Definition\n// Based on Atom's One Dark theme\n// ============================================================\n\nexport const oneDarkPalette: PaletteConfig = {\n id: 'one-dark',\n name: 'One Dark',\n light: {\n // One Light variant (Atom's light counterpart)\n bg: '#fafafa',\n surface: '#f0f0f0',\n overlay: '#e5e5e5',\n border: '#d0d0d0',\n text: '#383a42',\n textMuted: '#696c77',\n primary: '#4078f2',\n secondary: '#a626a4',\n accent: '#0184bc',\n destructive: '#e45649',\n colors: {\n red: '#e45649',\n orange: '#c18401',\n yellow: '#c18401',\n green: '#50a14f',\n blue: '#4078f2',\n purple: '#a626a4',\n teal: '#0184bc',\n cyan: '#0997b3',\n gray: '#696c77',\n },\n },\n dark: {\n // One Dark (Atom's dark theme)\n bg: '#282c34',\n surface: '#21252b',\n overlay: '#2c313a',\n border: '#3e4451',\n text: '#abb2bf',\n textMuted: '#5c6370',\n primary: '#61afef',\n secondary: '#c678dd',\n accent: '#56b6c2',\n destructive: '#e06c75',\n colors: {\n red: '#e06c75',\n orange: '#d19a66',\n yellow: '#e5c07b',\n green: '#98c379',\n blue: '#61afef',\n purple: '#c678dd',\n teal: '#56b6c2',\n cyan: '#56b6c2',\n gray: '#5c6370',\n },\n },\n};\n\nregisterPalette(oneDarkPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Bold Palette Definition\n// ============================================================\n\nexport const boldPalette: PaletteConfig = {\n id: 'bold',\n name: 'Bold',\n light: {\n bg: '#ffffff',\n surface: '#f0f0f0',\n overlay: '#f0f0f0',\n border: '#cccccc',\n text: '#000000',\n textMuted: '#666666',\n primary: '#0000ff',\n secondary: '#ff00ff',\n accent: '#00cccc',\n destructive: '#ff0000',\n colors: {\n red: '#ff0000',\n orange: '#ff8000',\n yellow: '#ffcc00',\n green: '#00cc00',\n blue: '#0000ff',\n purple: '#cc00cc',\n teal: '#008080',\n cyan: '#00cccc',\n gray: '#808080',\n },\n },\n dark: {\n bg: '#000000',\n surface: '#111111',\n overlay: '#1a1a1a',\n border: '#333333',\n text: '#ffffff',\n textMuted: '#aaaaaa',\n primary: '#00ccff',\n secondary: '#ff00ff',\n accent: '#ffff00',\n destructive: '#ff0000',\n colors: {\n red: '#ff0000',\n orange: '#ff8000',\n yellow: '#ffff00',\n green: '#00ff00',\n blue: '#0066ff',\n purple: '#ff00ff',\n teal: '#00cccc',\n cyan: '#00ffff',\n gray: '#808080',\n },\n },\n};\n\nregisterPalette(boldPalette);\n","import type { PaletteColors } from './types';\nimport { mute, tint, shade, contrastText } from './color-utils';\n\n// ============================================================\n// Mermaid Theme Variable Generator\n// ============================================================\n\n/**\n * Generates ~121 Mermaid theme variables from palette tokens.\n * Replaces the hardcoded lightThemeVars/darkThemeVars objects.\n *\n * Dark mode fills use `mute()` to derive desaturated variants\n * that are readable with light text.\n */\nexport function buildMermaidThemeVars(\n colors: PaletteColors,\n isDark: boolean\n): Record<string, string> {\n const c = colors.colors;\n\n // Ordered accent array for pie/cScale/fillType/actor slots\n const accentOrder = [\n c.blue,\n c.red,\n c.green,\n c.yellow,\n c.purple,\n c.orange,\n c.teal,\n c.cyan,\n colors.secondary,\n ];\n\n // Dark mode fills use muted variants for readability\n const fills = isDark ? accentOrder.map(mute) : accentOrder;\n\n return {\n // ── Backgrounds ──\n background: isDark ? colors.overlay : colors.border,\n mainBkg: colors.surface,\n\n // ── Primary/Secondary/Tertiary nodes ──\n primaryColor: isDark ? colors.primary : colors.surface,\n primaryTextColor: colors.text,\n primaryBorderColor: isDark ? colors.secondary : colors.border,\n secondaryColor: colors.secondary,\n secondaryTextColor: contrastText(colors.secondary, colors.text, colors.bg),\n secondaryBorderColor: colors.primary,\n tertiaryColor: colors.accent,\n tertiaryTextColor: contrastText(colors.accent, colors.text, colors.bg),\n tertiaryBorderColor: colors.border,\n\n // ── Lines & text ──\n lineColor: colors.textMuted,\n textColor: colors.text,\n\n // ── Clusters ──\n clusterBkg: colors.bg,\n clusterBorder: isDark ? colors.border : colors.textMuted,\n titleColor: colors.text,\n\n // ── Labels ──\n edgeLabelBackground: 'transparent',\n\n // ── Notes (sequence diagrams) ──\n noteBkgColor: colors.bg,\n noteTextColor: colors.text,\n noteBorderColor: isDark ? colors.border : colors.textMuted,\n\n // ── Actors (sequence diagrams) ──\n actorBkg: colors.surface,\n actorTextColor: colors.text,\n actorBorder: isDark ? colors.border : colors.textMuted,\n actorLineColor: colors.textMuted,\n\n // ── Signals (sequence diagrams) ──\n signalColor: colors.textMuted,\n signalTextColor: colors.text,\n\n // ── Labels ──\n labelColor: colors.text,\n labelTextColor: colors.text,\n labelBoxBkgColor: colors.surface,\n labelBoxBorderColor: isDark ? colors.border : colors.textMuted,\n\n // ── Loop boxes ──\n loopTextColor: colors.text,\n\n // ── Activation (sequence diagrams) ──\n activationBkgColor: isDark ? colors.overlay : colors.border,\n activationBorderColor: isDark ? colors.border : colors.textMuted,\n\n // ── Sequence numbers ──\n sequenceNumberColor: isDark ? colors.text : colors.bg,\n\n // ── State diagrams ──\n labelBackgroundColor: colors.surface,\n\n // ── Pie chart (9 slices) ──\n // Dark mode: use muted fills so light pieSectionTextColor stays readable\n ...Object.fromEntries(\n (isDark ? fills : accentOrder).map((col, i) => [`pie${i + 1}`, col])\n ),\n pieTitleTextColor: colors.text,\n pieSectionTextColor: isDark ? colors.text : colors.bg,\n pieLegendTextColor: colors.text,\n pieStrokeColor: 'transparent',\n pieOuterStrokeWidth: '0px',\n pieOuterStrokeColor: 'transparent',\n\n // ── cScale (9 tiers) — muted in dark mode ──\n ...Object.fromEntries(fills.map((f, i) => [`cScale${i}`, f])),\n ...Object.fromEntries(\n fills.map((_, i) => [\n `cScaleLabel${i}`,\n isDark ? colors.text : i < 2 || i > 6 ? colors.bg : colors.text,\n ])\n ),\n\n // ── fillType (8 slots) ──\n ...Object.fromEntries(\n [0, 1, 2, 3, 4, 5, 6, 7].map((i) => [\n `fillType${i}`,\n fills[i % fills.length],\n ])\n ),\n\n // ── Journey actors (6 slots) ──\n ...Object.fromEntries(\n [c.red, c.green, c.yellow, c.purple, c.orange, c.teal].map((color, i) => [\n `actor${i}`,\n color,\n ])\n ),\n\n // ── Flowchart ──\n nodeBorder: isDark ? colors.border : colors.textMuted,\n nodeTextColor: colors.text,\n\n // ── Gantt ──\n gridColor: isDark ? colors.textMuted : colors.border,\n doneTaskBkgColor: c.green,\n doneTaskBorderColor: isDark ? colors.border : colors.textMuted,\n activeTaskBkgColor: colors.secondary,\n activeTaskBorderColor: colors.primary,\n critBkgColor: c.orange,\n critBorderColor: c.red,\n taskBkgColor: colors.surface,\n taskBorderColor: isDark ? colors.border : colors.textMuted,\n taskTextColor: contrastText(colors.surface, colors.text, colors.bg),\n taskTextDarkColor: colors.bg,\n taskTextLightColor: colors.text,\n taskTextOutsideColor: colors.text,\n doneTaskTextColor: contrastText(c.green, colors.text, colors.bg),\n activeTaskTextColor: contrastText(colors.secondary, colors.text, colors.bg),\n critTaskTextColor: contrastText(c.orange, colors.text, colors.bg),\n sectionBkgColor: isDark\n ? shade(colors.primary, colors.bg, 0.6)\n : tint(colors.primary, 0.6),\n altSectionBkgColor: colors.bg,\n sectionBkgColor2: isDark\n ? shade(colors.primary, colors.bg, 0.6)\n : tint(colors.primary, 0.6),\n todayLineColor: c.yellow,\n\n // ── Quadrant ──\n quadrant1Fill: isDark\n ? shade(c.green, colors.bg, 0.75)\n : tint(c.green, 0.75),\n quadrant2Fill: isDark ? shade(c.blue, colors.bg, 0.75) : tint(c.blue, 0.75),\n quadrant3Fill: isDark ? shade(c.red, colors.bg, 0.75) : tint(c.red, 0.75),\n quadrant4Fill: isDark\n ? shade(c.yellow, colors.bg, 0.75)\n : tint(c.yellow, 0.75),\n quadrant1TextFill: colors.text,\n quadrant2TextFill: colors.text,\n quadrant3TextFill: colors.text,\n quadrant4TextFill: colors.text,\n quadrantPointFill: isDark ? c.cyan : c.blue,\n quadrantPointTextFill: colors.text,\n quadrantXAxisTextFill: colors.text,\n quadrantYAxisTextFill: colors.text,\n quadrantTitleFill: colors.text,\n quadrantInternalBorderStrokeFill: colors.border,\n quadrantExternalBorderStrokeFill: colors.border,\n };\n}\n\n// ============================================================\n// Mermaid Theme CSS Generator\n// ============================================================\n\n/**\n * Generates custom CSS overrides for Mermaid SVGs.\n * Handles git graph label backgrounds and dark-mode text readability.\n */\nexport function buildThemeCSS(palette: PaletteColors, isDark: boolean): string {\n const base = `\n .branchLabelBkg { fill: transparent !important; stroke: transparent !important; }\n .commit-label-bkg { fill: transparent !important; stroke: transparent !important; }\n .tag-label-bkg { fill: transparent !important; stroke: transparent !important; }\n\n /* GitGraph: ensure commit and branch label text matches palette */\n .commit-label { fill: ${palette.text} !important; }\n .branch-label { fill: ${palette.text} !important; }\n .tag-label { fill: ${palette.text} !important; }\n`;\n\n if (!isDark) return base;\n\n return (\n base +\n `\n /* Flowchart: ensure node and edge label text is readable */\n .nodeLabel, .label { color: ${palette.text} !important; fill: ${palette.text} !important; }\n .edgeLabel { color: ${palette.text} !important; fill: ${palette.text} !important; }\n .edgeLabel .label { color: ${palette.text} !important; fill: ${palette.text} !important; }\n`\n );\n}\n","// Re-export types\nexport type { PaletteConfig, PaletteColors } from './types';\n\n// Re-export registry\nexport {\n getPalette,\n getAvailablePalettes,\n registerPalette,\n isValidHex,\n} from './registry';\n\n// Re-export utilities\nexport {\n hexToHSL,\n hslToHex,\n hexToHSLString,\n mute,\n tint,\n shade,\n getSeriesColors,\n getSegmentColors,\n contrastText,\n} from './color-utils';\n\n// Re-export palette definitions\nexport { nordPalette } from './nord';\nexport { solarizedPalette } from './solarized';\nexport { catppuccinPalette } from './catppuccin';\nexport { rosePinePalette } from './rose-pine';\nexport { gruvboxPalette } from './gruvbox';\nexport { tokyoNightPalette } from './tokyo-night';\nexport { oneDarkPalette } from './one-dark';\nexport { boldPalette } from './bold';\n\n// Re-export Mermaid bridge\nexport { buildMermaidThemeVars, buildThemeCSS } from './mermaid-bridge';\n","// ============================================================\n// Participant Type Inference Engine\n// ============================================================\n//\n// Data-driven rules table that infers participant type from name.\n// First match wins. Infrastructure overrides come before suffix\n// rules to prevent false positives (e.g. \"Router\" → networking,\n// not actor despite the \"-er\" suffix).\n// ============================================================\n\nimport type { ParticipantType } from './parser';\n\n/**\n * A single inference rule: regex pattern → participant type.\n */\ninterface InferenceRule {\n pattern: RegExp;\n type: ParticipantType;\n}\n\n/**\n * Ordered rules table. First match wins.\n *\n * Priority order:\n * 0. Conflict overrides (prevent misclassification by general patterns)\n * 1. Infrastructure overrides (prevent false actor matches)\n * 2. Networking patterns\n * 3. Database patterns\n * 4. Cache patterns\n * 5. Queue/Messaging patterns\n * 6. Actor patterns (suffix + exact)\n * 7. Frontend patterns\n * 8. Service patterns\n * 9. External patterns\n */\nconst PARTICIPANT_RULES: readonly InferenceRule[] = [\n // ── 0. Conflict overrides ────────────────────────────────\n // Names that would incorrectly match general patterns in later groups\n { pattern: /^KeyDB$/i, type: 'cache' }, // not database (DB$ suffix)\n { pattern: /Webhook/i, type: 'external' }, // not frontend (Web contains)\n { pattern: /^Upstream$/i, type: 'external' }, // not queue (Stream$ suffix)\n { pattern: /^Downstream$/i, type: 'external' }, // not queue (Stream$ suffix)\n\n // ── 1. Infrastructure overrides ─────────────────────────\n // These names end in -er/-or but are NOT actors\n { pattern: /^.*Router$/i, type: 'networking' },\n { pattern: /^.*Scheduler$/i, type: 'service' },\n { pattern: /^.*Dispatcher$/i, type: 'service' },\n { pattern: /^.*Balancer$/i, type: 'networking' },\n { pattern: /^.*Controller$/i, type: 'service' },\n { pattern: /^.*Handler$/i, type: 'service' },\n { pattern: /^.*Processor$/i, type: 'service' },\n { pattern: /^.*Connector$/i, type: 'service' },\n { pattern: /^.*Adapter$/i, type: 'service' },\n { pattern: /^.*Provider$/i, type: 'service' },\n { pattern: /^.*Manager$/i, type: 'service' },\n { pattern: /^.*Orchestrator$/i, type: 'service' },\n { pattern: /^.*Monitor$/i, type: 'service' },\n { pattern: /^.*Resolver$/i, type: 'service' },\n { pattern: /^.*Logger$/i, type: 'service' },\n { pattern: /^.*Server$/i, type: 'service' },\n { pattern: /^.*Broker$/i, type: 'queue' },\n { pattern: /^.*Worker$/i, type: 'service' },\n { pattern: /^.*Consumer$/i, type: 'service' },\n { pattern: /^.*Producer$/i, type: 'service' },\n { pattern: /^.*Publisher$/i, type: 'service' },\n { pattern: /^.*Subscriber$/i, type: 'service' },\n { pattern: /^.*Listener$/i, type: 'service' },\n // New -er/-or suffixes that are services, not actors\n { pattern: /^.*Watcher$/i, type: 'service' },\n { pattern: /^.*Executor$/i, type: 'service' },\n { pattern: /^.*Aggregator$/i, type: 'service' },\n { pattern: /^.*Collector$/i, type: 'service' },\n { pattern: /^.*Transformer$/i, type: 'service' },\n { pattern: /^.*Validator$/i, type: 'service' },\n { pattern: /^.*Generator$/i, type: 'service' },\n { pattern: /^.*Indexer$/i, type: 'service' },\n { pattern: /^.*Crawler$/i, type: 'service' },\n { pattern: /^.*Scanner$/i, type: 'service' },\n { pattern: /^.*Parser$/i, type: 'service' },\n { pattern: /^.*Emitter$/i, type: 'service' },\n { pattern: /^.*Exporter$/i, type: 'service' },\n { pattern: /^.*Importer$/i, type: 'service' },\n { pattern: /^.*Loader$/i, type: 'service' },\n { pattern: /^.*Renderer$/i, type: 'service' },\n { pattern: /^.*Checker$/i, type: 'service' },\n { pattern: /^.*Inspector$/i, type: 'service' },\n { pattern: /^.*Encoder$/i, type: 'service' },\n { pattern: /^.*Decoder$/i, type: 'service' },\n { pattern: /^.*Notifier$/i, type: 'service' },\n\n // ── 2. Networking patterns ──────────────────────────────\n { pattern: /Gateway/i, type: 'networking' },\n { pattern: /GW$/i, type: 'networking' },\n { pattern: /Proxy/i, type: 'networking' },\n { pattern: /LB$/i, type: 'networking' },\n { pattern: /LoadBalancer/i, type: 'networking' },\n { pattern: /CDN/i, type: 'networking' },\n { pattern: /Firewall/i, type: 'networking' },\n { pattern: /WAF$/i, type: 'networking' },\n { pattern: /DNS/i, type: 'networking' },\n { pattern: /Ingress/i, type: 'networking' },\n // Named products & patterns\n { pattern: /Nginx/i, type: 'networking' },\n { pattern: /Traefik/i, type: 'networking' },\n { pattern: /Envoy/i, type: 'networking' },\n { pattern: /Istio/i, type: 'networking' },\n { pattern: /Kong/i, type: 'networking' },\n { pattern: /Akamai/i, type: 'networking' },\n { pattern: /Cloudflare/i, type: 'networking' },\n { pattern: /Mesh$/i, type: 'networking' },\n { pattern: /ServiceMesh/i, type: 'networking' },\n\n // ── 3. Database patterns ────────────────────────────────\n { pattern: /DB$/i, type: 'database' },\n { pattern: /Database/i, type: 'database' },\n { pattern: /Datastore/i, type: 'database' },\n { pattern: /Store$/i, type: 'database' },\n { pattern: /Storage/i, type: 'database' },\n { pattern: /Repo$/i, type: 'database' },\n { pattern: /Repository/i, type: 'database' },\n { pattern: /SQL/i, type: 'database' },\n { pattern: /Postgres/i, type: 'database' },\n { pattern: /MySQL/i, type: 'database' },\n { pattern: /Mongo/i, type: 'database' },\n { pattern: /Dynamo/i, type: 'database' },\n // Named products & patterns\n { pattern: /^Aurora$/i, type: 'database' },\n { pattern: /Spanner/i, type: 'database' },\n { pattern: /Supabase/i, type: 'database' },\n { pattern: /Firebase/i, type: 'database' },\n { pattern: /BigQuery/i, type: 'database' },\n { pattern: /Redshift/i, type: 'database' },\n { pattern: /Snowflake/i, type: 'database' },\n { pattern: /Cassandra/i, type: 'database' },\n { pattern: /Neo4j/i, type: 'database' },\n { pattern: /ClickHouse/i, type: 'database' },\n { pattern: /Elastic/i, type: 'database' },\n { pattern: /OpenSearch/i, type: 'database' },\n { pattern: /Druid/i, type: 'database' },\n { pattern: /Trino/i, type: 'database' },\n { pattern: /Pinecone/i, type: 'database' },\n { pattern: /Weaviate/i, type: 'database' },\n { pattern: /Qdrant/i, type: 'database' },\n { pattern: /Milvus/i, type: 'database' },\n { pattern: /Presto/i, type: 'database' },\n { pattern: /Table$/i, type: 'database' },\n\n // ── 4. Cache patterns ──────────────────────────────────\n { pattern: /Cache/i, type: 'cache' },\n { pattern: /Redis/i, type: 'cache' },\n { pattern: /Memcache/i, type: 'cache' },\n // CDN already matched by networking above\n // Named products\n { pattern: /Dragonfly/i, type: 'cache' },\n { pattern: /Hazelcast/i, type: 'cache' },\n { pattern: /Valkey/i, type: 'cache' },\n\n // ── 5. Queue/Messaging patterns ─────────────────────────\n { pattern: /Queue/i, type: 'queue' },\n { pattern: /MQ$/i, type: 'queue' },\n { pattern: /SQS/i, type: 'queue' },\n { pattern: /Kafka/i, type: 'queue' },\n { pattern: /RabbitMQ/i, type: 'queue' },\n { pattern: /EventBus/i, type: 'queue' },\n { pattern: /MessageBus/i, type: 'queue' },\n { pattern: /Bus$/i, type: 'queue' },\n { pattern: /Topic/i, type: 'queue' },\n { pattern: /Stream$/i, type: 'queue' },\n { pattern: /SNS/i, type: 'queue' },\n { pattern: /PubSub/i, type: 'queue' },\n // Named products & patterns\n { pattern: /NATS/i, type: 'queue' },\n { pattern: /Pulsar/i, type: 'queue' },\n { pattern: /Kinesis/i, type: 'queue' },\n { pattern: /EventBridge/i, type: 'queue' },\n { pattern: /CloudEvents/i, type: 'queue' },\n { pattern: /Celery/i, type: 'queue' },\n { pattern: /Sidekiq/i, type: 'queue' },\n { pattern: /EventHub/i, type: 'queue' },\n { pattern: /Channel$/i, type: 'queue' },\n\n // ── 6. Actor patterns ──────────────────────────────────\n // Exact matches first\n { pattern: /^Admin$/i, type: 'actor' },\n { pattern: /^User$/i, type: 'actor' },\n { pattern: /^Customer$/i, type: 'actor' },\n { pattern: /^Client$/i, type: 'actor' },\n { pattern: /^Agent$/i, type: 'actor' },\n { pattern: /^Person$/i, type: 'actor' },\n { pattern: /^Buyer$/i, type: 'actor' },\n { pattern: /^Seller$/i, type: 'actor' },\n { pattern: /^Guest$/i, type: 'actor' },\n { pattern: /^Visitor$/i, type: 'actor' },\n { pattern: /^Operator$/i, type: 'actor' },\n { pattern: /^Alice$/i, type: 'actor' },\n { pattern: /^Bob$/i, type: 'actor' },\n { pattern: /^Charlie$/i, type: 'actor' },\n { pattern: /^Fan$/i, type: 'actor' },\n { pattern: /^Purchaser$/i, type: 'actor' },\n { pattern: /^Reviewer$/i, type: 'actor' },\n // Suffix rules (after infrastructure overrides filtered above)\n { pattern: /User$/i, type: 'actor' },\n { pattern: /Actor$/i, type: 'actor' },\n { pattern: /Analyst$/i, type: 'actor' },\n\n // ── 7. Frontend patterns ────────────────────────────────\n { pattern: /App$/i, type: 'frontend' },\n { pattern: /Application/i, type: 'frontend' },\n { pattern: /Mobile/i, type: 'frontend' },\n { pattern: /iOS/i, type: 'frontend' },\n { pattern: /Android/i, type: 'frontend' },\n { pattern: /Web/i, type: 'frontend' },\n { pattern: /Browser/i, type: 'frontend' },\n { pattern: /Frontend/i, type: 'frontend' },\n { pattern: /UI$/i, type: 'frontend' },\n { pattern: /Dashboard/i, type: 'frontend' },\n { pattern: /CLI$/i, type: 'frontend' },\n { pattern: /Terminal/i, type: 'frontend' },\n // Frameworks & patterns\n { pattern: /React/i, type: 'frontend' },\n { pattern: /^Vue$/i, type: 'frontend' },\n { pattern: /Angular/i, type: 'frontend' },\n { pattern: /Svelte/i, type: 'frontend' },\n { pattern: /NextJS/i, type: 'frontend' },\n { pattern: /Nuxt/i, type: 'frontend' },\n { pattern: /Remix/i, type: 'frontend' },\n { pattern: /Electron/i, type: 'frontend' },\n { pattern: /Tauri/i, type: 'frontend' },\n { pattern: /Widget$/i, type: 'frontend' },\n { pattern: /Portal/i, type: 'frontend' },\n { pattern: /Console$/i, type: 'frontend' },\n { pattern: /^SPA$/i, type: 'frontend' },\n { pattern: /^PWA$/i, type: 'frontend' },\n\n // ── 8. Service patterns ─────────────────────────────────\n { pattern: /Service/i, type: 'service' },\n { pattern: /Svc$/i, type: 'service' },\n { pattern: /API$/i, type: 'service' },\n { pattern: /Lambda/i, type: 'service' },\n { pattern: /Function$/i, type: 'service' },\n { pattern: /Fn$/i, type: 'service' },\n { pattern: /Job$/i, type: 'service' },\n { pattern: /Cron/i, type: 'service' },\n { pattern: /Microservice/i, type: 'service' },\n // Auth\n { pattern: /^Auth$/i, type: 'service' },\n { pattern: /^AuthN$/i, type: 'service' },\n { pattern: /^AuthZ$/i, type: 'service' },\n { pattern: /^SSO$/i, type: 'service' },\n { pattern: /OAuth/i, type: 'service' },\n { pattern: /^OIDC$/i, type: 'service' },\n // SaaS\n { pattern: /Stripe/i, type: 'service' },\n { pattern: /Twilio/i, type: 'service' },\n { pattern: /SendGrid/i, type: 'service' },\n { pattern: /Mailgun/i, type: 'service' },\n // Cloud/infra\n { pattern: /^S3$/i, type: 'service' },\n { pattern: /^Blob$/i, type: 'service' },\n { pattern: /Vercel/i, type: 'service' },\n { pattern: /Netlify/i, type: 'service' },\n { pattern: /Heroku/i, type: 'service' },\n { pattern: /Docker/i, type: 'service' },\n { pattern: /Kubernetes/i, type: 'service' },\n { pattern: /K8s/i, type: 'service' },\n { pattern: /Terraform/i, type: 'service' },\n // Security\n { pattern: /Vault/i, type: 'service' },\n { pattern: /^HSM$/i, type: 'service' },\n { pattern: /KMS/i, type: 'service' },\n { pattern: /^IAM$/i, type: 'service' },\n // AI/ML\n { pattern: /^LLM$/i, type: 'service' },\n { pattern: /GPT/i, type: 'service' },\n { pattern: /^Claude$/i, type: 'service' },\n { pattern: /Embedding/i, type: 'service' },\n { pattern: /Inference/i, type: 'service' },\n // Suffixes & patterns\n { pattern: /Pipeline$/i, type: 'service' },\n { pattern: /Registry/i, type: 'service' },\n { pattern: /Engine$/i, type: 'service' },\n { pattern: /Daemon/i, type: 'service' },\n\n // ── 9. External patterns ────────────────────────────────\n { pattern: /External/i, type: 'external' },\n { pattern: /Ext$/i, type: 'external' },\n { pattern: /ThirdParty/i, type: 'external' },\n { pattern: /3P$/i, type: 'external' },\n { pattern: /Vendor/i, type: 'external' },\n // Named products & patterns\n { pattern: /Callback/i, type: 'external' },\n { pattern: /^AWS$/i, type: 'external' },\n { pattern: /^GCP$/i, type: 'external' },\n { pattern: /Azure/i, type: 'external' },\n];\n\n/**\n * Infer participant type from a name using the ordered rules table.\n * Returns 'default' if no rule matches.\n */\nexport function inferParticipantType(name: string): ParticipantType {\n for (const rule of PARTICIPANT_RULES) {\n if (rule.pattern.test(name)) {\n return rule.type;\n }\n }\n return 'default';\n}\n\n/**\n * Number of rules in the table. Exported for test assertions.\n */\nexport const RULE_COUNT = PARTICIPANT_RULES.length;\n","// ============================================================\n// Sequence Diagram Parser (.dgmo format)\n// ============================================================\n\nimport { inferParticipantType } from './participant-inference';\n\n/**\n * Participant types that can be declared via \"Name is a type\" syntax.\n */\nexport type ParticipantType =\n | 'default'\n | 'service'\n | 'database'\n | 'actor'\n | 'queue'\n | 'cache'\n | 'gateway'\n | 'external'\n | 'networking'\n | 'frontend';\n\nconst VALID_PARTICIPANT_TYPES: ReadonlySet<string> = new Set([\n 'service',\n 'database',\n 'actor',\n 'queue',\n 'cache',\n 'gateway',\n 'external',\n 'networking',\n 'frontend',\n]);\n\n/**\n * A declared or inferred participant in the sequence diagram.\n */\nexport interface SequenceParticipant {\n /** Internal identifier (e.g. \"AuthService\") */\n id: string;\n /** Display label — uses aka alias if provided, otherwise id */\n label: string;\n /** Participant shape type */\n type: ParticipantType;\n /** Source line number (1-based) */\n lineNumber: number;\n /** Explicit layout position override (0-based from left, negative from right) */\n position?: number;\n}\n\n/**\n * A message between two participants.\n * Placeholder for future stories — included in the interface now for completeness.\n */\nexport interface SequenceMessage {\n from: string;\n to: string;\n label: string;\n returnLabel?: string;\n lineNumber: number;\n async?: boolean;\n}\n\n/**\n * A conditional or loop block in the sequence diagram.\n */\nexport interface ElseIfBranch {\n label: string;\n children: SequenceElement[];\n}\n\nexport interface SequenceBlock {\n kind: 'block';\n type: 'if' | 'loop' | 'parallel';\n label: string;\n children: SequenceElement[];\n elseChildren: SequenceElement[];\n elseIfBranches?: ElseIfBranch[];\n lineNumber: number;\n}\n\n/**\n * A labeled horizontal divider between message phases.\n */\nexport interface SequenceSection {\n kind: 'section';\n label: string;\n color?: string;\n lineNumber: number;\n}\n\n/**\n * An annotation attached to a message, rendered as a folded-corner box.\n */\nexport interface SequenceNote {\n kind: 'note';\n text: string;\n position: 'right' | 'left';\n participantId: string;\n lineNumber: number;\n endLineNumber: number;\n}\n\nexport type SequenceElement =\n | SequenceMessage\n | SequenceBlock\n | SequenceSection\n | SequenceNote;\n\nexport function isSequenceBlock(el: SequenceElement): el is SequenceBlock {\n return 'kind' in el && (el as SequenceBlock).kind === 'block';\n}\n\nexport function isSequenceSection(el: SequenceElement): el is SequenceSection {\n return 'kind' in el && (el as SequenceSection).kind === 'section';\n}\n\nexport function isSequenceNote(el: SequenceElement): el is SequenceNote {\n return 'kind' in el && (el as SequenceNote).kind === 'note';\n}\n\n/**\n * A named group of participants rendered as a labeled box.\n */\nexport interface SequenceGroup {\n name: string;\n color?: string;\n participantIds: string[];\n lineNumber: number;\n}\n\n/**\n * Parsed result from a .dgmo sequence diagram.\n */\nexport interface ParsedSequenceDgmo {\n title: string | null;\n titleLineNumber: number | null;\n participants: SequenceParticipant[];\n messages: SequenceMessage[];\n elements: SequenceElement[];\n groups: SequenceGroup[];\n sections: SequenceSection[];\n options: Record<string, string>;\n error: string | null;\n}\n\n// \"Name is a type\" pattern — e.g. \"AuthService is a service\"\n// Remainder after type is parsed separately for aka/position modifiers\nconst IS_A_PATTERN = /^(\\S+)\\s+is\\s+an?\\s+(\\w+)(?:\\s+(.+))?$/i;\n\n// Standalone \"Name position N\" pattern — e.g. \"DB position -1\"\nconst POSITION_ONLY_PATTERN = /^(\\S+)\\s+position\\s+(-?\\d+)$/i;\n\n// Group heading pattern — \"## Backend\", \"## API Services(blue)\", \"## Backend(#hex)\"\nconst GROUP_HEADING_PATTERN = /^##\\s+(.+?)(?:\\(([^)]+)\\))?\\s*$/;\n\n// Section divider pattern — \"== Label ==\", \"== Label(color) ==\", or \"== Label\" (trailing == optional)\nconst SECTION_PATTERN = /^==\\s+(.+?)(?:\\s*==)?\\s*$/;\n\n// Arrow pattern for sequence inference — \"A -> B: message\" or \"A ~> B: message\"\nconst ARROW_PATTERN = /\\S+\\s*(?:->|~>)\\s*\\S+/;\n\n// <- return syntax: \"Login <- 200 OK\"\nconst ARROW_RETURN_PATTERN = /^(.+?)\\s*<-\\s*(.+)$/;\n\n// UML method(args): returnType syntax: \"getUser(id): UserObj\"\nconst UML_RETURN_PATTERN = /^(\\w+\\([^)]*\\))\\s*:\\s*(.+)$/;\n\n// Note patterns — \"note: text\", \"note right of API: text\", \"note left of User\"\nconst NOTE_SINGLE = /^note(?:\\s+(right|left)\\s+of\\s+(\\S+))?\\s*:\\s*(.+)$/i;\nconst NOTE_MULTI = /^note(?:\\s+(right|left)\\s+of\\s+([^\\s:]+))?\\s*:?\\s*$/i;\n\n/**\n * Extract return label from a message label string.\n * Priority: `<-` syntax first, then UML `method(): return` syntax,\n * then shorthand ` : ` separator (splits on last occurrence).\n */\nfunction parseReturnLabel(rawLabel: string): {\n label: string;\n returnLabel?: string;\n} {\n if (!rawLabel) return { label: '' };\n\n // Check <- syntax first\n const arrowReturn = rawLabel.match(ARROW_RETURN_PATTERN);\n if (arrowReturn) {\n return { label: arrowReturn[1].trim(), returnLabel: arrowReturn[2].trim() };\n }\n\n // Check UML method(args): returnType syntax\n const umlReturn = rawLabel.match(UML_RETURN_PATTERN);\n if (umlReturn) {\n return { label: umlReturn[1].trim(), returnLabel: umlReturn[2].trim() };\n }\n\n // Shorthand colon return syntax (split on last \":\")\n // Skip if the colon is part of a URL scheme (followed by //)\n const lastColon = rawLabel.lastIndexOf(':');\n if (lastColon > 0 && lastColon < rawLabel.length - 1) {\n const afterColon = rawLabel.substring(lastColon + 1);\n if (!afterColon.startsWith('//')) {\n const reqPart = rawLabel.substring(0, lastColon).trim();\n const resPart = afterColon.trim();\n if (reqPart && resPart) {\n return { label: reqPart, returnLabel: resPart };\n }\n }\n }\n\n return { label: rawLabel };\n}\n\n/**\n * Measure leading whitespace of a line, normalizing tabs to 4 spaces.\n */\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\n/**\n * Parse a .dgmo file with `chart: sequence` into a structured representation.\n */\nexport function parseSequenceDgmo(content: string): ParsedSequenceDgmo {\n const result: ParsedSequenceDgmo = {\n title: null,\n titleLineNumber: null,\n participants: [],\n messages: [],\n elements: [],\n groups: [],\n sections: [],\n options: {},\n error: null,\n };\n\n if (!content || !content.trim()) {\n result.error = 'Empty content';\n return result;\n }\n\n const lines = content.split('\\n');\n let hasExplicitChart = false;\n let contentStarted = false;\n\n // Group parsing state — tracks the active ## group heading\n let activeGroup: SequenceGroup | null = null;\n\n // Track participant → group name for duplicate membership detection\n const participantGroupMap = new Map<string, string>();\n\n // Block parsing state\n const blockStack: {\n block: SequenceBlock;\n indent: number;\n inElse: boolean;\n activeElseIfBranch?: ElseIfBranch;\n }[] = [];\n const currentContainer = (): SequenceElement[] => {\n if (blockStack.length === 0) return result.elements;\n const top = blockStack[blockStack.length - 1];\n if (top.activeElseIfBranch) return top.activeElseIfBranch.children;\n return top.inElse ? top.block.elseChildren : top.block.children;\n };\n\n // Track last message sender for default note positioning\n let lastMsgFrom: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!trimmed) {\n activeGroup = null;\n continue;\n }\n\n // Parse group heading — must be checked before comment skip since ## starts with #\n const groupMatch = trimmed.match(GROUP_HEADING_PATTERN);\n if (groupMatch) {\n const groupColor = groupMatch[2]?.trim();\n if (groupColor && groupColor.startsWith('#')) {\n result.error = `Line ${lineNumber}: Use a named color instead of hex (e.g., blue, red, teal)`;\n return result;\n }\n contentStarted = true;\n activeGroup = {\n name: groupMatch[1].trim(),\n color: groupColor || undefined,\n participantIds: [],\n lineNumber,\n };\n result.groups.push(activeGroup);\n continue;\n }\n\n // Close active group on non-indented, non-group lines\n if (activeGroup && measureIndent(raw) === 0) {\n activeGroup = null;\n }\n\n // Skip comments — only // is supported\n if (trimmed.startsWith('//')) continue;\n\n // Reject # as comment syntax (## is for group headings, handled above)\n if (trimmed.startsWith('#') && !trimmed.startsWith('##')) {\n result.error = `Line ${lineNumber}: Use // for comments. # is reserved for group headings (##)`;\n return result;\n }\n\n // Parse section dividers — \"== Label ==\" or \"== Label(color) ==\"\n // Close blocks first — sections at indent 0 should not nest inside blocks\n const sectionMatch = trimmed.match(SECTION_PATTERN);\n if (sectionMatch) {\n const sectionIndent = measureIndent(raw);\n while (blockStack.length > 0) {\n const top = blockStack[blockStack.length - 1];\n if (sectionIndent > top.indent) break;\n blockStack.pop();\n }\n const labelRaw = sectionMatch[1].trim();\n const colorMatch = labelRaw.match(/^(.+?)\\(([^)]+)\\)$/);\n if (colorMatch && colorMatch[2].trim().startsWith('#')) {\n result.error = `Line ${lineNumber}: Use a named color instead of hex (e.g., blue, red, teal)`;\n return result;\n }\n contentStarted = true;\n const section: SequenceSection = {\n kind: 'section',\n label: colorMatch ? colorMatch[1].trim() : labelRaw,\n color: colorMatch ? colorMatch[2].trim() : undefined,\n lineNumber,\n };\n result.sections.push(section);\n currentContainer().push(section);\n continue;\n }\n\n // Parse header key: value lines (always top-level)\n // Skip 'note' lines — parsed in the indent-aware section below\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex > 0 && !trimmed.includes('->') && !trimmed.includes('~>')) {\n const key = trimmed.substring(0, colonIndex).trim().toLowerCase();\n if (key === 'note' || key.startsWith('note ')) {\n // Fall through to indent-aware note parsing below\n } else {\n const value = trimmed.substring(colonIndex + 1).trim();\n\n if (key === 'chart') {\n hasExplicitChart = true;\n if (value.toLowerCase() !== 'sequence') {\n result.error = `Expected chart type \"sequence\", got \"${value}\"`;\n return result;\n }\n continue;\n }\n\n // Enforce headers-before-content\n if (contentStarted) {\n result.error = `Line ${lineNumber}: Options like '${key}: ${value}' must appear before the first message or declaration`;\n return result;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n // Store other options\n result.options[key] = value;\n continue;\n }\n }\n\n // Parse \"Name is a type [aka Alias]\" declarations (always top-level)\n const isAMatch = trimmed.match(IS_A_PATTERN);\n if (isAMatch) {\n contentStarted = true;\n const id = isAMatch[1];\n const typeStr = isAMatch[2].toLowerCase();\n const remainder = isAMatch[3]?.trim() || '';\n\n const participantType: ParticipantType = VALID_PARTICIPANT_TYPES.has(\n typeStr\n )\n ? (typeStr as ParticipantType)\n : 'default';\n\n // Parse modifiers from remainder: aka ALIAS, position N\n const akaMatch = remainder.match(\n /\\baka\\s+(.+?)(?:\\s+position\\s+-?\\d+\\s*$|$)/i\n );\n const posMatch = remainder.match(/\\bposition\\s+(-?\\d+)/i);\n const alias = akaMatch ? akaMatch[1].trim() : null;\n const position = posMatch ? parseInt(posMatch[1], 10) : undefined;\n\n // Avoid duplicate participant declarations\n if (!result.participants.some((p) => p.id === id)) {\n result.participants.push({\n id,\n label: alias || id,\n type: participantType,\n lineNumber,\n ...(position !== undefined ? { position } : {}),\n });\n }\n // Track group membership\n if (activeGroup && !activeGroup.participantIds.includes(id)) {\n const existingGroup = participantGroupMap.get(id);\n if (existingGroup) {\n result.error = `Line ${lineNumber}: Participant '${id}' is already in group '${existingGroup}' — participants can only belong to one group`;\n return result;\n }\n activeGroup.participantIds.push(id);\n participantGroupMap.set(id, activeGroup.name);\n }\n continue;\n }\n\n // Parse standalone \"Name position N\" (no \"is a\" type)\n const posOnlyMatch = trimmed.match(POSITION_ONLY_PATTERN);\n if (posOnlyMatch) {\n contentStarted = true;\n const id = posOnlyMatch[1];\n const position = parseInt(posOnlyMatch[2], 10);\n\n if (!result.participants.some((p) => p.id === id)) {\n result.participants.push({\n id,\n label: id,\n type: inferParticipantType(id),\n lineNumber,\n position,\n });\n }\n // Track group membership\n if (activeGroup && !activeGroup.participantIds.includes(id)) {\n const existingGroup = participantGroupMap.get(id);\n if (existingGroup) {\n result.error = `Line ${lineNumber}: Participant '${id}' is already in group '${existingGroup}' — participants can only belong to one group`;\n return result;\n }\n activeGroup.participantIds.push(id);\n participantGroupMap.set(id, activeGroup.name);\n }\n continue;\n }\n\n // Bare participant name inside an active group (single identifier on an indented line)\n if (activeGroup && measureIndent(raw) > 0 && /^\\S+$/.test(trimmed)) {\n contentStarted = true;\n const id = trimmed;\n if (!result.participants.some((p) => p.id === id)) {\n result.participants.push({\n id,\n label: id,\n type: inferParticipantType(id),\n lineNumber,\n });\n }\n if (!activeGroup.participantIds.includes(id)) {\n const existingGroup = participantGroupMap.get(id);\n if (existingGroup) {\n result.error = `Line ${lineNumber}: Participant '${id}' is already in group '${existingGroup}' — participants can only belong to one group`;\n return result;\n }\n activeGroup.participantIds.push(id);\n participantGroupMap.set(id, activeGroup.name);\n }\n continue;\n }\n\n // ---- Indent-aware parsing for messages and block keywords ----\n const indent = measureIndent(raw);\n\n // Close blocks whose scope has ended (indent decreased)\n while (blockStack.length > 0) {\n const top = blockStack[blockStack.length - 1];\n if (indent > top.indent) break;\n // Keep block on stack when 'else' or 'else if' matches current indent — handled below\n if (\n indent === top.indent &&\n (top.block.type === 'if' || top.block.type === 'parallel')\n ) {\n const lower = trimmed.toLowerCase();\n if (lower === 'else' || lower.startsWith('else if ')) break;\n }\n blockStack.pop();\n }\n\n // Parse message lines first — arrows take priority over keywords\n // Reject \"async\" keyword prefix — use ~> instead\n const asyncPrefixMatch = trimmed.match(/^async\\s+(.+)$/i);\n if (asyncPrefixMatch && ARROW_PATTERN.test(asyncPrefixMatch[1])) {\n result.error = `Line ${lineNumber}: Use ~> for async messages: A ~> B: message`;\n return result;\n }\n\n // Match ~> (async arrow) or -> (sync arrow)\n let isAsync = false;\n const asyncArrowMatch = trimmed.match(\n /^(\\S+)\\s*~>\\s*([^\\s:]+)\\s*(?::\\s*(.+))?$/\n );\n const syncArrowMatch = trimmed.match(\n /^(\\S+)\\s*->\\s*([^\\s:]+)\\s*(?::\\s*(.+))?$/\n );\n const arrowMatch = asyncArrowMatch || syncArrowMatch;\n if (asyncArrowMatch) isAsync = true;\n\n if (arrowMatch) {\n contentStarted = true;\n const from = arrowMatch[1];\n const to = arrowMatch[2];\n lastMsgFrom = from;\n const rawLabel = arrowMatch[3]?.trim() || '';\n\n // Extract return label — skip for async messages\n const { label, returnLabel } = isAsync\n ? { label: rawLabel, returnLabel: undefined }\n : parseReturnLabel(rawLabel);\n\n const msg: SequenceMessage = {\n from,\n to,\n label,\n returnLabel,\n lineNumber,\n ...(isAsync ? { async: true } : {}),\n };\n result.messages.push(msg);\n currentContainer().push(msg);\n\n // Auto-register participants from message usage with type inference\n if (!result.participants.some((p) => p.id === from)) {\n result.participants.push({\n id: from,\n label: from,\n type: inferParticipantType(from),\n lineNumber,\n });\n }\n if (!result.participants.some((p) => p.id === to)) {\n result.participants.push({\n id: to,\n label: to,\n type: inferParticipantType(to),\n lineNumber,\n });\n }\n continue;\n }\n\n // Parse 'if <label>' block keyword\n const ifMatch = trimmed.match(/^if\\s+(.+)$/i);\n if (ifMatch) {\n contentStarted = true;\n const block: SequenceBlock = {\n kind: 'block',\n type: 'if',\n label: ifMatch[1].trim(),\n children: [],\n elseChildren: [],\n lineNumber,\n };\n currentContainer().push(block);\n blockStack.push({ block, indent, inElse: false });\n continue;\n }\n\n // Parse 'loop <label>' block keyword\n const loopMatch = trimmed.match(/^loop\\s+(.+)$/i);\n if (loopMatch) {\n contentStarted = true;\n const block: SequenceBlock = {\n kind: 'block',\n type: 'loop',\n label: loopMatch[1].trim(),\n children: [],\n elseChildren: [],\n lineNumber,\n };\n currentContainer().push(block);\n blockStack.push({ block, indent, inElse: false });\n continue;\n }\n\n // Parse 'parallel [label]' block keyword\n const parallelMatch = trimmed.match(/^parallel(?:\\s+(.+))?$/i);\n if (parallelMatch) {\n contentStarted = true;\n const block: SequenceBlock = {\n kind: 'block',\n type: 'parallel',\n label: parallelMatch[1]?.trim() || '',\n children: [],\n elseChildren: [],\n lineNumber,\n };\n currentContainer().push(block);\n blockStack.push({ block, indent, inElse: false });\n continue;\n }\n\n // Parse 'else if <label>' keyword (must come before bare 'else')\n const elseIfMatch = trimmed.match(/^else\\s+if\\s+(.+)$/i);\n if (elseIfMatch) {\n if (blockStack.length > 0 && blockStack[blockStack.length - 1].indent === indent) {\n const top = blockStack[blockStack.length - 1];\n if (top.block.type === 'parallel') {\n result.error = `Line ${lineNumber}: parallel blocks don't support else if — list all concurrent messages directly inside the block`;\n return result;\n }\n if (top.block.type === 'if') {\n const branch: ElseIfBranch = { label: elseIfMatch[1].trim(), children: [] };\n if (!top.block.elseIfBranches) top.block.elseIfBranches = [];\n top.block.elseIfBranches.push(branch);\n top.activeElseIfBranch = branch;\n top.inElse = false;\n }\n }\n continue;\n }\n\n // Parse 'else' keyword (only applies to 'if' blocks)\n if (trimmed.toLowerCase() === 'else') {\n if (blockStack.length > 0 && blockStack[blockStack.length - 1].indent === indent) {\n const top = blockStack[blockStack.length - 1];\n if (top.block.type === 'parallel') {\n result.error = `Line ${lineNumber}: parallel blocks don't support else — list all concurrent messages directly inside the block`;\n return result;\n }\n if (top.block.type === 'if') {\n top.inElse = true;\n top.activeElseIfBranch = undefined;\n }\n }\n continue;\n }\n\n // Parse single-line note — \"note: text\" or \"note right of API: text\"\n const noteSingleMatch = trimmed.match(NOTE_SINGLE);\n if (noteSingleMatch) {\n const notePosition =\n (noteSingleMatch[1]?.toLowerCase() as 'right' | 'left') || 'right';\n let noteParticipant = noteSingleMatch[2] || null;\n if (!noteParticipant) {\n if (!lastMsgFrom) continue; // incomplete — skip during live typing\n noteParticipant = lastMsgFrom;\n }\n if (!result.participants.some((p) => p.id === noteParticipant)) {\n continue; // unknown participant — skip during live typing\n }\n const note: SequenceNote = {\n kind: 'note',\n text: noteSingleMatch[3].trim(),\n position: notePosition,\n participantId: noteParticipant,\n lineNumber,\n endLineNumber: lineNumber,\n };\n currentContainer().push(note);\n continue;\n }\n\n // Parse multi-line note — \"note\" or \"note right of API\" (no colon, body indented below)\n const noteMultiMatch = trimmed.match(NOTE_MULTI);\n if (noteMultiMatch) {\n const notePosition =\n (noteMultiMatch[1]?.toLowerCase() as 'right' | 'left') || 'right';\n let noteParticipant = noteMultiMatch[2] || null;\n if (!noteParticipant) {\n if (!lastMsgFrom) continue; // incomplete — skip during live typing\n noteParticipant = lastMsgFrom;\n }\n if (!result.participants.some((p) => p.id === noteParticipant)) {\n continue; // unknown participant — skip during live typing\n }\n // Collect indented body lines\n const noteLines: string[] = [];\n while (i + 1 < lines.length) {\n const nextRaw = lines[i + 1];\n const nextTrimmed = nextRaw.trim();\n if (!nextTrimmed) break;\n const nextIndent = measureIndent(nextRaw);\n if (nextIndent <= indent) break;\n noteLines.push(nextTrimmed);\n i++;\n }\n if (noteLines.length === 0) continue; // no body yet — skip during live typing\n const note: SequenceNote = {\n kind: 'note',\n text: noteLines.join('\\n'),\n position: notePosition,\n participantId: noteParticipant,\n lineNumber,\n endLineNumber: i + 1, // i has advanced past the body lines (1-based)\n };\n currentContainer().push(note);\n continue;\n }\n }\n\n // Validate: if no explicit chart line, check for arrow-based inference\n if (!hasExplicitChart && result.messages.length === 0) {\n // Check if raw content has arrow patterns for inference\n const hasArrows = lines.some((line) => ARROW_PATTERN.test(line.trim()));\n if (!hasArrows) {\n result.error =\n 'No \"chart: sequence\" header and no sequence content detected';\n return result;\n }\n }\n\n return result;\n}\n\n/**\n * Detect whether raw content looks like a sequence diagram.\n * Used by the chart type inference logic.\n */\nexport function looksLikeSequence(content: string): boolean {\n if (!content) return false;\n const lines = content.split('\\n');\n return lines.some((line) => {\n const trimmed = line.trim();\n if (trimmed.startsWith('//')) return false;\n return ARROW_PATTERN.test(trimmed);\n });\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\nimport type {\n ParsedGraph,\n GraphNode,\n GraphEdge,\n GraphGroup,\n GraphShape,\n GraphDirection,\n} from './types';\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nfunction nodeId(shape: GraphShape, label: string): string {\n return `${shape}:${label.toLowerCase().trim()}`;\n}\n\ninterface NodeRef {\n id: string;\n label: string;\n shape: GraphShape;\n color?: string;\n}\n\nconst COLOR_SUFFIX_RE = /\\(([^)]+)\\)\\s*$/;\n\nfunction extractColor(\n label: string,\n palette?: PaletteColors\n): { label: string; color?: string } {\n const m = label.match(COLOR_SUFFIX_RE);\n if (!m) return { label };\n const colorName = m[1].trim();\n return {\n label: label.substring(0, m.index!).trim(),\n color: resolveColor(colorName, palette),\n };\n}\n\n/**\n * Try to parse a node reference from a text fragment.\n * Order matters: subroutine & document before process.\n */\nfunction parseNodeRef(\n text: string,\n palette?: PaletteColors\n): NodeRef | null {\n const t = text.trim();\n if (!t) return null;\n\n // Subroutine: [[Label]]\n let m = t.match(/^\\[\\[([^\\]]+)\\]\\]$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('subroutine', label), label, shape: 'subroutine', color };\n }\n\n // Document: [Label~]\n m = t.match(/^\\[([^\\]]+)~\\]$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('document', label), label, shape: 'document', color };\n }\n\n // Process: [Label]\n m = t.match(/^\\[([^\\]]+)\\]$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('process', label), label, shape: 'process', color };\n }\n\n // Terminal: (Label) — use .+ (greedy) so (Label(color)) matches outermost parens\n m = t.match(/^\\((.+)\\)$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('terminal', label), label, shape: 'terminal', color };\n }\n\n // Decision: <Label>\n m = t.match(/^<([^>]+)>$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('decision', label), label, shape: 'decision', color };\n }\n\n // I/O: /Label/\n m = t.match(/^\\/([^/]+)\\/$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('io', label), label, shape: 'io', color };\n }\n\n return null;\n}\n\n/**\n * Split a line into segments around arrow tokens.\n * Arrows: `->`, `-label->`, `-(color)->`, `-label(color)->`\n *\n * Returns alternating: [nodeText, arrowText, nodeText, arrowText, nodeText, ...]\n * Where arrowText is the full arrow token like `-yes->` or `->`.\n */\nfunction splitArrows(line: string): string[] {\n const segments: string[] = [];\n // Match: optional `-label(color)->` or just `->`\n // We scan left to right looking for `->` and work backwards to find the `-` start.\n const arrowRe = /(?:^|\\s)-([^>\\s(][^(>]*?)?\\s*(?:\\(([^)]+)\\))?\\s*->|(?:^|\\s)->/g;\n\n let lastIndex = 0;\n // Simpler approach: find all `->` positions, then determine if there's a label prefix\n const arrowPositions: { start: number; end: number; label?: string; color?: string }[] = [];\n\n // Find all -> occurrences\n let searchFrom = 0;\n while (searchFrom < line.length) {\n const idx = line.indexOf('->', searchFrom);\n if (idx === -1) break;\n\n // Look backwards from idx to find the start of the arrow (the `-` that starts the label)\n let arrowStart = idx;\n let label: string | undefined;\n let color: string | undefined;\n\n // Check if there's content between a preceding `-` and this `->` (e.g., `-yes->`)\n // Walk backwards from idx-1 to find another `-` that could be the arrow start\n if (idx > 0 && line[idx - 1] !== ' ' && line[idx - 1] !== '\\t') {\n // There might be label/color content attached: e.g. `-yes->` or `-(blue)->`\n // The arrow token starts with `-` followed by optional label, optional (color), then `->`\n // We need to find the opening `-` before any label text\n // Scan backwards to find a `-` preceded by whitespace or start-of-line\n let scanBack = idx - 1;\n while (scanBack > 0 && line[scanBack] !== '-') {\n scanBack--;\n }\n // Check if this `-` could be the start of the arrow\n if (line[scanBack] === '-' && (scanBack === 0 || /\\s/.test(line[scanBack - 1]))) {\n // Content between opening `-` and `->` (strip trailing `-` that is part of `->`)\n let arrowContent = line.substring(scanBack + 1, idx);\n if (arrowContent.endsWith('-')) arrowContent = arrowContent.slice(0, -1);\n // Parse label and color from arrow content\n const colorMatch = arrowContent.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n color = colorMatch[1].trim();\n const labelPart = arrowContent.substring(0, colorMatch.index!).trim();\n if (labelPart) label = labelPart;\n } else {\n const labelPart = arrowContent.trim();\n if (labelPart) label = labelPart;\n }\n arrowStart = scanBack;\n }\n }\n\n arrowPositions.push({ start: arrowStart, end: idx + 2, label, color });\n searchFrom = idx + 2;\n }\n\n if (arrowPositions.length === 0) {\n return [line];\n }\n\n // Build segments\n for (let i = 0; i < arrowPositions.length; i++) {\n const arrow = arrowPositions[i];\n const beforeText = line.substring(lastIndex, arrow.start).trim();\n if (beforeText || i === 0) {\n segments.push(beforeText);\n }\n // Arrow marker\n let arrowToken = '->';\n if (arrow.label && arrow.color) arrowToken = `-${arrow.label}(${arrow.color})->`;\n else if (arrow.label) arrowToken = `-${arrow.label}->`;\n else if (arrow.color) arrowToken = `-(${arrow.color})->`;\n segments.push(arrowToken);\n lastIndex = arrow.end;\n }\n // Remaining text after last arrow\n const remaining = line.substring(lastIndex).trim();\n if (remaining) {\n segments.push(remaining);\n }\n\n return segments;\n}\n\ninterface ArrowInfo {\n label?: string;\n color?: string;\n}\n\nfunction parseArrowToken(token: string, palette?: PaletteColors): ArrowInfo {\n if (token === '->') return {};\n // Color-only: -(color)->\n const colorOnly = token.match(/^-\\(([^)]+)\\)->$/);\n if (colorOnly) {\n return { color: resolveColor(colorOnly[1].trim(), palette) };\n }\n // -label(color)-> or -label->\n const m = token.match(/^-(.+?)(?:\\(([^)]+)\\))?->$/);\n if (m) {\n const label = m[1]?.trim() || undefined;\n const color = m[2] ? resolveColor(m[2].trim(), palette) : undefined;\n return { label, color };\n }\n return {};\n}\n\n// ============================================================\n// Group heading pattern\n// ============================================================\nconst GROUP_HEADING_RE = /^##\\s+(.+?)(?:\\(([^)]+)\\))?\\s*$/;\n\n// ============================================================\n// Main parser\n// ============================================================\n\nexport function parseFlowchart(\n content: string,\n palette?: PaletteColors\n): ParsedGraph {\n const lines = content.split('\\n');\n const result: ParsedGraph = {\n type: 'flowchart',\n direction: 'TB',\n nodes: [],\n edges: [],\n };\n\n const nodeMap = new Map<string, GraphNode>();\n const indentStack: { nodeId: string; indent: number }[] = [];\n let currentGroup: GraphGroup | null = null;\n const groups: GraphGroup[] = [];\n let contentStarted = false;\n\n function getOrCreateNode(ref: NodeRef, lineNumber: number): GraphNode {\n const existing = nodeMap.get(ref.id);\n if (existing) return existing;\n\n const node: GraphNode = {\n id: ref.id,\n label: ref.label,\n shape: ref.shape,\n lineNumber,\n ...(ref.color && { color: ref.color }),\n ...(currentGroup && { group: currentGroup.id }),\n };\n nodeMap.set(ref.id, node);\n result.nodes.push(node);\n\n // Add to current group\n if (currentGroup && !currentGroup.nodeIds.includes(ref.id)) {\n currentGroup.nodeIds.push(ref.id);\n }\n\n return node;\n }\n\n function addEdge(\n sourceId: string,\n targetId: string,\n lineNumber: number,\n label?: string,\n color?: string\n ): void {\n const edge: GraphEdge = {\n source: sourceId,\n target: targetId,\n lineNumber,\n ...(label && { label }),\n ...(color && { color }),\n };\n result.edges.push(edge);\n }\n\n /**\n * Process a content line that may contain nodes and arrows.\n * Returns the last node ID encountered (for indent stack tracking).\n */\n function processContentLine(\n trimmed: string,\n lineNumber: number,\n indent: number\n ): string | null {\n contentStarted = true;\n\n // Determine implicit source from indent stack\n // Pop stack entries that are at same or deeper indent level\n while (indentStack.length > 0) {\n const top = indentStack[indentStack.length - 1];\n if (top.indent >= indent) {\n indentStack.pop();\n } else {\n break;\n }\n }\n\n const implicitSourceId =\n indentStack.length > 0\n ? indentStack[indentStack.length - 1].nodeId\n : null;\n\n // Split line into segments around arrows\n const segments = splitArrows(trimmed);\n\n if (segments.length === 1) {\n // Single node reference, no arrows\n const ref = parseNodeRef(segments[0], palette);\n if (ref) {\n const node = getOrCreateNode(ref, lineNumber);\n indentStack.push({ nodeId: node.id, indent });\n return node.id;\n }\n return null;\n }\n\n // Process chain: alternating nodeText / arrowToken / nodeText / ...\n let lastNodeId: string | null = null;\n let pendingArrow: ArrowInfo | null = null;\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n\n // Check if this is an arrow token\n if (seg === '->' || /^-.+->$/.test(seg)) {\n pendingArrow = parseArrowToken(seg, palette);\n continue;\n }\n\n // This is a node text segment\n const ref = parseNodeRef(seg, palette);\n if (!ref) continue;\n\n const node = getOrCreateNode(ref, lineNumber);\n\n if (pendingArrow !== null) {\n const sourceId = lastNodeId ?? implicitSourceId;\n if (sourceId) {\n addEdge(\n sourceId,\n node.id,\n lineNumber,\n pendingArrow.label,\n pendingArrow.color\n );\n }\n pendingArrow = null;\n } else if (lastNodeId === null && implicitSourceId === null) {\n // First node in chain, no arrow yet — just register\n }\n\n lastNodeId = node.id;\n }\n\n // If we ended with a pending arrow but no target node, that's an edge-only line\n // handled by: the arrow was at the start with implicit source\n if (pendingArrow !== null && lastNodeId === null && implicitSourceId) {\n // Edge-only line like ` -> ` with no target — ignore\n }\n\n // If line started with an arrow and we have an implicit source\n // but no explicit first node, the first segment was empty\n if (\n segments.length >= 2 &&\n segments[0] === '' &&\n implicitSourceId &&\n lastNodeId\n ) {\n // Already handled above — the implicit source was used\n }\n\n if (lastNodeId) {\n indentStack.push({ nodeId: lastNodeId, indent });\n }\n\n return lastNodeId;\n }\n\n // === Main loop ===\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n const indent = measureIndent(raw);\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // Group headings\n const groupMatch = trimmed.match(GROUP_HEADING_RE);\n if (groupMatch) {\n const groupLabel = groupMatch[1].trim();\n const groupColorName = groupMatch[2]?.trim();\n const groupColor = groupColorName\n ? resolveColor(groupColorName, palette)\n : undefined;\n\n currentGroup = {\n id: `group:${groupLabel.toLowerCase()}`,\n label: groupLabel,\n nodeIds: [],\n lineNumber,\n ...(groupColor && { color: groupColor }),\n };\n groups.push(currentGroup);\n continue;\n }\n\n // Metadata directives (before content)\n if (!contentStarted && trimmed.includes(':') && !trimmed.includes('->')) {\n const colonIdx = trimmed.indexOf(':');\n const key = trimmed.substring(0, colonIdx).trim().toLowerCase();\n const value = trimmed.substring(colonIdx + 1).trim();\n\n if (key === 'chart') {\n if (value.toLowerCase() !== 'flowchart') {\n result.error = `Line ${lineNumber}: Expected chart type \"flowchart\", got \"${value}\"`;\n return result;\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'direction') {\n const dir = value.toUpperCase() as GraphDirection;\n if (dir === 'TB' || dir === 'LR') {\n result.direction = dir;\n }\n continue;\n }\n\n // Unknown metadata — skip\n continue;\n }\n\n // Content line (nodes and edges)\n processContentLine(trimmed, lineNumber, indent);\n }\n\n if (groups.length > 0) result.groups = groups;\n\n // Validation: no nodes found\n if (result.nodes.length === 0 && !result.error) {\n result.error = 'No nodes found. Add flowchart content with shape syntax like [Process] or (Start).';\n }\n\n return result;\n}\n\n// ============================================================\n// Detection helper\n// ============================================================\n\n/**\n * Detect if content looks like a flowchart (without explicit `chart: flowchart` header).\n * Checks for shape delimiters combined with `->` arrows.\n * Avoids false-positives on sequence diagrams (which use bare names with `->`)\n */\nexport function looksLikeFlowchart(content: string): boolean {\n // Must have -> arrows\n if (!content.includes('->')) return false;\n\n // Must have at least one shape delimiter pattern\n // Shape delimiters: [...], (...), <...>, /.../, [[...]], [...~]\n // Sequence diagrams use bare names like \"Alice -> Bob: msg\" — no delimiters around names\n const hasShapeDelimiter =\n /\\[[^\\]]+\\]/.test(content) ||\n /\\([^)]+\\)/.test(content) ||\n /<[^>]+>/.test(content) ||\n /\\/[^/]+\\//.test(content);\n\n if (!hasShapeDelimiter) return false;\n\n // Check that shape delimiters appear near arrows (not just random brackets)\n // Look for patterns like `[X] ->` or `-> [X]` or `(X) ->` etc.\n const shapeNearArrow =\n /[\\])][ \\t]*-.*->/.test(content) || // shape ] or ) followed by arrow\n /->[ \\t]*[\\[(<\\/]/.test(content); // arrow followed by shape opener\n\n return shapeNearArrow;\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\nimport type {\n ParsedClassDiagram,\n ClassNode,\n ClassMember,\n ClassRelationship,\n ClassModifier,\n MemberVisibility,\n RelationshipType,\n} from './types';\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nfunction classId(name: string): string {\n return name.toLowerCase().trim();\n}\n\n// ============================================================\n// Regex patterns\n// ============================================================\n\n// Class declaration: ClassName [modifier] (color)\nconst CLASS_DECL_RE =\n /^([A-Z][A-Za-z0-9_]*)(?:\\s+\\[(abstract|interface|enum)\\])?(?:\\s+\\(([^)]+)\\))?\\s*$/;\n\n// Relationship — keyword syntax:\n// ClassName extends|implements|contains|has|uses TargetClass : label\nconst REL_KEYWORD_RE =\n /^([A-Z][A-Za-z0-9_]*)\\s+(extends|implements|contains|has|uses)\\s+([A-Z][A-Za-z0-9_]*)(?:\\s*:\\s*(.+))?$/;\n\n// Relationship — arrow syntax:\n// ClassName --|> TargetClass : label\n// Arrows: --|> ..|> *-- o-- ..> ->\nconst REL_ARROW_RE =\n /^([A-Z][A-Za-z0-9_]*)\\s+(--\\|>|\\.\\.\\|>|\\*--|o--|\\.\\.\\>|->)\\s+([A-Z][A-Za-z0-9_]*)(?:\\s*:\\s*(.+))?$/;\n\n// Member line patterns\nconst VISIBILITY_RE = /^([+\\-#])\\s*/;\nconst STATIC_SUFFIX_RE = /\\{static\\}\\s*$/;\nconst METHOD_RE = /^(.+?)\\(([^)]*)\\)(?:\\s*:\\s*(.+))?$/;\nconst FIELD_RE = /^(.+?)\\s*:\\s*(.+)$/;\n\nconst KEYWORD_TO_TYPE: Record<string, RelationshipType> = {\n extends: 'extends',\n implements: 'implements',\n contains: 'composes',\n has: 'aggregates',\n uses: 'depends',\n};\n\nconst ARROW_TO_TYPE: Record<string, RelationshipType> = {\n '--|>': 'extends',\n '..|>': 'implements',\n '*--': 'composes',\n 'o--': 'aggregates',\n '..>': 'depends',\n '->': 'associates',\n};\n\nfunction parseVisibility(prefix: string): MemberVisibility {\n switch (prefix) {\n case '-':\n return 'private';\n case '#':\n return 'protected';\n default:\n return 'public';\n }\n}\n\n// ============================================================\n// Member parser\n// ============================================================\n\nfunction parseMember(\n line: string,\n lineNumber: number,\n isEnum: boolean\n): ClassMember | null {\n let text = line.trim();\n if (!text) return null;\n\n // Enum values: plain text, no colon, no parens needed\n if (isEnum) {\n return {\n name: text,\n visibility: 'public',\n isStatic: false,\n isMethod: false,\n lineNumber,\n };\n }\n\n // Extract visibility prefix\n let visibility: MemberVisibility = 'public';\n const visMatch = text.match(VISIBILITY_RE);\n if (visMatch) {\n visibility = parseVisibility(visMatch[1]);\n text = text.substring(visMatch[0].length);\n }\n\n // Check for {static} suffix\n let isStatic = false;\n if (STATIC_SUFFIX_RE.test(text)) {\n isStatic = true;\n text = text.replace(STATIC_SUFFIX_RE, '').trim();\n }\n\n // Method: name(params) : returnType\n const methodMatch = text.match(METHOD_RE);\n if (methodMatch) {\n return {\n name: methodMatch[1].trim(),\n params: methodMatch[2].trim(),\n type: methodMatch[3]?.trim(),\n visibility,\n isStatic,\n isMethod: true,\n lineNumber,\n };\n }\n\n // Field: name : type\n const fieldMatch = text.match(FIELD_RE);\n if (fieldMatch) {\n return {\n name: fieldMatch[1].trim(),\n type: fieldMatch[2].trim(),\n visibility,\n isStatic,\n isMethod: false,\n lineNumber,\n };\n }\n\n // Plain name (field with no type)\n return {\n name: text,\n visibility,\n isStatic,\n isMethod: false,\n lineNumber,\n };\n}\n\n// ============================================================\n// Main parser\n// ============================================================\n\nexport function parseClassDiagram(\n content: string,\n palette?: PaletteColors\n): ParsedClassDiagram {\n const lines = content.split('\\n');\n const result: ParsedClassDiagram = {\n type: 'class',\n classes: [],\n relationships: [],\n };\n\n const classMap = new Map<string, ClassNode>();\n let currentClass: ClassNode | null = null;\n let contentStarted = false;\n\n function getOrCreateClass(name: string, lineNumber: number): ClassNode {\n const id = classId(name);\n const existing = classMap.get(id);\n if (existing) return existing;\n\n const node: ClassNode = {\n id,\n name,\n members: [],\n lineNumber,\n };\n classMap.set(id, node);\n result.classes.push(node);\n return node;\n }\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n const indent = measureIndent(raw);\n\n // Skip empty lines\n if (!trimmed) {\n // Empty line ends current class context\n if (indent === 0) currentClass = null;\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // Metadata directives (before content) — only simple keys (no spaces)\n if (!contentStarted && indent === 0 && /^[a-z][a-z0-9-]*\\s*:/i.test(trimmed)) {\n const colonIdx = trimmed.indexOf(':');\n const key = trimmed.substring(0, colonIdx).trim().toLowerCase();\n const value = trimmed.substring(colonIdx + 1).trim();\n\n // Only recognize known metadata keys\n if (key === 'chart') {\n if (value.toLowerCase() !== 'class') {\n result.error = `Line ${lineNumber}: Expected chart type \"class\", got \"${value}\"`;\n return result;\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n // Unknown single-word keys are metadata — skip\n if (!/\\s/.test(key)) continue;\n }\n\n // Indented lines = members of current class\n if (indent > 0 && currentClass) {\n const member = parseMember(\n trimmed,\n lineNumber,\n currentClass.modifier === 'enum'\n );\n if (member) {\n currentClass.members.push(member);\n }\n continue;\n }\n\n // At indent 0 — this ends any previous class context\n currentClass = null;\n contentStarted = true;\n\n // Try relationship — keyword syntax\n const relKeyword = trimmed.match(REL_KEYWORD_RE);\n if (relKeyword) {\n const sourceName = relKeyword[1];\n const keyword = relKeyword[2].toLowerCase();\n const targetName = relKeyword[3];\n const label = relKeyword[4]?.trim();\n\n // Ensure both classes exist\n getOrCreateClass(sourceName, lineNumber);\n getOrCreateClass(targetName, lineNumber);\n\n result.relationships.push({\n source: classId(sourceName),\n target: classId(targetName),\n type: KEYWORD_TO_TYPE[keyword],\n ...(label && { label }),\n lineNumber,\n });\n continue;\n }\n\n // Try relationship — arrow syntax\n const relArrow = trimmed.match(REL_ARROW_RE);\n if (relArrow) {\n const sourceName = relArrow[1];\n const arrow = relArrow[2];\n const targetName = relArrow[3];\n const label = relArrow[4]?.trim();\n\n // Ensure both classes exist\n getOrCreateClass(sourceName, lineNumber);\n getOrCreateClass(targetName, lineNumber);\n\n result.relationships.push({\n source: classId(sourceName),\n target: classId(targetName),\n type: ARROW_TO_TYPE[arrow],\n ...(label && { label }),\n lineNumber,\n });\n continue;\n }\n\n // Try class declaration\n const classDecl = trimmed.match(CLASS_DECL_RE);\n if (classDecl) {\n const name = classDecl[1];\n const modifier = classDecl[2] as ClassModifier | undefined;\n const colorName = classDecl[3]?.trim();\n const color = colorName ? resolveColor(colorName, palette) : undefined;\n\n const node = getOrCreateClass(name, lineNumber);\n if (modifier) node.modifier = modifier;\n if (color) node.color = color;\n // Update line number to the declaration line (may have been created by relationship)\n node.lineNumber = lineNumber;\n\n currentClass = node;\n continue;\n }\n }\n\n // Validation\n if (result.classes.length === 0 && !result.error) {\n result.error =\n 'No classes found. Add class declarations like \"ClassName\" or \"ClassName [interface]\".';\n }\n\n return result;\n}\n\n// ============================================================\n// Detection helper\n// ============================================================\n\n/**\n * Detect if content looks like a class diagram without explicit `chart: class`.\n * Requires class-like patterns (capitalized names with modifiers or UML relationships).\n * Must not false-positive on flowcharts.\n */\nexport function looksLikeClassDiagram(content: string): boolean {\n const lines = content.split('\\n');\n\n let hasModifier = false;\n let hasRelationship = false;\n let hasIndentedMember = false;\n let hasClassDecl = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('//')) continue;\n\n // Skip metadata\n if (/^(chart|title)\\s*:/i.test(trimmed)) continue;\n\n const indent = measureIndent(line);\n\n if (indent === 0) {\n // Check for modifier pattern: ClassName [abstract|interface|enum]\n if (/^[A-Z][A-Za-z0-9_]*\\s+\\[(abstract|interface|enum)\\]/i.test(trimmed)) {\n hasModifier = true;\n hasClassDecl = true;\n }\n // Check for relationship keywords\n if (REL_KEYWORD_RE.test(trimmed)) {\n hasRelationship = true;\n }\n // Check for relationship arrows\n if (REL_ARROW_RE.test(trimmed)) {\n hasRelationship = true;\n }\n // Check for plain class declaration (capitalized name only)\n if (CLASS_DECL_RE.test(trimmed)) {\n hasClassDecl = true;\n }\n } else {\n // Indented lines that look like members\n if (/^[+\\-#]?\\s*\\w+.*[:(]/.test(trimmed)) {\n hasIndentedMember = true;\n }\n }\n }\n\n // Require modifier OR (relationship + class-like declarations)\n // Modifier alone is strong enough signal\n if (hasModifier) return true;\n\n // Relationship keywords/arrows + at least one class declaration + member\n if (hasRelationship && hasClassDecl && hasIndentedMember) return true;\n\n return false;\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\nimport type {\n ParsedERDiagram,\n ERTable,\n ERColumn,\n ERConstraint,\n ERCardinality,\n} from './types';\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nfunction tableId(name: string): string {\n return name.toLowerCase().trim();\n}\n\n// ============================================================\n// Regex patterns\n// ============================================================\n\n// Table declaration: table_name or table_name (color)\n// Allows lowercase, uppercase, underscores, digits — must start with letter or underscore\nconst TABLE_DECL_RE = /^([a-zA-Z_]\\w*)(?:\\s+\\(([^)]+)\\))?\\s*$/;\n\n// Column: name: type [constraints] or name [constraints] or name: type or name\nconst COLUMN_RE = /^(\\w+)(?:\\s*:\\s*(\\w[\\w()]*(?:\\s*\\[\\])?))?(?:\\s+\\[([^\\]]+)\\])?\\s*$/;\n\n// Constraint keywords\nconst CONSTRAINT_MAP: Record<string, ERConstraint> = {\n pk: 'pk',\n fk: 'fk',\n unique: 'unique',\n nullable: 'nullable',\n};\n\n// ============================================================\n// Cardinality parsing\n// ============================================================\n\n// Cardinality keyword map\nconst CARD_WORD: Record<string, ERCardinality> = {\n one: '1',\n many: '*',\n '1': '1',\n '*': '*',\n '?': '?',\n zero: '?',\n};\n\n/**\n * Parse a cardinality side token (e.g. \"1\", \"*\", \"?\", \"one\", \"many\", \"zero\").\n */\nfunction parseCardSide(token: string): ERCardinality | null {\n return CARD_WORD[token.toLowerCase()] ?? null;\n}\n\n/**\n * Try to parse a relationship line with cardinality.\n *\n * Supported forms:\n * tableName 1--* tableName : label\n * tableName 1-* tableName : label\n * tableName one-to-many tableName : label\n * tableName one to many tableName : label\n * tableName 1 to many tableName : label\n * tableName ?--1 tableName : label\n */\nconst REL_SYMBOLIC_RE =\n /^([a-zA-Z_]\\w*)\\s+([1*?])\\s*-{1,2}\\s*([1*?])\\s+([a-zA-Z_]\\w*)(?:\\s*:\\s*(.+))?$/;\n\nconst REL_KEYWORD_RE =\n /^([a-zA-Z_]\\w*)\\s+(one|many|zero|1|\\*|\\?)[- ]to[- ](one|many|zero|1|\\*|\\?)\\s+([a-zA-Z_]\\w*)(?:\\s*:\\s*(.+))?$/i;\n\nfunction parseRelationship(\n trimmed: string\n): {\n source: string;\n target: string;\n from: ERCardinality;\n to: ERCardinality;\n label?: string;\n} | null {\n // Symbolic: 1--*, 1-*, ?--1, etc.\n const sym = trimmed.match(REL_SYMBOLIC_RE);\n if (sym) {\n const fromCard = parseCardSide(sym[2]);\n const toCard = parseCardSide(sym[3]);\n if (fromCard && toCard) {\n return {\n source: sym[1],\n target: sym[4],\n from: fromCard,\n to: toCard,\n label: sym[5]?.trim(),\n };\n }\n }\n\n // Keyword / natural: one-to-many, one to many, 1 to many, etc.\n const kw = trimmed.match(REL_KEYWORD_RE);\n if (kw) {\n const fromCard = parseCardSide(kw[2]);\n const toCard = parseCardSide(kw[3]);\n if (fromCard && toCard) {\n return {\n source: kw[1],\n target: kw[4],\n from: fromCard,\n to: toCard,\n label: kw[5]?.trim(),\n };\n }\n }\n\n return null;\n}\n\n// ============================================================\n// Constraint parser\n// ============================================================\n\nfunction parseConstraints(raw: string): ERConstraint[] {\n const parts = raw.split(',').map((s) => s.trim().toLowerCase());\n const result: ERConstraint[] = [];\n for (const part of parts) {\n const c = CONSTRAINT_MAP[part];\n if (c) result.push(c);\n }\n return result;\n}\n\n// ============================================================\n// Main parser\n// ============================================================\n\nexport function parseERDiagram(\n content: string,\n palette?: PaletteColors\n): ParsedERDiagram {\n const lines = content.split('\\n');\n const result: ParsedERDiagram = {\n type: 'er',\n options: {},\n tables: [],\n relationships: [],\n };\n\n const tableMap = new Map<string, ERTable>();\n let currentTable: ERTable | null = null;\n let contentStarted = false;\n\n function getOrCreateTable(name: string, lineNumber: number): ERTable {\n const id = tableId(name);\n const existing = tableMap.get(id);\n if (existing) return existing;\n\n const table: ERTable = {\n id,\n name,\n columns: [],\n lineNumber,\n };\n tableMap.set(id, table);\n result.tables.push(table);\n return table;\n }\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n const indent = measureIndent(raw);\n\n // Skip empty lines\n if (!trimmed) {\n if (indent === 0) currentTable = null;\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // Metadata directives (before content)\n if (!contentStarted && indent === 0 && /^[a-z][a-z0-9-]*\\s*:/i.test(trimmed)) {\n const colonIdx = trimmed.indexOf(':');\n const key = trimmed.substring(0, colonIdx).trim().toLowerCase();\n const value = trimmed.substring(colonIdx + 1).trim();\n\n if (key === 'chart') {\n if (value.toLowerCase() !== 'er') {\n result.error = `Line ${lineNumber}: Expected chart type \"er\", got \"${value}\"`;\n return result;\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'notation') {\n result.options.notation = value.toLowerCase();\n continue;\n }\n\n // Unknown single-word keys are metadata — skip\n if (!/\\s/.test(key)) continue;\n }\n\n // Indented lines = columns of current table\n if (indent > 0 && currentTable) {\n const colMatch = trimmed.match(COLUMN_RE);\n if (colMatch) {\n const colName = colMatch[1];\n const colType = colMatch[2]?.trim();\n const constraintRaw = colMatch[3];\n const constraints = constraintRaw ? parseConstraints(constraintRaw) : [];\n\n currentTable.columns.push({\n name: colName,\n ...(colType && { type: colType }),\n constraints,\n lineNumber,\n });\n }\n continue;\n }\n\n // At indent 0 — this ends any previous table context\n currentTable = null;\n contentStarted = true;\n\n // Try relationship\n const rel = parseRelationship(trimmed);\n if (rel) {\n getOrCreateTable(rel.source, lineNumber);\n getOrCreateTable(rel.target, lineNumber);\n\n result.relationships.push({\n source: tableId(rel.source),\n target: tableId(rel.target),\n cardinality: { from: rel.from, to: rel.to },\n ...(rel.label && { label: rel.label }),\n lineNumber,\n });\n continue;\n }\n\n // Try table declaration\n const tableDecl = trimmed.match(TABLE_DECL_RE);\n if (tableDecl) {\n const name = tableDecl[1];\n const colorName = tableDecl[2]?.trim();\n const color = colorName ? resolveColor(colorName, palette) : undefined;\n\n const table = getOrCreateTable(name, lineNumber);\n if (color) table.color = color;\n table.lineNumber = lineNumber;\n\n currentTable = table;\n continue;\n }\n }\n\n // Validation\n if (result.tables.length === 0 && !result.error) {\n result.error =\n 'No tables found. Add table declarations like \"users\" or \"orders (blue)\".';\n }\n\n return result;\n}\n\n// ============================================================\n// Detection helper\n// ============================================================\n\n/**\n * Detect if content looks like an ER diagram without explicit `chart: er`.\n * Looks for indented lines with [pk] or [fk] constraint patterns.\n */\nexport function looksLikeERDiagram(content: string): boolean {\n const lines = content.split('\\n');\n\n let hasConstraint = false;\n let hasTableDecl = false;\n let hasRelationship = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('//')) continue;\n\n // Skip metadata\n if (/^(chart|title|notation)\\s*:/i.test(trimmed)) continue;\n\n const indent = measureIndent(line);\n\n if (indent > 0) {\n // Indented line with [pk] or [fk] is strong ER signal\n if (/\\[(pk|fk)\\]/i.test(trimmed)) {\n hasConstraint = true;\n }\n } else {\n // Check for table-like declaration\n if (TABLE_DECL_RE.test(trimmed)) {\n hasTableDecl = true;\n }\n // Check for relationship patterns\n if (REL_SYMBOLIC_RE.test(trimmed) || REL_KEYWORD_RE.test(trimmed)) {\n hasRelationship = true;\n }\n }\n }\n\n // [pk]/[fk] constraint is a strong enough signal\n if (hasConstraint && hasTableDecl) return true;\n\n // Relationship with table declarations and constraints\n if (hasRelationship && hasTableDecl && hasConstraint) return true;\n\n return false;\n}\n","// ============================================================\n// .dgmo Unified Format — Chart Type Router\n// ============================================================\n\nimport { looksLikeSequence } from './sequence/parser';\nimport { looksLikeFlowchart } from './graph/flowchart-parser';\nimport { looksLikeClassDiagram } from './class/parser';\nimport { looksLikeERDiagram } from './er/parser';\n\n/**\n * Framework identifiers used by the .dgmo router.\n * Maps to the existing preview components and export paths.\n */\nexport type DgmoFramework = 'echart' | 'd3' | 'mermaid';\n\n/**\n * Maps every supported chart type string to its backing framework.\n *\n * ECharts: standard chart types (bar, line, pie, etc.), scatter, flow/relationship diagrams, math, heatmap\n * D3: slope, wordcloud, arc diagram, timeline\n */\nexport const DGMO_CHART_TYPE_MAP: Record<string, DgmoFramework> = {\n // Standard charts (via ECharts)\n bar: 'echart',\n line: 'echart',\n 'multi-line': 'echart',\n area: 'echart',\n pie: 'echart',\n doughnut: 'echart',\n radar: 'echart',\n 'polar-area': 'echart',\n 'bar-stacked': 'echart',\n\n // ECharts\n scatter: 'echart',\n sankey: 'echart',\n chord: 'echart',\n function: 'echart',\n heatmap: 'echart',\n funnel: 'echart',\n\n // D3\n slope: 'd3',\n wordcloud: 'd3',\n arc: 'd3',\n timeline: 'd3',\n venn: 'd3',\n quadrant: 'd3',\n sequence: 'd3',\n flowchart: 'd3',\n class: 'd3',\n er: 'd3',\n org: 'd3',\n};\n\n/**\n * Returns the framework for a given chart type, or `null` if unknown.\n */\nexport function getDgmoFramework(chartType: string): DgmoFramework | null {\n return DGMO_CHART_TYPE_MAP[chartType.toLowerCase()] ?? null;\n}\n\n/**\n * Extracts the `chart:` type value from raw file content.\n * Falls back to inference when no explicit `chart:` line is found\n * (e.g. content containing `->` is inferred as `sequence`).\n */\nexport function parseDgmoChartType(content: string): string | null {\n const lines = content.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n // Skip empty lines and comments\n if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('//'))\n continue;\n const match = trimmed.match(/^chart\\s*:\\s*(.+)/i);\n if (match) return match[1].trim().toLowerCase();\n }\n\n // Infer chart type from content patterns (sequence before flowchart —\n // both use `->` but sequence uses bare names while flowchart uses shape delimiters)\n if (looksLikeSequence(content)) return 'sequence';\n if (looksLikeFlowchart(content)) return 'flowchart';\n if (looksLikeClassDiagram(content)) return 'class';\n if (looksLikeERDiagram(content)) return 'er';\n\n return null;\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface OrgTagEntry {\n value: string;\n color: string;\n lineNumber: number;\n}\n\nexport interface OrgTagGroup {\n name: string;\n alias?: string;\n entries: OrgTagEntry[];\n /** Value of the entry marked `default` (nodes without metadata get this) */\n defaultValue?: string;\n lineNumber: number;\n}\n\nexport interface OrgNode {\n id: string;\n label: string;\n metadata: Record<string, string>;\n children: OrgNode[];\n parentId: string | null;\n isContainer: boolean;\n lineNumber: number;\n color?: string;\n}\n\nexport interface ParsedOrg {\n title: string | null;\n titleLineNumber: number | null;\n roots: OrgNode[];\n tagGroups: OrgTagGroup[];\n options: Record<string, string>;\n error: string | null;\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nconst COLOR_SUFFIX_RE = /\\(([^)]+)\\)\\s*$/;\n\nfunction extractColor(\n label: string,\n palette?: PaletteColors\n): { label: string; color?: string } {\n const m = label.match(COLOR_SUFFIX_RE);\n if (!m) return { label };\n const colorName = m[1].trim();\n return {\n label: label.substring(0, m.index!).trim(),\n color: resolveColor(colorName, palette),\n };\n}\n\nconst GROUP_HEADING_RE = /^##\\s+(.+?)(?:\\s+alias\\s+(\\w+))?(?:\\s*\\(([^)]+)\\))?\\s*$/;\nconst CONTAINER_RE = /^\\[([^\\]]+)\\]$/;\nconst METADATA_RE = /^([^:]+):\\s*(.+)$/;\nconst CHART_TYPE_RE = /^chart\\s*:\\s*(.+)/i;\nconst TITLE_RE = /^title\\s*:\\s*(.+)/i;\nconst OPTION_RE = /^([a-z][a-z0-9-]*)\\s*:\\s*(.+)$/i;\n\n// ============================================================\n// Parser\n// ============================================================\n\nexport function parseOrg(\n content: string,\n palette?: PaletteColors\n): ParsedOrg {\n const result: ParsedOrg = {\n title: null,\n titleLineNumber: null,\n roots: [],\n tagGroups: [],\n options: {},\n error: null,\n };\n\n if (!content || !content.trim()) {\n result.error = 'No content provided';\n return result;\n }\n\n const lines = content.split('\\n');\n let contentStarted = false;\n let nodeCounter = 0;\n let containerCounter = 0;\n\n // Tag group parsing state\n let currentTagGroup: OrgTagGroup | null = null;\n\n // Alias map: alias (lowercased) → group name (lowercased)\n const aliasMap = new Map<string, string>();\n\n // Indent stack for hierarchy tracking\n // Each entry: { node, indent }\n const indentStack: { node: OrgNode; indent: number }[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNumber = i + 1;\n const trimmed = line.trim();\n\n // Skip empty lines\n if (!trimmed) {\n // Empty line ends a tag group\n if (currentTagGroup) {\n currentTagGroup = null;\n }\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // --- Header phase ---\n\n // chart: type\n if (!contentStarted) {\n const chartMatch = trimmed.match(CHART_TYPE_RE);\n if (chartMatch) {\n const chartType = chartMatch[1].trim().toLowerCase();\n if (chartType !== 'org') {\n result.error = `Line ${lineNumber}: Expected chart type \"org\", got \"${chartType}\"`;\n return result;\n }\n continue;\n }\n }\n\n // title: value\n if (!contentStarted) {\n const titleMatch = trimmed.match(TITLE_RE);\n if (titleMatch) {\n result.title = titleMatch[1].trim();\n result.titleLineNumber = lineNumber;\n continue;\n }\n }\n\n // Generic header options (key: value lines before content/tag groups)\n // Only match non-indented lines with simple hyphenated keys\n if (!contentStarted && !currentTagGroup && measureIndent(line) === 0) {\n const optMatch = trimmed.match(OPTION_RE);\n if (optMatch && !trimmed.startsWith('##')) {\n const key = optMatch[1].trim().toLowerCase();\n if (key !== 'chart' && key !== 'title') {\n result.options[key] = optMatch[2].trim();\n continue;\n }\n }\n }\n\n // ## Tag group heading\n const groupMatch = trimmed.match(GROUP_HEADING_RE);\n if (groupMatch) {\n if (contentStarted) {\n result.error = `Line ${lineNumber}: Tag groups (##) must appear before org content`;\n return result;\n }\n const groupName = groupMatch[1].trim();\n const alias = groupMatch[2] || undefined;\n currentTagGroup = {\n name: groupName,\n alias,\n entries: [],\n lineNumber,\n };\n if (alias) {\n aliasMap.set(alias.toLowerCase(), groupName.toLowerCase());\n }\n result.tagGroups.push(currentTagGroup);\n continue;\n }\n\n // Tag group entries (indented Value(color) [default] under ## heading)\n if (currentTagGroup && !contentStarted) {\n const indent = measureIndent(line);\n if (indent > 0) {\n // Strip trailing `default` keyword before extracting color\n const isDefault = /\\bdefault\\s*$/.test(trimmed);\n const entryText = isDefault\n ? trimmed.replace(/\\s+default\\s*$/, '').trim()\n : trimmed;\n const { label, color } = extractColor(entryText, palette);\n if (!color) {\n result.error = `Line ${lineNumber}: Expected 'Value(color)' in tag group '${currentTagGroup.name}'`;\n return result;\n }\n if (isDefault) {\n currentTagGroup.defaultValue = label;\n }\n currentTagGroup.entries.push({\n value: label,\n color,\n lineNumber,\n });\n continue;\n }\n // Non-indented line after tag group — fall through to content parsing\n currentTagGroup = null;\n }\n\n // --- Org content phase ---\n contentStarted = true;\n currentTagGroup = null;\n\n const indent = measureIndent(line);\n\n // Check for container syntax: [Team Name]\n const containerMatch = trimmed.match(CONTAINER_RE);\n\n // Check for metadata syntax: key: value\n // Lines containing '|' are pipe-delimited nodes (e.g. \"Alice | role: Engineer\"),\n // not metadata — skip the metadata regex for them.\n const metadataMatch = trimmed.includes('|') ? null : trimmed.match(METADATA_RE);\n\n if (containerMatch) {\n // It's a container node\n const rawLabel = containerMatch[1].trim();\n const { label, color } = extractColor(rawLabel, palette);\n\n containerCounter++;\n const node: OrgNode = {\n id: `container-${containerCounter}`,\n label,\n metadata: {},\n children: [],\n parentId: null,\n isContainer: true,\n lineNumber,\n color,\n };\n\n attachNode(node, indent, indentStack, result);\n } else if (metadataMatch && indentStack.length > 0) {\n // It's a metadata line — attach to most recent node on stack at shallower indent\n const rawKey = metadataMatch[1].trim().toLowerCase();\n const key = aliasMap.get(rawKey) ?? rawKey;\n const value = metadataMatch[2].trim();\n\n // Find the parent node: top of stack (the most recent node)\n const parent = findMetadataParent(indent, indentStack);\n if (!parent) {\n result.error = `Line ${lineNumber}: Metadata has no parent node`;\n return result;\n }\n parent.metadata[key] = value;\n } else if (metadataMatch && indentStack.length === 0) {\n // Metadata with no parent — could be a node label that happens to contain ':'\n // Treat it as a node if it's at indent 0 and no nodes exist yet\n // Otherwise it's an orphan metadata error\n if (indent === 0) {\n // Treat as a node label (e.g., \"Dr. Smith: Surgeon\" is a valid name)\n const node = parseNodeLabel(trimmed, indent, lineNumber, palette, ++nodeCounter, aliasMap);\n attachNode(node, indent, indentStack, result);\n } else {\n result.error = `Line ${lineNumber}: Metadata has no parent node`;\n return result;\n }\n } else {\n // It's a node label — possibly with single-line pipe-delimited metadata\n const node = parseNodeLabel(trimmed, indent, lineNumber, palette, ++nodeCounter, aliasMap);\n attachNode(node, indent, indentStack, result);\n }\n }\n\n if (result.roots.length === 0 && !result.error) {\n result.error = 'No nodes found in org chart';\n }\n\n return result;\n}\n\n// ============================================================\n// Internal helpers\n// ============================================================\n\nfunction parseNodeLabel(\n trimmed: string,\n _indent: number,\n lineNumber: number,\n palette: PaletteColors | undefined,\n counter: number,\n aliasMap: Map<string, string> = new Map()\n): OrgNode {\n // Check for single-line compact metadata: \"Alice Park | role: Senior | location: NY\"\n const segments = trimmed.split('|').map((s) => s.trim());\n\n let rawLabel = segments[0];\n const { label, color } = extractColor(rawLabel, palette);\n\n const metadata: Record<string, string> = {};\n // Collect all metadata parts: split pipe segments further on commas\n const metaParts: string[] = [];\n for (let j = 1; j < segments.length; j++) {\n for (const part of segments[j].split(',')) {\n const trimmedPart = part.trim();\n if (trimmedPart) metaParts.push(trimmedPart);\n }\n }\n for (const part of metaParts) {\n const colonIdx = part.indexOf(':');\n if (colonIdx > 0) {\n const rawKey = part.substring(0, colonIdx).trim().toLowerCase();\n const key = aliasMap.get(rawKey) ?? rawKey;\n const value = part.substring(colonIdx + 1).trim();\n metadata[key] = value;\n }\n }\n\n return {\n id: `node-${counter}`,\n label,\n metadata,\n children: [],\n parentId: null,\n isContainer: false,\n lineNumber,\n color,\n };\n}\n\nfunction attachNode(\n node: OrgNode,\n indent: number,\n indentStack: { node: OrgNode; indent: number }[],\n result: ParsedOrg\n): void {\n // Pop stack entries with indent >= current indent\n while (indentStack.length > 0) {\n const top = indentStack[indentStack.length - 1];\n if (top.indent < indent) break;\n indentStack.pop();\n }\n\n if (indentStack.length > 0) {\n // Stack top becomes parent\n const parent = indentStack[indentStack.length - 1].node;\n node.parentId = parent.id;\n parent.children.push(node);\n } else {\n // Top-level root\n result.roots.push(node);\n }\n\n // Push new node onto stack\n indentStack.push({ node, indent });\n}\n\nfunction findMetadataParent(\n indent: number,\n indentStack: { node: OrgNode; indent: number }[]\n): OrgNode | null {\n // Walk backward from the top of the stack to find the most recent node\n // at a shallower indent than the metadata line\n for (let i = indentStack.length - 1; i >= 0; i--) {\n if (indentStack[i].indent < indent) {\n return indentStack[i].node;\n }\n }\n // If metadata is at same indent as top node, attach to top node\n if (indentStack.length > 0) {\n return indentStack[indentStack.length - 1].node;\n }\n return null;\n}\n","// ============================================================\n// Org Chart Tree Layout Engine (d3-hierarchy)\n// ============================================================\n\nimport { hierarchy, tree } from 'd3-hierarchy';\nimport type { ParsedOrg, OrgNode, OrgTagGroup } from './parser';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface OrgLayoutNode {\n id: string;\n label: string;\n metadata: Record<string, string>;\n isContainer: boolean;\n lineNumber: number;\n color?: string;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Count of hidden descendants when this node is collapsed */\n hiddenCount?: number;\n /** True if node has children (expanded or collapsed) — drives toggle UI */\n hasChildren?: boolean;\n}\n\nexport interface OrgLayoutEdge {\n sourceId: string;\n targetId: string;\n points: { x: number; y: number }[];\n}\n\nexport interface OrgContainerBounds {\n nodeId: string;\n label: string;\n lineNumber: number;\n color?: string;\n metadata: Record<string, string>;\n x: number;\n y: number;\n width: number;\n height: number;\n labelHeight: number;\n /** Count of hidden descendants when this container is collapsed */\n hiddenCount?: number;\n /** True if container has children (expanded or collapsed) — drives toggle UI */\n hasChildren?: boolean;\n}\n\nexport interface OrgLegendEntry {\n value: string;\n color: string;\n}\n\nexport interface OrgLegendGroup {\n name: string;\n entries: OrgLegendEntry[];\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface OrgLayoutResult {\n nodes: OrgLayoutNode[];\n edges: OrgLayoutEdge[];\n containers: OrgContainerBounds[];\n legend: OrgLegendGroup[];\n width: number;\n height: number;\n}\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst CHAR_WIDTH = 7.5;\nconst LABEL_FONT_SIZE = 13;\nconst META_FONT_SIZE = 11;\nconst META_LINE_HEIGHT = 16;\nconst HEADER_HEIGHT = 28;\nconst SEPARATOR_GAP = 6;\nconst CARD_H_PAD = 20;\nconst CARD_V_PAD = 10;\nconst MIN_CARD_WIDTH = 140;\nconst H_GAP = 30;\nconst V_GAP = 50;\nconst MARGIN = 40;\nconst CONTAINER_PAD_X = 24;\nconst CONTAINER_PAD_BOTTOM = 24;\nconst CONTAINER_LABEL_HEIGHT = 28;\nconst CONTAINER_META_LINE_HEIGHT = 16;\nconst STACK_V_GAP = 20;\n\n\n// Legend\nconst LEGEND_GAP = 30;\nconst LEGEND_DOT_R = 5;\nconst LEGEND_DOT_TEXT_GAP = 6;\nconst LEGEND_ENTRY_GAP = 12;\nconst LEGEND_PAD = 10;\nconst LEGEND_HEADER_H = 20;\nconst LEGEND_ENTRY_H = 18;\nconst LEGEND_MAX_PER_ROW = 3;\nconst LEGEND_V_GAP = 12;\nconst EYE_ICON_WIDTH = 16;\nconst EYE_ICON_GAP = 6;\n\n// ============================================================\n// Helpers\n// ============================================================\n\n/** Count all non-container descendants recursively, including hidden (collapsed) ones. */\nfunction countDescendantNodes(node: OrgNode, hiddenCounts?: Map<string, number>): number {\n let count = 0;\n for (const child of node.children) {\n count += (child.isContainer ? 0 : 1) + countDescendantNodes(child, hiddenCounts);\n const hc = hiddenCounts?.get(child.id);\n if (hc) count += hc;\n }\n return count;\n}\n\n// ============================================================\n// Card Sizing\n// ============================================================\n\nfunction filterMetadata(\n metadata: Record<string, string>,\n hiddenAttributes?: Set<string>\n): Record<string, string> {\n if (!hiddenAttributes || hiddenAttributes.size === 0) return metadata;\n const filtered: Record<string, string> = {};\n for (const [key, value] of Object.entries(metadata)) {\n if (!hiddenAttributes.has(key)) {\n filtered[key] = value;\n }\n }\n return filtered;\n}\n\nfunction computeCardWidth(label: string, meta: Record<string, string>): number {\n let maxChars = label.length;\n\n for (const [key, value] of Object.entries(meta)) {\n const lineChars = key.length + 2 + value.length; // \"key: value\"\n if (lineChars > maxChars) maxChars = lineChars;\n }\n\n return Math.max(MIN_CARD_WIDTH, Math.ceil(maxChars * CHAR_WIDTH) + CARD_H_PAD * 2);\n}\n\nfunction computeCardHeight(meta: Record<string, string>): number {\n const metaCount = Object.keys(meta).length;\n if (metaCount === 0) return HEADER_HEIGHT + CARD_V_PAD;\n return HEADER_HEIGHT + SEPARATOR_GAP + metaCount * META_LINE_HEIGHT + CARD_V_PAD;\n}\n\n// ============================================================\n// Tag Group Color Resolution\n// ============================================================\n\nfunction resolveNodeColor(\n node: OrgNode,\n tagGroups: OrgTagGroup[],\n activeGroupName: string | null\n): string | undefined {\n if (node.color) return node.color;\n if (!activeGroupName) return undefined;\n\n const group = tagGroups.find(\n (g) => g.name.toLowerCase() === activeGroupName.toLowerCase()\n );\n if (!group) return undefined;\n const metaValue =\n node.metadata[group.name.toLowerCase()] ??\n (node.isContainer ? undefined : group.defaultValue);\n if (!metaValue) return '#999999';\n return group.entries.find(\n (e) => e.value.toLowerCase() === metaValue.toLowerCase()\n )?.color ?? '#999999';\n}\n\n// ============================================================\n// Hierarchy Helpers\n// ============================================================\n\ninterface TreeNode {\n orgNode: OrgNode;\n children: TreeNode[];\n width: number;\n height: number;\n}\n\nfunction buildTreeNodes(\n nodes: OrgNode[],\n hiddenCounts?: Map<string, number>,\n hiddenAttributes?: Set<string>,\n subNodeLabel?: string,\n showSubNodeCount?: boolean\n): TreeNode[] {\n return nodes.map((orgNode) => {\n const meta = filterMetadata(orgNode.metadata, hiddenAttributes);\n const hc = hiddenCounts?.get(orgNode.id);\n if (!orgNode.isContainer && showSubNodeCount && !(hc != null && hc > 0)) {\n const count = countDescendantNodes(orgNode, hiddenCounts);\n if (count > 0) {\n meta[subNodeLabel ?? 'Sub-node Count'] = String(count);\n }\n }\n return {\n orgNode,\n children: buildTreeNodes(orgNode.children, hiddenCounts, hiddenAttributes, subNodeLabel, showSubNodeCount),\n width: computeCardWidth(orgNode.label, meta),\n height: computeCardHeight(meta),\n };\n });\n}\n\n/**\n * Count total descendants (children + grandchildren + ...) of a TreeNode.\n */\nfunction countDescendants(node: TreeNode): number {\n let count = 0;\n for (const child of node.children) {\n count += 1 + countDescendants(child);\n }\n return count;\n}\n\n/**\n * Recursively reorder children so subtrees with the most descendants\n * occupy center positions. Produces a balanced, symmetrical layout.\n * Skips nodes with ≤2 children (no meaningful center to target).\n */\nfunction centerHeavyChildren(node: TreeNode): void {\n for (const child of node.children) {\n centerHeavyChildren(child);\n }\n if (node.children.length <= 2) return;\n\n const weighted = node.children\n .map((child) => ({ child, weight: countDescendants(child) }))\n .sort((a, b) => b.weight - a.weight);\n\n const result: TreeNode[] = new Array(weighted.length);\n const mid = Math.floor((weighted.length - 1) / 2);\n let left = mid;\n let right = mid;\n\n for (let i = 0; i < weighted.length; i++) {\n if (i === 0) {\n result[mid] = weighted[i].child;\n } else if (i % 2 === 1) {\n right++;\n result[right] = weighted[i].child;\n } else {\n left--;\n result[left] = weighted[i].child;\n }\n }\n\n node.children = result;\n}\n\n// ============================================================\n// Layout\n// ============================================================\n\nfunction computeLegendGroups(tagGroups: OrgTagGroup[], showEyeIcons: boolean): OrgLegendGroup[] {\n const groups: OrgLegendGroup[] = [];\n\n for (const group of tagGroups) {\n if (group.entries.length === 0) continue;\n\n const entryWidths = group.entries.map(\n (e) =>\n LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP + e.value.length * CHAR_WIDTH\n );\n\n // Compute max width per column so columns align across rows\n const numRows = Math.ceil(entryWidths.length / LEGEND_MAX_PER_ROW);\n const colWidths: number[] = [];\n for (let col = 0; col < LEGEND_MAX_PER_ROW; col++) {\n let maxW = 0;\n for (let row = 0; row < numRows; row++) {\n const idx = row * LEGEND_MAX_PER_ROW + col;\n if (idx < entryWidths.length && entryWidths[idx] > maxW) {\n maxW = entryWidths[idx];\n }\n }\n if (maxW > 0) colWidths.push(maxW);\n }\n\n const eyeExtra = showEyeIcons ? EYE_ICON_GAP + EYE_ICON_WIDTH : 0;\n const headerWidth = group.name.length * CHAR_WIDTH + eyeExtra;\n const totalColumnsWidth =\n colWidths.reduce((s, w) => s + w, 0) +\n (colWidths.length - 1) * LEGEND_ENTRY_GAP;\n const maxRowWidth = Math.max(headerWidth, totalColumnsWidth);\n\n groups.push({\n name: group.name,\n entries: group.entries.map((e) => ({ value: e.value, color: e.color })),\n x: 0,\n y: 0,\n width: maxRowWidth + LEGEND_PAD * 2,\n height: LEGEND_HEADER_H + numRows * LEGEND_ENTRY_H + LEGEND_PAD,\n });\n }\n\n return groups;\n}\n\n/**\n * Inject default tag group values into non-container node metadata.\n * Idempotent — only sets keys not already present.\n */\nfunction injectDefaultMetadata(\n roots: OrgNode[],\n tagGroups: OrgTagGroup[]\n): void {\n const defaults: { key: string; value: string }[] = [];\n for (const group of tagGroups) {\n if (group.defaultValue) {\n defaults.push({ key: group.name.toLowerCase(), value: group.defaultValue });\n }\n }\n if (defaults.length === 0) return;\n\n const walk = (node: OrgNode) => {\n if (!node.isContainer) {\n for (const { key, value } of defaults) {\n if (!(key in node.metadata)) {\n node.metadata[key] = value;\n }\n }\n }\n for (const child of node.children) walk(child);\n };\n for (const root of roots) walk(root);\n}\n\nexport function layoutOrg(\n parsed: ParsedOrg,\n hiddenCounts?: Map<string, number>,\n activeTagGroup?: string | null,\n hiddenAttributes?: Set<string>\n): OrgLayoutResult {\n if (parsed.roots.length === 0) {\n return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };\n }\n\n // Inject default tag group values into node metadata for display.\n // Must happen before buildTreeNodes so card sizing accounts for extra rows.\n injectDefaultMetadata(parsed.roots, parsed.tagGroups);\n\n // Build tree structure\n const subNodeLabel = parsed.options['sub-node-label'] ?? undefined;\n const showSubNodeCount = parsed.options['show-sub-node-count']?.toLowerCase() === 'yes';\n const treeNodes = buildTreeNodes(parsed.roots, hiddenCounts, hiddenAttributes, subNodeLabel, showSubNodeCount);\n\n // Single root or virtual root for multiple roots\n let root: TreeNode;\n if (treeNodes.length === 1) {\n root = treeNodes[0];\n } else {\n root = {\n orgNode: {\n id: '__virtual_root__',\n label: '',\n metadata: {},\n children: parsed.roots,\n parentId: null,\n isContainer: false,\n lineNumber: 0,\n },\n children: treeNodes,\n width: 0,\n height: 0,\n };\n }\n\n // Pre-compute max card dimensions for node separation\n let maxWidth = 0;\n let maxHeight = 0;\n const allTreeNodes: TreeNode[] = [];\n const collectNodes = (tn: TreeNode) => {\n if (tn.orgNode.id !== '__virtual_root__') {\n allTreeNodes.push(tn);\n if (tn.width > maxWidth) maxWidth = tn.width;\n if (tn.height > maxHeight) maxHeight = tn.height;\n }\n for (const child of tn.children) collectNodes(child);\n };\n collectNodes(root);\n\n // Standardize all cards to the widest width for uniform appearance\n for (const tn of allTreeNodes) {\n tn.width = maxWidth;\n }\n\n // Collapse leaf containers: when a container's children are ALL leaves\n // (no grandchildren), replace them with a single virtual stack node so\n // the d3 tree allocates a narrow column instead of a wide row.\n const leafStacks = new Map<\n string,\n { children: TreeNode[]; placeholderId: string }\n >();\n\n const collapseLeafContainers = (tn: TreeNode): void => {\n for (const child of tn.children) collapseLeafContainers(child);\n\n if (\n tn.orgNode.isContainer &&\n tn.children.length > 0 &&\n tn.children.every((c) => c.children.length === 0)\n ) {\n const placeholderId = `__stack_${tn.orgNode.id}`;\n leafStacks.set(tn.orgNode.id, {\n children: [...tn.children],\n placeholderId,\n });\n\n const maxW = Math.max(...tn.children.map((c) => c.width));\n // Standardize all children to the widest card width\n for (const child of tn.children) {\n child.width = maxW;\n }\n const totalH =\n tn.children.reduce((s, c) => s + c.height, 0) +\n (tn.children.length - 1) * STACK_V_GAP;\n\n tn.children = [\n {\n orgNode: {\n id: placeholderId,\n label: '',\n metadata: {},\n children: [],\n parentId: tn.orgNode.id,\n isContainer: false,\n lineNumber: 0,\n },\n children: [],\n width: maxW,\n height: totalH,\n },\n ];\n }\n };\n collapseLeafContainers(root);\n\n // Reorder children: heaviest subtrees in center positions\n centerHeavyChildren(root);\n\n // Build d3 hierarchy\n const h = hierarchy<TreeNode>(root, (d) => d.children);\n\n // Run Reingold-Tilford tree layout with nodeSize\n // x = horizontal spread, y = vertical (depth)\n const treeLayout = tree<TreeNode>().nodeSize([\n maxWidth + H_GAP,\n maxHeight + V_GAP,\n ]);\n treeLayout(h);\n\n // Post-layout: compact vertical spacing per depth level.\n // D3 tree uses uniform nodeSize (maxHeight + V_GAP) for every level, which\n // creates disproportionate gaps when short nodes (no metadata) are placed at\n // the same level-spacing as tall nodes (multiple metadata rows). Recompute\n // Y positions so each level's gap is based on the actual max height at that\n // level rather than the global max.\n {\n const descendants = h.descendants().filter(\n (d) => d.data.orgNode.id !== '__virtual_root__'\n );\n\n // Collect max actual card height per depth level\n const levelMaxHeight = new Map<number, number>();\n for (const d of descendants) {\n const cur = levelMaxHeight.get(d.depth) ?? 0;\n if (d.data.height > cur) levelMaxHeight.set(d.depth, d.data.height);\n }\n\n // Compute compacted Y position for each depth level\n const maxDepth = Math.max(...levelMaxHeight.keys(), 0);\n const compactedY = new Map<number, number>();\n // Virtual root (depth 0 in hierarchy) stays at y=0\n // First real level starts at depth 1 for multi-root or depth 0 for single root.\n // We compute based on the d3 hierarchy's depth numbering.\n const rootDepth = treeNodes.length === 1 ? 0 : 1;\n compactedY.set(rootDepth, 0);\n for (let d = rootDepth + 1; d <= maxDepth; d++) {\n const parentH = levelMaxHeight.get(d - 1) ?? maxHeight;\n const prevY = compactedY.get(d - 1) ?? 0;\n compactedY.set(d, prevY + parentH + V_GAP);\n }\n\n // Shift each node from uniform Y to compacted Y (top-aligned).\n // Siblings share the same Y so connecting edges align cleanly.\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n d.y = compactedY.get(d.depth) ?? d.y!;\n }\n }\n\n // Post-layout: tighten vertical spacing inside containers.\n // Container-with-children nodes render as background boxes (not cards),\n // so their children can sit closer to the container header.\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (!d.data.orgNode.isContainer) continue;\n if (!d.children || d.children.length === 0) continue;\n\n // Actual gap between this container and its direct children\n const childY = d.children[0].y!;\n const actualLevelGap = childY - d.y!;\n\n const metaCount = Object.keys(d.data.orgNode.metadata).length;\n const headerHeight =\n CONTAINER_LABEL_HEIGHT + metaCount * CONTAINER_META_LINE_HEIGHT;\n const desiredGap = headerHeight + 15;\n const shiftUp = actualLevelGap - desiredGap;\n if (shiftUp <= 0) continue;\n\n // Shift all descendants upward\n const shift = (node: typeof d) => {\n if (node.children) {\n for (const child of node.children) {\n child.y! -= shiftUp;\n shift(child);\n }\n }\n };\n shift(d);\n }\n\n // Post-layout: tighten gap between non-container parents and their\n // container children. Containers render as header boxes (not full cards),\n // so the standard inter-level gap is visually excessive.\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (d.data.orgNode.isContainer) continue; // only non-container parents\n if (!d.children || d.children.length === 0) continue;\n\n // Only apply when ALL direct children are containers — mixed children\n // need standard spacing so siblings stay aligned.\n if (!d.children.every((c) => c.data.orgNode.isContainer)) continue;\n\n const parentBottomY = d.y! + d.data.height;\n const firstChildY = Math.min(...d.children.map((c) => c.y!));\n const currentGap = firstChildY - parentBottomY;\n const desiredGap = V_GAP * 0.6;\n const shiftUp = currentGap - desiredGap;\n if (shiftUp <= 0) continue;\n\n // Shift all container children and their descendants up\n const shiftDown = (node: typeof d) => {\n node.y! -= shiftUp;\n if (node.children) {\n for (const child of node.children) {\n shiftDown(child);\n }\n }\n };\n for (const child of d.children) {\n shiftDown(child);\n }\n }\n\n // Post-layout: compact sibling spacing based on actual subtree widths.\n // D3 uses uniform nodeSize so narrow stacks get the same gap as wide\n // subtrees. Process bottom-up so inner subtrees are compact first.\n {\n type HNode = (typeof h);\n const subtreeExtent = (node: HNode): { minX: number; maxX: number } => {\n let min = Infinity;\n let max = -Infinity;\n const walk = (n: HNode) => {\n // Container boxes extend beyond card bounds by padding\n const pad = n.data.orgNode.isContainer ? CONTAINER_PAD_X : 0;\n const l = n.x! - n.data.width / 2 - pad;\n const r = n.x! + n.data.width / 2 + pad;\n if (l < min) min = l;\n if (r > max) max = r;\n if (n.children) n.children.forEach(walk);\n };\n walk(node);\n return { minX: min, maxX: max };\n };\n\n const shiftX = (node: HNode, dx: number) => {\n node.x! += dx;\n if (node.children) node.children.forEach((c) => shiftX(c, dx));\n };\n\n const internalNodes = h\n .descendants()\n .filter((d) => d.children && d.children.length >= 2)\n .sort((a, b) => b.depth - a.depth);\n\n for (const parent of internalNodes) {\n const children = parent.children!;\n\n const extents = children.map((child) => {\n const ext = subtreeExtent(child);\n return {\n relLeft: ext.minX - child.x!,\n relRight: ext.maxX - child.x!,\n };\n });\n\n const currentCenter =\n (children[0].x! + children[children.length - 1].x!) / 2;\n\n const positions: number[] = [0];\n for (let i = 1; i < children.length; i++) {\n const prevRight = positions[i - 1] + extents[i - 1].relRight;\n positions[i] = prevRight + H_GAP - extents[i].relLeft;\n }\n\n const newCenter =\n (positions[0] + positions[positions.length - 1]) / 2;\n const centerShift = currentCenter - newCenter;\n\n for (let i = 0; i < children.length; i++) {\n const newX = positions[i] + centerShift;\n const dx = newX - children[i].x!;\n if (Math.abs(dx) > 0.001) {\n shiftX(children[i], dx);\n }\n }\n }\n }\n\n // Post-layout: center each parent exactly over its direct children.\n // d3-hierarchy centers over the subtree centroid, which drifts when\n // grandchildren have asymmetric widths. Process bottom-up so parents\n // see already-adjusted child positions.\n {\n const parentNodes = h\n .descendants()\n .filter(\n (d) =>\n d.children &&\n d.children.length >= 1 &&\n d.data.orgNode.id !== '__virtual_root__'\n )\n .sort((a, b) => b.depth - a.depth);\n\n for (const parent of parentNodes) {\n const childXs = parent.children!.map((c) => c.x!);\n const desiredX = (Math.min(...childXs) + Math.max(...childXs)) / 2;\n parent.x = desiredX;\n }\n }\n\n // Collect positioned nodes and edges\n const layoutNodes: OrgLayoutNode[] = [];\n const layoutEdges: OrgLayoutEdge[] = [];\n\n // Find bounding box and build outputs\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n\n // Expand leaf container stacks: compute individual child positions\n // in d3 coordinate space (before offset) so bounding box is correct\n interface ExpandedChild {\n orgNode: OrgNode;\n width: number;\n height: number;\n cx: number;\n cy: number;\n }\n const expandedChildren: ExpandedChild[] = [];\n\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (!d.data.orgNode.id.startsWith('__stack_')) continue;\n\n const containerId = d.data.orgNode.id.replace('__stack_', '');\n const stack = leafStacks.get(containerId);\n if (!stack) continue;\n\n let currentY = d.y!;\n for (const child of stack.children) {\n expandedChildren.push({\n orgNode: child.orgNode,\n width: child.width,\n height: child.height,\n cx: d.x!,\n cy: currentY,\n });\n currentY += child.height + STACK_V_GAP;\n }\n }\n\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (d.data.orgNode.id.startsWith('__stack_')) continue;\n\n const w = d.data.width;\n const ht = d.data.height;\n const cx = d.x!;\n const cy = d.y!;\n\n if (cx - w / 2 < minX) minX = cx - w / 2;\n if (cx + w / 2 > maxX) maxX = cx + w / 2;\n if (cy < minY) minY = cy;\n if (cy + ht > maxY) maxY = cy + ht;\n }\n\n for (const ec of expandedChildren) {\n if (ec.cx - ec.width / 2 < minX) minX = ec.cx - ec.width / 2;\n if (ec.cx + ec.width / 2 > maxX) maxX = ec.cx + ec.width / 2;\n if (ec.cy < minY) minY = ec.cy;\n if (ec.cy + ec.height > maxY) maxY = ec.cy + ec.height;\n }\n\n // Translate so all coordinates are positive, starting at MARGIN\n const offsetX = -minX + MARGIN;\n const offsetY = -minY + MARGIN;\n\n // Add expanded stack children as layout nodes\n const subNodeKey = subNodeLabel ?? 'Sub-node Count';\n for (const ec of expandedChildren) {\n const hc = hiddenCounts?.get(ec.orgNode.id);\n const meta = filterMetadata(ec.orgNode.metadata, hiddenAttributes);\n if (!ec.orgNode.isContainer && showSubNodeCount && !(hc != null && hc > 0)) {\n const count = countDescendantNodes(ec.orgNode, hiddenCounts);\n if (count > 0) meta[subNodeKey] = String(count);\n }\n layoutNodes.push({\n id: ec.orgNode.id,\n label: ec.orgNode.label,\n metadata: meta,\n isContainer: ec.orgNode.isContainer,\n lineNumber: ec.orgNode.lineNumber,\n color: resolveNodeColor(ec.orgNode, parsed.tagGroups, activeTagGroup ?? null),\n x: ec.cx + offsetX,\n y: ec.cy + offsetY,\n width: ec.width,\n height: ec.height,\n hiddenCount: hc,\n hasChildren: (ec.orgNode.children.length > 0 || (hc != null && hc > 0)) || undefined,\n });\n }\n\n // Map parent ID → { parentX, parentBottomY, children[] } for bus-style edges\n const busGroups = new Map<\n string,\n {\n parentX: number;\n parentBottomY: number;\n children: { id: string; x: number; topY: number }[];\n }\n >();\n\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (d.data.orgNode.id.startsWith('__stack_')) continue;\n\n const orgNode = d.data.orgNode;\n const w = d.data.width;\n const ht = d.data.height;\n const x = d.x! + offsetX;\n const y = d.y! + offsetY;\n\n const hc = hiddenCounts?.get(orgNode.id);\n const nodeMeta = filterMetadata(orgNode.metadata, hiddenAttributes);\n if (!orgNode.isContainer && showSubNodeCount && !(hc != null && hc > 0)) {\n const count = countDescendantNodes(orgNode, hiddenCounts);\n if (count > 0) nodeMeta[subNodeKey] = String(count);\n }\n layoutNodes.push({\n id: orgNode.id,\n label: orgNode.label,\n metadata: nodeMeta,\n isContainer: orgNode.isContainer,\n lineNumber: orgNode.lineNumber,\n color: resolveNodeColor(orgNode, parsed.tagGroups, activeTagGroup ?? null),\n x,\n y,\n width: w,\n height: ht,\n hiddenCount: hc,\n hasChildren: (d.children != null && d.children.length > 0) || (hc != null && hc > 0) || undefined,\n });\n\n // Collect children per parent for bus-style edge generation\n const parentIsContainerBox =\n d.parent?.data.orgNode.isContainer &&\n d.parent.children &&\n d.parent.children.length > 0;\n if (\n d.parent &&\n d.parent.data.orgNode.id !== '__virtual_root__' &&\n !parentIsContainerBox\n ) {\n const parentId = d.parent.data.orgNode.id;\n if (!busGroups.has(parentId)) {\n const px = d.parent.x! + offsetX;\n const py = d.parent.y! + offsetY;\n const parentH = d.parent.data.height;\n busGroups.set(parentId, {\n parentX: px,\n parentBottomY: py + parentH,\n children: [],\n });\n }\n busGroups.get(parentId)!.children.push({\n id: orgNode.id,\n x,\n topY: y,\n });\n }\n }\n\n // Generate non-overlapping edges using bus pattern\n for (const [parentId, group] of busGroups) {\n const { parentX, parentBottomY, children } = group;\n\n if (children.length === 1) {\n // Single child: simple elbow (no overlap possible)\n const child = children[0];\n const midY = (parentBottomY + child.topY) / 2;\n layoutEdges.push({\n sourceId: parentId,\n targetId: child.id,\n points: [\n { x: parentX, y: parentBottomY },\n { x: parentX, y: midY },\n { x: child.x, y: midY },\n { x: child.x, y: child.topY },\n ],\n });\n } else {\n // Bus pattern: trunk + horizontal bar + per-child drops\n const midY = (parentBottomY + children[0].topY) / 2;\n const childXs = children.map((c) => c.x);\n const leftX = Math.min(...childXs);\n const rightX = Math.max(...childXs);\n\n // Trunk: parent bottom → midY\n layoutEdges.push({\n sourceId: parentId,\n targetId: parentId,\n points: [\n { x: parentX, y: parentBottomY },\n { x: parentX, y: midY },\n ],\n });\n\n // Horizontal bus: leftmost child → rightmost child at midY\n layoutEdges.push({\n sourceId: parentId,\n targetId: parentId,\n points: [\n { x: leftX, y: midY },\n { x: rightX, y: midY },\n ],\n });\n\n // Drops: midY → child top for each child\n for (const child of children) {\n layoutEdges.push({\n sourceId: parentId,\n targetId: child.id,\n points: [\n { x: child.x, y: midY },\n { x: child.x, y: child.topY },\n ],\n });\n }\n }\n }\n\n // Compute container bounds from d3 hierarchy (bottom-up so inner\n // container boxes are available when computing outer containers)\n const allContainerNodes = h.descendants().filter(\n (d) =>\n d.data.orgNode.id !== '__virtual_root__' &&\n d.data.orgNode.isContainer\n );\n\n // Map from node ID to computed visual bounds (offset-space)\n const containerBoundsMap = new Map<\n string,\n { minX: number; maxX: number; minY: number; maxY: number }\n >();\n\n const containers: OrgContainerBounds[] = [];\n\n // First pass: childless containers — simple boxes at their own position.\n // Must be computed before parent containers so their bounds are available.\n const EMPTY_CONTAINER_MIN_HEIGHT = 60;\n for (const d of allContainerNodes) {\n if (d.children && d.children.length > 0) continue;\n\n const cx = d.x! + offsetX;\n const cy = d.y! + offsetY;\n const metaCount = Object.keys(d.data.orgNode.metadata).length;\n const labelHeight =\n CONTAINER_LABEL_HEIGHT + metaCount * CONTAINER_META_LINE_HEIGHT;\n const boxWidth = d.data.width;\n const boxHeight = Math.max(labelHeight + CONTAINER_PAD_BOTTOM, EMPTY_CONTAINER_MIN_HEIGHT);\n const boxX = cx - boxWidth / 2;\n const boxY = cy;\n\n containerBoundsMap.set(d.data.orgNode.id, {\n minX: boxX,\n maxX: boxX + boxWidth,\n minY: boxY,\n maxY: boxY + boxHeight,\n });\n\n const chc = hiddenCounts?.get(d.data.orgNode.id);\n const cMeta = filterMetadata(d.data.orgNode.metadata, hiddenAttributes);\n containers.push({\n nodeId: d.data.orgNode.id,\n label: d.data.orgNode.label,\n lineNumber: d.data.orgNode.lineNumber,\n color: resolveNodeColor(d.data.orgNode, parsed.tagGroups, activeTagGroup ?? null),\n metadata: cMeta,\n x: boxX,\n y: boxY,\n width: boxWidth,\n height: boxHeight,\n labelHeight,\n hiddenCount: chc,\n hasChildren: (chc != null && chc > 0) || undefined,\n });\n }\n\n // Second pass: containers with children, deepest first\n const containerCandidates = allContainerNodes.filter(\n (d) => d.children && d.children.length > 0\n );\n containerCandidates.sort((a, b) => b.depth - a.depth);\n\n for (const d of containerCandidates) {\n // Collect all descendants (not just direct children)\n const allDesc: typeof d[] = [];\n const collectDesc = (node: typeof d) => {\n if (node.children) {\n for (const child of node.children) {\n allDesc.push(child);\n collectDesc(child);\n }\n }\n };\n collectDesc(d);\n\n if (allDesc.length === 0) continue;\n\n // Compute bounding box from all descendants, using inner container\n // bounds when available (so nested boxes don't overlap)\n let descMinX = Infinity;\n let descMaxX = -Infinity;\n let descMaxY = -Infinity;\n\n for (const desc of allDesc) {\n const innerBounds = containerBoundsMap.get(desc.data.orgNode.id);\n if (innerBounds) {\n // Use the inner container's expanded box\n if (innerBounds.minX < descMinX) descMinX = innerBounds.minX;\n if (innerBounds.maxX > descMaxX) descMaxX = innerBounds.maxX;\n if (innerBounds.maxY > descMaxY) descMaxY = innerBounds.maxY;\n } else if (desc.data.orgNode.id.startsWith('__stack_')) {\n // Use expanded children positions for stack placeholders\n const cid = desc.data.orgNode.id.replace('__stack_', '');\n const stack = leafStacks.get(cid);\n if (stack) {\n for (const ec of expandedChildren) {\n if (ec.orgNode.parentId !== cid) continue;\n const ex = ec.cx + offsetX;\n const ey = ec.cy + offsetY;\n if (ex - ec.width / 2 < descMinX) descMinX = ex - ec.width / 2;\n if (ex + ec.width / 2 > descMaxX) descMaxX = ex + ec.width / 2;\n if (ey + ec.height > descMaxY) descMaxY = ey + ec.height;\n }\n }\n } else {\n // Use card dimensions\n const dw = desc.data.width;\n const dh = desc.data.height;\n const dx = desc.x! + offsetX;\n const dy = desc.y! + offsetY;\n\n if (dx - dw / 2 < descMinX) descMinX = dx - dw / 2;\n if (dx + dw / 2 > descMaxX) descMaxX = dx + dw / 2;\n if (dy + dh > descMaxY) descMaxY = dy + dh;\n }\n }\n\n const containerX = d.x! + offsetX;\n const containerY = d.y! + offsetY;\n const metaCount = Object.keys(d.data.orgNode.metadata).length;\n const labelHeight =\n CONTAINER_LABEL_HEIGHT + metaCount * CONTAINER_META_LINE_HEIGHT;\n\n // Box top = container's own y, extends to cover all children\n const boxY = containerY;\n const boxHeight = descMaxY - containerY + CONTAINER_PAD_BOTTOM;\n\n // Tight-fit box around content with padding\n const boxX = descMinX - CONTAINER_PAD_X;\n const contentWidth = descMaxX - descMinX + CONTAINER_PAD_X * 2;\n const finalBoxWidth = Math.max(contentWidth, d.data.width);\n // Center the box if the label is wider than the content\n const centeredBoxX =\n finalBoxWidth > contentWidth\n ? containerX - finalBoxWidth / 2\n : boxX;\n\n // Store bounds for parent containers to reference\n containerBoundsMap.set(d.data.orgNode.id, {\n minX: centeredBoxX,\n maxX: centeredBoxX + finalBoxWidth,\n minY: boxY,\n maxY: boxY + boxHeight,\n });\n\n const chc2 = hiddenCounts?.get(d.data.orgNode.id);\n const cMeta2 = filterMetadata(d.data.orgNode.metadata, hiddenAttributes);\n containers.push({\n nodeId: d.data.orgNode.id,\n label: d.data.orgNode.label,\n lineNumber: d.data.orgNode.lineNumber,\n color: resolveNodeColor(d.data.orgNode, parsed.tagGroups, activeTagGroup ?? null),\n metadata: cMeta2,\n x: centeredBoxX,\n y: boxY,\n width: finalBoxWidth,\n height: boxHeight,\n labelHeight,\n hiddenCount: chc2,\n hasChildren: true,\n });\n }\n\n // Reverse so outer containers render first (behind inner containers)\n containers.reverse();\n\n // Bounding box — expand for container backgrounds that may extend beyond nodes\n // Convert container coords (offset space) back to pre-offset space for comparison\n let finalMinX = minX;\n let finalMaxX = maxX;\n let finalMaxY = maxY;\n for (const c of containers) {\n const cLeft = c.x - offsetX;\n const cRight = cLeft + c.width;\n const cBottom = c.y - offsetY + c.height;\n if (cLeft < finalMinX) finalMinX = cLeft;\n if (cRight > finalMaxX) finalMaxX = cRight;\n if (cBottom > finalMaxY) finalMaxY = cBottom;\n }\n\n const totalWidth = finalMaxX - finalMinX + MARGIN * 2;\n const totalHeight = finalMaxY - minY + MARGIN * 2;\n\n // Compute legend for tag groups\n const showEyeIcons = hiddenAttributes !== undefined;\n const legendGroups = computeLegendGroups(parsed.tagGroups, showEyeIcons);\n let finalWidth = totalWidth;\n let finalHeight = totalHeight;\n\n const legendPosition = parsed.options?.['legend-position'] ?? 'bottom';\n\n if (legendGroups.length > 0) {\n if (legendPosition === 'bottom') {\n // Bottom: center legend groups horizontally below diagram content\n const totalGroupsWidth =\n legendGroups.reduce((s, g) => s + g.width, 0) +\n (legendGroups.length - 1) * H_GAP;\n const neededWidth = totalGroupsWidth + MARGIN * 2;\n\n if (neededWidth > totalWidth) {\n finalWidth = neededWidth;\n const shift = (finalWidth - totalWidth) / 2;\n for (const n of layoutNodes) n.x += shift;\n for (const c of containers) c.x += shift;\n for (const e of layoutEdges) {\n for (const p of e.points) p.x += shift;\n }\n }\n\n const contentBottom = totalHeight - MARGIN;\n const legendY = contentBottom + LEGEND_GAP;\n const startX = (finalWidth - totalGroupsWidth) / 2;\n\n let cx = startX;\n let maxH = 0;\n for (const g of legendGroups) {\n g.x = cx;\n g.y = legendY;\n cx += g.width + H_GAP;\n if (g.height > maxH) maxH = g.height;\n }\n\n finalHeight = totalHeight + LEGEND_GAP + maxH;\n } else {\n // Top (default): stack legend groups vertically at top-right\n const maxLegendWidth = Math.max(...legendGroups.map((g) => g.width));\n const legendStartX = totalWidth - MARGIN + LEGEND_GAP;\n let legendY = MARGIN;\n\n for (const g of legendGroups) {\n g.x = legendStartX;\n g.y = legendY;\n legendY += g.height + LEGEND_V_GAP;\n }\n\n const legendRight = legendStartX + maxLegendWidth + MARGIN;\n if (legendRight > finalWidth) {\n finalWidth = legendRight;\n }\n\n const legendBottom = legendY - LEGEND_V_GAP + MARGIN;\n if (legendBottom > finalHeight) {\n finalHeight = legendBottom;\n }\n }\n }\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n containers,\n legend: legendGroups,\n width: finalWidth,\n height: finalHeight,\n };\n}\n","// ============================================================\n// Org Chart Collapse/Expand — prune subtrees of collapsed nodes\n// ============================================================\n\nimport type { OrgNode, ParsedOrg } from './parser';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface CollapsedOrgResult {\n /** ParsedOrg with collapsed subtrees pruned (deep-cloned, never mutates original) */\n parsed: ParsedOrg;\n /** nodeId → count of hidden descendants */\n hiddenCounts: Map<string, number>;\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction cloneNode(node: OrgNode): OrgNode {\n return {\n id: node.id,\n label: node.label,\n metadata: { ...node.metadata },\n children: node.children.map(cloneNode),\n parentId: node.parentId,\n isContainer: node.isContainer,\n lineNumber: node.lineNumber,\n color: node.color,\n };\n}\n\nfunction countDescendants(node: OrgNode): number {\n let count = 0;\n for (const child of node.children) {\n count += (child.isContainer ? 0 : 1) + countDescendants(child);\n }\n return count;\n}\n\n/** Compute hidden counts from the ORIGINAL (unpruned) tree so nested\n * collapses don't lose ancestor descendant totals. */\nfunction computeHiddenCounts(\n nodes: OrgNode[],\n collapsedIds: Set<string>,\n hiddenCounts: Map<string, number>\n): void {\n for (const node of nodes) {\n if (collapsedIds.has(node.id) && node.children.length > 0) {\n hiddenCounts.set(node.id, countDescendants(node));\n }\n computeHiddenCounts(node.children, collapsedIds, hiddenCounts);\n }\n}\n\n/** Remove children of collapsed nodes on the cloned tree. */\nfunction pruneCollapsed(\n node: OrgNode,\n collapsedIds: Set<string>\n): void {\n for (const child of node.children) {\n pruneCollapsed(child, collapsedIds);\n }\n if (collapsedIds.has(node.id) && node.children.length > 0) {\n node.children = [];\n }\n}\n\n// ============================================================\n// Main\n// ============================================================\n\nexport function collapseOrgTree(\n original: ParsedOrg,\n collapsedIds: Set<string>\n): CollapsedOrgResult {\n const hiddenCounts = new Map<string, number>();\n\n if (collapsedIds.size === 0) {\n return { parsed: original, hiddenCounts };\n }\n\n // Compute counts from the ORIGINAL tree before any pruning\n computeHiddenCounts(original.roots, collapsedIds, hiddenCounts);\n\n // Deep-clone roots and prune collapsed subtrees\n const clonedRoots = original.roots.map(cloneNode);\n for (const root of clonedRoots) {\n pruneCollapsed(root, collapsedIds);\n }\n\n return {\n parsed: {\n ...original,\n roots: clonedRoots,\n },\n hiddenCounts,\n };\n}\n","// ============================================================\n// Org Chart SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport type { ParsedOrg } from './parser';\nimport type { OrgLayoutResult, OrgLayoutNode } from './layout';\nimport { parseOrg } from './parser';\nimport { layoutOrg } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst TITLE_HEIGHT = 30;\nconst TITLE_FONT_SIZE = 18;\nconst LABEL_FONT_SIZE = 13;\nconst META_FONT_SIZE = 11;\nconst META_LINE_HEIGHT = 16;\nconst HEADER_HEIGHT = 28;\nconst SEPARATOR_GAP = 6;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst CARD_RADIUS = 6;\nconst CONTAINER_RADIUS = 8;\nconst CONTAINER_LABEL_FONT_SIZE = 13;\nconst CONTAINER_META_FONT_SIZE = 11;\nconst CONTAINER_META_LINE_HEIGHT = 16;\nconst CONTAINER_HEADER_HEIGHT = 28;\n\n// Collapsed-node accent bar\nconst COLLAPSE_BAR_HEIGHT = 6;\nconst COLLAPSE_BAR_INSET = 0;\n\n// Legend\nconst LEGEND_RADIUS = 6;\nconst LEGEND_DOT_R = 5;\nconst LEGEND_DOT_TEXT_GAP = 6;\nconst LEGEND_ENTRY_GAP = 12;\nconst LEGEND_PAD = 10;\nconst LEGEND_HEADER_H = 20;\nconst LEGEND_ENTRY_H = 18;\nconst LEGEND_FONT_SIZE = 11;\nconst LEGEND_MAX_PER_ROW = 3;\nconst LEGEND_CHAR_WIDTH = 7.5;\n\n// Eye icon (12×12 viewBox, scaled from 0,0 to 12,12)\nconst EYE_ICON_SIZE = 12;\nconst EYE_ICON_GAP = 6;\n// Open eye: elliptical outline + circle pupil\nconst EYE_OPEN_PATH =\n 'M1 6C1 6 3 2 6 2C9 2 11 6 11 6C11 6 9 10 6 10C3 10 1 6 1 6Z';\nconst EYE_PUPIL_CX = 6;\nconst EYE_PUPIL_CY = 6;\nconst EYE_PUPIL_R = 1.8;\n// Closed eye: same outline + diagonal slash\nconst EYE_SLASH_PATH = 'M2 2L10 10';\n\n// ============================================================\n// Color helpers (inline to avoid cross-module import issues)\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;\n return [\n parseInt(f.substring(0, 2), 16),\n parseInt(f.substring(2, 4), 16),\n parseInt(f.substring(4, 6), 16),\n ];\n };\n const [ar, ag, ab] = parse(a),\n [br, bg, bb] = parse(b),\n t = pct / 100;\n const c = (x: number, y: number) =>\n Math.round(x * t + y * (1 - t))\n .toString(16)\n .padStart(2, '0');\n return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;\n}\n\nfunction nodeFill(\n palette: PaletteColors,\n isDark: boolean,\n nodeColor?: string\n): string {\n if (nodeColor) {\n return mix(nodeColor, isDark ? palette.surface : palette.bg, 25);\n }\n return mix(palette.primary, isDark ? palette.surface : palette.bg, 15);\n}\n\nfunction nodeStroke(palette: PaletteColors, nodeColor?: string): string {\n return nodeColor ?? palette.textMuted;\n}\n\nfunction containerFill(\n palette: PaletteColors,\n isDark: boolean,\n nodeColor?: string\n): string {\n if (nodeColor) {\n return mix(nodeColor, isDark ? palette.surface : palette.bg, 10);\n }\n return mix(palette.surface, palette.bg, 40);\n}\n\nfunction containerStroke(palette: PaletteColors, nodeColor?: string): string {\n return nodeColor ?? palette.textMuted;\n}\n\n// ============================================================\n// Main Renderer\n// ============================================================\n\ntype GSelection = d3Selection.Selection<SVGGElement, unknown, null, undefined>;\n\nexport function renderOrg(\n container: HTMLDivElement,\n parsed: ParsedOrg,\n layout: OrgLayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number },\n activeTagGroup?: string | null,\n hiddenAttributes?: Set<string>\n): void {\n // Clear existing content\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleOffset = parsed.title ? TITLE_HEIGHT : 0;\n\n // Compute scale to fit diagram in viewport\n const diagramW = layout.width;\n const diagramH = layout.height + titleOffset;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (height - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(scaleX, scaleY);\n\n // Center the diagram\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = DIAGRAM_PADDING;\n\n // Create SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // Main content group with scale/translate\n const mainG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // Title\n if (parsed.title) {\n const titleEl = mainG\n .append('text')\n .attr('x', diagramW / 2)\n .attr('y', TITLE_FONT_SIZE)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', TITLE_FONT_SIZE)\n .attr('font-weight', 'bold')\n .attr('class', 'org-title chart-title')\n .style(\n 'cursor',\n onClickItem && parsed.titleLineNumber ? 'pointer' : 'default'\n )\n .text(parsed.title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n }\n }\n }\n\n // Content group (offset by title)\n const contentG = mainG\n .append('g')\n .attr('transform', `translate(0, ${titleOffset})`);\n\n // Build display name map from tag groups (lowercase key → original casing)\n const displayNames = new Map<string, string>();\n for (const group of parsed.tagGroups) {\n displayNames.set(group.name.toLowerCase(), group.name);\n }\n\n // Render container backgrounds (bottom layer)\n for (const c of layout.containers) {\n const cG = contentG\n .append('g')\n .attr('transform', `translate(${c.x}, ${c.y})`)\n .attr('class', 'org-container')\n .attr('data-line-number', String(c.lineNumber)) as GSelection;\n\n // Toggle attribute for containers that have (or had) children\n if (c.hasChildren) {\n cG.attr('data-node-toggle', c.nodeId)\n .attr('tabindex', '0')\n .attr('role', 'button')\n .attr(\n 'aria-expanded',\n String(!c.hiddenCount)\n )\n .attr('aria-label', c.label);\n }\n\n if (onClickItem) {\n cG.style('cursor', 'pointer').on('click', () => {\n onClickItem(c.lineNumber);\n });\n }\n\n const fill = containerFill(palette, isDark, c.color);\n const stroke = containerStroke(palette, c.color);\n\n // Background rect\n cG.append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', c.width)\n .attr('height', c.height)\n .attr('rx', CONTAINER_RADIUS)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-opacity', 0.35)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Container label (bold, at top)\n cG.append('text')\n .attr('x', c.width / 2)\n .attr('y', CONTAINER_HEADER_HEIGHT / 2 + CONTAINER_LABEL_FONT_SIZE / 2 - 2)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', CONTAINER_LABEL_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(c.label);\n\n // Container metadata (below label)\n const metaEntries = Object.entries(c.metadata);\n if (metaEntries.length > 0) {\n // Compute max key width so values align vertically\n const metaDisplayKeys = metaEntries.map(([k]) => displayNames.get(k) ?? k);\n const maxKeyLen = Math.max(...metaDisplayKeys.map((k) => k.length));\n const valueX = 10 + (maxKeyLen + 2) * (CONTAINER_META_FONT_SIZE * 0.6);\n\n const metaStartY = CONTAINER_HEADER_HEIGHT + CONTAINER_META_FONT_SIZE - 2;\n for (let i = 0; i < metaEntries.length; i++) {\n const [, value] = metaEntries[i];\n const displayKey = metaDisplayKeys[i];\n const rowY = metaStartY + i * CONTAINER_META_LINE_HEIGHT;\n\n cG.append('text')\n .attr('x', 10)\n .attr('y', rowY)\n .attr('fill', palette.textMuted)\n .attr('font-size', CONTAINER_META_FONT_SIZE)\n .text(`${displayKey}: `);\n\n cG.append('text')\n .attr('x', valueX)\n .attr('y', rowY)\n .attr('fill', palette.text)\n .attr('font-size', CONTAINER_META_FONT_SIZE)\n .text(value);\n }\n }\n\n // Collapsed accent bar (interactive only), clipped to card shape\n if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {\n const clipId = `clip-${c.nodeId}`;\n cG.append('clipPath').attr('id', clipId)\n .append('rect')\n .attr('width', c.width).attr('height', c.height)\n .attr('rx', CONTAINER_RADIUS);\n cG.append('rect')\n .attr('x', COLLAPSE_BAR_INSET)\n .attr('y', c.height - COLLAPSE_BAR_HEIGHT)\n .attr('width', c.width - COLLAPSE_BAR_INSET * 2)\n .attr('height', COLLAPSE_BAR_HEIGHT)\n .attr('fill', containerStroke(palette, c.color))\n .attr('clip-path', `url(#${clipId})`)\n .attr('class', 'org-collapse-bar');\n }\n\n }\n\n // Render edges\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n\n const pathParts: string[] = [];\n pathParts.push(`M ${edge.points[0].x} ${edge.points[0].y}`);\n for (let i = 1; i < edge.points.length; i++) {\n pathParts.push(`L ${edge.points[i].x} ${edge.points[i].y}`);\n }\n\n contentG\n .append('path')\n .attr('d', pathParts.join(' '))\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('class', 'org-edge');\n }\n\n // Collect container node IDs so we can skip them in card rendering\n const containerNodeIds = new Set(layout.containers.map((c) => c.nodeId));\n\n // Render node cards (top layer) — skip containers (already drawn as background boxes)\n for (const node of layout.nodes) {\n if (containerNodeIds.has(node.id)) continue;\n\n const nodeG = contentG\n .append('g')\n .attr(\n 'transform',\n `translate(${node.x - node.width / 2}, ${node.y})`\n )\n .attr('class', 'org-node')\n .attr('data-line-number', String(node.lineNumber)) as GSelection;\n\n // Toggle attribute for nodes that have (or had) children\n if (node.hasChildren) {\n nodeG\n .attr('data-node-toggle', node.id)\n .attr('tabindex', '0')\n .attr('role', 'button')\n .attr('aria-expanded', String(!node.hiddenCount))\n .attr('aria-label', node.label);\n }\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n // Card background\n const fill = nodeFill(palette, isDark, node.color);\n const stroke = nodeStroke(palette, node.color);\n\n const rect = nodeG\n .append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', node.width)\n .attr('height', node.height)\n .attr('rx', CARD_RADIUS)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Container nodes: dashed border\n if (node.isContainer) {\n rect.attr('stroke-dasharray', '6 3');\n }\n\n // Label\n nodeG\n .append('text')\n .attr('x', node.width / 2)\n .attr('y', HEADER_HEIGHT / 2 + LABEL_FONT_SIZE / 2 - 2)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', LABEL_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(node.label);\n\n // Metadata\n const metaEntries = Object.entries(node.metadata);\n if (metaEntries.length > 0) {\n // Header separator line\n nodeG\n .append('line')\n .attr('x1', 0)\n .attr('y1', HEADER_HEIGHT)\n .attr('x2', node.width)\n .attr('y2', HEADER_HEIGHT)\n .attr('stroke', stroke)\n .attr('stroke-opacity', 0.3)\n .attr('stroke-width', 1);\n\n // Metadata rows — compute max key width so values align vertically\n const metaDisplayKeys = metaEntries.map(([k]) => displayNames.get(k) ?? k);\n const maxKeyLen = Math.max(...metaDisplayKeys.map((k) => k.length));\n const valueX = 10 + (maxKeyLen + 2) * (META_FONT_SIZE * 0.6);\n\n const metaStartY = HEADER_HEIGHT + SEPARATOR_GAP + META_FONT_SIZE;\n for (let i = 0; i < metaEntries.length; i++) {\n const [, value] = metaEntries[i];\n const displayKey = metaDisplayKeys[i];\n const rowY = metaStartY + i * META_LINE_HEIGHT;\n\n // Key (muted)\n nodeG\n .append('text')\n .attr('x', 10)\n .attr('y', rowY)\n .attr('fill', palette.textMuted)\n .attr('font-size', META_FONT_SIZE)\n .text(`${displayKey}: `);\n\n // Value (normal)\n nodeG\n .append('text')\n .attr('x', valueX)\n .attr('y', rowY)\n .attr('fill', palette.text)\n .attr('font-size', META_FONT_SIZE)\n .text(value);\n }\n }\n\n // Collapsed accent bar (interactive only), clipped to card shape\n if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {\n const clipId = `clip-${node.id}`;\n nodeG.append('clipPath').attr('id', clipId)\n .append('rect')\n .attr('width', node.width).attr('height', node.height)\n .attr('rx', CARD_RADIUS);\n nodeG\n .append('rect')\n .attr('x', COLLAPSE_BAR_INSET)\n .attr('y', node.height - COLLAPSE_BAR_HEIGHT)\n .attr('width', node.width - COLLAPSE_BAR_INSET * 2)\n .attr('height', COLLAPSE_BAR_HEIGHT)\n .attr('fill', nodeStroke(palette, node.color))\n .attr('clip-path', `url(#${clipId})`)\n .attr('class', 'org-collapse-bar');\n }\n\n }\n\n // Render legend — skip entirely in export mode; hide non-active groups when one is active\n if (!exportDims) for (const group of layout.legend) {\n const isActive =\n activeTagGroup != null &&\n group.name.toLowerCase() === activeTagGroup.toLowerCase();\n\n // When a group is active, skip rendering all other groups\n if (activeTagGroup != null && !isActive) continue;\n\n const gEl = contentG\n .append('g')\n .attr('transform', `translate(${group.x}, ${group.y})`)\n .attr('class', 'org-legend-group')\n .attr('data-legend-group', group.name.toLowerCase())\n .style('cursor', 'pointer');\n\n // Background rect\n const legendFill = mix(palette.surface, palette.bg, 40);\n const bgRect = gEl\n .append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', group.width)\n .attr('height', group.height)\n .attr('rx', LEGEND_RADIUS)\n .attr('fill', legendFill);\n\n if (isActive) {\n bgRect\n .attr('stroke', palette.primary)\n .attr('stroke-opacity', 0.8)\n .attr('stroke-width', 2);\n } else {\n bgRect\n .attr('stroke', palette.textMuted)\n .attr('stroke-opacity', 0.35)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n }\n\n // Group name header\n gEl\n .append('text')\n .attr('x', LEGEND_PAD)\n .attr('y', LEGEND_HEADER_H / 2 + LEGEND_FONT_SIZE / 2 - 2)\n .attr('fill', palette.text)\n .attr('font-size', LEGEND_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(group.name);\n\n // Eye icon for visibility toggle (interactive only, not export)\n if (hiddenAttributes !== undefined && !exportDims) {\n const groupKey = group.name.toLowerCase();\n const isHidden = hiddenAttributes.has(groupKey);\n const eyeX =\n LEGEND_PAD + group.name.length * LEGEND_CHAR_WIDTH + EYE_ICON_GAP;\n const eyeY = (LEGEND_HEADER_H - EYE_ICON_SIZE) / 2;\n\n const eyeG = gEl\n .append('g')\n .attr('class', 'org-legend-eye')\n .attr('data-legend-visibility', groupKey)\n .attr('transform', `translate(${eyeX}, ${eyeY})`);\n\n // Transparent hit area\n eyeG\n .append('rect')\n .attr('x', -4)\n .attr('y', -4)\n .attr('width', EYE_ICON_SIZE + 8)\n .attr('height', EYE_ICON_SIZE + 8)\n .attr('fill', 'transparent');\n\n // Eye outline\n eyeG\n .append('path')\n .attr('d', EYE_OPEN_PATH)\n .attr('fill', isHidden ? 'none' : palette.textMuted)\n .attr('fill-opacity', isHidden ? 0 : 0.15)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.2)\n .attr('opacity', isHidden ? 0.5 : 0.7);\n\n if (!isHidden) {\n // Pupil (only when visible)\n eyeG\n .append('circle')\n .attr('cx', EYE_PUPIL_CX)\n .attr('cy', EYE_PUPIL_CY)\n .attr('r', EYE_PUPIL_R)\n .attr('fill', palette.textMuted)\n .attr('opacity', 0.7);\n } else {\n // Slash through the eye (hidden state)\n eyeG\n .append('line')\n .attr('x1', 2)\n .attr('y1', 2)\n .attr('x2', 10)\n .attr('y2', 10)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.5)\n .attr('opacity', 0.5);\n }\n }\n\n // Pre-compute column widths so dots align across rows\n const entryWidths = group.entries.map(\n (e) =>\n LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP + e.value.length * LEGEND_CHAR_WIDTH\n );\n const numRows = Math.ceil(group.entries.length / LEGEND_MAX_PER_ROW);\n const colWidths: number[] = [];\n for (let col = 0; col < LEGEND_MAX_PER_ROW; col++) {\n let maxW = 0;\n for (let r = 0; r < numRows; r++) {\n const idx = r * LEGEND_MAX_PER_ROW + col;\n if (idx < entryWidths.length && entryWidths[idx] > maxW) {\n maxW = entryWidths[idx];\n }\n }\n if (maxW > 0) colWidths.push(maxW);\n }\n const colX: number[] = [LEGEND_PAD];\n for (let c = 1; c < colWidths.length; c++) {\n colX.push(colX[c - 1] + colWidths[c - 1] + LEGEND_ENTRY_GAP);\n }\n\n // Entries: colored dot + value label\n for (let i = 0; i < group.entries.length; i++) {\n const entry = group.entries[i];\n const row = Math.floor(i / LEGEND_MAX_PER_ROW);\n const col = i % LEGEND_MAX_PER_ROW;\n const entryX = colX[col];\n\n const entryY =\n LEGEND_HEADER_H + row * LEGEND_ENTRY_H + LEGEND_ENTRY_H / 2;\n\n // Colored dot\n gEl\n .append('circle')\n .attr('cx', entryX + LEGEND_DOT_R)\n .attr('cy', entryY)\n .attr('r', LEGEND_DOT_R)\n .attr('fill', entry.color);\n\n // Value label\n gEl\n .append('text')\n .attr('x', entryX + LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP)\n .attr('y', entryY + LEGEND_FONT_SIZE / 2 - 2)\n .attr('fill', palette.text)\n .attr('font-size', LEGEND_FONT_SIZE)\n .text(entry.value);\n }\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderOrgForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseOrg(content, palette);\n if (parsed.error || parsed.roots.length === 0) return '';\n\n // Extract hide option for export: cards sized without hidden attributes\n const hideOption = parsed.options?.['hide'];\n const exportHidden = hideOption\n ? new Set(hideOption.split(',').map((s) => s.trim().toLowerCase()))\n : undefined;\n\n const layout = layoutOrg(parsed, undefined, undefined, exportHidden);\n const isDark = theme === 'dark';\n\n // Create offscreen container\n const container = document.createElement('div');\n const titleOffset = parsed.title ? TITLE_HEIGHT : 0;\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight =\n layout.height + DIAGRAM_PADDING * 2 + titleOffset;\n\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n // No hiddenAttributes passed to renderOrg — export never shows eye icons\n renderOrg(container, parsed, layout, palette, isDark, undefined, {\n width: exportWidth,\n height: exportHeight,\n });\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n ParsedClassDiagram,\n ClassNode,\n ClassRelationship,\n RelationshipType,\n} from './types';\n\n// ============================================================\n// Layout types\n// ============================================================\n\nexport interface ClassLayoutNode extends ClassNode {\n x: number;\n y: number;\n width: number;\n height: number;\n headerHeight: number;\n fieldsHeight: number;\n methodsHeight: number;\n}\n\nexport interface ClassLayoutEdge {\n source: string;\n target: string;\n type: RelationshipType;\n points: { x: number; y: number }[];\n label?: string;\n lineNumber: number;\n}\n\nexport interface ClassLayoutResult {\n nodes: ClassLayoutNode[];\n edges: ClassLayoutEdge[];\n width: number;\n height: number;\n}\n\n// ============================================================\n// Sizing constants\n// ============================================================\n\nconst MIN_WIDTH = 140;\nconst CHAR_WIDTH = 7.5;\nconst PADDING_X = 24;\nconst HEADER_BASE = 36;\nconst MODIFIER_BADGE = 16; // extra height for <<interface>> etc.\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst SEPARATOR_HEIGHT = 1;\n\n// ============================================================\n// Node sizing\n// ============================================================\n\nfunction computeNodeDimensions(node: ClassNode): {\n width: number;\n height: number;\n headerHeight: number;\n fieldsHeight: number;\n methodsHeight: number;\n} {\n const fields = node.members.filter((m) => !m.isMethod);\n const methods = node.members.filter((m) => m.isMethod);\n const isEnum = node.modifier === 'enum';\n\n // Width: max of class name, member text lengths\n let maxTextLen = node.name.length;\n if (node.modifier) {\n maxTextLen = Math.max(maxTextLen, `<<${node.modifier}>>`.length);\n }\n for (const m of node.members) {\n let memberText = m.name;\n if (m.isMethod) {\n memberText += `(${m.params ?? ''})`;\n if (m.type) memberText += `: ${m.type}`;\n } else if (m.type) {\n memberText += `: ${m.type}`;\n }\n // Add visibility prefix width\n memberText = `+ ${memberText}`;\n maxTextLen = Math.max(maxTextLen, memberText.length);\n }\n const width = Math.max(MIN_WIDTH, maxTextLen * CHAR_WIDTH + PADDING_X);\n\n // Header height\n const headerHeight = HEADER_BASE + (node.modifier ? MODIFIER_BADGE : 0);\n\n // Fields compartment\n let fieldsHeight = 0;\n if (isEnum) {\n // Enum values go in fields compartment\n const enumValues = node.members; // all members are enum values\n if (enumValues.length > 0) {\n fieldsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n enumValues.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n } else {\n if (fields.length > 0) {\n fieldsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n fields.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n }\n\n // Methods compartment (not for enums)\n let methodsHeight = 0;\n if (!isEnum && methods.length > 0) {\n methodsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n methods.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n\n // If no members at all, add minimal padding\n const height =\n headerHeight +\n fieldsHeight +\n methodsHeight +\n (fieldsHeight === 0 && methodsHeight === 0 ? 4 : 0);\n\n return { width, height, headerHeight, fieldsHeight, methodsHeight };\n}\n\n// ============================================================\n// Layout engine\n// ============================================================\n\nexport function layoutClassDiagram(\n parsed: ParsedClassDiagram\n): ClassLayoutResult {\n if (parsed.classes.length === 0) {\n return { nodes: [], edges: [], width: 0, height: 0 };\n }\n\n const g = new dagre.graphlib.Graph();\n g.setGraph({\n rankdir: 'TB',\n nodesep: 60,\n ranksep: 80,\n edgesep: 20,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n // Compute dimensions and add nodes\n const dimMap = new Map<\n string,\n {\n width: number;\n height: number;\n headerHeight: number;\n fieldsHeight: number;\n methodsHeight: number;\n }\n >();\n\n for (const node of parsed.classes) {\n const dims = computeNodeDimensions(node);\n dimMap.set(node.id, dims);\n g.setNode(node.id, {\n label: node.name,\n width: dims.width,\n height: dims.height,\n });\n }\n\n // Add edges\n for (const rel of parsed.relationships) {\n g.setEdge(rel.source, rel.target, { label: rel.label ?? '' });\n }\n\n // Run layout\n dagre.layout(g);\n\n // Extract positioned nodes\n const layoutNodes: ClassLayoutNode[] = parsed.classes.map((node) => {\n const pos = g.node(node.id);\n const dims = dimMap.get(node.id)!;\n return {\n ...node,\n x: pos.x,\n y: pos.y,\n width: dims.width,\n height: dims.height,\n headerHeight: dims.headerHeight,\n fieldsHeight: dims.fieldsHeight,\n methodsHeight: dims.methodsHeight,\n };\n });\n\n // Extract edge waypoints\n const layoutEdges: ClassLayoutEdge[] = parsed.relationships.map((rel) => {\n const edgeData = g.edge(rel.source, rel.target);\n return {\n source: rel.source,\n target: rel.target,\n type: rel.type,\n points: edgeData?.points ?? [],\n label: rel.label,\n lineNumber: rel.lineNumber,\n };\n });\n\n // Compute total dimensions\n let totalWidth = 0;\n let totalHeight = 0;\n for (const node of layoutNodes) {\n const right = node.x + node.width / 2;\n const bottom = node.y + node.height / 2;\n if (right > totalWidth) totalWidth = right;\n if (bottom > totalHeight) totalHeight = bottom;\n }\n totalWidth += 40;\n totalHeight += 40;\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n width: totalWidth,\n height: totalHeight,\n };\n}\n","// ============================================================\n// Class Diagram SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport type { ParsedClassDiagram, ClassModifier, RelationshipType } from './types';\nimport type { ClassLayoutResult, ClassLayoutNode, ClassLayoutEdge } from './layout';\nimport { parseClassDiagram } from './parser';\nimport { layoutClassDiagram } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst CLASS_FONT_SIZE = 13;\nconst MEMBER_FONT_SIZE = 11;\nconst EDGE_LABEL_FONT_SIZE = 11;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst MEMBER_PADDING_X = 10;\n\n// ============================================================\n// Color helpers\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\nfunction modifierColor(modifier: ClassModifier | undefined, palette: PaletteColors): string {\n switch (modifier) {\n case 'interface': return palette.colors.blue;\n case 'abstract': return palette.colors.purple;\n case 'enum': return palette.colors.yellow;\n default: return palette.colors.teal;\n }\n}\n\nfunction nodeFill(palette: PaletteColors, isDark: boolean, modifier: ClassModifier | undefined, nodeColor?: string): string {\n const color = nodeColor ?? modifierColor(modifier, palette);\n return mix(color, isDark ? palette.surface : palette.bg, 20);\n}\n\nfunction nodeStroke(palette: PaletteColors, modifier: ClassModifier | undefined, nodeColor?: string): string {\n return nodeColor ?? modifierColor(modifier, palette);\n}\n\n// ============================================================\n// Visibility symbols\n// ============================================================\n\nfunction visibilitySymbol(vis: 'public' | 'private' | 'protected'): string {\n switch (vis) {\n case 'public': return '+';\n case 'private': return '-';\n case 'protected': return '#';\n }\n}\n\n// ============================================================\n// Edge path generator\n// ============================================================\n\nconst lineGenerator = d3Shape.line<{ x: number; y: number }>()\n .x((d) => d.x)\n .y((d) => d.y)\n .curve(d3Shape.curveBasis);\n\n// ============================================================\n// Edge line style\n// ============================================================\n\nfunction isDashedEdge(type: RelationshipType): boolean {\n return type === 'implements' || type === 'depends';\n}\n\nfunction markerIdForType(type: RelationshipType): string {\n switch (type) {\n case 'extends': return 'cd-arrow-inherit';\n case 'implements': return 'cd-arrow-implement';\n case 'composes': return 'cd-arrow-compose';\n case 'aggregates': return 'cd-arrow-aggregate';\n case 'depends': return 'cd-arrow-depend';\n case 'associates': return 'cd-arrow-assoc';\n }\n}\n\n// Where to place marker — source-end for compose/aggregate, target-end for others\nfunction isSourceMarker(type: RelationshipType): boolean {\n return type === 'composes' || type === 'aggregates';\n}\n\n// ============================================================\n// Main renderer\n// ============================================================\n\ntype GSelection = d3Selection.Selection<SVGGElement, unknown, null, undefined>;\n\nexport function renderClassDiagram(\n container: HTMLDivElement,\n parsed: ParsedClassDiagram,\n layout: ClassLayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number }\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = parsed.title ? 40 : 0;\n const diagramW = layout.width;\n const diagramH = layout.height;\n const availH = height - titleHeight;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (availH - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(1, scaleX, scaleY);\n\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = titleHeight + (availH - scaledH) / 2;\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // ── Marker defs ──\n const defs = svg.append('defs');\n const AW = 12; // arrowhead width\n const AH = 8; // arrowhead height\n\n // Filled triangle (inheritance) — filled with stroke color\n defs.append('marker')\n .attr('id', 'cd-arrow-inherit')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', palette.textMuted)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Hollow triangle (implementation) — white/bg fill\n defs.append('marker')\n .attr('id', 'cd-arrow-implement')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', palette.bg)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Filled diamond (composition) — at source end\n const DW = 12;\n const DH = 8;\n defs.append('marker')\n .attr('id', 'cd-arrow-compose')\n .attr('viewBox', `0 0 ${DW} ${DH}`)\n .attr('refX', 0).attr('refY', DH / 2)\n .attr('markerWidth', DW).attr('markerHeight', DH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `${DW / 2},0 ${DW},${DH / 2} ${DW / 2},${DH} 0,${DH / 2}`)\n .attr('fill', palette.textMuted)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Hollow diamond (aggregation) — at source end\n defs.append('marker')\n .attr('id', 'cd-arrow-aggregate')\n .attr('viewBox', `0 0 ${DW} ${DH}`)\n .attr('refX', 0).attr('refY', DH / 2)\n .attr('markerWidth', DW).attr('markerHeight', DH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `${DW / 2},0 ${DW},${DH / 2} ${DW / 2},${DH} 0,${DH / 2}`)\n .attr('fill', palette.bg)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Open arrowhead (dependency)\n defs.append('marker')\n .attr('id', 'cd-arrow-depend')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polyline')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.5);\n\n // Open arrowhead (association)\n defs.append('marker')\n .attr('id', 'cd-arrow-assoc')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polyline')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.5);\n\n // ── Title ──\n if (parsed.title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(parsed.title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // ── Content group ──\n const contentG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // ── Edges (behind nodes) ──\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n\n const edgeG = contentG\n .append('g')\n .attr('class', 'cd-edge-group')\n .attr('data-line-number', String(edge.lineNumber));\n\n const edgeColor = palette.textMuted;\n const markerId = markerIdForType(edge.type);\n const dashed = isDashedEdge(edge.type);\n const sourceMarker = isSourceMarker(edge.type);\n\n const pathD = lineGenerator(edge.points);\n if (pathD) {\n const pathEl = edgeG\n .append('path')\n .attr('d', pathD)\n .attr('fill', 'none')\n .attr('stroke', edgeColor)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('class', 'cd-edge');\n\n if (dashed) {\n pathEl.attr('stroke-dasharray', '6 3');\n }\n\n if (sourceMarker) {\n pathEl.attr('marker-start', `url(#${markerId})`);\n } else {\n pathEl.attr('marker-end', `url(#${markerId})`);\n }\n }\n\n // Edge label at midpoint\n if (edge.label) {\n const midIdx = Math.floor(edge.points.length / 2);\n const midPt = edge.points[midIdx];\n const labelLen = edge.label.length;\n const bgW = labelLen * 7 + 8;\n const bgH = 16;\n\n edgeG.append('rect')\n .attr('x', midPt.x - bgW / 2)\n .attr('y', midPt.y - bgH / 2 - 1)\n .attr('width', bgW)\n .attr('height', bgH)\n .attr('rx', 3)\n .attr('fill', palette.bg)\n .attr('opacity', 0.85)\n .attr('class', 'cd-edge-label-bg');\n\n edgeG.append('text')\n .attr('x', midPt.x)\n .attr('y', midPt.y + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', edgeColor)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .attr('class', 'cd-edge-label')\n .text(edge.label);\n }\n }\n\n // ── Nodes (top layer) ──\n for (const node of layout.nodes) {\n const nodeG = contentG\n .append('g')\n .attr('transform', `translate(${node.x}, ${node.y})`)\n .attr('class', 'cd-class')\n .attr('data-line-number', String(node.lineNumber))\n .attr('data-node-id', node.id);\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n const w = node.width;\n const h = node.height;\n const fill = nodeFill(palette, isDark, node.modifier, node.color);\n const stroke = nodeStroke(palette, node.modifier, node.color);\n\n // Outer rectangle\n nodeG.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Header section\n let yPos = -h / 2;\n const headerCenterY = yPos + node.headerHeight / 2;\n\n // Modifier badge <<interface>> etc.\n if (node.modifier) {\n const badgeText = `\\u00AB${node.modifier}\\u00BB`; // « »\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY - 6)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.textMuted)\n .attr('font-size', MEMBER_FONT_SIZE)\n .attr('font-style', 'italic')\n .text(badgeText);\n\n // Class name below badge\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY + 10)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', CLASS_FONT_SIZE)\n .attr('font-weight', 'bold')\n .attr('font-style', node.modifier === 'abstract' ? 'italic' : 'normal')\n .text(node.name);\n } else {\n // Just class name centered\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', CLASS_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(node.name);\n }\n\n yPos += node.headerHeight;\n\n const isEnum = node.modifier === 'enum';\n const fields = node.members.filter((m) => !m.isMethod);\n const methods = node.members.filter((m) => m.isMethod);\n\n if (isEnum) {\n // Enum: all members as values\n if (node.members.length > 0) {\n // Separator\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const member of node.members) {\n nodeG.append('text')\n .attr('x', -w / 2 + MEMBER_PADDING_X)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', MEMBER_FONT_SIZE)\n .text(member.name);\n memberY += MEMBER_LINE_HEIGHT;\n }\n }\n } else {\n // Fields compartment\n if (fields.length > 0) {\n // Separator\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const field of fields) {\n const vis = visibilitySymbol(field.visibility);\n let text = `${vis} ${field.name}`;\n if (field.type) text += `: ${field.type}`;\n\n const textEl = nodeG.append('text')\n .attr('x', -w / 2 + MEMBER_PADDING_X)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', MEMBER_FONT_SIZE);\n\n if (field.isStatic) {\n textEl.attr('text-decoration', 'underline');\n }\n textEl.text(text);\n\n memberY += MEMBER_LINE_HEIGHT;\n }\n yPos += node.fieldsHeight;\n }\n\n // Methods compartment\n if (methods.length > 0) {\n // Separator\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const method of methods) {\n const vis = visibilitySymbol(method.visibility);\n let text = `${vis} ${method.name}(${method.params ?? ''})`;\n if (method.type) text += `: ${method.type}`;\n\n const textEl = nodeG.append('text')\n .attr('x', -w / 2 + MEMBER_PADDING_X)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', MEMBER_FONT_SIZE);\n\n if (method.isStatic) {\n textEl.attr('text-decoration', 'underline');\n }\n textEl.text(text);\n\n memberY += MEMBER_LINE_HEIGHT;\n }\n }\n }\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderClassDiagramForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseClassDiagram(content, palette);\n if (parsed.error || parsed.classes.length === 0) return '';\n\n const layout = layoutClassDiagram(parsed);\n const isDark = theme === 'dark';\n\n const container = document.createElement('div');\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0);\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderClassDiagram(\n container,\n parsed,\n layout,\n palette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","import dagre from '@dagrejs/dagre';\nimport type { ParsedERDiagram, ERTable } from './types';\n\n// ============================================================\n// Layout types\n// ============================================================\n\nexport interface ERLayoutNode extends ERTable {\n x: number;\n y: number;\n width: number;\n height: number;\n headerHeight: number;\n columnsHeight: number;\n}\n\nexport interface ERLayoutEdge {\n source: string;\n target: string;\n cardinality: { from: string; to: string };\n points: { x: number; y: number }[];\n label?: string;\n lineNumber: number;\n}\n\nexport interface ERLayoutResult {\n nodes: ERLayoutNode[];\n edges: ERLayoutEdge[];\n width: number;\n height: number;\n}\n\n// ============================================================\n// Sizing constants\n// ============================================================\n\nconst MIN_WIDTH = 140;\nconst CHAR_WIDTH = 7.5;\nconst PADDING_X = 24;\nconst HEADER_BASE = 36;\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst SEPARATOR_HEIGHT = 1;\n\n// ============================================================\n// Node sizing\n// ============================================================\n\nfunction computeNodeDimensions(table: ERTable): {\n width: number;\n height: number;\n headerHeight: number;\n columnsHeight: number;\n} {\n // Width: max of table name, column text lengths\n let maxTextLen = table.name.length;\n for (const col of table.columns) {\n let colText = col.name;\n if (col.type) colText += ` ${col.type}`;\n if (col.constraints.length > 0) colText += ` XX`; // icon space\n maxTextLen = Math.max(maxTextLen, colText.length);\n }\n const width = Math.max(MIN_WIDTH, maxTextLen * CHAR_WIDTH + PADDING_X);\n\n const headerHeight = HEADER_BASE;\n\n let columnsHeight = 0;\n if (table.columns.length > 0) {\n columnsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n table.columns.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n\n const height =\n headerHeight + columnsHeight + (columnsHeight === 0 ? 4 : 0);\n\n return { width, height, headerHeight, columnsHeight };\n}\n\n// ============================================================\n// Layout engine\n// ============================================================\n\nexport function layoutERDiagram(parsed: ParsedERDiagram): ERLayoutResult {\n if (parsed.tables.length === 0) {\n return { nodes: [], edges: [], width: 0, height: 0 };\n }\n\n const g = new dagre.graphlib.Graph();\n g.setGraph({\n rankdir: 'TB',\n nodesep: 60,\n ranksep: 80,\n edgesep: 20,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n // Compute dimensions and add nodes\n const dimMap = new Map<\n string,\n {\n width: number;\n height: number;\n headerHeight: number;\n columnsHeight: number;\n }\n >();\n\n for (const table of parsed.tables) {\n const dims = computeNodeDimensions(table);\n dimMap.set(table.id, dims);\n g.setNode(table.id, {\n label: table.name,\n width: dims.width,\n height: dims.height,\n });\n }\n\n // Add edges\n for (const rel of parsed.relationships) {\n g.setEdge(rel.source, rel.target, { label: rel.label ?? '' });\n }\n\n // Run layout\n dagre.layout(g);\n\n // Extract positioned nodes\n const layoutNodes: ERLayoutNode[] = parsed.tables.map((table) => {\n const pos = g.node(table.id);\n const dims = dimMap.get(table.id)!;\n return {\n ...table,\n x: pos.x,\n y: pos.y,\n width: dims.width,\n height: dims.height,\n headerHeight: dims.headerHeight,\n columnsHeight: dims.columnsHeight,\n };\n });\n\n // Extract edge waypoints\n const layoutEdges: ERLayoutEdge[] = parsed.relationships.map((rel) => {\n const edgeData = g.edge(rel.source, rel.target);\n return {\n source: rel.source,\n target: rel.target,\n cardinality: rel.cardinality,\n points: edgeData?.points ?? [],\n label: rel.label,\n lineNumber: rel.lineNumber,\n };\n });\n\n // Compute total dimensions\n let totalWidth = 0;\n let totalHeight = 0;\n for (const node of layoutNodes) {\n const right = node.x + node.width / 2;\n const bottom = node.y + node.height / 2;\n if (right > totalWidth) totalWidth = right;\n if (bottom > totalHeight) totalHeight = bottom;\n }\n totalWidth += 40;\n totalHeight += 40;\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n width: totalWidth,\n height: totalHeight,\n };\n}\n","// ============================================================\n// ER Diagram SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport { getSeriesColors } from '../palettes';\nimport type { ParsedERDiagram, ERConstraint } from './types';\nimport type { ERLayoutResult, ERLayoutNode, ERLayoutEdge } from './layout';\nimport { parseERDiagram } from './parser';\nimport { layoutERDiagram } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst TABLE_FONT_SIZE = 13;\nconst COLUMN_FONT_SIZE = 11;\nconst EDGE_LABEL_FONT_SIZE = 11;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst MEMBER_PADDING_X = 10;\n\n// ============================================================\n// Color helpers\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\n// ============================================================\n// Constraint icons (text glyphs for resvg compat)\n// ============================================================\n\nfunction constraintIcon(constraint: ERConstraint): string {\n switch (constraint) {\n case 'pk': return '\\u2666'; // ♦\n case 'fk': return '\\u2192'; // →\n case 'unique': return '\\u25C6'; // ◆\n case 'nullable': return '\\u25CB'; // ○\n }\n}\n\n// ============================================================\n// Edge path generator\n// ============================================================\n\nconst lineGenerator = d3Shape.line<{ x: number; y: number }>()\n .x((d) => d.x)\n .y((d) => d.y)\n .curve(d3Shape.curveBasis);\n\n// ============================================================\n// Crow's foot marker drawing\n// ============================================================\n\n/**\n * Draw a crow's foot cardinality indicator at the given endpoint.\n *\n * Crow's foot notation:\n * 1 = perpendicular bar across the line\n * * = three prongs splaying outward from the line toward the entity\n * ? = open circle on the line + perpendicular bar\n *\n * The prongs fan out from a point on the line toward the entity edge,\n * like a bird's foot — NOT converging inward like an arrowhead.\n *\n * @param g - parent SVG group\n * @param point - endpoint position (where edge meets the entity)\n * @param prevPoint - previous point to determine angle\n * @param cardinality - '1', '*', or '?'\n * @param color - stroke color\n * @param useLabels - if true, render text labels instead of crow's foot\n */\nfunction drawCardinality(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n point: { x: number; y: number },\n prevPoint: { x: number; y: number },\n cardinality: string,\n color: string,\n useLabels: boolean\n): void {\n const dx = point.x - prevPoint.x;\n const dy = point.y - prevPoint.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n if (len === 0) return;\n\n // Unit vector from prev toward endpoint (direction of edge arriving at entity)\n const ux = dx / len;\n const uy = dy / len;\n // Perpendicular\n const px = -uy;\n const py = ux;\n\n const sw = EDGE_STROKE_WIDTH + 0.5; // slightly heavier for visibility\n\n if (useLabels) {\n const offset = 15;\n const bx = point.x - ux * offset;\n const by = point.y - uy * offset;\n const labelText = cardinality === '1' ? '1' : cardinality === '*' ? '*' : '0..1';\n g.append('text')\n .attr('x', bx + px * 12)\n .attr('y', by + py * 12)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', color)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .text(labelText);\n return;\n }\n\n // Crow's foot notation\n const barOffset = 14; // how far back from the entity the bar sits\n const spread = 9; // half-width of the perpendicular bar / prong span\n\n if (cardinality === '1') {\n // Single perpendicular bar\n const bx = point.x - ux * barOffset;\n const by = point.y - uy * barOffset;\n g.append('line')\n .attr('x1', bx + px * spread)\n .attr('y1', by + py * spread)\n .attr('x2', bx - px * spread)\n .attr('y2', by - py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n } else if (cardinality === '*') {\n // Crow's foot: three prongs fan out FROM a point on the line\n // TOWARD the entity — the fork opens at the entity side.\n const forkOrigin = 18; // distance back from entity where prongs originate\n const forkEnd = 5; // distance from entity where prongs terminate\n\n // Origin point (on the line, away from entity)\n const ox = point.x - ux * forkOrigin;\n const oy = point.y - uy * forkOrigin;\n\n // End points (near entity, splayed outward)\n const ex = point.x - ux * forkEnd;\n const ey = point.y - uy * forkEnd;\n\n // Top prong\n g.append('line')\n .attr('x1', ox)\n .attr('y1', oy)\n .attr('x2', ex + px * spread)\n .attr('y2', ey + py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n // Bottom prong\n g.append('line')\n .attr('x1', ox)\n .attr('y1', oy)\n .attr('x2', ex - px * spread)\n .attr('y2', ey - py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n // Middle prong (straight to entity)\n g.append('line')\n .attr('x1', ox)\n .attr('y1', oy)\n .attr('x2', ex)\n .attr('y2', ey)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n } else if (cardinality === '?') {\n // Circle (zero) + perpendicular bar (one)\n const circleR = 5;\n const circleCenter = barOffset + circleR * 2 + 2; // circle sits behind the bar\n const cx = point.x - ux * circleCenter;\n const cy = point.y - uy * circleCenter;\n g.append('circle')\n .attr('cx', cx)\n .attr('cy', cy)\n .attr('r', circleR)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', sw);\n // Perpendicular bar\n const bx = point.x - ux * barOffset;\n const by = point.y - uy * barOffset;\n g.append('line')\n .attr('x1', bx + px * spread)\n .attr('y1', by + py * spread)\n .attr('x2', bx - px * spread)\n .attr('y2', by - py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n }\n}\n\n// ============================================================\n// Main renderer\n// ============================================================\n\nexport function renderERDiagram(\n container: HTMLDivElement,\n parsed: ParsedERDiagram,\n layout: ERLayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number }\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = parsed.title ? 40 : 0;\n const diagramW = layout.width;\n const diagramH = layout.height;\n const availH = height - titleHeight;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (availH - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(1, scaleX, scaleY);\n\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = titleHeight + (availH - scaledH) / 2;\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // ── Title ──\n if (parsed.title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(parsed.title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // ── Content group ──\n const contentG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // ── Auto-assign colors ──\n const seriesColors = getSeriesColors(palette);\n\n // ── Edges (behind nodes) ──\n const useLabels = parsed.options.notation === 'labels';\n\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n\n const edgeG = contentG\n .append('g')\n .attr('class', 'er-edge-group')\n .attr('data-line-number', String(edge.lineNumber));\n\n const edgeColor = palette.textMuted;\n\n const pathD = lineGenerator(edge.points);\n if (pathD) {\n edgeG\n .append('path')\n .attr('d', pathD)\n .attr('fill', 'none')\n .attr('stroke', edgeColor)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('class', 'er-edge');\n }\n\n // Cardinality markers at endpoints\n const pts = edge.points;\n // Source side (from cardinality)\n drawCardinality(\n edgeG,\n pts[0],\n pts[1],\n edge.cardinality.from,\n edgeColor,\n useLabels\n );\n // Target side (to cardinality)\n drawCardinality(\n edgeG,\n pts[pts.length - 1],\n pts[pts.length - 2],\n edge.cardinality.to,\n edgeColor,\n useLabels\n );\n\n // Edge label at midpoint\n if (edge.label) {\n const midIdx = Math.floor(pts.length / 2);\n const midPt = pts[midIdx];\n const labelLen = edge.label.length;\n const bgW = labelLen * 7 + 8;\n const bgH = 16;\n\n edgeG.append('rect')\n .attr('x', midPt.x - bgW / 2)\n .attr('y', midPt.y - bgH / 2 - 1)\n .attr('width', bgW)\n .attr('height', bgH)\n .attr('rx', 3)\n .attr('fill', palette.bg)\n .attr('opacity', 0.85)\n .attr('class', 'er-edge-label-bg');\n\n edgeG.append('text')\n .attr('x', midPt.x)\n .attr('y', midPt.y + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', edgeColor)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .attr('class', 'er-edge-label')\n .text(edge.label);\n }\n }\n\n // ── Nodes (top layer) ──\n for (let ni = 0; ni < layout.nodes.length; ni++) {\n const node = layout.nodes[ni];\n const nodeColor = node.color ?? seriesColors[ni % seriesColors.length];\n\n const nodeG = contentG\n .append('g')\n .attr('transform', `translate(${node.x}, ${node.y})`)\n .attr('class', 'er-table')\n .attr('data-line-number', String(node.lineNumber))\n .attr('data-node-id', node.id);\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n const w = node.width;\n const h = node.height;\n const fill = mix(nodeColor, isDark ? palette.surface : palette.bg, 20);\n const stroke = nodeColor;\n\n // Outer rectangle\n nodeG.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Header section — table name\n let yPos = -h / 2;\n const headerCenterY = yPos + node.headerHeight / 2;\n\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', TABLE_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(node.name);\n\n yPos += node.headerHeight;\n\n // Columns compartment\n if (node.columns.length > 0) {\n // Separator line\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const col of node.columns) {\n // Constraint icon (leftmost)\n const iconX = -w / 2 + MEMBER_PADDING_X;\n const primaryConstraint = col.constraints[0];\n if (primaryConstraint) {\n nodeG.append('text')\n .attr('x', iconX)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.textMuted)\n .attr('font-size', COLUMN_FONT_SIZE)\n .text(constraintIcon(primaryConstraint));\n }\n\n // Column name + type\n const textX = -w / 2 + MEMBER_PADDING_X + (primaryConstraint ? 16 : 0);\n let colText = col.name;\n if (col.type) colText += `: ${col.type}`;\n\n nodeG.append('text')\n .attr('x', textX)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', COLUMN_FONT_SIZE)\n .text(colText);\n\n memberY += MEMBER_LINE_HEIGHT;\n }\n }\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderERDiagramForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseERDiagram(content, palette);\n if (parsed.error || parsed.tables.length === 0) return '';\n\n const layout = layoutERDiagram(parsed);\n const isDark = theme === 'dark';\n\n const container = document.createElement('div');\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0);\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderERDiagram(\n container,\n parsed,\n layout,\n palette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n ParsedGraph,\n GraphNode,\n GraphEdge,\n GraphShape,\n} from './types';\n\nexport interface LayoutNode {\n id: string;\n label: string;\n shape: GraphShape;\n color?: string;\n group?: string;\n lineNumber: number;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface LayoutEdge {\n source: string;\n target: string;\n points: { x: number; y: number }[];\n label?: string;\n color?: string;\n lineNumber: number;\n}\n\nexport interface LayoutGroup {\n id: string;\n label: string;\n color?: string;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface LayoutResult {\n nodes: LayoutNode[];\n edges: LayoutEdge[];\n groups: LayoutGroup[];\n width: number;\n height: number;\n}\n\nconst GROUP_PADDING = 20;\n\nfunction computeNodeWidth(label: string, shape: GraphShape): number {\n const base = Math.max(120, label.length * 9 + 40);\n if (shape === 'subroutine') return base + 10;\n return base;\n}\n\nfunction computeNodeHeight(shape: GraphShape): number {\n return shape === 'decision' ? 60 : 50;\n}\n\nexport function layoutGraph(graph: ParsedGraph): LayoutResult {\n if (graph.nodes.length === 0) {\n return { nodes: [], edges: [], groups: [], width: 0, height: 0 };\n }\n\n const g = new dagre.graphlib.Graph({ compound: true });\n g.setGraph({\n rankdir: graph.direction,\n nodesep: 50,\n ranksep: 60,\n edgesep: 20,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n // Build a lookup for original node data\n const nodeDataMap = new Map<string, GraphNode>();\n for (const node of graph.nodes) {\n nodeDataMap.set(node.id, node);\n }\n\n // Add group parent nodes\n if (graph.groups) {\n for (const group of graph.groups) {\n g.setNode(group.id, {\n label: group.label,\n clusterLabelPos: 'top',\n });\n }\n }\n\n // Add nodes with computed dimensions\n for (const node of graph.nodes) {\n const width = computeNodeWidth(node.label, node.shape);\n const height = computeNodeHeight(node.shape);\n g.setNode(node.id, { label: node.label, width, height });\n\n // Set parent for grouped nodes\n if (node.group && graph.groups?.some((gr) => gr.id === node.group)) {\n g.setParent(node.id, node.group);\n }\n }\n\n // Build edge lookup for original data\n const edgeDataMap = new Map<string, GraphEdge>();\n for (const edge of graph.edges) {\n const key = `${edge.source}->${edge.target}`;\n edgeDataMap.set(key, edge);\n g.setEdge(edge.source, edge.target, {\n label: edge.label ?? '',\n });\n }\n\n // Run layout\n dagre.layout(g);\n\n // Extract positioned nodes\n const layoutNodes: LayoutNode[] = graph.nodes.map((node) => {\n const pos = g.node(node.id);\n return {\n id: node.id,\n label: node.label,\n shape: node.shape,\n color: node.color,\n group: node.group,\n lineNumber: node.lineNumber,\n x: pos.x,\n y: pos.y,\n width: pos.width,\n height: pos.height,\n };\n });\n\n // Extract edge waypoints\n const layoutEdges: LayoutEdge[] = graph.edges.map((edge) => {\n const edgeData = g.edge(edge.source, edge.target);\n return {\n source: edge.source,\n target: edge.target,\n points: edgeData?.points ?? [],\n label: edge.label,\n color: edge.color,\n lineNumber: edge.lineNumber,\n };\n });\n\n // Compute group bounding boxes from member node positions\n const layoutGroups: LayoutGroup[] = [];\n if (graph.groups) {\n const nodeMap = new Map(layoutNodes.map((n) => [n.id, n]));\n for (const group of graph.groups) {\n const members = group.nodeIds\n .map((id) => nodeMap.get(id))\n .filter((n): n is LayoutNode => n !== undefined);\n\n if (members.length === 0) {\n layoutGroups.push({\n id: group.id,\n label: group.label,\n color: group.color,\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n });\n continue;\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const member of members) {\n const left = member.x - member.width / 2;\n const right = member.x + member.width / 2;\n const top = member.y - member.height / 2;\n const bottom = member.y + member.height / 2;\n if (left < minX) minX = left;\n if (right > maxX) maxX = right;\n if (top < minY) minY = top;\n if (bottom > maxY) maxY = bottom;\n }\n\n layoutGroups.push({\n id: group.id,\n label: group.label,\n color: group.color,\n x: minX - GROUP_PADDING,\n y: minY - GROUP_PADDING,\n width: maxX - minX + GROUP_PADDING * 2,\n height: maxY - minY + GROUP_PADDING * 2,\n });\n }\n }\n\n // Compute total diagram dimensions\n let totalWidth = 0;\n let totalHeight = 0;\n for (const node of layoutNodes) {\n const right = node.x + node.width / 2;\n const bottom = node.y + node.height / 2;\n if (right > totalWidth) totalWidth = right;\n if (bottom > totalHeight) totalHeight = bottom;\n }\n for (const group of layoutGroups) {\n const right = group.x + group.width;\n const bottom = group.y + group.height;\n if (right > totalWidth) totalWidth = right;\n if (bottom > totalHeight) totalHeight = bottom;\n }\n // Add margin\n totalWidth += 40;\n totalHeight += 40;\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n groups: layoutGroups,\n width: totalWidth,\n height: totalHeight,\n };\n}\n","// ============================================================\n// Flowchart SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport type { ParsedGraph, GraphShape } from './types';\nimport type { LayoutResult, LayoutNode, LayoutEdge, LayoutGroup } from './layout';\nimport { parseFlowchart } from './flowchart-parser';\nimport { layoutGraph } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst NODE_FONT_SIZE = 13;\nconst EDGE_LABEL_FONT_SIZE = 11;\nconst GROUP_LABEL_FONT_SIZE = 11;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst ARROWHEAD_W = 10;\nconst ARROWHEAD_H = 7;\nconst IO_SKEW = 15;\nconst SUBROUTINE_INSET = 8;\nconst DOC_WAVE_HEIGHT = 10;\nconst GROUP_EXTRA_PADDING = 12;\n\n// ============================================================\n// Color helpers (inline mix to avoid cross-module import issues)\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\nfunction shapeDefaultColor(shape: GraphShape, palette: PaletteColors, isEndTerminal?: boolean): string {\n switch (shape) {\n case 'terminal': return isEndTerminal ? palette.colors.red : palette.colors.green;\n case 'process': return palette.colors.blue;\n case 'decision': return palette.colors.yellow;\n case 'io': return palette.colors.purple;\n case 'subroutine': return palette.colors.teal;\n case 'document': return palette.colors.orange;\n }\n}\n\nfunction nodeFill(palette: PaletteColors, isDark: boolean, shape: GraphShape, nodeColor?: string, isEndTerminal?: boolean): string {\n const color = nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal);\n return mix(color, isDark ? palette.surface : palette.bg, 25);\n}\n\nfunction nodeStroke(palette: PaletteColors, shape: GraphShape, nodeColor?: string, isEndTerminal?: boolean): string {\n return nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal);\n}\n\n// ============================================================\n// Shape renderers\n// ============================================================\n\ntype GSelection = d3Selection.Selection<SVGGElement, unknown, null, undefined>;\n\nfunction renderTerminal(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, isEnd: boolean): void {\n const w = node.width;\n const h = node.height;\n const rx = h / 2;\n g.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', rx)\n .attr('ry', rx)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color, isEnd))\n .attr('stroke', nodeStroke(palette, node.shape, node.color, isEnd))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderProcess(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean): void {\n const w = node.width;\n const h = node.height;\n g.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color))\n .attr('stroke', nodeStroke(palette, node.shape, node.color))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderDecision(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean): void {\n const w = node.width / 2;\n const h = node.height / 2;\n const points = [\n `${0},${-h}`, // top\n `${w},${0}`, // right\n `${0},${h}`, // bottom\n `${-w},${0}`, // left\n ].join(' ');\n g.append('polygon')\n .attr('points', points)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color))\n .attr('stroke', nodeStroke(palette, node.shape, node.color))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderIO(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean): void {\n const w = node.width / 2;\n const h = node.height / 2;\n const sk = IO_SKEW;\n const points = [\n `${-w + sk},${-h}`, // top-left (shifted right)\n `${w + sk},${-h}`, // top-right (shifted right)\n `${w - sk},${h}`, // bottom-right (shifted left)\n `${-w - sk},${h}`, // bottom-left (shifted left)\n ].join(' ');\n g.append('polygon')\n .attr('points', points)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color))\n .attr('stroke', nodeStroke(palette, node.shape, node.color))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderSubroutine(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean): void {\n const w = node.width;\n const h = node.height;\n const s = nodeStroke(palette, node.shape, node.color);\n // Outer rectangle\n g.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color))\n .attr('stroke', s)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n // Left inner border\n g.append('line')\n .attr('x1', -w / 2 + SUBROUTINE_INSET)\n .attr('y1', -h / 2)\n .attr('x2', -w / 2 + SUBROUTINE_INSET)\n .attr('y2', h / 2)\n .attr('stroke', s)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n // Right inner border\n g.append('line')\n .attr('x1', w / 2 - SUBROUTINE_INSET)\n .attr('y1', -h / 2)\n .attr('x2', w / 2 - SUBROUTINE_INSET)\n .attr('y2', h / 2)\n .attr('stroke', s)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderDocument(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean): void {\n const w = node.width;\n const h = node.height;\n const waveH = DOC_WAVE_HEIGHT;\n const left = -w / 2;\n const right = w / 2;\n const top = -h / 2;\n const bottom = h / 2 - waveH;\n\n // Path: straight top, straight right side, wavy bottom, straight left side\n const d = [\n `M ${left} ${top}`,\n `L ${right} ${top}`,\n `L ${right} ${bottom}`,\n `C ${right - w * 0.25} ${bottom + waveH * 2}, ${left + w * 0.25} ${bottom - waveH}, ${left} ${bottom}`,\n 'Z',\n ].join(' ');\n\n g.append('path')\n .attr('d', d)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color))\n .attr('stroke', nodeStroke(palette, node.shape, node.color))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderNodeShape(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, endTerminalIds: Set<string>): void {\n switch (node.shape) {\n case 'terminal':\n renderTerminal(g, node, palette, isDark, endTerminalIds.has(node.id));\n break;\n case 'process':\n renderProcess(g, node, palette, isDark);\n break;\n case 'decision':\n renderDecision(g, node, palette, isDark);\n break;\n case 'io':\n renderIO(g, node, palette, isDark);\n break;\n case 'subroutine':\n renderSubroutine(g, node, palette, isDark);\n break;\n case 'document':\n renderDocument(g, node, palette, isDark);\n break;\n }\n}\n\n// ============================================================\n// Edge path generator\n// ============================================================\n\nconst lineGenerator = d3Shape.line<{ x: number; y: number }>()\n .x((d) => d.x)\n .y((d) => d.y)\n .curve(d3Shape.curveBasis);\n\n// ============================================================\n// Main renderer\n// ============================================================\n\nexport function renderFlowchart(\n container: HTMLDivElement,\n graph: ParsedGraph,\n layout: LayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number }\n): void {\n // Clear existing content (preserve tooltips)\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = graph.title ? 40 : 0;\n\n // Compute scale to fit diagram in available space below title\n const diagramW = layout.width;\n const diagramH = layout.height;\n const availH = height - titleHeight;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (availH - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(1, scaleX, scaleY);\n\n // Center the diagram in the area below the title\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = titleHeight + (availH - scaledH) / 2;\n\n // Create SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // Defs: arrowhead markers\n const defs = svg.append('defs');\n\n // Default arrowhead\n defs\n .append('marker')\n .attr('id', 'fc-arrow')\n .attr('viewBox', `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`)\n .attr('refX', ARROWHEAD_W)\n .attr('refY', ARROWHEAD_H / 2)\n .attr('markerWidth', ARROWHEAD_W)\n .attr('markerHeight', ARROWHEAD_H)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`)\n .attr('fill', palette.textMuted);\n\n // Collect unique edge colors for custom markers\n const edgeColors = new Set<string>();\n for (const edge of layout.edges) {\n if (edge.color) edgeColors.add(edge.color);\n }\n for (const color of edgeColors) {\n const id = `fc-arrow-${color.replace('#', '')}`;\n defs\n .append('marker')\n .attr('id', id)\n .attr('viewBox', `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`)\n .attr('refX', ARROWHEAD_W)\n .attr('refY', ARROWHEAD_H / 2)\n .attr('markerWidth', ARROWHEAD_W)\n .attr('markerHeight', ARROWHEAD_H)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`)\n .attr('fill', color);\n }\n\n // Title (rendered directly on SVG, not inside scaled group)\n if (graph.title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && graph.titleLineNumber ? 'pointer' : 'default')\n .text(graph.title);\n\n if (graph.titleLineNumber) {\n titleEl.attr('data-line-number', graph.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(graph.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // Main content group with scale/translate\n const contentG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // Render groups (background layer)\n for (const group of layout.groups) {\n if (group.width === 0 && group.height === 0) continue;\n const gx = group.x - GROUP_EXTRA_PADDING;\n const gy = group.y - GROUP_EXTRA_PADDING - GROUP_LABEL_FONT_SIZE - 4;\n const gw = group.width + GROUP_EXTRA_PADDING * 2;\n const gh = group.height + GROUP_EXTRA_PADDING * 2 + GROUP_LABEL_FONT_SIZE + 4;\n\n const fillColor = group.color\n ? mix(group.color, isDark ? palette.surface : palette.bg, 10)\n : isDark\n ? palette.surface\n : mix(palette.border, palette.bg, 30);\n const strokeColor = group.color ?? palette.textMuted;\n\n contentG\n .append('rect')\n .attr('x', gx)\n .attr('y', gy)\n .attr('width', gw)\n .attr('height', gh)\n .attr('rx', 6)\n .attr('fill', fillColor)\n .attr('stroke', strokeColor)\n .attr('stroke-width', 1)\n .attr('stroke-opacity', 0.5)\n .attr('class', 'fc-group');\n\n contentG\n .append('text')\n .attr('x', gx + 8)\n .attr('y', gy + GROUP_LABEL_FONT_SIZE + 4)\n .attr('fill', strokeColor)\n .attr('font-size', GROUP_LABEL_FONT_SIZE)\n .attr('font-weight', 'bold')\n .attr('opacity', 0.7)\n .attr('class', 'fc-group-label')\n .text(group.label);\n }\n\n // Render edges (middle layer)\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n const edgeG = contentG\n .append('g')\n .attr('class', 'fc-edge-group')\n .attr('data-line-number', String(edge.lineNumber));\n\n const edgeColor = edge.color ?? palette.textMuted;\n const markerId = edge.color\n ? `fc-arrow-${edge.color.replace('#', '')}`\n : 'fc-arrow';\n\n const pathD = lineGenerator(edge.points);\n if (pathD) {\n edgeG\n .append('path')\n .attr('d', pathD)\n .attr('fill', 'none')\n .attr('stroke', edgeColor)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('marker-end', `url(#${markerId})`)\n .attr('class', 'fc-edge');\n }\n\n // Edge label at midpoint\n if (edge.label) {\n const midIdx = Math.floor(edge.points.length / 2);\n const midPt = edge.points[midIdx];\n\n // Background rect for legibility\n const labelLen = edge.label.length;\n const bgW = labelLen * 7 + 8;\n const bgH = 16;\n edgeG\n .append('rect')\n .attr('x', midPt.x - bgW / 2)\n .attr('y', midPt.y - bgH / 2 - 1)\n .attr('width', bgW)\n .attr('height', bgH)\n .attr('rx', 3)\n .attr('fill', palette.bg)\n .attr('opacity', 0.85)\n .attr('class', 'fc-edge-label-bg');\n\n edgeG\n .append('text')\n .attr('x', midPt.x)\n .attr('y', midPt.y + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', edgeColor)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .attr('class', 'fc-edge-label')\n .text(edge.label);\n }\n }\n\n // Identify end terminals (terminal nodes with no outgoing edges)\n const nodesWithOutgoing = new Set<string>();\n for (const edge of layout.edges) nodesWithOutgoing.add(edge.source);\n const endTerminalIds = new Set<string>();\n for (const node of layout.nodes) {\n if (node.shape === 'terminal' && !nodesWithOutgoing.has(node.id)) {\n endTerminalIds.add(node.id);\n }\n }\n\n // Render nodes (top layer)\n for (const node of layout.nodes) {\n const nodeG = contentG\n .append('g')\n .attr('transform', `translate(${node.x}, ${node.y})`)\n .attr('class', 'fc-node')\n .attr('data-line-number', String(node.lineNumber))\n .attr('data-node-id', node.id);\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n // Shape\n renderNodeShape(nodeG as GSelection, node, palette, isDark, endTerminalIds);\n\n // Label\n nodeG\n .append('text')\n .attr('x', 0)\n .attr('y', 0)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', NODE_FONT_SIZE)\n .text(node.label);\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderFlowchartForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseFlowchart(content, palette);\n if (parsed.error || parsed.nodes.length === 0) return '';\n\n const layout = layoutGraph(parsed);\n const isDark = theme === 'dark';\n\n // Create offscreen container\n const container = document.createElement('div');\n container.style.width = `${layout.width + DIAGRAM_PADDING * 2}px`;\n container.style.height = `${layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0)}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0);\n\n try {\n renderFlowchart(\n container,\n parsed,\n layout,\n palette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","// ============================================================\n// Sequence Diagram SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport type { PaletteColors } from '../palettes';\nimport { resolveColor } from '../colors';\nimport { FONT_FAMILY } from '../fonts';\nimport type {\n ParsedSequenceDgmo,\n SequenceElement,\n SequenceGroup,\n SequenceMessage,\n SequenceNote,\n SequenceParticipant,\n} from './parser';\nimport { isSequenceBlock, isSequenceSection, isSequenceNote } from './parser';\n\n// ============================================================\n// Layout Constants\n// ============================================================\n\nconst PARTICIPANT_GAP = 160;\nconst PARTICIPANT_BOX_WIDTH = 120;\nconst PARTICIPANT_BOX_HEIGHT = 50;\nconst TOP_MARGIN = 20;\nconst TITLE_HEIGHT = 30;\nconst PARTICIPANT_Y_OFFSET = 10;\nconst SERVICE_BORDER_RADIUS = 10;\nconst MESSAGE_START_OFFSET = 30;\nconst LIFELINE_TAIL = 30;\nconst ARROWHEAD_SIZE = 8;\n\n// Note rendering constants\nconst NOTE_MAX_W = 200;\nconst NOTE_FOLD = 10;\nconst NOTE_PAD_H = 8;\nconst NOTE_PAD_V = 6;\nconst NOTE_FONT_SIZE = 10;\nconst NOTE_LINE_H = 14;\nconst NOTE_GAP = 15;\nconst NOTE_CHAR_W = 6;\nconst NOTE_CHARS_PER_LINE = Math.floor((NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W);\nconst COLLAPSED_NOTE_H = 20;\nconst COLLAPSED_NOTE_W = 40;\n\ninterface InlineSpan {\n text: string;\n bold?: boolean;\n italic?: boolean;\n code?: boolean;\n href?: string;\n}\n\nexport function parseInlineMarkdown(text: string): InlineSpan[] {\n const spans: InlineSpan[] = [];\n const regex =\n /\\*\\*(.+?)\\*\\*|__(.+?)__|\\*(.+?)\\*|_(.+?)_|`(.+?)`|\\[(.+?)\\]\\((.+?)\\)|(https?:\\/\\/[^\\s)>\\]]+|www\\.[^\\s)>\\]]+)|([^*_`[]+?(?=https?:\\/\\/|www\\.|$)|[^*_`[]+)/g;\n let match;\n while ((match = regex.exec(text)) !== null) {\n if (match[1]) spans.push({ text: match[1], bold: true }); // **bold**\n else if (match[2]) spans.push({ text: match[2], bold: true }); // __bold__\n else if (match[3]) spans.push({ text: match[3], italic: true }); // *italic*\n else if (match[4]) spans.push({ text: match[4], italic: true }); // _italic_\n else if (match[5]) spans.push({ text: match[5], code: true }); // `code`\n else if (match[6]) spans.push({ text: match[6], href: match[7] }); // [text](url)\n else if (match[8]) { // bare URL\n const url = match[8];\n const href = url.startsWith('www.') ? `https://${url}` : url;\n spans.push({ text: url, href });\n } else if (match[9]) spans.push({ text: match[9] }); // plain text\n }\n return spans;\n}\n\nconst BARE_URL_MAX_DISPLAY = 35;\n\nexport function truncateBareUrl(url: string): string {\n const stripped = url.replace(/^https?:\\/\\//, '').replace(/^www\\./, '');\n if (stripped.length <= BARE_URL_MAX_DISPLAY) return stripped;\n return stripped.slice(0, BARE_URL_MAX_DISPLAY - 1) + '\\u2026';\n}\n\nfunction renderInlineText(\n textEl: d3Selection.Selection<SVGTextElement, unknown, null, undefined>,\n text: string,\n palette: PaletteColors,\n fontSize?: number\n): void {\n const spans = parseInlineMarkdown(text);\n for (const span of spans) {\n if (span.href) {\n // Bare URLs (text === href or href with https:// prepended) get truncated display;\n // markdown links [text](url) keep their user-chosen text as-is.\n const isBareUrl =\n span.text === span.href ||\n `https://${span.text}` === span.href;\n const display = isBareUrl ? truncateBareUrl(span.text) : span.text;\n const a = textEl.append('a').attr('href', span.href);\n a.append('tspan')\n .text(display)\n .attr('fill', palette.primary)\n .style('text-decoration', 'underline');\n } else {\n const tspan = textEl.append('tspan').text(span.text);\n if (span.bold) tspan.attr('font-weight', 'bold');\n if (span.italic) tspan.attr('font-style', 'italic');\n if (span.code) {\n tspan.attr('font-family', 'monospace');\n if (fontSize) tspan.attr('font-size', fontSize - 1);\n }\n }\n }\n}\n\nfunction wrapTextLines(text: string, maxChars: number): string[] {\n const rawLines = text.split('\\n');\n const wrapped: string[] = [];\n for (const line of rawLines) {\n if (line.length <= maxChars) {\n wrapped.push(line);\n } else {\n const words = line.split(' ');\n let current = '';\n for (const word of words) {\n if (current && (current + ' ' + word).length > maxChars) {\n wrapped.push(current);\n current = word;\n } else {\n current = current ? current + ' ' + word : word;\n }\n }\n if (current) wrapped.push(current);\n }\n }\n return wrapped;\n}\n\n// Mix two hex colors in sRGB: pct% of a, rest of b\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\n// Shared fill/stroke helpers\nconst fill = (palette: PaletteColors, isDark: boolean): string =>\n mix(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);\nconst stroke = (palette: PaletteColors): string => palette.textMuted;\nconst SW = 1.5;\nconst W = PARTICIPANT_BOX_WIDTH;\nconst H = PARTICIPANT_BOX_HEIGHT;\n\n// ============================================================\n// Participant Shape Renderers\n// ============================================================\n\nfunction renderRectParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', H)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW);\n}\n\nfunction renderServiceParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', H)\n .attr('rx', SERVICE_BORDER_RADIUS)\n .attr('ry', SERVICE_BORDER_RADIUS)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW);\n}\n\nfunction renderActorParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors\n): void {\n // Stick figure — no background, natural proportions\n const headR = 8;\n const cx = 0;\n const headY = headR + 2;\n const bodyTopY = headY + headR + 1;\n const bodyBottomY = H * 0.65;\n const legY = H - 2;\n const armSpan = 16;\n const legSpan = 12;\n const s = stroke(palette);\n const actorSW = 2.5;\n\n g.append('circle')\n .attr('cx', cx)\n .attr('cy', headY)\n .attr('r', headR)\n .attr('fill', 'none')\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx)\n .attr('y1', bodyTopY)\n .attr('x2', cx)\n .attr('y2', bodyBottomY)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx - armSpan)\n .attr('y1', bodyTopY + 5)\n .attr('x2', cx + armSpan)\n .attr('y2', bodyTopY + 5)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx)\n .attr('y1', bodyBottomY)\n .attr('x2', cx - legSpan)\n .attr('y2', legY)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx)\n .attr('y1', bodyBottomY)\n .attr('x2', cx + legSpan)\n .attr('y2', legY)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n}\n\nfunction renderDatabaseParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Cylinder fitting within W x H\n const ry = 7;\n const topY = ry;\n const bodyH = H - ry * 2;\n const f = fill(palette, isDark);\n const s = stroke(palette);\n\n // Bottom ellipse (drawn first — rect will cover its top arc)\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY + bodyH)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Filled body (no stroke) to hide the top arc of the bottom ellipse\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', topY)\n .attr('width', W)\n .attr('height', bodyH)\n .attr('fill', f)\n .attr('stroke', 'none');\n\n // Side lines\n g.append('line')\n .attr('x1', -W / 2)\n .attr('y1', topY)\n .attr('x2', -W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n g.append('line')\n .attr('x1', W / 2)\n .attr('y1', topY)\n .attr('x2', W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Top ellipse cap (drawn last, on top)\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n}\n\nfunction renderQueueParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Horizontal cylinder (pipe) — like database rotated 90 degrees\n const rx = 10;\n const leftX = -W / 2 + rx;\n const bodyW = W - rx * 2;\n const f = fill(palette, isDark);\n const s = stroke(palette);\n\n // Right ellipse (back face, drawn first — rect will cover its left arc)\n g.append('ellipse')\n .attr('cx', leftX + bodyW)\n .attr('cy', H / 2)\n .attr('rx', rx)\n .attr('ry', H / 2)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Body rect (no stroke) to hide left arc of right ellipse\n g.append('rect')\n .attr('x', leftX)\n .attr('y', 0)\n .attr('width', bodyW)\n .attr('height', H)\n .attr('fill', f)\n .attr('stroke', 'none');\n\n // Top and bottom lines\n g.append('line')\n .attr('x1', leftX)\n .attr('y1', 0)\n .attr('x2', leftX + bodyW)\n .attr('y2', 0)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n g.append('line')\n .attr('x1', leftX)\n .attr('y1', H)\n .attr('x2', leftX + bodyW)\n .attr('y2', H)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Left ellipse (front face, drawn last)\n g.append('ellipse')\n .attr('cx', leftX)\n .attr('cy', H / 2)\n .attr('rx', rx)\n .attr('ry', H / 2)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n}\n\nfunction renderCacheParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Dashed cylinder — variation of database to convey ephemeral storage\n const ry = 7;\n const topY = ry;\n const bodyH = H - ry * 2;\n const f = fill(palette, isDark);\n const s = stroke(palette);\n const dash = '4 3';\n\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY + bodyH)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', topY)\n .attr('width', W)\n .attr('height', bodyH)\n .attr('fill', f)\n .attr('stroke', 'none');\n\n g.append('line')\n .attr('x1', -W / 2)\n .attr('y1', topY)\n .attr('x2', -W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n g.append('line')\n .attr('x1', W / 2)\n .attr('y1', topY)\n .attr('x2', W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n}\n\nfunction renderNetworkingParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Hexagon fitting within W x H\n const inset = 16;\n const points = [\n `${-W / 2 + inset},0`,\n `${W / 2 - inset},0`,\n `${W / 2},${H / 2}`,\n `${W / 2 - inset},${H}`,\n `${-W / 2 + inset},${H}`,\n `${-W / 2},${H / 2}`,\n ].join(' ');\n g.append('polygon')\n .attr('points', points)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW);\n}\n\nfunction renderFrontendParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Monitor shape fitting within W x H\n const screenH = H - 10;\n const s = stroke(palette);\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', screenH)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', s)\n .attr('stroke-width', SW);\n // Stand\n g.append('line')\n .attr('x1', 0)\n .attr('y1', screenH)\n .attr('x2', 0)\n .attr('y2', H - 2)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n // Base\n g.append('line')\n .attr('x1', -14)\n .attr('y1', H - 2)\n .attr('x2', 14)\n .attr('y2', H - 2)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n}\n\nfunction renderExternalParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Dashed border rectangle\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', H)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', '6 3');\n}\n\nfunction renderGatewayParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n renderRectParticipant(g, palette, isDark);\n}\n\n// ============================================================\n// Collapsible Section Support\n// ============================================================\n\nexport interface SectionMessageGroup {\n section: import('./parser').SequenceSection;\n messageIndices: number[]; // indices into messages[]\n}\n\nexport interface SequenceRenderOptions {\n collapsedSections?: Set<number>; // keyed by section lineNumber\n expandedNoteLines?: Set<number>; // keyed by note lineNumber; undefined = all expanded (CLI default)\n exportWidth?: number; // Explicit width for CLI/export rendering (bypasses getBoundingClientRect)\n}\n\n/**\n * Group messages by the top-level section that precedes them.\n * Messages before the first section are ungrouped (always visible).\n * Only top-level sections are collapsible — sections inside blocks are excluded.\n */\nexport function groupMessagesBySection(\n elements: SequenceElement[],\n messages: SequenceMessage[]\n): SectionMessageGroup[] {\n const groups: SectionMessageGroup[] = [];\n let currentGroup: SectionMessageGroup | null = null;\n\n // Recursively collect all message indices from an element subtree\n const collectIndices = (els: SequenceElement[]): number[] => {\n const indices: number[] = [];\n for (const el of els) {\n if (isSequenceBlock(el)) {\n indices.push(\n ...collectIndices(el.children),\n ...collectIndices(el.elseChildren)\n );\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n indices.push(...collectIndices(branch.children));\n }\n }\n } else if (isSequenceSection(el) || isSequenceNote(el)) {\n // Sections and notes inside blocks are not messages — skip\n continue;\n } else {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n return indices;\n };\n\n for (const el of elements) {\n if (isSequenceSection(el)) {\n // Start a new group for this top-level section\n currentGroup = { section: el, messageIndices: [] };\n groups.push(currentGroup);\n } else if (currentGroup) {\n // Collect messages from this element into the current group\n if (isSequenceBlock(el)) {\n currentGroup.messageIndices.push(...collectIndices([el]));\n } else if (!isSequenceNote(el)) {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) currentGroup.messageIndices.push(idx);\n }\n }\n // Messages before the first section are ungrouped — skip\n }\n\n return groups;\n}\n\n// ============================================================\n// Render Sequence Builder (stack-based return placement)\n// ============================================================\n\nexport interface RenderStep {\n type: 'call' | 'return';\n from: string;\n to: string;\n label: string;\n messageIndex: number;\n async?: boolean;\n}\n\n/**\n * Build an ordered render sequence from flat messages.\n * Uses a call stack to infer where returns should be placed:\n * returns appear after all nested sub-calls complete.\n */\nexport function buildRenderSequence(messages: SequenceMessage[]): RenderStep[] {\n const steps: RenderStep[] = [];\n const stack: {\n from: string;\n to: string;\n returnLabel?: string;\n messageIndex: number;\n }[] = [];\n\n for (let mi = 0; mi < messages.length; mi++) {\n const msg = messages[mi];\n // Pop returns for callees that are no longer the sender\n while (stack.length > 0) {\n const top = stack[stack.length - 1];\n if (top.to === msg.from) break; // callee is still working\n stack.pop();\n steps.push({\n type: 'return',\n from: top.to,\n to: top.from,\n label: top.returnLabel || '',\n messageIndex: top.messageIndex,\n });\n }\n\n // Emit call\n steps.push({\n type: 'call',\n from: msg.from,\n to: msg.to,\n label: msg.label,\n messageIndex: mi,\n ...(msg.async ? { async: true } : {}),\n });\n\n // Async messages: no return arrow, no activation on target\n if (msg.async) {\n continue;\n }\n\n if (msg.from === msg.to) {\n // Self-call: immediately emit return (completes instantly)\n steps.push({\n type: 'return',\n from: msg.to,\n to: msg.from,\n label: msg.returnLabel || '',\n messageIndex: mi,\n });\n } else {\n // Push onto stack for pending return\n stack.push({\n from: msg.from,\n to: msg.to,\n returnLabel: msg.returnLabel,\n messageIndex: mi,\n });\n }\n }\n\n // Flush remaining returns\n while (stack.length > 0) {\n const top = stack.pop()!;\n steps.push({\n type: 'return',\n from: top.to,\n to: top.from,\n label: top.returnLabel || '',\n messageIndex: top.messageIndex,\n });\n }\n\n return steps;\n}\n\n// ============================================================\n// Activation Computation\n// ============================================================\n\nexport interface Activation {\n participantId: string;\n startStep: number;\n endStep: number;\n depth: number;\n}\n\n/**\n * Compute activation rectangles from render steps.\n * Each call pushes onto the callee's stack; each return pops it.\n */\nexport function computeActivations(steps: RenderStep[]): Activation[] {\n const activations: Activation[] = [];\n // Per-participant stack of open activations (step index)\n const stacks = new Map<string, number[]>();\n\n const getStack = (id: string): number[] => {\n if (!stacks.has(id)) stacks.set(id, []);\n return stacks.get(id)!;\n };\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n if (step.type === 'call') {\n const s = getStack(step.to);\n s.push(i);\n } else {\n // return: step.from is the callee returning\n const s = getStack(step.from);\n if (s.length > 0) {\n const startIdx = s.pop()!;\n activations.push({\n participantId: step.from,\n startStep: startIdx,\n endStep: i,\n depth: s.length,\n });\n }\n }\n }\n\n return activations;\n}\n\n// ============================================================\n// Position Override Sorting\n// ============================================================\n\n/**\n * Reorder participants based on explicit `position` overrides.\n * Positive positions are 0-based from the left; negative positions count from the right (-1 = last).\n * Unpositioned participants maintain their relative order, filling remaining slots.\n */\nexport function applyPositionOverrides(\n participants: SequenceParticipant[]\n): SequenceParticipant[] {\n if (!participants.some((p) => p.position !== undefined)) return participants;\n\n const total = participants.length;\n const positioned: { participant: SequenceParticipant; index: number }[] = [];\n const unpositioned: SequenceParticipant[] = [];\n\n for (const p of participants) {\n if (p.position !== undefined) {\n // Resolve negative: -1 → last, -2 → second-to-last\n let idx = p.position < 0 ? total + p.position : p.position;\n // Clamp to valid range\n idx = Math.max(0, Math.min(total - 1, idx));\n positioned.push({ participant: p, index: idx });\n } else {\n unpositioned.push(p);\n }\n }\n\n // Sort positioned by target index for deterministic placement\n positioned.sort((a, b) => a.index - b.index);\n\n // Place positioned participants, resolving conflicts by finding nearest free slot\n const result: (SequenceParticipant | null)[] = new Array(total).fill(null);\n const usedIndices = new Set<number>();\n\n for (const { participant, index } of positioned) {\n let idx = index;\n if (usedIndices.has(idx)) {\n // Find nearest free slot\n for (let offset = 1; offset < total; offset++) {\n if (idx + offset < total && !usedIndices.has(idx + offset)) {\n idx = idx + offset;\n break;\n }\n if (idx - offset >= 0 && !usedIndices.has(idx - offset)) {\n idx = idx - offset;\n break;\n }\n }\n }\n result[idx] = participant;\n usedIndices.add(idx);\n }\n\n // Fill remaining slots with unpositioned participants in order\n let uIdx = 0;\n for (let i = 0; i < total; i++) {\n if (result[i] === null) {\n result[i] = unpositioned[uIdx++];\n }\n }\n\n return result as SequenceParticipant[];\n}\n\n// Group Ordering\n// ============================================================\n\n/**\n * Reorder participants so that members of the same group are adjacent.\n * Groups appear in declaration order, followed by ungrouped participants.\n */\nexport function applyGroupOrdering(\n participants: SequenceParticipant[],\n groups: SequenceGroup[]\n): SequenceParticipant[] {\n if (groups.length === 0) return participants;\n\n const groupedIds = new Set(groups.flatMap((g) => g.participantIds));\n const result: SequenceParticipant[] = [];\n const placed = new Set<string>();\n\n // Place grouped participants in group declaration order\n for (const group of groups) {\n for (const id of group.participantIds) {\n const p = participants.find((pp) => pp.id === id);\n if (p && !placed.has(id)) {\n result.push(p);\n placed.add(id);\n }\n }\n }\n\n // Append ungrouped participants in their original order\n for (const p of participants) {\n if (!groupedIds.has(p.id) && !placed.has(p.id)) {\n result.push(p);\n placed.add(p.id);\n }\n }\n\n return result;\n}\n\n// Main Renderer\n// ============================================================\n\n/**\n * Render a sequence diagram into the given container element.\n */\nexport function renderSequenceDiagram(\n container: HTMLDivElement,\n parsed: ParsedSequenceDgmo,\n palette: PaletteColors,\n isDark: boolean,\n _onNavigateToLine?: (line: number) => void,\n options?: SequenceRenderOptions\n): void {\n // Clear previous content\n d3Selection.select(container).selectAll('*').remove();\n\n const { title, messages, elements, groups, options: parsedOptions } = parsed;\n const collapsedSections = options?.collapsedSections;\n const expandedNoteLines = options?.expandedNoteLines;\n const collapseNotesDisabled = parsedOptions['collapse-notes']?.toLowerCase() === 'no';\n // A note is expanded if: expandedNoteLines is undefined (CLI/export),\n // collapse-notes: no is set, or the note's lineNumber is in the set.\n const isNoteExpanded = (note: SequenceNote): boolean =>\n expandedNoteLines === undefined || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);\n const participants = applyPositionOverrides(\n applyGroupOrdering(parsed.participants, groups)\n );\n if (participants.length === 0) return;\n\n const activationsOff = parsedOptions.activations?.toLowerCase() === 'off';\n\n // Build hidden message set for collapse support\n const hiddenMsgIndices = new Set<number>();\n if (collapsedSections && collapsedSections.size > 0) {\n const sectionGroups = groupMessagesBySection(elements, messages);\n for (const grp of sectionGroups) {\n if (collapsedSections.has(grp.section.lineNumber)) {\n for (const idx of grp.messageIndices) {\n hiddenMsgIndices.add(idx);\n }\n }\n }\n }\n\n // Build render sequence with stack-based return placement\n // Run on ALL messages first (preserves call stack correctness), then filter\n const allRenderSteps = buildRenderSequence(messages);\n let renderSteps =\n hiddenMsgIndices.size > 0\n ? allRenderSteps.filter((s) => !hiddenMsgIndices.has(s.messageIndex))\n : allRenderSteps;\n // Drop unlabeled returns — they add visual noise without conveying information.\n // Labeled returns (explicit <- value) are kept.\n renderSteps = renderSteps.filter(\n (s) => s.type === 'call' || s.label\n );\n const activations = activationsOff ? [] : computeActivations(renderSteps);\n const stepSpacing = 35;\n\n // --- Block-aware Y spacing ---\n // Extra spacing constants for block boundaries\n const BLOCK_HEADER_SPACE = 30; // Extra space for frame label above first message in a block\n const BLOCK_AFTER_SPACE = 15; // Extra space after a block ends (before next sibling)\n const FRAME_PADDING_TOP = 42; // Vertical padding from frame top to first message\n\n // Build maps from messageIndex to render step indices (needed early for spacing)\n const msgToFirstStep = new Map<number, number>();\n const msgToLastStep = new Map<number, number>();\n renderSteps.forEach((step, si) => {\n if (!msgToFirstStep.has(step.messageIndex)) {\n msgToFirstStep.set(step.messageIndex, si);\n }\n msgToLastStep.set(step.messageIndex, si);\n });\n\n // Map a note to the first render-step index of its preceding message\n // (the forward/call arrow, not the return arrow).\n // If the note's closest preceding message is hidden (collapsed section), return -1\n // so the note is hidden along with its section.\n const findAssociatedFirstStep = (note: SequenceNote): number => {\n // First find the closest preceding message (ignoring hidden filter)\n let closestMsgIndex = -1;\n let closestLine = -1;\n for (let mi = 0; mi < messages.length; mi++) {\n if (\n messages[mi].lineNumber < note.lineNumber &&\n messages[mi].lineNumber > closestLine\n ) {\n closestLine = messages[mi].lineNumber;\n closestMsgIndex = mi;\n }\n }\n // If the closest preceding message is hidden, hide the note too\n if (closestMsgIndex >= 0 && hiddenMsgIndices.has(closestMsgIndex)) {\n return -1;\n }\n if (closestMsgIndex < 0) return -1;\n return msgToFirstStep.get(closestMsgIndex) ?? -1;\n };\n\n // Find the first visible message index in an element subtree\n const findFirstMsgIndex = (els: SequenceElement[]): number => {\n for (const el of els) {\n if (isSequenceBlock(el)) {\n const idx = findFirstMsgIndex(el.children);\n if (idx >= 0) return idx;\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n const branchIdx = findFirstMsgIndex(branch.children);\n if (branchIdx >= 0) return branchIdx;\n }\n }\n const elseIdx = findFirstMsgIndex(el.elseChildren);\n if (elseIdx >= 0) return elseIdx;\n } else if (!isSequenceSection(el) && !isSequenceNote(el)) {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0 && !hiddenMsgIndices.has(idx)) return idx;\n }\n }\n return -1;\n };\n\n // Section layout constants\n const SECTION_TOP_PAD = 35; // space above section divider line (matches stepSpacing)\n const SECTION_BOTTOM_PAD = 45; // space below section divider line before next content\n\n // Block spacing via extraBeforeMsg (sections handled separately below)\n const extraBeforeMsg = new Map<number, number>();\n const addExtra = (msgIdx: number, amount: number) => {\n extraBeforeMsg.set(msgIdx, (extraBeforeMsg.get(msgIdx) || 0) + amount);\n };\n\n const markBlockSpacing = (els: SequenceElement[]): void => {\n for (let i = 0; i < els.length; i++) {\n const el = els[i];\n if (isSequenceSection(el)) continue; // sections handled separately\n if (!isSequenceBlock(el)) continue;\n\n const firstIdx = findFirstMsgIndex(el.children);\n if (firstIdx >= 0) addExtra(firstIdx, BLOCK_HEADER_SPACE);\n\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n const firstBranchIdx = findFirstMsgIndex(branch.children);\n if (firstBranchIdx >= 0) addExtra(firstBranchIdx, BLOCK_HEADER_SPACE);\n markBlockSpacing(branch.children);\n }\n }\n\n const firstElseIdx = findFirstMsgIndex(el.elseChildren);\n if (firstElseIdx >= 0) addExtra(firstElseIdx, BLOCK_HEADER_SPACE);\n\n markBlockSpacing(el.children);\n markBlockSpacing(el.elseChildren);\n\n if (i + 1 < els.length) {\n const nextIdx = findFirstMsgIndex([els[i + 1]]);\n if (nextIdx >= 0) addExtra(nextIdx, BLOCK_AFTER_SPACE);\n }\n }\n };\n\n if (elements && elements.length > 0) {\n markBlockSpacing(elements);\n }\n\n // Note spacing — add vertical room after messages that have notes attached\n const NOTE_OFFSET_BELOW = 14; // gap between message arrow and top of note box\n // The next message label extends ~17px above its arrow line (8px offset + 9px cap height).\n // When notes share horizontal space with subsequent arrows, generous vertical clearance\n // is needed so note boxes don't visually cover message labels.\n const NOTE_TRAILING_GAP = 35;\n const computeNoteHeight = (text: string): number => {\n const lines = wrapTextLines(text, NOTE_CHARS_PER_LINE);\n return lines.length * NOTE_LINE_H + NOTE_PAD_V * 2;\n };\n let trailingNoteSpace = 0; // extra space for notes at the end with no following message\n const markNoteSpacing = (els: SequenceElement[]): void => {\n for (let i = 0; i < els.length; i++) {\n const el = els[i];\n if (isSequenceNote(el)) {\n // Total vertical extent of notes from the message arrow:\n // NOTE_OFFSET_BELOW (gap above first note)\n // + each note's height + NOTE_OFFSET_BELOW (inter-note gap)\n // + NOTE_TRAILING_GAP (gap below last note — clears next message label)\n let totalExtent = NOTE_OFFSET_BELOW;\n let j = i;\n while (j < els.length && isSequenceNote(els[j])) {\n const note = els[j] as SequenceNote;\n const noteH = isNoteExpanded(note)\n ? computeNoteHeight(note.text)\n : COLLAPSED_NOTE_H;\n totalExtent += noteH + NOTE_OFFSET_BELOW;\n j++;\n }\n // Replace the final inter-note gap with the larger trailing gap\n totalExtent += NOTE_TRAILING_GAP - NOTE_OFFSET_BELOW;\n // Only reserve space beyond the existing stepSpacing gap\n let extraNeeded = Math.max(0, totalExtent - stepSpacing);\n // Scan forward past sections, blocks, and other non-message elements to find next message\n let nextMsgIdx = -1;\n for (let k = j; k < els.length; k++) {\n nextMsgIdx = findFirstMsgIndex([els[k]]);\n if (nextMsgIdx >= 0) break;\n }\n // If a block follows, its frame extends FRAME_PADDING_TOP above the first\n // message but only BLOCK_HEADER_SPACE is reserved. Add the difference so\n // the note doesn't overlap the frame.\n if (j < els.length && isSequenceBlock(els[j])) {\n extraNeeded += FRAME_PADDING_TOP - BLOCK_HEADER_SPACE;\n }\n if (nextMsgIdx >= 0) {\n addExtra(nextMsgIdx, extraNeeded);\n } else {\n // Notes at the end — reserve only the excess beyond stepSpacing\n trailingNoteSpace = Math.max(trailingNoteSpace, extraNeeded);\n }\n // Skip over the consecutive notes we just processed\n i = j - 1;\n } else if (isSequenceBlock(el)) {\n markNoteSpacing(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n markNoteSpacing(branch.children);\n }\n }\n markNoteSpacing(el.elseChildren);\n }\n }\n };\n if (elements && elements.length > 0) {\n markNoteSpacing(elements);\n }\n\n // --- Section-aware Y layout ---\n // Sections get their own Y positions computed from content above them (not anchored\n // to messages below). This ensures toggling collapse/expand doesn't move the divider.\n\n // Walk top-level elements to build section regions\n interface SectionRegion {\n section: import('./parser').SequenceSection;\n msgIndices: number[]; // message indices belonging to this section\n }\n const preSectionMsgIndices: number[] = [];\n const sectionRegions: SectionRegion[] = [];\n {\n const collectMsgIndicesFromBlock = (\n block: import('./parser').SequenceBlock\n ): number[] => {\n const indices: number[] = [];\n for (const child of block.children) {\n if (isSequenceBlock(child)) {\n indices.push(...collectMsgIndicesFromBlock(child));\n } else if (!isSequenceSection(child) && !isSequenceNote(child)) {\n const idx = messages.indexOf(child as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n if (block.elseIfBranches) {\n for (const branch of block.elseIfBranches) {\n for (const child of branch.children) {\n if (isSequenceBlock(child)) {\n indices.push(...collectMsgIndicesFromBlock(child));\n } else if (!isSequenceSection(child) && !isSequenceNote(child)) {\n const idx = messages.indexOf(child as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n }\n }\n for (const child of block.elseChildren) {\n if (isSequenceBlock(child)) {\n indices.push(...collectMsgIndicesFromBlock(child));\n } else if (!isSequenceSection(child) && !isSequenceNote(child)) {\n const idx = messages.indexOf(child as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n return indices;\n };\n\n let currentTarget = preSectionMsgIndices;\n for (const el of elements) {\n if (isSequenceSection(el)) {\n const region: SectionRegion = { section: el, msgIndices: [] };\n sectionRegions.push(region);\n currentTarget = region.msgIndices;\n } else if (isSequenceBlock(el)) {\n currentTarget.push(...collectMsgIndicesFromBlock(el));\n } else {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) currentTarget.push(idx);\n }\n }\n }\n\n // Build mapping from original (all) render step index → filtered step index\n const allMsgToFirstStep = new Map<number, number>();\n allRenderSteps.forEach((step, si) => {\n if (!allMsgToFirstStep.has(step.messageIndex)) {\n allMsgToFirstStep.set(step.messageIndex, si);\n }\n });\n\n const originalToFiltered = new Map<number, number>();\n {\n let fi = 0;\n for (let oi = 0; oi < allRenderSteps.length; oi++) {\n const step = allRenderSteps[oi];\n if (\n !hiddenMsgIndices.has(step.messageIndex) &&\n (step.type === 'call' || step.label)\n ) {\n originalToFiltered.set(oi, fi);\n fi++;\n }\n }\n }\n\n // For each section, find the filtered step index where its padding should be inserted\n const findFilteredInsertionPoint = (origStep: number): number | null => {\n for (let i = origStep; i < allRenderSteps.length; i++) {\n const fi = originalToFiltered.get(i);\n if (fi !== undefined) return fi;\n }\n return null;\n };\n\n // Map: filtered step index → sections to insert before it (in document order)\n const sectionsBeforeStep = new Map<\n number,\n import('./parser').SequenceSection[]\n >();\n const trailingSections: import('./parser').SequenceSection[] = [];\n\n for (const region of sectionRegions) {\n if (region.msgIndices.length === 0) {\n trailingSections.push(region.section);\n continue;\n }\n const firstMsgIdx = region.msgIndices[0];\n const origStep = allMsgToFirstStep.get(firstMsgIdx);\n if (origStep === undefined) {\n trailingSections.push(region.section);\n continue;\n }\n const filteredStep = findFilteredInsertionPoint(origStep);\n if (filteredStep === null) {\n trailingSections.push(region.section);\n continue;\n }\n const existing = sectionsBeforeStep.get(filteredStep) || [];\n existing.push(region.section);\n sectionsBeforeStep.set(filteredStep, existing);\n }\n\n // Section message counts for collapsed labels\n const sectionMsgCounts = new Map<number, number>();\n for (const region of sectionRegions) {\n sectionMsgCounts.set(region.section.lineNumber, region.msgIndices.length);\n }\n\n // Group box layout constants (needed early for Y offset)\n const GROUP_PADDING_X = 15;\n const GROUP_PADDING_TOP = 22;\n const GROUP_PADDING_BOTTOM = 8;\n const GROUP_LABEL_SIZE = 11;\n\n // Compute cumulative Y positions for each step, with section dividers as stable anchors\n const titleOffset = title ? TITLE_HEIGHT : 0;\n const groupOffset =\n groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;\n const participantStartY =\n TOP_MARGIN + titleOffset + PARTICIPANT_Y_OFFSET + groupOffset;\n const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;\n const hasActors = participants.some((p) => p.type === 'actor');\n const messageStartOffset = MESSAGE_START_OFFSET + (hasActors ? 20 : 0);\n const stepYPositions: number[] = [];\n const sectionYPositions = new Map<number, number>(); // section lineNumber → Y\n let layoutEndY: number; // final Y after all steps and trailing sections\n {\n let curY = lifelineStartY0 + messageStartOffset;\n for (let i = 0; i < renderSteps.length; i++) {\n // Insert section padding before this step if needed\n const sections = sectionsBeforeStep.get(i);\n if (sections) {\n for (const sec of sections) {\n curY += SECTION_TOP_PAD;\n sectionYPositions.set(sec.lineNumber, curY);\n curY += SECTION_BOTTOM_PAD;\n }\n }\n\n const step = renderSteps[i];\n // Add extra spacing before the first render step of a flagged message (block spacing)\n if (msgToFirstStep.get(step.messageIndex) === i) {\n const extra = extraBeforeMsg.get(step.messageIndex) || 0;\n curY += extra;\n }\n stepYPositions.push(curY);\n curY += stepSpacing;\n }\n // Handle trailing sections (after all steps)\n for (const sec of trailingSections) {\n curY += SECTION_TOP_PAD;\n sectionYPositions.set(sec.lineNumber, curY);\n curY += SECTION_BOTTOM_PAD;\n }\n // Extend for trailing notes that have no following message\n curY += trailingNoteSpace;\n layoutEndY = curY;\n }\n\n // Helper: compute Y for a step index\n const stepY = (i: number) => stepYPositions[i];\n\n // Compute absolute Y positions for each note element\n const noteYMap = new Map<SequenceNote, number>();\n {\n const computeNotePositions = (els: SequenceElement[]): void => {\n for (let i = 0; i < els.length; i++) {\n const el = els[i];\n if (isSequenceNote(el)) {\n const si = findAssociatedFirstStep(el);\n if (si < 0) continue;\n // Check if there's a preceding note that we should stack below\n const prevNote = i > 0 && isSequenceNote(els[i - 1]) ? (els[i - 1] as SequenceNote) : null;\n const prevNoteY = prevNote ? noteYMap.get(prevNote) : undefined;\n let noteTopY: number;\n if (prevNoteY !== undefined && prevNote) {\n // Stack below previous note\n const prevNoteH = isNoteExpanded(prevNote)\n ? computeNoteHeight(prevNote.text)\n : COLLAPSED_NOTE_H;\n noteTopY = prevNoteY + prevNoteH + NOTE_OFFSET_BELOW;\n } else {\n // First note after a message\n noteTopY = stepY(si) + NOTE_OFFSET_BELOW;\n }\n noteYMap.set(el, noteTopY);\n } else if (isSequenceBlock(el)) {\n computeNotePositions(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n computeNotePositions(branch.children);\n }\n }\n computeNotePositions(el.elseChildren);\n }\n }\n };\n if (elements && elements.length > 0) {\n computeNotePositions(elements);\n }\n }\n\n // Ensure contentBottomY accounts for all note extents\n let contentBottomY =\n renderSteps.length > 0\n ? Math.max(\n stepYPositions[stepYPositions.length - 1] + stepSpacing,\n layoutEndY\n )\n : layoutEndY;\n for (const [note, noteTopY] of noteYMap) {\n const noteH = isNoteExpanded(note) ? computeNoteHeight(note.text) : COLLAPSED_NOTE_H;\n contentBottomY = Math.max(contentBottomY, noteTopY + noteH + NOTE_TRAILING_GAP);\n }\n const messageAreaHeight = contentBottomY - lifelineStartY0;\n const lifelineLength = messageAreaHeight + LIFELINE_TAIL;\n const totalWidth = Math.max(\n participants.length * PARTICIPANT_GAP,\n PARTICIPANT_BOX_WIDTH + 40\n );\n const totalHeight =\n participantStartY +\n PARTICIPANT_BOX_HEIGHT +\n Math.max(lifelineLength, 40) +\n 40;\n\n const containerWidth = options?.exportWidth ?? container.getBoundingClientRect().width;\n const svgWidth = Math.max(totalWidth, containerWidth);\n\n // Center the diagram horizontally\n const diagramWidth = participants.length * PARTICIPANT_GAP;\n const offsetX =\n Math.max(0, (svgWidth - diagramWidth) / 2) + PARTICIPANT_GAP / 2;\n\n // Build participant x-position lookup\n const participantX = new Map<string, number>();\n participants.forEach((p, i) => {\n participantX.set(p.id, offsetX + i * PARTICIPANT_GAP);\n });\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', '100%')\n .attr('height', totalHeight)\n .attr('viewBox', `0 0 ${svgWidth} ${totalHeight}`)\n .attr('preserveAspectRatio', 'xMidYMin meet')\n .attr('class', 'sequence-diagram')\n .style('font-family', FONT_FAMILY);\n\n // Define arrowhead markers\n const defs = svg.append('defs');\n\n // Filled arrowhead for call arrows\n defs\n .append('marker')\n .attr('id', 'seq-arrowhead')\n .attr('viewBox', `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`)\n .attr('refX', ARROWHEAD_SIZE)\n .attr('refY', ARROWHEAD_SIZE / 2)\n .attr('markerWidth', ARROWHEAD_SIZE)\n .attr('markerHeight', ARROWHEAD_SIZE)\n .attr('orient', 'auto')\n .append('polygon')\n .attr(\n 'points',\n `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`\n )\n .attr('fill', palette.text);\n\n // Open arrowhead for return arrows\n defs\n .append('marker')\n .attr('id', 'seq-arrowhead-open')\n .attr('viewBox', `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`)\n .attr('refX', ARROWHEAD_SIZE)\n .attr('refY', ARROWHEAD_SIZE / 2)\n .attr('markerWidth', ARROWHEAD_SIZE)\n .attr('markerHeight', ARROWHEAD_SIZE)\n .attr('orient', 'auto')\n .append('polyline')\n .attr(\n 'points',\n `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`\n )\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.2);\n\n // Open arrowhead for async (fire-and-forget) arrows — same as return but text color\n defs\n .append('marker')\n .attr('id', 'seq-arrowhead-async')\n .attr('viewBox', `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`)\n .attr('refX', ARROWHEAD_SIZE)\n .attr('refY', ARROWHEAD_SIZE / 2)\n .attr('markerWidth', ARROWHEAD_SIZE)\n .attr('markerHeight', ARROWHEAD_SIZE)\n .attr('orient', 'auto')\n .append('polyline')\n .attr(\n 'points',\n `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`\n )\n .attr('fill', 'none')\n .attr('stroke', palette.text)\n .attr('stroke-width', 1.2);\n\n // Render title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', svgWidth / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', 20)\n .attr('font-weight', 'bold')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n }\n }\n\n // Render group boxes (behind participant shapes)\n for (const group of groups) {\n if (group.participantIds.length === 0) continue;\n\n // Find X bounds from member participant positions\n const memberXs = group.participantIds\n .map((id) => participantX.get(id))\n .filter((x): x is number => x !== undefined);\n if (memberXs.length === 0) continue;\n\n const minX =\n Math.min(...memberXs) - PARTICIPANT_BOX_WIDTH / 2 - GROUP_PADDING_X;\n const maxX =\n Math.max(...memberXs) + PARTICIPANT_BOX_WIDTH / 2 + GROUP_PADDING_X;\n const boxY = participantStartY - GROUP_PADDING_TOP;\n const boxH =\n PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;\n\n // Group box background\n const resolvedGroupColor = group.color\n ? resolveColor(group.color, palette)\n : undefined;\n const fillColor = resolvedGroupColor\n ? mix(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10)\n : isDark\n ? palette.surface\n : palette.bg;\n const strokeColor = resolvedGroupColor || palette.textMuted;\n\n svg\n .append('rect')\n .attr('x', minX)\n .attr('y', boxY)\n .attr('width', maxX - minX)\n .attr('height', boxH)\n .attr('rx', 6)\n .attr('fill', fillColor)\n .attr('stroke', strokeColor)\n .attr('stroke-width', 1)\n .attr('stroke-opacity', 0.5)\n .attr('class', 'group-box')\n .attr('data-group-line', String(group.lineNumber));\n\n // Group label\n svg\n .append('text')\n .attr('x', minX + 8)\n .attr('y', boxY + GROUP_LABEL_SIZE + 4)\n .attr('fill', strokeColor)\n .attr('font-size', GROUP_LABEL_SIZE)\n .attr('font-weight', 'bold')\n .attr('opacity', 0.7)\n .attr('class', 'group-label')\n .attr('data-group-line', String(group.lineNumber))\n .text(group.name);\n }\n\n // Render each participant\n const lifelineStartY = lifelineStartY0;\n participants.forEach((participant, index) => {\n const cx = offsetX + index * PARTICIPANT_GAP;\n const cy = participantStartY;\n\n renderParticipant(svg, participant, cx, cy, palette, isDark);\n\n // Render lifeline\n svg\n .append('line')\n .attr('x1', cx)\n .attr('y1', lifelineStartY)\n .attr('x2', cx)\n .attr('y2', lifelineStartY + lifelineLength)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '6 4')\n .attr('class', 'lifeline');\n });\n\n // Render block frames (behind everything else)\n const FRAME_PADDING_X = 30;\n // FRAME_PADDING_TOP declared earlier (near BLOCK_HEADER_SPACE)\n const FRAME_PADDING_BOTTOM = 15;\n const FRAME_LABEL_HEIGHT = 18;\n\n // Collect message indices from an element subtree\n const collectMsgIndices = (els: SequenceElement[]): number[] => {\n const indices: number[] = [];\n for (const el of els) {\n if (isSequenceBlock(el)) {\n indices.push(\n ...collectMsgIndices(el.children),\n ...collectMsgIndices(el.elseChildren)\n );\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n indices.push(...collectMsgIndices(branch.children));\n }\n }\n } else if (!isSequenceSection(el) && !isSequenceNote(el)) {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n return indices;\n };\n\n // Collect deferred draws (rendered after activations so they appear on top)\n const deferredLabels: Array<{\n x: number;\n y: number;\n text: string;\n bold: boolean;\n italic: boolean;\n blockLine?: number;\n }> = [];\n const deferredLines: Array<{\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n }> = [];\n\n // Recursive block renderer — draws borders/dividers now, defers label text\n const renderBlockFrames = (els: SequenceElement[], depth: number): void => {\n for (const el of els) {\n if (!isSequenceBlock(el)) continue;\n\n const ifIndices = collectMsgIndices(el.children);\n const elseIfBranchData: { label: string; indices: number[] }[] = [];\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n elseIfBranchData.push({\n label: branch.label,\n indices: collectMsgIndices(branch.children),\n });\n }\n }\n const elseIndices = collectMsgIndices(el.elseChildren);\n const allIndices = [\n ...ifIndices,\n ...elseIfBranchData.flatMap((b) => b.indices),\n ...elseIndices,\n ];\n if (allIndices.length === 0) continue;\n\n // Find render step range\n let minStep = Infinity;\n let maxStep = -Infinity;\n for (const mi of allIndices) {\n const first = msgToFirstStep.get(mi);\n const last = msgToLastStep.get(mi);\n if (first !== undefined) minStep = Math.min(minStep, first);\n if (last !== undefined) maxStep = Math.max(maxStep, last);\n }\n if (minStep === Infinity) continue;\n\n // Find participant X range\n const involved = new Set<string>();\n for (const mi of allIndices) {\n involved.add(messages[mi].from);\n involved.add(messages[mi].to);\n }\n let minPX = Infinity;\n let maxPX = -Infinity;\n for (const pid of involved) {\n const px = participantX.get(pid);\n if (px !== undefined) {\n minPX = Math.min(minPX, px);\n maxPX = Math.max(maxPX, px);\n }\n }\n\n const frameX = minPX - FRAME_PADDING_X;\n const frameY = stepY(minStep) - FRAME_PADDING_TOP;\n const frameW = maxPX - minPX + FRAME_PADDING_X * 2;\n const frameH =\n stepY(maxStep) -\n stepY(minStep) +\n FRAME_PADDING_TOP +\n FRAME_PADDING_BOTTOM;\n\n // Frame border\n svg\n .append('rect')\n .attr('x', frameX)\n .attr('y', frameY)\n .attr('width', frameW)\n .attr('height', frameH)\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '2 3')\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('class', 'block-frame')\n .attr('data-block-line', String(el.lineNumber));\n\n // Defer label text (rendered on top of activations later)\n deferredLabels.push({\n x: frameX + 6,\n y: frameY + FRAME_LABEL_HEIGHT - 4,\n text: `${el.type} ${el.label}`,\n bold: true,\n italic: false,\n blockLine: el.lineNumber,\n });\n\n // Else-if dividers\n for (const branchData of elseIfBranchData) {\n if (branchData.indices.length > 0) {\n let firstBranchStep = Infinity;\n for (const mi of branchData.indices) {\n const first = msgToFirstStep.get(mi);\n if (first !== undefined)\n firstBranchStep = Math.min(firstBranchStep, first);\n }\n if (firstBranchStep < Infinity) {\n const dividerY = stepY(firstBranchStep) - stepSpacing / 2;\n deferredLines.push({\n x1: frameX,\n y1: dividerY,\n x2: frameX + frameW,\n y2: dividerY,\n });\n deferredLabels.push({\n x: frameX + 6,\n y: dividerY + 14,\n text: `else if ${branchData.label}`,\n bold: false,\n italic: true,\n });\n }\n }\n }\n\n // Else divider\n if (elseIndices.length > 0) {\n let firstElseStep = Infinity;\n for (const mi of elseIndices) {\n const first = msgToFirstStep.get(mi);\n if (first !== undefined)\n firstElseStep = Math.min(firstElseStep, first);\n }\n if (firstElseStep < Infinity) {\n const dividerY = stepY(firstElseStep) - stepSpacing / 2;\n deferredLines.push({\n x1: frameX,\n y1: dividerY,\n x2: frameX + frameW,\n y2: dividerY,\n });\n deferredLabels.push({\n x: frameX + 6,\n y: dividerY + 14,\n text: 'else',\n bold: false,\n italic: true,\n });\n }\n }\n\n // Recurse into nested blocks\n renderBlockFrames(el.children, depth + 1);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n renderBlockFrames(branch.children, depth + 1);\n }\n }\n renderBlockFrames(el.elseChildren, depth + 1);\n }\n };\n\n if (elements && elements.length > 0) {\n renderBlockFrames(elements, 0);\n }\n\n // Render activation rectangles (behind arrows)\n const ACTIVATION_WIDTH = 10;\n const ACTIVATION_NEST_OFFSET = 6;\n activations.forEach((act) => {\n const px = participantX.get(act.participantId);\n if (px === undefined) return;\n\n const x = px - ACTIVATION_WIDTH / 2 + act.depth * ACTIVATION_NEST_OFFSET;\n const y1 = stepY(act.startStep);\n const y2 = stepY(act.endStep);\n\n // Collect message line numbers covered by this activation\n const coveredLines: number[] = [];\n for (let si = act.startStep; si <= act.endStep; si++) {\n const step = renderSteps[si];\n const msg = messages[step.messageIndex];\n if (msg) coveredLines.push(msg.lineNumber);\n }\n\n // Opaque background to mask the lifeline\n svg\n .append('rect')\n .attr('x', x)\n .attr('y', y1)\n .attr('width', ACTIVATION_WIDTH)\n .attr('height', y2 - y1)\n .attr('fill', isDark ? palette.surface : palette.bg);\n\n const actFill = mix(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);\n svg\n .append('rect')\n .attr('x', x)\n .attr('y', y1)\n .attr('width', ACTIVATION_WIDTH)\n .attr('height', y2 - y1)\n .attr('fill', actFill)\n .attr('stroke', palette.primary)\n .attr('stroke-width', 1)\n .attr('stroke-opacity', 0.5)\n .attr('data-participant-id', act.participantId)\n .attr('data-msg-lines', coveredLines.join(','))\n .attr('class', 'activation');\n });\n\n // Render deferred else dividers (on top of activations)\n for (const ln of deferredLines) {\n svg\n .append('line')\n .attr('x1', ln.x1)\n .attr('y1', ln.y1)\n .attr('x2', ln.x2)\n .attr('y2', ln.y2)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '2 3');\n }\n\n // Render deferred block labels (on top of activations)\n for (const lbl of deferredLabels) {\n const t = svg\n .append('text')\n .attr('x', lbl.x)\n .attr('y', lbl.y)\n .attr('fill', palette.text)\n .attr('font-size', 11)\n .attr('class', 'block-label')\n .text(lbl.text);\n if (lbl.bold) t.attr('font-weight', 'bold');\n if (lbl.italic) t.attr('font-style', 'italic');\n if (lbl.blockLine !== undefined)\n t.attr('data-block-line', String(lbl.blockLine));\n }\n\n // Helper: find max active activation depth for a participant at a step\n const activeDepthAt = (pid: string, stepIdx: number): number => {\n let maxDepth = -1;\n for (const act of activations) {\n if (\n act.participantId === pid &&\n act.startStep <= stepIdx &&\n stepIdx <= act.endStep &&\n act.depth > maxDepth\n ) {\n maxDepth = act.depth;\n }\n }\n return maxDepth;\n };\n\n // Helper: compute arrow endpoint X, snapping to activation box edge\n const arrowEdgeX = (\n pid: string,\n stepIdx: number,\n side: 'left' | 'right'\n ): number => {\n const px = participantX.get(pid)!;\n const depth = activeDepthAt(pid, stepIdx);\n if (depth < 0) return px;\n const offset = depth * ACTIVATION_NEST_OFFSET;\n return side === 'right'\n ? px + ACTIVATION_WIDTH / 2 + offset\n : px - ACTIVATION_WIDTH / 2 + offset;\n };\n\n // Render section dividers\n const leftmostX = Math.min(...Array.from(participantX.values()));\n const rightmostX = Math.max(...Array.from(participantX.values()));\n const sectionLineX1 = leftmostX - PARTICIPANT_BOX_WIDTH / 2 - 10;\n const sectionLineX2 = rightmostX + PARTICIPANT_BOX_WIDTH / 2 + 10;\n\n for (const region of sectionRegions) {\n const sec = region.section;\n const secY = sectionYPositions.get(sec.lineNumber);\n if (secY === undefined) continue;\n\n const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;\n const lineColor = sec.color\n ? resolveColor(sec.color, palette)\n : palette.textMuted;\n\n // Wrap section elements in a <g> for toggle.\n // IMPORTANT: only the <g> carries data-line-number / data-section —\n // children must NOT have them, otherwise the click walk-up resolves\n // to a line-number navigation before reaching data-section-toggle.\n const HIT_AREA_HEIGHT = 36;\n const sectionG = svg\n .append('g')\n .attr('data-section-toggle', '')\n .attr('data-line-number', String(sec.lineNumber))\n .attr('data-section', '')\n .attr('tabindex', '0')\n .attr('role', 'button')\n .attr('aria-expanded', String(!isCollapsed));\n\n // Full-width tinted band\n const BAND_HEIGHT = 22;\n const bandX = sectionLineX1 - 10;\n const bandWidth = sectionLineX2 - sectionLineX1 + 20;\n const bandOpacity = isCollapsed\n ? (isDark ? 0.35 : 0.25)\n : (isDark ? 0.1 : 0.08);\n sectionG\n .append('rect')\n .attr('x', bandX)\n .attr('y', secY - BAND_HEIGHT / 2)\n .attr('width', bandWidth)\n .attr('height', BAND_HEIGHT)\n .attr('fill', lineColor)\n .attr('opacity', bandOpacity)\n .attr('rx', 2)\n .attr('class', 'section-divider');\n\n // Build display label\n const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;\n const labelText = isCollapsed\n ? `${sec.label} (${msgCount} ${msgCount === 1 ? 'message' : 'messages'})`\n : sec.label;\n\n // Collapsed sections use white text for contrast against the darker band\n const labelColor = isCollapsed ? '#ffffff' : lineColor;\n\n // Chevron indicator\n const chevronSpace = 14;\n const labelX = (sectionLineX1 + sectionLineX2) / 2;\n const chevronX = labelX - (labelText.length * 3.5 + 8 + chevronSpace / 2);\n const chevronY = secY;\n if (isCollapsed) {\n // Right-pointing triangle ▶\n sectionG\n .append('path')\n .attr(\n 'd',\n `M ${chevronX} ${chevronY - 4} L ${chevronX + 6} ${chevronY} L ${chevronX} ${chevronY + 4} Z`\n )\n .attr('fill', labelColor)\n .attr('class', 'section-chevron');\n } else {\n // Down-pointing triangle ▼\n sectionG\n .append('path')\n .attr(\n 'd',\n `M ${chevronX - 1} ${chevronY - 3} L ${chevronX + 7} ${chevronY - 3} L ${chevronX + 3} ${chevronY + 3} Z`\n )\n .attr('fill', labelColor)\n .attr('class', 'section-chevron');\n }\n\n // Centered label text\n sectionG\n .append('text')\n .attr('x', labelX + chevronSpace / 2)\n .attr('y', secY + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', labelColor)\n .attr('font-size', 11)\n .attr('font-weight', 'bold')\n .attr('class', 'section-label')\n .text(labelText);\n }\n\n // Render steps (calls and returns in stack-inferred order)\n const SELF_CALL_WIDTH = 30;\n const SELF_CALL_HEIGHT = 25;\n renderSteps.forEach((step, i) => {\n const fromX = participantX.get(step.from);\n const toX = participantX.get(step.to);\n if (fromX === undefined || toX === undefined) return;\n\n const y = stepY(i);\n\n if (step.type === 'call') {\n if (step.from === step.to) {\n // Self-call: loopback arrow from right edge of activation\n const x = arrowEdgeX(step.from, i, 'right');\n svg\n .append('path')\n .attr(\n 'd',\n `M ${x} ${y} H ${x + SELF_CALL_WIDTH} V ${y + SELF_CALL_HEIGHT} H ${x}`\n )\n .attr('fill', 'none')\n .attr('stroke', palette.text)\n .attr('stroke-width', 1.2)\n .attr('marker-end', 'url(#seq-arrowhead)')\n .attr('class', 'message-arrow self-call')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n\n if (step.label) {\n const labelEl = svg\n .append('text')\n .attr('x', x + SELF_CALL_WIDTH + 5)\n .attr('y', y + SELF_CALL_HEIGHT / 2 + 4)\n .attr('text-anchor', 'start')\n .attr('fill', palette.text)\n .attr('font-size', 12)\n .attr('class', 'message-label')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n renderInlineText(labelEl, step.label, palette);\n }\n } else {\n // Normal call arrow — snap to activation box edges\n const goingRight = fromX < toX;\n const x1 = arrowEdgeX(step.from, i, goingRight ? 'right' : 'left');\n const x2 = arrowEdgeX(step.to, i, goingRight ? 'left' : 'right');\n\n const markerRef = step.async\n ? 'url(#seq-arrowhead-async)'\n : 'url(#seq-arrowhead)';\n svg\n .append('line')\n .attr('x1', x1)\n .attr('y1', y)\n .attr('x2', x2)\n .attr('y2', y)\n .attr('stroke', palette.text)\n .attr('stroke-width', 1.2)\n .attr('marker-end', markerRef)\n .attr('class', 'message-arrow')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n\n if (step.label) {\n const midX = (x1 + x2) / 2;\n const labelEl = svg\n .append('text')\n .attr('x', midX)\n .attr('y', y - 8)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', 12)\n .attr('class', 'message-label')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n renderInlineText(labelEl, step.label, palette);\n }\n }\n } else {\n if (step.from === step.to) {\n // Self-call return — already handled by the loopback path, skip\n return;\n }\n // Return arrow — snap to activation box edges\n const goingRight = fromX < toX;\n const x1 = arrowEdgeX(step.from, i, goingRight ? 'right' : 'left');\n const x2 = arrowEdgeX(step.to, i, goingRight ? 'left' : 'right');\n\n svg\n .append('line')\n .attr('x1', x1)\n .attr('y1', y)\n .attr('x2', x2)\n .attr('y2', y)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '6 4')\n .attr('marker-end', 'url(#seq-arrowhead-open)')\n .attr('class', 'return-arrow')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n\n if (step.label) {\n const midX = (x1 + x2) / 2;\n const labelEl = svg\n .append('text')\n .attr('x', midX)\n .attr('y', y - 6)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.textMuted)\n .attr('font-size', 11)\n .attr('class', 'message-label')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n renderInlineText(labelEl, step.label, palette);\n }\n }\n });\n\n // Render notes — folded-corner boxes attached to participant lifelines\n const noteFill = isDark\n ? mix(palette.surface, palette.bg, 50)\n : mix(palette.bg, palette.surface, 15);\n\n const collapsedNoteFill = mix(palette.textMuted, palette.bg, 15);\n\n const renderNoteElements = (els: SequenceElement[]): void => {\n for (const el of els) {\n if (isSequenceNote(el)) {\n const px = participantX.get(el.participantId);\n if (px === undefined) continue;\n const noteTopY = noteYMap.get(el);\n if (noteTopY === undefined) continue;\n\n const expanded = isNoteExpanded(el);\n const isRight = el.position === 'right';\n\n if (expanded) {\n // --- Expanded note: full folded-corner box with wrapped text ---\n const wrappedLines = wrapTextLines(el.text, NOTE_CHARS_PER_LINE);\n const noteH = wrappedLines.length * NOTE_LINE_H + NOTE_PAD_V * 2;\n const maxLineLen = Math.max(...wrappedLines.map((l) => l.length));\n const noteW = Math.min(\n NOTE_MAX_W,\n Math.max(80, maxLineLen * NOTE_CHAR_W + NOTE_PAD_H * 2 + NOTE_FOLD)\n );\n const noteX = isRight\n ? px + ACTIVATION_WIDTH + NOTE_GAP\n : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;\n\n const noteG = svg\n .append('g')\n .attr('class', 'note')\n .attr('data-note-toggle', '')\n .attr('data-line-number', String(el.lineNumber))\n .attr('data-line-end', String(el.endLineNumber));\n\n // Folded-corner path\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX} ${noteTopY}`,\n `L ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,\n `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,\n `L ${noteX + noteW} ${noteTopY + noteH}`,\n `L ${noteX} ${noteTopY + noteH}`,\n 'Z',\n ].join(' ')\n )\n .attr('fill', noteFill)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-box');\n\n // Fold triangle\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,\n `L ${noteX + noteW - NOTE_FOLD} ${noteTopY + NOTE_FOLD}`,\n `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,\n ].join(' ')\n )\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-fold');\n\n // Render text with inline markdown\n wrappedLines.forEach((line, li) => {\n const textY =\n noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;\n const isBullet = line.startsWith('- ');\n const bulletIndent = isBullet ? 10 : 0;\n const displayLine = isBullet ? line.slice(2) : line;\n const textEl = noteG\n .append('text')\n .attr('x', noteX + NOTE_PAD_H + bulletIndent)\n .attr('y', textY)\n .attr('fill', palette.text)\n .attr('font-size', NOTE_FONT_SIZE)\n .attr('class', 'note-text');\n\n if (isBullet) {\n noteG\n .append('text')\n .attr('x', noteX + NOTE_PAD_H)\n .attr('y', textY)\n .attr('fill', palette.text)\n .attr('font-size', NOTE_FONT_SIZE)\n .text('\\u2022');\n }\n\n renderInlineText(textEl, displayLine, palette, NOTE_FONT_SIZE);\n });\n } else {\n // --- Collapsed note: compact indicator ---\n const cFold = 6;\n const noteX = isRight\n ? px + ACTIVATION_WIDTH + NOTE_GAP\n : px - ACTIVATION_WIDTH - NOTE_GAP - COLLAPSED_NOTE_W;\n\n const noteG = svg\n .append('g')\n .attr('class', 'note note-collapsed')\n .attr('data-note-toggle', '')\n .attr('data-line-number', String(el.lineNumber))\n .attr('data-line-end', String(el.endLineNumber))\n .style('cursor', 'pointer');\n\n // Small folded-corner rectangle\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX} ${noteTopY}`,\n `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,\n `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`,\n `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + COLLAPSED_NOTE_H}`,\n `L ${noteX} ${noteTopY + COLLAPSED_NOTE_H}`,\n 'Z',\n ].join(' ')\n )\n .attr('fill', collapsedNoteFill)\n .attr('stroke', palette.border)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-box');\n\n // Fold triangle\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,\n `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY + cFold}`,\n `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`,\n ].join(' ')\n )\n .attr('fill', 'none')\n .attr('stroke', palette.border)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-fold');\n\n // \"...\" text\n noteG\n .append('text')\n .attr('x', noteX + COLLAPSED_NOTE_W / 2)\n .attr('y', noteTopY + COLLAPSED_NOTE_H / 2 + 3)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.textMuted)\n .attr('font-size', 9)\n .attr('class', 'note-text')\n .text('\\u2026');\n }\n } else if (isSequenceBlock(el)) {\n renderNoteElements(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n renderNoteElements(branch.children);\n }\n }\n renderNoteElements(el.elseChildren);\n }\n }\n };\n\n if (elements && elements.length > 0) {\n renderNoteElements(elements);\n }\n}\n\n/**\n * Build a mapping from each note's lineNumber to the lineNumber of its\n * associated message (the last message before the note in document order).\n * Used by the app to expand notes when cursor is on the associated message.\n */\nexport function buildNoteMessageMap(elements: SequenceElement[]): Map<number, number> {\n const map = new Map<number, number>();\n let lastMessageLine = -1;\n\n const walk = (els: SequenceElement[]): void => {\n for (const el of els) {\n if (isSequenceNote(el)) {\n if (lastMessageLine >= 0) {\n map.set(el.lineNumber, lastMessageLine);\n }\n } else if (isSequenceBlock(el)) {\n walk(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n walk(branch.children);\n }\n }\n walk(el.elseChildren);\n } else if (!isSequenceSection(el)) {\n // It's a message\n const msg = el as SequenceMessage;\n lastMessageLine = msg.lineNumber;\n }\n }\n };\n walk(elements);\n return map;\n}\n\nfunction renderParticipant(\n svg: d3Selection.Selection<SVGSVGElement, unknown, null, undefined>,\n participant: SequenceParticipant,\n cx: number,\n cy: number,\n palette: PaletteColors,\n isDark: boolean\n): void {\n const g = svg\n .append('g')\n .attr('transform', `translate(${cx}, ${cy})`)\n .attr('class', 'participant')\n .attr('data-participant-id', participant.id);\n\n // Render shape based on type\n switch (participant.type) {\n case 'actor':\n renderActorParticipant(g, palette);\n break;\n case 'database':\n renderDatabaseParticipant(g, palette, isDark);\n break;\n case 'service':\n renderServiceParticipant(g, palette, isDark);\n break;\n case 'queue':\n renderQueueParticipant(g, palette, isDark);\n break;\n case 'cache':\n renderCacheParticipant(g, palette, isDark);\n break;\n case 'networking':\n renderNetworkingParticipant(g, palette, isDark);\n break;\n case 'frontend':\n renderFrontendParticipant(g, palette, isDark);\n break;\n case 'external':\n renderExternalParticipant(g, palette, isDark);\n break;\n case 'gateway':\n renderGatewayParticipant(g, palette, isDark);\n break;\n default:\n renderRectParticipant(g, palette, isDark);\n break;\n }\n\n // Render label — below the shape for actors, centered inside for others\n const isActor = participant.type === 'actor';\n g.append('text')\n .attr('x', 0)\n .attr(\n 'y',\n isActor ? PARTICIPANT_BOX_HEIGHT + 14 : PARTICIPANT_BOX_HEIGHT / 2 + 5\n )\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', 13)\n .attr('font-weight', 500)\n .text(participant.label);\n}\n","// ============================================================\n// Unified API\n// ============================================================\n\nexport { render } from './render';\n\n// ============================================================\n// Router\n// ============================================================\n\nexport {\n parseDgmoChartType,\n getDgmoFramework,\n DGMO_CHART_TYPE_MAP,\n} from './dgmo-router';\nexport type { DgmoFramework } from './dgmo-router';\n\n// ============================================================\n// Parsers\n// ============================================================\n\nexport { parseChart } from './chart';\nexport type {\n ParsedChart,\n ChartType,\n ChartDataPoint,\n} from './chart';\n\nexport { parseEChart } from './echarts';\nexport type { ParsedEChart, EChartsChartType } from './echarts';\n\nexport {\n parseD3,\n orderArcNodes,\n parseTimelineDate,\n addDurationToDate,\n computeTimeTicks,\n formatDateLabel,\n} from './d3';\nexport type { ParsedD3, D3ChartType, D3ExportDimensions, ArcLink, ArcNodeGroup } from './d3';\n\nexport {\n parseSequenceDgmo,\n looksLikeSequence,\n isSequenceBlock,\n isSequenceNote,\n} from './sequence/parser';\nexport type {\n ParsedSequenceDgmo,\n SequenceParticipant,\n SequenceMessage,\n SequenceBlock,\n ElseIfBranch,\n SequenceSection,\n SequenceNote,\n SequenceElement,\n SequenceGroup,\n ParticipantType,\n} from './sequence/parser';\n\nexport {\n inferParticipantType,\n RULE_COUNT,\n} from './sequence/participant-inference';\n\nexport { parseQuadrant } from './dgmo-mermaid';\nexport type { ParsedQuadrant } from './dgmo-mermaid';\n\nexport { parseFlowchart, looksLikeFlowchart } from './graph/flowchart-parser';\n\nexport { parseClassDiagram, looksLikeClassDiagram } from './class/parser';\n\nexport type {\n ParsedClassDiagram,\n ClassNode,\n ClassMember,\n ClassRelationship,\n ClassModifier,\n MemberVisibility,\n RelationshipType,\n} from './class/types';\n\nexport { layoutClassDiagram } from './class/layout';\nexport type {\n ClassLayoutResult,\n ClassLayoutNode,\n ClassLayoutEdge,\n} from './class/layout';\n\nexport { renderClassDiagram, renderClassDiagramForExport } from './class/renderer';\n\nexport { parseERDiagram, looksLikeERDiagram } from './er/parser';\n\nexport type {\n ParsedERDiagram,\n ERTable,\n ERColumn,\n ERRelationship,\n ERConstraint,\n ERCardinality,\n} from './er/types';\n\nexport { layoutERDiagram } from './er/layout';\nexport type {\n ERLayoutResult,\n ERLayoutNode,\n ERLayoutEdge,\n} from './er/layout';\n\nexport { renderERDiagram, renderERDiagramForExport } from './er/renderer';\n\nexport type {\n ParsedGraph,\n GraphNode,\n GraphEdge,\n GraphGroup,\n GraphShape,\n GraphDirection,\n} from './graph/types';\n\nexport { parseOrg } from './org/parser';\nexport type {\n ParsedOrg,\n OrgNode,\n OrgTagGroup,\n OrgTagEntry,\n} from './org/parser';\n\nexport { layoutOrg } from './org/layout';\nexport type {\n OrgLayoutResult,\n OrgLayoutNode,\n OrgLayoutEdge,\n OrgContainerBounds,\n} from './org/layout';\n\nexport { renderOrg, renderOrgForExport } from './org/renderer';\n\nexport { collapseOrgTree } from './org/collapse';\nexport type { CollapsedOrgResult } from './org/collapse';\n\nexport { layoutGraph } from './graph/layout';\nexport type {\n LayoutResult,\n LayoutNode,\n LayoutEdge,\n LayoutGroup,\n} from './graph/layout';\n\nexport { renderFlowchart, renderFlowchartForExport } from './graph/flowchart-renderer';\n\n// ============================================================\n// Config Builders (produce framework-specific config objects)\n// ============================================================\n\nexport { buildEChartsOption, buildEChartsOptionFromChart, renderEChartsForExport } from './echarts';\nexport { buildMermaidQuadrant } from './dgmo-mermaid';\n\n// ============================================================\n// Renderers (produce SVG output)\n// ============================================================\n\nexport {\n renderSlopeChart,\n renderArcDiagram,\n renderTimeline,\n renderWordCloud,\n renderVenn,\n renderQuadrant,\n renderD3ForExport,\n} from './d3';\n\nexport {\n renderSequenceDiagram,\n buildRenderSequence,\n computeActivations,\n applyPositionOverrides,\n applyGroupOrdering,\n groupMessagesBySection,\n buildNoteMessageMap,\n} from './sequence/renderer';\nexport type {\n RenderStep,\n Activation,\n SectionMessageGroup,\n SequenceRenderOptions,\n} from './sequence/renderer';\n\n// ============================================================\n// Colors & Palettes\n// ============================================================\n\nexport { resolveColor, colorNames, nord, seriesColors } from './colors';\n\nexport {\n // Registry\n getPalette,\n getAvailablePalettes,\n registerPalette,\n isValidHex,\n // Utilities\n hexToHSL,\n hslToHex,\n hexToHSLString,\n mute,\n tint,\n shade,\n getSeriesColors,\n contrastText,\n // Palette definitions\n nordPalette,\n solarizedPalette,\n catppuccinPalette,\n rosePinePalette,\n gruvboxPalette,\n tokyoNightPalette,\n oneDarkPalette,\n boldPalette,\n // Mermaid bridge\n buildMermaidThemeVars,\n buildThemeCSS,\n} from './palettes';\n\nexport type { PaletteConfig, PaletteColors } from './palettes';\n\n// ============================================================\n// Sharing (URL encoding/decoding)\n// ============================================================\n\nexport { encodeDiagramUrl, decodeDiagramUrl } from './sharing';\nexport type {\n EncodeDiagramUrlOptions,\n EncodeDiagramUrlResult,\n DiagramViewState,\n DecodedDiagramUrl,\n} from './sharing';\n\n// ============================================================\n// Branding\n// ============================================================\n\nexport { injectBranding } from './branding';\n","import * as d3Scale from 'd3-scale';\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport * as d3Array from 'd3-array';\nimport cloud from 'd3-cloud';\nimport { FONT_FAMILY } from './fonts';\nimport { injectBranding } from './branding';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport type D3ChartType =\n | 'slope'\n | 'wordcloud'\n | 'arc'\n | 'timeline'\n | 'venn'\n | 'quadrant'\n | 'sequence';\n\nexport interface D3DataItem {\n label: string;\n values: number[];\n color: string | null;\n lineNumber: number;\n}\n\nexport interface WordCloudWord {\n text: string;\n weight: number;\n lineNumber: number;\n}\n\nexport type WordCloudRotate = 'none' | 'mixed' | 'angled';\n\nexport interface WordCloudOptions {\n rotate: WordCloudRotate;\n max: number;\n minSize: number;\n maxSize: number;\n}\n\nconst DEFAULT_CLOUD_OPTIONS: WordCloudOptions = {\n rotate: 'none',\n max: 0,\n minSize: 14,\n maxSize: 80,\n};\n\nexport interface ArcLink {\n source: string;\n target: string;\n value: number;\n color: string | null;\n lineNumber: number;\n}\n\nexport type ArcOrder = 'appearance' | 'name' | 'group' | 'degree';\n\nexport interface ArcNodeGroup {\n name: string;\n nodes: string[];\n color: string | null;\n lineNumber: number;\n}\n\nexport type TimelineSort = 'time' | 'group';\n\nexport interface TimelineEvent {\n date: string;\n endDate: string | null;\n label: string;\n group: string | null;\n lineNumber: number;\n uncertain?: boolean;\n}\n\nexport interface TimelineGroup {\n name: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface TimelineEra {\n startDate: string;\n endDate: string;\n label: string;\n color: string | null;\n}\n\nexport interface TimelineMarker {\n date: string;\n label: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface VennSet {\n name: string;\n size: number;\n color: string | null;\n label: string | null;\n lineNumber: number;\n}\n\nexport interface VennOverlap {\n sets: string[];\n size: number;\n label: string | null;\n lineNumber: number;\n}\n\nexport interface QuadrantLabel {\n text: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface QuadrantPoint {\n label: string;\n x: number;\n y: number;\n lineNumber: number;\n}\n\nexport interface QuadrantLabels {\n topRight: QuadrantLabel | null;\n topLeft: QuadrantLabel | null;\n bottomLeft: QuadrantLabel | null;\n bottomRight: QuadrantLabel | null;\n}\n\n/** Optional explicit dimensions for CLI/export rendering (bypasses DOM layout). */\nexport interface D3ExportDimensions {\n width?: number;\n height?: number;\n}\n\nexport interface ParsedD3 {\n type: D3ChartType | null;\n title: string | null;\n titleLineNumber: number | null;\n orientation: 'horizontal' | 'vertical';\n periods: string[];\n data: D3DataItem[];\n words: WordCloudWord[];\n cloudOptions: WordCloudOptions;\n links: ArcLink[];\n arcOrder: ArcOrder;\n arcNodeGroups: ArcNodeGroup[];\n timelineEvents: TimelineEvent[];\n timelineGroups: TimelineGroup[];\n timelineEras: TimelineEra[];\n timelineMarkers: TimelineMarker[];\n timelineSort: TimelineSort;\n timelineScale: boolean;\n timelineSwimlanes: boolean;\n vennSets: VennSet[];\n vennOverlaps: VennOverlap[];\n vennShowValues: boolean;\n // Quadrant chart fields\n quadrantLabels: QuadrantLabels;\n quadrantPoints: QuadrantPoint[];\n quadrantXAxis: [string, string] | null;\n quadrantXAxisLineNumber: number | null;\n quadrantYAxis: [string, string] | null;\n quadrantYAxisLineNumber: number | null;\n quadrantTitleLineNumber: number | null;\n error: string | null;\n}\n\n// ============================================================\n// Color Imports\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { PaletteColors } from './palettes';\nimport { getSeriesColors } from './palettes';\n\n// ============================================================\n// Timeline Date Helper\n// ============================================================\n\n/**\n * Converts a date string (YYYY, YYYY-MM, YYYY-MM-DD) to a fractional year number.\n */\nexport function parseTimelineDate(s: string): number {\n const parts = s.split('-').map((p) => parseInt(p, 10));\n const year = parts[0];\n const month = parts.length >= 2 ? parts[1] : 1;\n const day = parts.length >= 3 ? parts[2] : 1;\n return year + (month - 1) / 12 + (day - 1) / 365;\n}\n\n/**\n * Adds a duration to a date string and returns the resulting date string.\n * Supports: d (days), w (weeks), m (months), y (years)\n * Supports decimals up to 2 places (e.g., 1.25y = 1 year 3 months)\n * Preserves the precision of the input date (YYYY, YYYY-MM, or YYYY-MM-DD).\n */\nexport function addDurationToDate(\n startDate: string,\n amount: number,\n unit: 'd' | 'w' | 'm' | 'y'\n): string {\n const parts = startDate.split('-').map((p) => parseInt(p, 10));\n const year = parts[0];\n const month = parts.length >= 2 ? parts[1] : 1;\n const day = parts.length >= 3 ? parts[2] : 1;\n\n const date = new Date(year, month - 1, day);\n\n switch (unit) {\n case 'd':\n // Round days to nearest integer\n date.setDate(date.getDate() + Math.round(amount));\n break;\n case 'w':\n // Convert weeks to days, round to nearest integer\n date.setDate(date.getDate() + Math.round(amount * 7));\n break;\n case 'm': {\n // Add whole months, then remaining days\n const wholeMonths = Math.floor(amount);\n const fractionalDays = Math.round((amount - wholeMonths) * 30);\n date.setMonth(date.getMonth() + wholeMonths);\n if (fractionalDays > 0) {\n date.setDate(date.getDate() + fractionalDays);\n }\n break;\n }\n case 'y': {\n // Add whole years, then remaining months\n const wholeYears = Math.floor(amount);\n const fractionalMonths = Math.round((amount - wholeYears) * 12);\n date.setFullYear(date.getFullYear() + wholeYears);\n if (fractionalMonths > 0) {\n date.setMonth(date.getMonth() + fractionalMonths);\n }\n break;\n }\n }\n\n // Preserve original precision\n const endYear = date.getFullYear();\n const endMonth = String(date.getMonth() + 1).padStart(2, '0');\n const endDay = String(date.getDate()).padStart(2, '0');\n\n if (parts.length === 1) {\n return String(endYear);\n } else if (parts.length === 2) {\n return `${endYear}-${endMonth}`;\n } else {\n return `${endYear}-${endMonth}-${endDay}`;\n }\n}\n\n// ============================================================\n// Parser\n// ============================================================\n\n/**\n * Parses D3 chart text format into structured data.\n */\nexport function parseD3(content: string, palette?: PaletteColors): ParsedD3 {\n const result: ParsedD3 = {\n type: null,\n title: null,\n titleLineNumber: null,\n orientation: 'horizontal',\n periods: [],\n data: [],\n words: [],\n cloudOptions: { ...DEFAULT_CLOUD_OPTIONS },\n links: [],\n arcOrder: 'appearance',\n arcNodeGroups: [],\n timelineEvents: [],\n timelineGroups: [],\n timelineEras: [],\n timelineMarkers: [],\n timelineSort: 'time',\n timelineScale: true,\n timelineSwimlanes: false,\n vennSets: [],\n vennOverlaps: [],\n vennShowValues: false,\n quadrantLabels: {\n topRight: null,\n topLeft: null,\n bottomLeft: null,\n bottomRight: null,\n },\n quadrantPoints: [],\n quadrantXAxis: null,\n quadrantXAxisLineNumber: null,\n quadrantYAxis: null,\n quadrantYAxisLineNumber: null,\n quadrantTitleLineNumber: null,\n error: null,\n };\n\n if (!content || !content.trim()) {\n result.error = 'Empty content';\n return result;\n }\n\n const lines = content.split('\\n');\n const freeformLines: string[] = [];\n let currentArcGroup: string | null = null;\n let currentTimelineGroup: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!line) continue;\n\n // ## Section headers for arc diagram node grouping (before # comment check)\n const sectionMatch = line.match(/^#{2,}\\s+(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/);\n if (sectionMatch) {\n if (result.type === 'arc') {\n const name = sectionMatch[1].trim();\n const color = sectionMatch[2]\n ? resolveColor(sectionMatch[2].trim(), palette)\n : null;\n result.arcNodeGroups.push({ name, nodes: [], color, lineNumber });\n currentArcGroup = name;\n } else if (result.type === 'timeline') {\n const name = sectionMatch[1].trim();\n const color = sectionMatch[2]\n ? resolveColor(sectionMatch[2].trim(), palette)\n : null;\n result.timelineGroups.push({ name, color, lineNumber });\n currentTimelineGroup = name;\n }\n continue;\n }\n\n // Skip comments\n if (line.startsWith('#') || line.startsWith('//')) {\n continue;\n }\n\n // Arc link line: source -> target(color): weight\n if (result.type === 'arc') {\n const linkMatch = line.match(\n /^(.+?)\\s*->\\s*(.+?)(?:\\(([^)]+)\\))?\\s*(?::\\s*(\\d+(?:\\.\\d+)?))?$/\n );\n if (linkMatch) {\n const source = linkMatch[1].trim();\n const target = linkMatch[2].trim();\n const linkColor = linkMatch[3]\n ? resolveColor(linkMatch[3].trim(), palette)\n : null;\n result.links.push({\n source,\n target,\n value: linkMatch[4] ? parseFloat(linkMatch[4]) : 1,\n color: linkColor,\n lineNumber,\n });\n // Assign nodes to current group (first-appearance wins)\n if (currentArcGroup !== null) {\n const group = result.arcNodeGroups.find(\n (g) => g.name === currentArcGroup\n );\n if (group) {\n const allGrouped = new Set(\n result.arcNodeGroups.flatMap((g) => g.nodes)\n );\n if (!allGrouped.has(source)) group.nodes.push(source);\n if (!allGrouped.has(target)) group.nodes.push(target);\n }\n }\n continue;\n }\n }\n\n // Timeline era lines: era YYYY->YYYY: Label (color)\n if (result.type === 'timeline') {\n const eraMatch = line.match(\n /^era\\s+(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*->\\s*(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/\n );\n if (eraMatch) {\n const colorAnnotation = eraMatch[4]?.trim() || null;\n result.timelineEras.push({\n startDate: eraMatch[1],\n endDate: eraMatch[2],\n label: eraMatch[3].trim(),\n color: colorAnnotation\n ? resolveColor(colorAnnotation, palette)\n : null,\n });\n continue;\n }\n\n // Timeline marker lines: marker YYYY: Label (color)\n const markerMatch = line.match(\n /^marker\\s+(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/\n );\n if (markerMatch) {\n const colorAnnotation = markerMatch[3]?.trim() || null;\n result.timelineMarkers.push({\n date: markerMatch[1],\n label: markerMatch[2].trim(),\n color: colorAnnotation\n ? resolveColor(colorAnnotation, palette)\n : null,\n lineNumber,\n });\n continue;\n }\n }\n\n // Timeline event lines: duration, range, or point\n if (result.type === 'timeline') {\n // Duration event: 2026-07-15->30d: description (d=days, w=weeks, m=months, y=years)\n // Supports decimals up to 2 places (e.g., 1.25y = 1 year 3 months)\n // Supports uncertain end with ? prefix (e.g., ->?3m fades out the last 20%)\n const durationMatch = line.match(\n /^(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*->\\s*(\\?)?(\\d+(?:\\.\\d{1,2})?)([dwmy])\\s*:\\s*(.+)$/\n );\n if (durationMatch) {\n const startDate = durationMatch[1];\n const uncertain = durationMatch[2] === '?';\n const amount = parseFloat(durationMatch[3]);\n const unit = durationMatch[4] as 'd' | 'w' | 'm' | 'y';\n const endDate = addDurationToDate(startDate, amount, unit);\n result.timelineEvents.push({\n date: startDate,\n endDate,\n label: durationMatch[5].trim(),\n group: currentTimelineGroup,\n lineNumber,\n uncertain,\n });\n continue;\n }\n\n // Range event: 1655->1667: description (supports uncertain end: 1655->?1667)\n const rangeMatch = line.match(\n /^(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*->\\s*(\\?)?(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+)$/\n );\n if (rangeMatch) {\n result.timelineEvents.push({\n date: rangeMatch[1],\n endDate: rangeMatch[3],\n label: rangeMatch[4].trim(),\n group: currentTimelineGroup,\n lineNumber,\n uncertain: rangeMatch[2] === '?',\n });\n continue;\n }\n\n // Point event: 1718: description\n const pointMatch = line.match(\n /^(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+)$/\n );\n if (pointMatch) {\n result.timelineEvents.push({\n date: pointMatch[1],\n endDate: null,\n label: pointMatch[2].trim(),\n group: currentTimelineGroup,\n lineNumber,\n });\n continue;\n }\n }\n\n // Venn overlap line: \"A & B: size\" or \"A & B & C: size \\\"label\\\"\"\n if (result.type === 'venn') {\n const overlapMatch = line.match(\n /^(.+?&.+?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*(?:\"([^\"]*)\")?\\s*$/\n );\n if (overlapMatch) {\n const sets = overlapMatch[1]\n .split('&')\n .map((s) => s.trim())\n .filter(Boolean)\n .sort();\n const size = parseFloat(overlapMatch[2]);\n const label = overlapMatch[3] ?? null;\n result.vennOverlaps.push({ sets, size, label, lineNumber });\n continue;\n }\n\n // Venn set line: \"Name: size\" or \"Name(color): size \\\"label\\\"\"\n const setMatch = line.match(\n /^(.+?)(?:\\(([^)]+)\\))?\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*(?:\"([^\"]*)\")?\\s*$/\n );\n if (setMatch) {\n const name = setMatch[1].trim();\n const color = setMatch[2]\n ? resolveColor(setMatch[2].trim(), palette)\n : null;\n const size = parseFloat(setMatch[3]);\n const label = setMatch[4] ?? null;\n result.vennSets.push({ name, size, color, label, lineNumber });\n continue;\n }\n }\n\n // Quadrant-specific parsing\n if (result.type === 'quadrant') {\n // x-axis: Low, High\n const xAxisMatch = line.match(/^x-axis\\s*:\\s*(.+)/i);\n if (xAxisMatch) {\n const parts = xAxisMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.quadrantXAxis = [parts[0], parts[1]];\n result.quadrantXAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // y-axis: Low, High\n const yAxisMatch = line.match(/^y-axis\\s*:\\s*(.+)/i);\n if (yAxisMatch) {\n const parts = yAxisMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.quadrantYAxis = [parts[0], parts[1]];\n result.quadrantYAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // Quadrant position labels: top-right: Label (color)\n const quadrantLabelRe =\n /^(top-right|top-left|bottom-left|bottom-right)\\s*:\\s*(.+)/i;\n const quadrantMatch = line.match(quadrantLabelRe);\n if (quadrantMatch) {\n const position = quadrantMatch[1].toLowerCase();\n const labelPart = quadrantMatch[2].trim();\n // Check for color annotation: \"Label (color)\" or \"Label(color)\"\n const labelColorMatch = labelPart.match(/^(.+?)\\s*\\(([^)]+)\\)\\s*$/);\n const text = labelColorMatch ? labelColorMatch[1].trim() : labelPart;\n const color = labelColorMatch\n ? resolveColor(labelColorMatch[2].trim(), palette)\n : null;\n const label: QuadrantLabel = { text, color, lineNumber };\n\n if (position === 'top-right') result.quadrantLabels.topRight = label;\n else if (position === 'top-left') result.quadrantLabels.topLeft = label;\n else if (position === 'bottom-left')\n result.quadrantLabels.bottomLeft = label;\n else if (position === 'bottom-right')\n result.quadrantLabels.bottomRight = label;\n continue;\n }\n\n // Data points: Label: x, y\n const pointMatch = line.match(\n /^(.+?):\\s*([0-9]*\\.?[0-9]+)\\s*,\\s*([0-9]*\\.?[0-9]+)\\s*$/\n );\n if (pointMatch) {\n const label = pointMatch[1].trim();\n // Skip if it looks like a quadrant position keyword\n const lowerLabel = label.toLowerCase();\n if (\n lowerLabel !== 'top-right' &&\n lowerLabel !== 'top-left' &&\n lowerLabel !== 'bottom-left' &&\n lowerLabel !== 'bottom-right'\n ) {\n result.quadrantPoints.push({\n label,\n x: parseFloat(pointMatch[2]),\n y: parseFloat(pointMatch[3]),\n lineNumber,\n });\n }\n continue;\n }\n }\n\n // Check for metadata lines\n const colonIndex = line.indexOf(':');\n\n if (colonIndex !== -1) {\n const rawKey = line.substring(0, colonIndex).trim();\n const key = rawKey.toLowerCase();\n\n // Check for color annotation in raw key: \"Label(color)\"\n const colorMatch = rawKey.match(/^(.+?)\\(([^)]+)\\)\\s*$/);\n\n if (key === 'chart') {\n const value = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (\n value === 'slope' ||\n value === 'wordcloud' ||\n value === 'arc' ||\n value === 'timeline' ||\n value === 'venn' ||\n value === 'quadrant' ||\n value === 'sequence'\n ) {\n result.type = value;\n } else {\n result.error = `Unsupported chart type: ${value}. Supported types: slope, wordcloud, arc, timeline, venn, quadrant, sequence`;\n return result;\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = line.substring(colonIndex + 1).trim();\n result.titleLineNumber = lineNumber;\n if (result.type === 'quadrant') {\n result.quadrantTitleLineNumber = lineNumber;\n }\n continue;\n }\n\n if (key === 'orientation') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'horizontal' || v === 'vertical') {\n result.orientation = v;\n }\n continue;\n }\n\n if (key === 'order') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'name' || v === 'group' || v === 'degree') {\n result.arcOrder = v;\n }\n continue;\n }\n\n if (key === 'sort') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'time' || v === 'group') {\n result.timelineSort = v;\n }\n continue;\n }\n\n if (key === 'swimlanes') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'on') {\n result.timelineSwimlanes = true;\n } else if (v === 'off') {\n result.timelineSwimlanes = false;\n }\n continue;\n }\n\n if (key === 'values') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'off') {\n result.vennShowValues = false;\n } else if (v === 'on') {\n result.vennShowValues = true;\n }\n continue;\n }\n\n if (key === 'rotate') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'none' || v === 'mixed' || v === 'angled') {\n result.cloudOptions.rotate = v;\n }\n continue;\n }\n\n if (key === 'max') {\n const v = parseInt(line.substring(colonIndex + 1).trim(), 10);\n if (!isNaN(v) && v > 0) {\n result.cloudOptions.max = v;\n }\n continue;\n }\n\n if (key === 'size') {\n const v = line.substring(colonIndex + 1).trim();\n const parts = v.split(',').map((s) => parseInt(s.trim(), 10));\n if (\n parts.length === 2 &&\n parts.every((n) => !isNaN(n) && n > 0) &&\n parts[0] < parts[1]\n ) {\n result.cloudOptions.minSize = parts[0];\n result.cloudOptions.maxSize = parts[1];\n }\n continue;\n }\n\n // Data line: \"Label: value1, value2\" or \"Label(color): value1, value2\"\n const labelPart = colorMatch ? colorMatch[1].trim() : rawKey;\n const colorPart = colorMatch\n ? resolveColor(colorMatch[2].trim(), palette)\n : null;\n const valuePart = line.substring(colonIndex + 1).trim();\n const values = valuePart.split(',').map((v) => v.trim());\n\n // Check if this looks like a data line (values should be numeric)\n const numericValues: number[] = [];\n let allNumeric = true;\n for (const v of values) {\n const num = parseFloat(v);\n if (isNaN(num)) {\n allNumeric = false;\n break;\n }\n numericValues.push(num);\n }\n\n if (allNumeric && numericValues.length > 0) {\n // For wordcloud, single numeric value = word weight\n if (result.type === 'wordcloud' && numericValues.length === 1) {\n result.words.push({\n text: labelPart,\n weight: numericValues[0],\n lineNumber,\n });\n } else {\n result.data.push({\n label: labelPart,\n values: numericValues,\n color: colorPart,\n lineNumber,\n });\n }\n continue;\n }\n }\n\n // For wordcloud: collect non-metadata lines for freeform fallback\n if (result.type === 'wordcloud') {\n if (colonIndex === -1 && !line.includes(' ')) {\n // Single bare word — structured mode\n result.words.push({ text: line, weight: 10, lineNumber });\n } else {\n // Multi-word line or non-numeric colon line — freeform text\n freeformLines.push(line);\n }\n continue;\n }\n\n // Period line: comma-separated labels with no colon before first comma\n // e.g., \"2020, 2024\" or \"Q1 2023, Q2 2023, Q3 2023\"\n if (\n result.periods.length === 0 &&\n line.includes(',') &&\n !line.includes(':')\n ) {\n const periods = line\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n if (periods.length >= 2) {\n result.periods = periods;\n continue;\n }\n }\n }\n\n // Validation\n if (!result.type) {\n result.error = 'Missing required \"chart:\" line (e.g., \"chart: slope\")';\n return result;\n }\n\n // Sequence diagrams are parsed by their own dedicated parser\n if (result.type === 'sequence') {\n return result;\n }\n\n if (result.type === 'wordcloud') {\n // If no structured words were found, parse freeform text as word frequencies\n if (result.words.length === 0 && freeformLines.length > 0) {\n result.words = tokenizeFreeformText(freeformLines.join(' '));\n }\n if (result.words.length === 0) {\n result.error =\n 'No words found. Add words as \"word: weight\", one per line, or paste freeform text';\n return result;\n }\n // Apply max word limit (words are already sorted by weight desc for freeform)\n if (\n result.cloudOptions.max > 0 &&\n result.words.length > result.cloudOptions.max\n ) {\n result.words = result.words\n .slice()\n .sort((a, b) => b.weight - a.weight)\n .slice(0, result.cloudOptions.max);\n }\n return result;\n }\n\n if (result.type === 'arc') {\n if (result.links.length === 0) {\n result.error =\n 'No links found. Add links as \"Source -> Target: weight\" (e.g., \"Alice -> Bob: 5\")';\n return result;\n }\n // Validate arc ordering vs groups\n if (result.arcNodeGroups.length > 0) {\n if (result.arcOrder === 'name' || result.arcOrder === 'degree') {\n result.error = `Cannot use \"order: ${result.arcOrder}\" with ## section headers. Use \"order: group\" or remove section headers.`;\n return result;\n }\n if (result.arcOrder === 'appearance') {\n result.arcOrder = 'group';\n }\n }\n return result;\n }\n\n if (result.type === 'timeline') {\n if (result.timelineEvents.length === 0) {\n result.error =\n 'No events found. Add events as \"YYYY: description\" or \"YYYY->YYYY: description\"';\n return result;\n }\n return result;\n }\n\n if (result.type === 'venn') {\n if (result.vennSets.length < 2) {\n result.error =\n 'At least 2 sets are required. Add sets as \"Name: size\" (e.g., \"Math: 100\")';\n return result;\n }\n if (result.vennSets.length > 3) {\n result.error = 'At most 3 sets are supported. Remove extra sets.';\n return result;\n }\n // Validate overlap references and sizes\n const setMap = new Map(result.vennSets.map((s) => [s.name, s.size]));\n for (const ov of result.vennOverlaps) {\n for (const setName of ov.sets) {\n if (!setMap.has(setName)) {\n result.error = `Overlap references unknown set \"${setName}\". Define it first as \"${setName}: <size>\"`;\n return result;\n }\n }\n const minSetSize = Math.min(...ov.sets.map((s) => setMap.get(s)!));\n if (ov.size > minSetSize) {\n result.error = `Overlap size ${ov.size} exceeds smallest constituent set size ${minSetSize}`;\n return result;\n }\n }\n return result;\n }\n\n if (result.type === 'quadrant') {\n if (result.quadrantPoints.length === 0) {\n result.error =\n 'No data points found. Add points as \"Label: x, y\" (e.g., \"Item A: 0.5, 0.7\")';\n return result;\n }\n return result;\n }\n\n // Slope chart validation\n if (result.periods.length < 2) {\n result.error =\n 'Missing or invalid periods line. Provide at least 2 comma-separated period labels (e.g., \"2020, 2024\")';\n return result;\n }\n\n if (result.data.length === 0) {\n result.error =\n 'No data lines found. Add data as \"Label: value1, value2\" (e.g., \"Apple: 25, 35\")';\n return result;\n }\n\n // Validate value counts match period count\n for (const item of result.data) {\n if (item.values.length !== result.periods.length) {\n result.error = `Data item \"${item.label}\" has ${item.values.length} value(s) but ${result.periods.length} period(s) are defined`;\n return result;\n }\n }\n\n return result;\n}\n\n// ============================================================\n// Freeform Text Tokenizer (for word cloud)\n// ============================================================\n\nconst STOP_WORDS = new Set([\n 'a',\n 'an',\n 'the',\n 'and',\n 'or',\n 'but',\n 'in',\n 'on',\n 'at',\n 'to',\n 'for',\n 'of',\n 'with',\n 'by',\n 'is',\n 'am',\n 'are',\n 'was',\n 'were',\n 'be',\n 'been',\n 'being',\n 'have',\n 'has',\n 'had',\n 'do',\n 'does',\n 'did',\n 'will',\n 'would',\n 'could',\n 'should',\n 'may',\n 'might',\n 'shall',\n 'can',\n 'it',\n 'its',\n 'this',\n 'that',\n 'these',\n 'those',\n 'i',\n 'me',\n 'my',\n 'we',\n 'us',\n 'our',\n 'you',\n 'your',\n 'he',\n 'him',\n 'his',\n 'she',\n 'her',\n 'they',\n 'them',\n 'their',\n 'what',\n 'which',\n 'who',\n 'whom',\n 'how',\n 'when',\n 'where',\n 'why',\n 'not',\n 'no',\n 'nor',\n 'so',\n 'if',\n 'then',\n 'than',\n 'too',\n 'very',\n 'just',\n 'about',\n 'up',\n 'out',\n 'from',\n 'into',\n 'over',\n 'after',\n 'before',\n 'between',\n 'under',\n 'again',\n 'there',\n 'here',\n 'all',\n 'each',\n 'every',\n 'both',\n 'few',\n 'more',\n 'most',\n 'other',\n 'some',\n 'such',\n 'only',\n 'own',\n 'same',\n 'also',\n 'as',\n 'because',\n 'until',\n 'while',\n 'during',\n 'through',\n]);\n\nfunction tokenizeFreeformText(text: string): WordCloudWord[] {\n const counts = new Map<string, number>();\n\n // Split on non-letter/non-apostrophe chars, lowercase everything\n const tokens = text\n .toLowerCase()\n .split(/[^a-zA-Z']+/)\n .filter(Boolean);\n\n for (const raw of tokens) {\n // Strip leading/trailing apostrophes\n const word = raw.replace(/^'+|'+$/g, '');\n if (word.length < 2 || STOP_WORDS.has(word)) continue;\n counts.set(word, (counts.get(word) ?? 0) + 1);\n }\n\n return Array.from(counts.entries())\n .map(([text, count]) => ({ text, weight: count, lineNumber: 0 }))\n .sort((a, b) => b.weight - a.weight);\n}\n\n// ============================================================\n// Slope Chart Renderer\n// ============================================================\n\nconst SLOPE_MARGIN = { top: 80, bottom: 40, left: 80 };\nconst SLOPE_LABEL_FONT_SIZE = 14;\nconst SLOPE_CHAR_WIDTH = 8; // approximate px per character at 14px\n\n/**\n * Renders a slope chart into the given container using D3.\n */\nexport function renderSlopeChart(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n // Clear existing content\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { periods, data, title } = parsed;\n if (data.length === 0 || periods.length < 2) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n // Compute right margin from the longest end-of-line label\n const maxLabelText = data.reduce((longest, item) => {\n const text = `${item.values[item.values.length - 1]} — ${item.label}`;\n return text.length > longest.length ? text : longest;\n }, '');\n const estimatedLabelWidth = maxLabelText.length * SLOPE_CHAR_WIDTH;\n const maxRightMargin = Math.floor(width * 0.35);\n const rightMargin = Math.min(\n Math.max(estimatedLabelWidth + 30, 120),\n maxRightMargin\n );\n\n const innerWidth = width - SLOPE_MARGIN.left - rightMargin;\n const innerHeight = height - SLOPE_MARGIN.top - SLOPE_MARGIN.bottom;\n\n // Theme colors\n const textColor = palette.text;\n const mutedColor = palette.border;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n // Scales\n const allValues = data.flatMap((d) => d.values);\n const [minVal, maxVal] = d3Array.extent(allValues) as [number, number];\n const valuePadding = (maxVal - minVal) * 0.1 || 1;\n\n const yScale = d3Scale\n .scaleLinear()\n .domain([minVal - valuePadding, maxVal + valuePadding])\n .range([innerHeight, 0]);\n\n const xScale = d3Scale\n .scalePoint<string>()\n .domain(periods)\n .range([0, innerWidth])\n .padding(0);\n\n // SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);\n\n // Tooltip\n const tooltip = createTooltip(container, palette, isDark);\n\n // Title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // Period column headers\n for (const period of periods) {\n const x = xScale(period)!;\n g.append('text')\n .attr('x', x)\n .attr('y', -15)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '600')\n .text(period);\n\n // Vertical guide line\n g.append('line')\n .attr('x1', x)\n .attr('y1', 0)\n .attr('x2', x)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n }\n\n // Line generator\n const lineGen = d3Shape\n .line<number>()\n .x((_d, i) => xScale(periods[i])!)\n .y((d) => yScale(d));\n\n // Render each data series\n data.forEach((item, idx) => {\n const color = item.color ?? colors[idx % colors.length];\n\n // Wrap each series in a group with data-line-number for sync adapter\n const seriesG = g\n .append('g')\n .attr('class', 'slope-series')\n .attr('data-line-number', String(item.lineNumber));\n\n // Tooltip content – overall change for this series\n const firstVal = item.values[0];\n const lastVal = item.values[item.values.length - 1];\n const absChange = lastVal - firstVal;\n const pctChange = firstVal !== 0 ? (absChange / firstVal) * 100 : null;\n const sign = absChange > 0 ? '+' : '';\n const pctPart =\n pctChange !== null ? ` (${sign}${pctChange.toFixed(1)}%)` : '';\n const tipLines = [`${sign}${absChange}`];\n if (pctChange !== null) tipLines.push(`${sign}${pctChange.toFixed(1)}%`);\n const tipHtml = tipLines.join('<br>');\n\n // Line\n seriesG.append('path')\n .datum(item.values)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', 2.5)\n .attr('d', lineGen);\n\n // Invisible wider path for easier hover targeting\n seriesG.append('path')\n .datum(item.values)\n .attr('fill', 'none')\n .attr('stroke', 'transparent')\n .attr('stroke-width', 14)\n .attr('d', lineGen)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mousemove', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mouseleave', () => hideTooltip(tooltip))\n .on('click', () => {\n if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);\n });\n\n // Points and value labels\n item.values.forEach((val, i) => {\n const x = xScale(periods[i])!;\n const y = yScale(val);\n\n // Point circle\n seriesG.append('circle')\n .attr('cx', x)\n .attr('cy', y)\n .attr('r', 4)\n .attr('fill', color)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mousemove', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mouseleave', () => hideTooltip(tooltip))\n .on('click', () => {\n if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);\n });\n\n // Value label — skip last point (shown in series label instead)\n const isFirst = i === 0;\n const isLast = i === periods.length - 1;\n if (!isLast) {\n seriesG.append('text')\n .attr('x', isFirst ? x - 10 : x)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', isFirst ? 'end' : 'middle')\n .attr('fill', textColor)\n .attr('font-size', '16px')\n .text(val.toString());\n }\n });\n\n // Series label with value at end of line — wraps if it exceeds available space\n const lastX = xScale(periods[periods.length - 1])!;\n const lastY = yScale(lastVal);\n const labelText = `${lastVal} — ${item.label}`;\n const availableWidth = rightMargin - 15;\n const maxChars = Math.floor(availableWidth / SLOPE_CHAR_WIDTH);\n\n const labelEl = seriesG\n .append('text')\n .attr('x', lastX + 10)\n .attr('y', lastY)\n .attr('text-anchor', 'start')\n .attr('fill', color)\n .attr('font-size', `${SLOPE_LABEL_FONT_SIZE}px`)\n .attr('font-weight', '500');\n\n if (labelText.length <= maxChars) {\n labelEl.attr('dy', '0.35em').text(labelText);\n } else {\n // Wrap into lines that fit the available width\n const words = labelText.split(/\\s+/);\n const lines: string[] = [];\n let current = '';\n for (const word of words) {\n const test = current ? `${current} ${word}` : word;\n if (test.length > maxChars && current) {\n lines.push(current);\n current = word;\n } else {\n current = test;\n }\n }\n if (current) lines.push(current);\n\n const lineHeight = SLOPE_LABEL_FONT_SIZE * 1.2;\n const totalHeight = (lines.length - 1) * lineHeight;\n const startDy = -totalHeight / 2;\n\n lines.forEach((line, li) => {\n labelEl\n .append('tspan')\n .attr('x', lastX + 10)\n .attr(\n 'dy',\n li === 0\n ? `${startDy + SLOPE_LABEL_FONT_SIZE * 0.35}px`\n : `${lineHeight}px`\n )\n .text(line);\n });\n }\n });\n}\n\n// ============================================================\n// Arc Node Ordering\n// ============================================================\n\n/**\n * Orders arc diagram nodes based on the selected ordering strategy.\n */\nexport function orderArcNodes(\n links: ArcLink[],\n order: ArcOrder,\n groups: ArcNodeGroup[]\n): string[] {\n // Collect all unique nodes in first-appearance order\n const nodeSet = new Set<string>();\n for (const link of links) {\n nodeSet.add(link.source);\n nodeSet.add(link.target);\n }\n const allNodes = Array.from(nodeSet);\n\n if (order === 'name') {\n return allNodes.slice().sort((a, b) => a.localeCompare(b));\n }\n\n if (order === 'degree') {\n const degree = new Map<string, number>();\n for (const node of allNodes) degree.set(node, 0);\n for (const link of links) {\n degree.set(link.source, degree.get(link.source)! + link.value);\n degree.set(link.target, degree.get(link.target)! + link.value);\n }\n return allNodes.slice().sort((a, b) => {\n const diff = degree.get(b)! - degree.get(a)!;\n return diff !== 0 ? diff : a.localeCompare(b);\n });\n }\n\n if (order === 'group') {\n if (groups.length > 0) {\n // Explicit groups: order by ## header order, appearance within each group\n const ordered: string[] = [];\n const placed = new Set<string>();\n for (const group of groups) {\n for (const node of group.nodes) {\n if (!placed.has(node)) {\n ordered.push(node);\n placed.add(node);\n }\n }\n }\n // Orphans at end in first-appearance order\n for (const node of allNodes) {\n if (!placed.has(node)) {\n ordered.push(node);\n placed.add(node);\n }\n }\n return ordered;\n }\n // No explicit groups: connectivity clustering via BFS\n const adj = new Map<string, Set<string>>();\n for (const node of allNodes) adj.set(node, new Set());\n for (const link of links) {\n adj.get(link.source)!.add(link.target);\n adj.get(link.target)!.add(link.source);\n }\n\n const degree = new Map<string, number>();\n for (const node of allNodes) degree.set(node, 0);\n for (const link of links) {\n degree.set(link.source, degree.get(link.source)! + link.value);\n degree.set(link.target, degree.get(link.target)! + link.value);\n }\n\n const visited = new Set<string>();\n const components: string[][] = [];\n\n const remaining = new Set(allNodes);\n while (remaining.size > 0) {\n // Pick highest-degree unvisited node as BFS root\n let root = '';\n let maxDeg = -1;\n for (const node of remaining) {\n if (degree.get(node)! > maxDeg) {\n maxDeg = degree.get(node)!;\n root = node;\n }\n }\n // BFS\n const component: string[] = [];\n const queue = [root];\n visited.add(root);\n remaining.delete(root);\n while (queue.length > 0) {\n const curr = queue.shift()!;\n component.push(curr);\n for (const neighbor of adj.get(curr)!) {\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n remaining.delete(neighbor);\n queue.push(neighbor);\n }\n }\n }\n components.push(component);\n }\n // Sort components by size descending\n components.sort((a, b) => b.length - a.length);\n return components.flat();\n }\n\n // 'appearance' — first-appearance order (default)\n return allNodes;\n}\n\n// ============================================================\n// Arc Diagram Renderer\n// ============================================================\n\nconst ARC_MARGIN = { top: 60, right: 40, bottom: 60, left: 40 };\n\n/**\n * Renders an arc diagram into the given container using D3.\n */\nexport function renderArcDiagram(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n _isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;\n if (links.length === 0) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const isVertical = orientation === 'vertical';\n const margin = isVertical\n ? {\n top: ARC_MARGIN.top,\n right: ARC_MARGIN.right,\n bottom: ARC_MARGIN.bottom,\n left: 120,\n }\n : ARC_MARGIN;\n\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n\n // Theme colors\n const textColor = palette.text;\n const mutedColor = palette.border;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n // Order nodes by selected strategy\n const nodes = orderArcNodes(links, arcOrder, arcNodeGroups);\n\n // Build node color map from group colors\n const nodeColorMap = new Map<string, string>();\n for (const group of arcNodeGroups) {\n if (group.color) {\n for (const node of group.nodes) {\n if (!nodeColorMap.has(node)) {\n nodeColorMap.set(node, group.color);\n }\n }\n }\n }\n\n // Build group-to-nodes lookup for group hover\n const groupNodeSets = new Map<string, Set<string>>();\n for (const group of arcNodeGroups) {\n groupNodeSets.set(group.name, new Set(group.nodes));\n }\n\n // Scales\n const values = links.map((l) => l.value);\n const [minVal, maxVal] = d3Array.extent(values) as [number, number];\n const strokeScale = d3Scale\n .scaleLinear()\n .domain([minVal, maxVal])\n .range([1.5, 6]);\n\n // SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n // Title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // Build adjacency map for hover interactions\n const neighbors = new Map<string, Set<string>>();\n for (const node of nodes) neighbors.set(node, new Set());\n for (const link of links) {\n neighbors.get(link.source)!.add(link.target);\n neighbors.get(link.target)!.add(link.source);\n }\n\n const FADE_OPACITY = 0.1;\n\n function handleMouseEnter(hovered: string) {\n const connected = neighbors.get(hovered)!;\n\n g.selectAll<SVGPathElement, unknown>('.arc-link').each(function () {\n const el = d3Selection.select(this);\n const src = el.attr('data-source');\n const tgt = el.attr('data-target');\n const isRelated = src === hovered || tgt === hovered;\n el.attr('stroke-opacity', isRelated ? 0.85 : FADE_OPACITY);\n });\n\n g.selectAll<SVGGElement, unknown>('.arc-node').each(function () {\n const el = d3Selection.select(this);\n const name = el.attr('data-node');\n const isRelated = name === hovered || connected.has(name!);\n el.attr('opacity', isRelated ? 1 : FADE_OPACITY);\n });\n }\n\n function handleMouseLeave() {\n g.selectAll<SVGPathElement, unknown>('.arc-link').attr(\n 'stroke-opacity',\n 0.7\n );\n g.selectAll<SVGGElement, unknown>('.arc-node').attr('opacity', 1);\n g.selectAll<SVGRectElement, unknown>('.arc-group-band').attr(\n 'fill-opacity',\n 0.06\n );\n g.selectAll<SVGTextElement, unknown>('.arc-group-label').attr(\n 'fill-opacity',\n 0.5\n );\n }\n\n function handleGroupEnter(groupName: string) {\n const members = groupNodeSets.get(groupName);\n if (!members) return;\n\n g.selectAll<SVGPathElement, unknown>('.arc-link').each(function () {\n const el = d3Selection.select(this);\n const isRelated =\n members.has(el.attr('data-source')!) ||\n members.has(el.attr('data-target')!);\n el.attr('stroke-opacity', isRelated ? 0.85 : FADE_OPACITY);\n });\n\n g.selectAll<SVGGElement, unknown>('.arc-node').each(function () {\n const el = d3Selection.select(this);\n el.attr('opacity', members.has(el.attr('data-node')!) ? 1 : FADE_OPACITY);\n });\n\n g.selectAll<SVGRectElement, unknown>('.arc-group-band').each(function () {\n const el = d3Selection.select(this);\n el.attr(\n 'fill-opacity',\n el.attr('data-group') === groupName ? 0.18 : 0.03\n );\n });\n\n g.selectAll<SVGTextElement, unknown>('.arc-group-label').each(function () {\n const el = d3Selection.select(this);\n el.attr('fill-opacity', el.attr('data-group') === groupName ? 1 : 0.2);\n });\n }\n\n if (isVertical) {\n // Vertical layout: nodes along Y axis, arcs curve to the right\n const yScale = d3Scale\n .scalePoint<string>()\n .domain(nodes)\n .range([0, innerHeight])\n .padding(0.5);\n\n const baseX = innerWidth / 2;\n\n // Group bands (shaded regions bounding grouped nodes)\n if (arcNodeGroups.length > 0) {\n const bandPad = (yScale.step?.() ?? 20) * 0.4;\n const bandHalfW = 60;\n for (const group of arcNodeGroups) {\n const groupNodes = group.nodes.filter((n) => nodes.includes(n));\n if (groupNodes.length === 0) continue;\n const positions = groupNodes.map((n) => yScale(n)!);\n const minY = Math.min(...positions) - bandPad;\n const maxY = Math.max(...positions) + bandPad;\n const bandColor = group.color ?? mutedColor;\n\n g.append('rect')\n .attr('class', 'arc-group-band')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', baseX - bandHalfW)\n .attr('y', minY)\n .attr('width', bandHalfW * 2)\n .attr('height', maxY - minY)\n .attr('rx', 4)\n .attr('fill', textColor)\n .attr('fill-opacity', 0.06)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n\n g.append('text')\n .attr('class', 'arc-group-label')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', baseX - bandHalfW + 6)\n .attr('y', minY + 14)\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .attr('fill-opacity', 0.5)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .text(group.name)\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n }\n }\n\n // Dashed vertical baseline\n g.append('line')\n .attr('x1', baseX)\n .attr('y1', 0)\n .attr('x2', baseX)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n // Arcs\n links.forEach((link, idx) => {\n const y1 = yScale(link.source)!;\n const y2 = yScale(link.target)!;\n const midY = (y1 + y2) / 2;\n const distance = Math.abs(y2 - y1);\n const controlX = baseX + distance * 0.4;\n const color = link.color ?? colors[idx % colors.length];\n\n g.append('path')\n .attr('class', 'arc-link')\n .attr('data-source', link.source)\n .attr('data-target', link.target)\n .attr('data-line-number', String(link.lineNumber))\n .attr('d', `M ${baseX},${y1} Q ${controlX},${midY} ${baseX},${y2}`)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', strokeScale(link.value))\n .attr('stroke-opacity', 0.7)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('click', () => {\n if (onClickItem && link.lineNumber) onClickItem(link.lineNumber);\n });\n });\n\n // Node circles and labels\n for (const node of nodes) {\n const y = yScale(node)!;\n const nodeColor = nodeColorMap.get(node) ?? textColor;\n // Find the first link involving this node (for line number and click target)\n const nodeLink = links.find((l) => l.source === node || l.target === node);\n\n const nodeG = g\n .append('g')\n .attr('class', 'arc-node')\n .attr('data-node', node)\n .attr('data-line-number', nodeLink?.lineNumber ? String(nodeLink.lineNumber) : null)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleMouseEnter(node))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem && nodeLink?.lineNumber)\n onClickItem(nodeLink.lineNumber);\n });\n\n nodeG\n .append('circle')\n .attr('cx', baseX)\n .attr('cy', y)\n .attr('r', 5)\n .attr('fill', nodeColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n\n // Label to the left of baseline\n nodeG\n .append('text')\n .attr('x', baseX - 14)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'end')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(node);\n }\n } else {\n // Horizontal layout (default): nodes along X axis, arcs curve upward\n const xScale = d3Scale\n .scalePoint<string>()\n .domain(nodes)\n .range([0, innerWidth])\n .padding(0.5);\n\n const baseY = innerHeight / 2;\n\n // Group bands (shaded regions bounding grouped nodes)\n if (arcNodeGroups.length > 0) {\n const bandPad = (xScale.step?.() ?? 20) * 0.4;\n const bandHalfH = 40;\n for (const group of arcNodeGroups) {\n const groupNodes = group.nodes.filter((n) => nodes.includes(n));\n if (groupNodes.length === 0) continue;\n const positions = groupNodes.map((n) => xScale(n)!);\n const minX = Math.min(...positions) - bandPad;\n const maxX = Math.max(...positions) + bandPad;\n const bandColor = group.color ?? mutedColor;\n\n g.append('rect')\n .attr('class', 'arc-group-band')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', minX)\n .attr('y', baseY - bandHalfH)\n .attr('width', maxX - minX)\n .attr('height', bandHalfH * 2)\n .attr('rx', 4)\n .attr('fill', textColor)\n .attr('fill-opacity', 0.06)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n\n g.append('text')\n .attr('class', 'arc-group-label')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', (minX + maxX) / 2)\n .attr('y', baseY + bandHalfH - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .attr('fill-opacity', 0.5)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .text(group.name)\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n }\n }\n\n // Dashed horizontal baseline\n g.append('line')\n .attr('x1', 0)\n .attr('y1', baseY)\n .attr('x2', innerWidth)\n .attr('y2', baseY)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n // Arcs\n links.forEach((link, idx) => {\n const x1 = xScale(link.source)!;\n const x2 = xScale(link.target)!;\n const midX = (x1 + x2) / 2;\n const distance = Math.abs(x2 - x1);\n const controlY = baseY - distance * 0.4;\n const color = link.color ?? colors[idx % colors.length];\n\n g.append('path')\n .attr('class', 'arc-link')\n .attr('data-source', link.source)\n .attr('data-target', link.target)\n .attr('data-line-number', String(link.lineNumber))\n .attr('d', `M ${x1},${baseY} Q ${midX},${controlY} ${x2},${baseY}`)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', strokeScale(link.value))\n .attr('stroke-opacity', 0.7)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('click', () => {\n if (onClickItem && link.lineNumber) onClickItem(link.lineNumber);\n });\n });\n\n // Node circles and labels\n for (const node of nodes) {\n const x = xScale(node)!;\n const nodeColor = nodeColorMap.get(node) ?? textColor;\n // Find the first link involving this node (for line number and click target)\n const nodeLink = links.find((l) => l.source === node || l.target === node);\n\n const nodeG = g\n .append('g')\n .attr('class', 'arc-node')\n .attr('data-node', node)\n .attr('data-line-number', nodeLink?.lineNumber ? String(nodeLink.lineNumber) : null)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleMouseEnter(node))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem && nodeLink?.lineNumber)\n onClickItem(nodeLink.lineNumber);\n });\n\n nodeG\n .append('circle')\n .attr('cx', x)\n .attr('cy', baseY)\n .attr('r', 5)\n .attr('fill', nodeColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n\n // Label below baseline\n nodeG\n .append('text')\n .attr('x', x)\n .attr('y', baseY + 20)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(node);\n }\n }\n}\n\n// ============================================================\n// Timeline Era Bands\n// ============================================================\n\nfunction getEraColors(palette: PaletteColors): string[] {\n return [\n palette.colors.blue,\n palette.colors.green,\n palette.colors.yellow,\n palette.colors.orange,\n palette.colors.purple,\n ];\n}\n\n/**\n * Renders semi-transparent era background bands behind timeline events.\n */\nfunction renderEras(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n eras: TimelineEra[],\n scale: d3Scale.ScaleLinear<number, number>,\n isVertical: boolean,\n innerWidth: number,\n innerHeight: number,\n onEnter: (eraStart: number, eraEnd: number) => void,\n onLeave: () => void,\n hasScale: boolean = false,\n tooltip: HTMLDivElement | null = null,\n palette?: PaletteColors\n): void {\n const eraColors = palette\n ? getEraColors(palette)\n : ['#5e81ac', '#a3be8c', '#ebcb8b', '#d08770', '#b48ead'];\n eras.forEach((era, i) => {\n const startVal = parseTimelineDate(era.startDate);\n const endVal = parseTimelineDate(era.endDate);\n const start = scale(startVal);\n const end = scale(endVal);\n const color = era.color || eraColors[i % eraColors.length];\n\n const eraG = g\n .append('g')\n .attr('class', 'tl-era')\n .attr('data-era-start', String(startVal))\n .attr('data-era-end', String(endVal))\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n onEnter(startVal, endVal);\n if (tooltip) showTooltip(tooltip, buildEraTooltipHtml(era), event);\n })\n .on('mouseleave', function () {\n onLeave();\n if (tooltip) hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n if (tooltip) showTooltip(tooltip, buildEraTooltipHtml(era), event);\n });\n\n if (isVertical) {\n const y = Math.min(start, end);\n const h = Math.abs(end - start);\n eraG\n .append('rect')\n .attr('x', 0)\n .attr('y', y)\n .attr('width', innerWidth)\n .attr('height', h)\n .attr('fill', color)\n .attr('opacity', 0.08);\n eraG\n .append('text')\n .attr('x', 6)\n .attr('y', y + 18)\n .attr('text-anchor', 'start')\n .attr('fill', color)\n .attr('font-size', '13px')\n .attr('font-weight', '600')\n .attr('opacity', 0.8)\n .text(era.label);\n } else {\n const x = Math.min(start, end);\n const w = Math.abs(end - start);\n // When scale is on, extend the shading above the chart area\n // so the label sits above the scale marks but inside the band.\n const rectTop = hasScale ? -48 : 0;\n eraG\n .append('rect')\n .attr('x', x)\n .attr('y', rectTop)\n .attr('width', w)\n .attr('height', innerHeight - rectTop)\n .attr('fill', color)\n .attr('opacity', 0.08);\n eraG\n .append('text')\n .attr('x', x + w / 2)\n .attr('y', hasScale ? -32 : 18)\n .attr('text-anchor', 'middle')\n .attr('fill', color)\n .attr('font-size', '13px')\n .attr('font-weight', '600')\n .attr('opacity', 0.8)\n .text(era.label);\n }\n });\n}\n\n/**\n * Renders timeline markers as dashed vertical lines with diamond indicators and labels.\n */\nfunction renderMarkers(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n markers: TimelineMarker[],\n scale: d3Scale.ScaleLinear<number, number>,\n isVertical: boolean,\n innerWidth: number,\n innerHeight: number,\n _hasScale: boolean = false,\n tooltip: HTMLDivElement | null = null,\n palette?: PaletteColors\n): void {\n // Default marker color - bright orange/red that \"pops\"\n const defaultColor = palette?.accent || '#d08770';\n\n markers.forEach((marker) => {\n const dateVal = parseTimelineDate(marker.date);\n const pos = scale(dateVal);\n const color = marker.color || defaultColor;\n const lineOpacity = 0.5;\n const diamondSize = 5;\n\n const markerG = g\n .append('g')\n .attr('class', 'tl-marker')\n .attr('data-marker-date', String(dateVal))\n .attr('data-line-number', String(marker.lineNumber))\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n if (tooltip) {\n showTooltip(tooltip, formatDateLabel(marker.date), event);\n }\n })\n .on('mouseleave', function () {\n if (tooltip) hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n if (tooltip) {\n showTooltip(tooltip, formatDateLabel(marker.date), event);\n }\n });\n\n if (isVertical) {\n // Vertical orientation: horizontal dashed line across the chart\n markerG\n .append('line')\n .attr('x1', 0)\n .attr('y1', pos)\n .attr('x2', innerWidth)\n .attr('y2', pos)\n .attr('stroke', color)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '6 4')\n .attr('opacity', lineOpacity);\n\n // Label above diamond\n markerG\n .append('text')\n .attr('x', -diamondSize - 8)\n .attr('y', pos - diamondSize - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', color)\n .attr('font-size', '11px')\n .attr('font-weight', '600')\n .text(marker.label);\n\n // Diamond at the left edge\n markerG\n .append('path')\n .attr(\n 'd',\n `M${-diamondSize - 8},${pos} l${diamondSize},-${diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} Z`\n )\n .attr('fill', color)\n .attr('opacity', 0.9);\n } else {\n // Horizontal orientation: vertical dashed line down the chart\n // Label above diamond, diamond below, then dashed line to chart bottom\n const labelY = 6;\n const diamondY = labelY + 14;\n\n // Label above diamond\n markerG\n .append('text')\n .attr('x', pos)\n .attr('y', labelY)\n .attr('text-anchor', 'middle')\n .attr('fill', color)\n .attr('font-size', '11px')\n .attr('font-weight', '600')\n .text(marker.label);\n\n // Diamond below label\n markerG\n .append('path')\n .attr(\n 'd',\n `M${pos},${diamondY - diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} l-${diamondSize},-${diamondSize} Z`\n )\n .attr('fill', color)\n .attr('opacity', 0.9);\n\n // Line starts from bottom of diamond and goes down to chart bottom\n markerG\n .append('line')\n .attr('x1', pos)\n .attr('y1', diamondY + diamondSize)\n .attr('x2', pos)\n .attr('y2', innerHeight)\n .attr('stroke', color)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '6 4')\n .attr('opacity', lineOpacity);\n }\n });\n}\n\n// ============================================================\n// Timeline Time Scale\n// ============================================================\n\nconst MONTH_ABBR = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n];\n\n/**\n * Converts a DSL date string (YYYY, YYYY-MM, YYYY-MM-DD) to a human-readable label.\n * '1718' → '1718'\n * '1718-05' → 'May 1718'\n * '1718-05-22' → 'May 22, 1718'\n */\nexport function formatDateLabel(dateStr: string): string {\n const parts = dateStr.split('-');\n const year = parts[0];\n if (parts.length === 1) return year;\n const month = MONTH_ABBR[parseInt(parts[1], 10) - 1];\n if (parts.length === 2) return `${month} ${year}`;\n const day = parseInt(parts[2], 10);\n return `${month} ${day}, ${year}`;\n}\n\n/**\n * Computes adaptive tick marks for a timeline scale.\n * - Multi-year spans → year ticks\n * - Within ~1 year → month ticks\n * - Within ~3 months → week ticks (1st, 8th, 15th, 22nd)\n *\n * Optional boundary parameters add ticks at exact data start/end:\n * - boundaryStart/boundaryEnd: numeric date values\n * - boundaryStartLabel/boundaryEndLabel: formatted labels for those dates\n */\nexport function computeTimeTicks(\n domainMin: number,\n domainMax: number,\n scale: d3Scale.ScaleLinear<number, number>,\n boundaryStart?: number,\n boundaryEnd?: number,\n boundaryStartLabel?: string,\n boundaryEndLabel?: string\n): { pos: number; label: string }[] {\n const minYear = Math.floor(domainMin);\n const maxYear = Math.floor(domainMax);\n const span = domainMax - domainMin;\n\n let ticks: { pos: number; label: string }[] = [];\n\n // Year ticks for multi-year spans (need at least 2 boundaries)\n const firstYear = Math.ceil(domainMin);\n const lastYear = Math.floor(domainMax);\n if (lastYear >= firstYear + 1) {\n // Decimate ticks for long spans so labels don't overlap\n const yearSpan = lastYear - firstYear;\n let step = 1;\n if (yearSpan > 80) step = 20;\n else if (yearSpan > 40) step = 10;\n else if (yearSpan > 20) step = 5;\n else if (yearSpan > 10) step = 2;\n\n // Align to step boundary so ticks land on round years (1700, 1710, …)\n const alignedFirst = Math.ceil(firstYear / step) * step;\n for (let y = alignedFirst; y <= lastYear; y += step) {\n ticks.push({ pos: scale(y), label: String(y) });\n }\n } else if (span > 0.25) {\n // Month ticks for spans > ~3 months\n const crossesYear = maxYear > minYear;\n for (let y = minYear; y <= maxYear + 1; y++) {\n for (let m = 1; m <= 12; m++) {\n const val = y + (m - 1) / 12;\n if (val > domainMax) break;\n if (val >= domainMin) {\n ticks.push({\n pos: scale(val),\n label: crossesYear\n ? `${MONTH_ABBR[m - 1]} '${String(y).slice(-2)}`\n : MONTH_ABBR[m - 1],\n });\n }\n }\n }\n } else {\n // Week ticks for spans ≤ ~3 months (1st, 8th, 15th, 22nd of each month)\n for (let y = minYear; y <= maxYear + 1; y++) {\n for (let m = 1; m <= 12; m++) {\n for (const d of [1, 8, 15, 22]) {\n const val = y + (m - 1) / 12 + (d - 1) / 365;\n if (val > domainMax) break;\n if (val >= domainMin) {\n ticks.push({\n pos: scale(val),\n label: `${MONTH_ABBR[m - 1]} ${d}`,\n });\n }\n }\n }\n }\n }\n\n // Add boundary ticks at exact data start/end if provided\n // When a boundary tick collides with a standard tick, replace the standard tick\n const collisionThreshold = 40; // pixels\n\n if (boundaryStart !== undefined && boundaryStartLabel) {\n const boundaryPos = scale(boundaryStart);\n // Remove any standard ticks that would collide with the start boundary\n ticks = ticks.filter(\n (t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold\n );\n ticks.unshift({ pos: boundaryPos, label: boundaryStartLabel });\n }\n\n if (boundaryEnd !== undefined && boundaryEndLabel) {\n const boundaryPos = scale(boundaryEnd);\n // Remove any standard ticks that would collide with the end boundary\n ticks = ticks.filter(\n (t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold\n );\n ticks.push({ pos: boundaryPos, label: boundaryEndLabel });\n }\n\n return ticks;\n}\n\n/**\n * Renders adaptive tick marks along the time axis.\n * Optional boundary parameters add ticks at exact data start/end.\n */\nfunction renderTimeScale(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n scale: d3Scale.ScaleLinear<number, number>,\n isVertical: boolean,\n innerWidth: number,\n innerHeight: number,\n textColor: string,\n boundaryStart?: number,\n boundaryEnd?: number,\n boundaryStartLabel?: string,\n boundaryEndLabel?: string\n): void {\n const [domainMin, domainMax] = scale.domain();\n const ticks = computeTimeTicks(\n domainMin,\n domainMax,\n scale,\n boundaryStart,\n boundaryEnd,\n boundaryStartLabel,\n boundaryEndLabel\n );\n if (ticks.length < 2) return;\n\n const tickLen = 6;\n const opacity = 0.4;\n\n const guideOpacity = 0.15;\n\n for (const tick of ticks) {\n if (isVertical) {\n // Guide line spanning full width\n g.append('line')\n .attr('x1', 0)\n .attr('y1', tick.pos)\n .attr('x2', innerWidth)\n .attr('y2', tick.pos)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', guideOpacity);\n\n // Left edge\n g.append('line')\n .attr('x1', -tickLen)\n .attr('y1', tick.pos)\n .attr('x2', 0)\n .attr('y2', tick.pos)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('x', -tickLen - 3)\n .attr('y', tick.pos)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'end')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n\n // Right edge\n g.append('line')\n .attr('x1', innerWidth)\n .attr('y1', tick.pos)\n .attr('x2', innerWidth + tickLen)\n .attr('y2', tick.pos)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('x', innerWidth + tickLen + 3)\n .attr('y', tick.pos)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n } else {\n // Guide line spanning full height\n g.append('line')\n .attr('class', 'tl-scale-tick')\n .attr('x1', tick.pos)\n .attr('y1', 0)\n .attr('x2', tick.pos)\n .attr('y2', innerHeight)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', guideOpacity);\n\n // Bottom edge\n g.append('line')\n .attr('class', 'tl-scale-tick')\n .attr('x1', tick.pos)\n .attr('y1', innerHeight)\n .attr('x2', tick.pos)\n .attr('y2', innerHeight + tickLen)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('class', 'tl-scale-tick')\n .attr('x', tick.pos)\n .attr('y', innerHeight + tickLen + 12)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n\n // Top edge\n g.append('line')\n .attr('class', 'tl-scale-tick')\n .attr('x1', tick.pos)\n .attr('y1', -tickLen)\n .attr('x2', tick.pos)\n .attr('y2', 0)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('class', 'tl-scale-tick')\n .attr('x', tick.pos)\n .attr('y', -tickLen - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n }\n }\n}\n\n// ============================================================\n// Timeline Event Date Scale Helpers\n// ============================================================\n\n/**\n * Shows event start/end dates on the scale, fading existing scale ticks.\n * For horizontal timelines, displays dates at the top of the scale.\n */\nfunction showEventDatesOnScale(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n scale: d3Scale.ScaleLinear<number, number>,\n startDate: string,\n endDate: string | null,\n innerHeight: number,\n accentColor: string\n): void {\n // Fade existing scale ticks\n g.selectAll('.tl-scale-tick').attr('opacity', 0.1);\n\n const tickLen = 6;\n const startPos = scale(parseTimelineDate(startDate));\n const startLabel = formatDateLabel(startDate);\n\n // Start date - top\n g.append('line')\n .attr('class', 'tl-event-date')\n .attr('x1', startPos)\n .attr('y1', -tickLen)\n .attr('x2', startPos)\n .attr('y2', innerHeight)\n .attr('stroke', accentColor)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', 0.6);\n\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', startPos)\n .attr('y', -tickLen - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(startLabel);\n\n // Start date - bottom\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', startPos)\n .attr('y', innerHeight + tickLen + 12)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(startLabel);\n\n if (endDate) {\n const endPos = scale(parseTimelineDate(endDate));\n const endLabel = formatDateLabel(endDate);\n\n // End date - top\n g.append('line')\n .attr('class', 'tl-event-date')\n .attr('x1', endPos)\n .attr('y1', -tickLen)\n .attr('x2', endPos)\n .attr('y2', innerHeight)\n .attr('stroke', accentColor)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', 0.6);\n\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', endPos)\n .attr('y', -tickLen - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(endLabel);\n\n // End date - bottom\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', endPos)\n .attr('y', innerHeight + tickLen + 12)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(endLabel);\n }\n}\n\n/**\n * Hides event dates and restores scale tick visibility.\n */\nfunction hideEventDatesOnScale(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>\n): void {\n // Remove event date elements\n g.selectAll('.tl-event-date').remove();\n\n // Restore scale tick visibility\n g.selectAll('.tl-scale-tick').each(function () {\n const el = d3Selection.select(this);\n // Restore original opacity based on element type\n const isDashed = el.attr('stroke-dasharray');\n el.attr('opacity', isDashed ? 0.15 : 0.4);\n });\n}\n\n// ============================================================\n// Timeline Tooltip Helpers\n// ============================================================\n\nfunction createTooltip(\n container: HTMLElement,\n palette: PaletteColors,\n isDark: boolean\n): HTMLDivElement {\n container.style.position = 'relative';\n\n // Reuse existing tooltip element if present (avoids DOM churn on re-renders)\n const existing = container.querySelector<HTMLDivElement>('[data-d3-tooltip]');\n if (existing) {\n existing.style.display = 'none';\n existing.style.background = palette.surface;\n existing.style.color = palette.text;\n existing.style.boxShadow = isDark\n ? '0 2px 6px rgba(0,0,0,0.3)'\n : '0 2px 6px rgba(0,0,0,0.12)';\n return existing;\n }\n\n const tip = document.createElement('div');\n tip.setAttribute('data-d3-tooltip', '');\n tip.style.position = 'absolute';\n tip.style.display = 'none';\n tip.style.pointerEvents = 'none';\n tip.style.background = palette.surface;\n tip.style.color = palette.text;\n tip.style.padding = '6px 10px';\n tip.style.borderRadius = '4px';\n tip.style.fontSize = '12px';\n tip.style.lineHeight = '1.4';\n tip.style.whiteSpace = 'nowrap';\n tip.style.zIndex = '10';\n tip.style.boxShadow = isDark\n ? '0 2px 6px rgba(0,0,0,0.3)'\n : '0 2px 6px rgba(0,0,0,0.12)';\n container.appendChild(tip);\n return tip;\n}\n\nfunction showTooltip(\n tooltip: HTMLDivElement,\n html: string,\n event: MouseEvent\n): void {\n tooltip.innerHTML = html;\n tooltip.style.display = 'block';\n const container = tooltip.parentElement!;\n const rect = container.getBoundingClientRect();\n let left = event.clientX - rect.left + 12;\n let top = event.clientY - rect.top - 28;\n // Clamp so tooltip stays inside the container\n const tipW = tooltip.offsetWidth;\n const tipH = tooltip.offsetHeight;\n if (left + tipW > rect.width) left = rect.width - tipW - 4;\n if (top < 0) top = event.clientY - rect.top + 16;\n if (top + tipH > rect.height) top = rect.height - tipH - 4;\n tooltip.style.left = `${left}px`;\n tooltip.style.top = `${top}px`;\n}\n\nfunction hideTooltip(tooltip: HTMLDivElement): void {\n tooltip.style.display = 'none';\n}\n\nfunction buildEventTooltipHtml(ev: TimelineEvent): string {\n const datePart = ev.endDate\n ? `${formatDateLabel(ev.date)} → ${formatDateLabel(ev.endDate)}`\n : formatDateLabel(ev.date);\n return `<strong>${ev.label}</strong><br>${datePart}`;\n}\n\nfunction buildEraTooltipHtml(era: TimelineEra): string {\n return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} → ${formatDateLabel(era.endDate)}`;\n}\n\n// ============================================================\n// Timeline Renderer\n// ============================================================\n\n/**\n * Renders a timeline chart into the given container using D3.\n * Supports horizontal (default) and vertical orientation.\n */\nexport function renderTimeline(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const {\n timelineEvents,\n timelineGroups,\n timelineEras,\n timelineMarkers,\n timelineSort,\n timelineScale,\n timelineSwimlanes,\n title,\n orientation,\n } = parsed;\n if (timelineEvents.length === 0) return;\n\n const tooltip = createTooltip(container, palette, isDark);\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const isVertical = orientation === 'vertical';\n\n // Theme colors\n const textColor = palette.text;\n const mutedColor = palette.border;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n // Assign colors to groups\n const groupColorMap = new Map<string, string>();\n timelineGroups.forEach((grp, i) => {\n groupColorMap.set(grp.name, grp.color ?? colors[i % colors.length]);\n });\n\n function eventColor(ev: TimelineEvent): string {\n if (ev.group && groupColorMap.has(ev.group)) {\n return groupColorMap.get(ev.group)!;\n }\n return textColor;\n }\n\n // Convert dates to numeric values and find boundary dates\n let minDate = Infinity;\n let maxDate = -Infinity;\n let earliestStartDateStr = '';\n let latestEndDateStr = '';\n\n for (const ev of timelineEvents) {\n const startNum = parseTimelineDate(ev.date);\n const endNum = ev.endDate ? parseTimelineDate(ev.endDate) : startNum;\n\n if (startNum < minDate) {\n minDate = startNum;\n earliestStartDateStr = ev.date;\n }\n if (endNum > maxDate) {\n maxDate = endNum;\n latestEndDateStr = ev.endDate ?? ev.date;\n }\n }\n const datePadding = (maxDate - minDate) * 0.05 || 0.5;\n\n const FADE_OPACITY = 0.1;\n\n // ------------------------------------------------------------------\n // Shared hover helpers (operate on CSS classes, orientation-agnostic)\n // ------------------------------------------------------------------\n\n function fadeToGroup(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n groupName: string\n ) {\n g.selectAll<SVGGElement, unknown>('.tl-event').each(function () {\n const el = d3Selection.select(this);\n const evGroup = el.attr('data-group');\n el.attr('opacity', evGroup === groupName ? 1 : FADE_OPACITY);\n });\n g.selectAll<SVGGElement, unknown>('.tl-legend-item, .tl-lane-header').each(\n function () {\n const el = d3Selection.select(this);\n const name = el.attr('data-group');\n el.attr('opacity', name === groupName ? 1 : FADE_OPACITY);\n }\n );\n g.selectAll<SVGGElement, unknown>('.tl-marker').attr(\n 'opacity',\n FADE_OPACITY\n );\n }\n\n function fadeToEra(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n eraStart: number,\n eraEnd: number\n ) {\n g.selectAll<SVGGElement, unknown>('.tl-event').each(function () {\n const el = d3Selection.select(this);\n const date = parseFloat(el.attr('data-date')!);\n const endDate = el.attr('data-end-date');\n const evEnd = endDate ? parseFloat(endDate) : date;\n const inside = evEnd >= eraStart && date <= eraEnd;\n el.attr('opacity', inside ? 1 : FADE_OPACITY);\n });\n g.selectAll<SVGGElement, unknown>('.tl-legend-item, .tl-lane-header').attr(\n 'opacity',\n FADE_OPACITY\n );\n g.selectAll<SVGGElement, unknown>('.tl-era').each(function () {\n const el = d3Selection.select(this);\n const s = parseFloat(el.attr('data-era-start')!);\n const e = parseFloat(el.attr('data-era-end')!);\n const isSelf = s === eraStart && e === eraEnd;\n el.attr('opacity', isSelf ? 1 : FADE_OPACITY);\n });\n g.selectAll<SVGGElement, unknown>('.tl-marker').each(function () {\n const el = d3Selection.select(this);\n const date = parseFloat(el.attr('data-marker-date')!);\n const inside = date >= eraStart && date <= eraEnd;\n el.attr('opacity', inside ? 1 : FADE_OPACITY);\n });\n }\n\n function fadeReset(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>\n ) {\n g.selectAll<SVGGElement, unknown>(\n '.tl-event, .tl-legend-item, .tl-lane-header, .tl-marker'\n ).attr('opacity', 1);\n g.selectAll<SVGGElement, unknown>('.tl-era').attr('opacity', 1);\n }\n\n // ================================================================\n // VERTICAL orientation (time flows top→bottom)\n // ================================================================\n if (isVertical) {\n if (timelineSort === 'group' && timelineGroups.length > 0) {\n // === GROUPED: one column/lane per group, vertical ===\n const groupNames = timelineGroups.map((gr) => gr.name);\n const ungroupedEvents = timelineEvents.filter(\n (ev) => ev.group === null || !groupNames.includes(ev.group)\n );\n const laneNames =\n ungroupedEvents.length > 0 ? [...groupNames, '(Other)'] : groupNames;\n\n const laneCount = laneNames.length;\n const scaleMargin = timelineScale ? 40 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n const margin = {\n top: 104 + markerMargin,\n right: 40 + scaleMargin,\n bottom: 40,\n left: 60 + scaleMargin,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const laneWidth = innerWidth / laneCount;\n\n const yScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerHeight]);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n yScale,\n true,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n yScale,\n true,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n yScale,\n true,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n laneNames.forEach((laneName, laneIdx) => {\n const laneX = laneIdx * laneWidth;\n const laneColor = groupColorMap.get(laneName) ?? textColor;\n const laneCenter = laneX + laneWidth / 2;\n\n const headerG = g\n .append('g')\n .attr('class', 'tl-lane-header')\n .attr('data-group', laneName)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, laneName))\n .on('mouseleave', () => fadeReset(g));\n\n headerG\n .append('text')\n .attr('x', laneCenter)\n .attr('y', -15)\n .attr('text-anchor', 'middle')\n .attr('fill', laneColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .text(laneName);\n\n g.append('line')\n .attr('x1', laneCenter)\n .attr('y1', 0)\n .attr('x2', laneCenter)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n const laneEvents = timelineEvents.filter((ev) =>\n laneName === '(Other)'\n ? ev.group === null || !groupNames.includes(ev.group)\n : ev.group === laneName\n );\n\n for (const ev of laneEvents) {\n const y = yScale(parseTimelineDate(ev.date));\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', laneName)\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n fadeToGroup(g, laneName);\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('mouseleave', function () {\n fadeReset(g);\n hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const y2 = yScale(parseTimelineDate(ev.endDate));\n const rectH = Math.max(y2 - y, 4);\n evG\n .append('rect')\n .attr('x', laneCenter - 6)\n .attr('y', y)\n .attr('width', 12)\n .attr('height', rectH)\n .attr('rx', 4)\n .attr('fill', laneColor);\n evG\n .append('text')\n .attr('x', laneCenter + 14)\n .attr('y', y + rectH / 2)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .text(ev.label);\n } else {\n evG\n .append('circle')\n .attr('cx', laneCenter)\n .attr('cy', y)\n .attr('r', 4)\n .attr('fill', laneColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', laneCenter + 10)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .text(ev.label);\n }\n }\n });\n } else {\n // === TIME SORT, vertical: single vertical axis ===\n const scaleMargin = timelineScale ? 40 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n const margin = {\n top: 104 + markerMargin,\n right: 200,\n bottom: 40,\n left: 60 + scaleMargin,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const axisX = 20;\n\n const yScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerHeight]);\n\n const sorted = timelineEvents\n .slice()\n .sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n yScale,\n true,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n yScale,\n true,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n yScale,\n true,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n // Group legend\n if (timelineGroups.length > 0) {\n let legendX = 0;\n const legendY = -55;\n for (const grp of timelineGroups) {\n const color = groupColorMap.get(grp.name) ?? textColor;\n const itemG = g\n .append('g')\n .attr('class', 'tl-legend-item')\n .attr('data-group', grp.name)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, grp.name))\n .on('mouseleave', () => fadeReset(g));\n\n itemG\n .append('circle')\n .attr('cx', legendX)\n .attr('cy', legendY)\n .attr('r', 5)\n .attr('fill', color);\n\n itemG\n .append('text')\n .attr('x', legendX + 10)\n .attr('y', legendY)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(grp.name);\n\n legendX += grp.name.length * 7 + 30;\n }\n }\n\n g.append('line')\n .attr('x1', axisX)\n .attr('y1', 0)\n .attr('x2', axisX)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n for (const ev of sorted) {\n const y = yScale(parseTimelineDate(ev.date));\n const color = eventColor(ev);\n\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', ev.group || '')\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('mouseleave', function () {\n fadeReset(g);\n hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const y2 = yScale(parseTimelineDate(ev.endDate));\n const rectH = Math.max(y2 - y, 4);\n evG\n .append('rect')\n .attr('x', axisX - 6)\n .attr('y', y)\n .attr('width', 12)\n .attr('height', rectH)\n .attr('rx', 4)\n .attr('fill', color);\n evG\n .append('text')\n .attr('x', axisX + 16)\n .attr('y', y + rectH / 2)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(ev.label);\n } else {\n evG\n .append('circle')\n .attr('cx', axisX)\n .attr('cy', y)\n .attr('r', 4)\n .attr('fill', color)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', axisX + 16)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(ev.label);\n }\n\n // Date label to the left\n evG\n .append('text')\n .attr('x', axisX - 14)\n .attr(\n 'y',\n ev.endDate\n ? yScale(parseTimelineDate(ev.date)) +\n Math.max(\n yScale(parseTimelineDate(ev.endDate)) -\n yScale(parseTimelineDate(ev.date)),\n 4\n ) /\n 2\n : y\n )\n .attr('dy', '0.35em')\n .attr('text-anchor', 'end')\n .attr('fill', mutedColor)\n .attr('font-size', '10px')\n .text(ev.date + (ev.endDate ? `→${ev.endDate}` : ''));\n }\n }\n\n return; // vertical done\n }\n\n // ================================================================\n // HORIZONTAL orientation (default — time flows left→right)\n // Each event gets its own row, stacked vertically.\n // ================================================================\n\n const BAR_H = 22; // range bar thickness (tall enough for text inside)\n const GROUP_GAP = 12; // vertical gap between group swim-lanes\n\n if (timelineSort === 'group' && timelineGroups.length > 0) {\n // === GROUPED: swim-lanes stacked vertically, events on own rows ===\n const groupNames = timelineGroups.map((gr) => gr.name);\n const ungroupedEvents = timelineEvents.filter(\n (ev) => ev.group === null || !groupNames.includes(ev.group)\n );\n const laneNames =\n ungroupedEvents.length > 0 ? [...groupNames, '(Other)'] : groupNames;\n\n // Build lane data\n const lanes = laneNames.map((name) => ({\n name,\n events: timelineEvents.filter((ev) =>\n name === '(Other)'\n ? ev.group === null || !groupNames.includes(ev.group)\n : ev.group === name\n ),\n }));\n\n const totalEventRows = lanes.reduce((s, l) => s + l.events.length, 0);\n const scaleMargin = timelineScale ? 24 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n // Calculate left margin based on longest group name (~7px per char + padding)\n const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));\n const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);\n // Group-sorted doesn't need legend space (group names shown on left)\n const baseTopMargin = title ? 50 : 20;\n const margin = {\n top: baseTopMargin + (timelineScale ? 40 : 0) + markerMargin,\n right: 40,\n bottom: 40 + scaleMargin,\n left: dynamicLeftMargin,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const totalGaps = (lanes.length - 1) * GROUP_GAP;\n const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);\n\n const xScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerWidth]);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n xScale,\n false,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n xScale,\n false,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n xScale,\n false,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n // Offset events below marker area when markers are present\n let curY = markerMargin;\n\n // Render swimlane backgrounds first (so they appear behind events)\n // Extend into left margin to include group names\n if (timelineSwimlanes) {\n let swimY = markerMargin;\n lanes.forEach((lane, idx) => {\n const laneSpan = lane.events.length * rowH;\n // Alternate between light gray and transparent for visual separation\n const fillColor = idx % 2 === 0 ? textColor : 'transparent';\n g.append('rect')\n .attr('class', 'tl-swimlane')\n .attr('data-group', lane.name)\n .attr('x', -margin.left)\n .attr('y', swimY)\n .attr('width', innerWidth + margin.left)\n .attr('height', laneSpan + (idx < lanes.length - 1 ? GROUP_GAP : 0))\n .attr('fill', fillColor)\n .attr('opacity', 0.06);\n swimY += laneSpan + GROUP_GAP;\n });\n }\n\n for (const lane of lanes) {\n const laneColor = groupColorMap.get(lane.name) ?? textColor;\n const laneSpan = lane.events.length * rowH;\n\n // Group label — left of lane, vertically centred\n const group = timelineGroups.find((grp) => grp.name === lane.name);\n const headerG = g\n .append('g')\n .attr('class', 'tl-lane-header')\n .attr('data-group', lane.name)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, lane.name))\n .on('mouseleave', () => fadeReset(g))\n .on('click', () => {\n if (onClickItem && group?.lineNumber) onClickItem(group.lineNumber);\n });\n\n headerG\n .append('text')\n .attr('x', -margin.left + 10)\n .attr('y', curY + laneSpan / 2)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', laneColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .text(lane.name);\n\n lane.events.forEach((ev, i) => {\n const y = curY + i * rowH + rowH / 2;\n const x = xScale(parseTimelineDate(ev.date));\n\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', lane.name)\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n fadeToGroup(g, lane.name);\n if (timelineScale) {\n showEventDatesOnScale(\n g,\n xScale,\n ev.date,\n ev.endDate,\n innerHeight,\n laneColor\n );\n } else {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('mouseleave', function () {\n fadeReset(g);\n if (timelineScale) {\n hideEventDatesOnScale(g);\n } else {\n hideTooltip(tooltip);\n }\n })\n .on('mousemove', function (event: MouseEvent) {\n if (!timelineScale) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const x2 = xScale(parseTimelineDate(ev.endDate));\n const rectW = Math.max(x2 - x, 4);\n // Estimate label width (~7px per char at 13px font) + padding\n const estLabelWidth = ev.label.length * 7 + 16;\n const labelFitsInside = rectW >= estLabelWidth;\n\n let fill: string = laneColor;\n if (ev.uncertain) {\n // Create gradient for uncertain end - fades last 20%\n const gradientId = `uncertain-${ev.lineNumber}`;\n const defs = svg.select('defs').node() || svg.append('defs').node();\n d3Selection\n .select(defs as Element)\n .append('linearGradient')\n .attr('id', gradientId)\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n .selectAll('stop')\n .data([\n { offset: '0%', opacity: 1 },\n { offset: '80%', opacity: 1 },\n { offset: '100%', opacity: 0 },\n ])\n .enter()\n .append('stop')\n .attr('offset', (d) => d.offset)\n .attr('stop-color', laneColor)\n .attr('stop-opacity', (d) => d.opacity);\n fill = `url(#${gradientId})`;\n }\n\n evG\n .append('rect')\n .attr('x', x)\n .attr('y', y - BAR_H / 2)\n .attr('width', rectW)\n .attr('height', BAR_H)\n .attr('rx', 4)\n .attr('fill', fill);\n\n if (labelFitsInside) {\n // Text inside bar - always white for readability\n evG\n .append('text')\n .attr('x', x + 8)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', '#ffffff')\n .attr('font-size', '14px')\n .attr('font-weight', '700')\n .text(ev.label);\n } else {\n // Text outside bar - check if it fits on left or must go right\n const wouldFlipLeft = x + rectW > innerWidth * 0.6;\n const labelFitsLeft = x - 6 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('text')\n .attr('x', flipLeft ? x - 6 : x + rectW + 6)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '13px')\n .text(ev.label);\n }\n } else {\n // Point event (no end date) - render as circle with label\n const estLabelWidth = ev.label.length * 7;\n // Only flip left if past 60% AND label fits without colliding with group name area\n const wouldFlipLeft = x > innerWidth * 0.6;\n const labelFitsLeft = x - 10 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('circle')\n .attr('cx', x)\n .attr('cy', y)\n .attr('r', 5)\n .attr('fill', laneColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', flipLeft ? x - 10 : x + 10)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .text(ev.label);\n }\n });\n\n curY += laneSpan + GROUP_GAP;\n }\n } else {\n // === TIME SORT, horizontal: each event on its own row ===\n const sorted = timelineEvents\n .slice()\n .sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));\n\n const scaleMargin = timelineScale ? 24 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n const margin = {\n top: 104 + (timelineScale ? 40 : 0) + markerMargin,\n right: 40,\n bottom: 40 + scaleMargin,\n left: 60,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const rowH = Math.min(28, innerHeight / sorted.length);\n\n const xScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerWidth]);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n xScale,\n false,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n xScale,\n false,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n xScale,\n false,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n // Group legend at top-left\n if (timelineGroups.length > 0) {\n let legendX = 0;\n const legendY = timelineScale ? -75 : -55;\n for (const grp of timelineGroups) {\n const color = groupColorMap.get(grp.name) ?? textColor;\n const itemG = g\n .append('g')\n .attr('class', 'tl-legend-item')\n .attr('data-group', grp.name)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, grp.name))\n .on('mouseleave', () => fadeReset(g));\n\n itemG\n .append('circle')\n .attr('cx', legendX)\n .attr('cy', legendY)\n .attr('r', 5)\n .attr('fill', color);\n\n itemG\n .append('text')\n .attr('x', legendX + 10)\n .attr('y', legendY)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(grp.name);\n\n legendX += grp.name.length * 7 + 30;\n }\n }\n\n sorted.forEach((ev, i) => {\n // Offset events below marker area when markers are present\n const y = markerMargin + i * rowH + rowH / 2;\n const x = xScale(parseTimelineDate(ev.date));\n const color = eventColor(ev);\n\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', ev.group || '')\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);\n if (timelineScale) {\n showEventDatesOnScale(\n g,\n xScale,\n ev.date,\n ev.endDate,\n innerHeight,\n color\n );\n } else {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('mouseleave', function () {\n fadeReset(g);\n if (timelineScale) {\n hideEventDatesOnScale(g);\n } else {\n hideTooltip(tooltip);\n }\n })\n .on('mousemove', function (event: MouseEvent) {\n if (!timelineScale) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const x2 = xScale(parseTimelineDate(ev.endDate));\n const rectW = Math.max(x2 - x, 4);\n // Estimate label width (~7px per char at 13px font) + padding\n const estLabelWidth = ev.label.length * 7 + 16;\n const labelFitsInside = rectW >= estLabelWidth;\n\n let fill: string = color;\n if (ev.uncertain) {\n // Create gradient for uncertain end - fades last 20%\n const gradientId = `uncertain-ts-${ev.lineNumber}`;\n const defs = svg.select('defs').node() || svg.append('defs').node();\n d3Selection\n .select(defs as Element)\n .append('linearGradient')\n .attr('id', gradientId)\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n .selectAll('stop')\n .data([\n { offset: '0%', opacity: 1 },\n { offset: '80%', opacity: 1 },\n { offset: '100%', opacity: 0 },\n ])\n .enter()\n .append('stop')\n .attr('offset', (d) => d.offset)\n .attr('stop-color', color)\n .attr('stop-opacity', (d) => d.opacity);\n fill = `url(#${gradientId})`;\n }\n\n evG\n .append('rect')\n .attr('x', x)\n .attr('y', y - BAR_H / 2)\n .attr('width', rectW)\n .attr('height', BAR_H)\n .attr('rx', 4)\n .attr('fill', fill);\n\n if (labelFitsInside) {\n // Text inside bar - always white for readability\n evG\n .append('text')\n .attr('x', x + 8)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', '#ffffff')\n .attr('font-size', '14px')\n .attr('font-weight', '700')\n .text(ev.label);\n } else {\n // Text outside bar - check if it fits on left or must go right\n const wouldFlipLeft = x + rectW > innerWidth * 0.6;\n const labelFitsLeft = x - 6 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('text')\n .attr('x', flipLeft ? x - 6 : x + rectW + 6)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '13px')\n .text(ev.label);\n }\n } else {\n // Point event (no end date) - render as circle with label\n const estLabelWidth = ev.label.length * 7;\n // Only flip left if past 60% AND label fits without going off-chart\n const wouldFlipLeft = x > innerWidth * 0.6;\n const labelFitsLeft = x - 10 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('circle')\n .attr('cx', x)\n .attr('cy', y)\n .attr('r', 5)\n .attr('fill', color)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', flipLeft ? x - 10 : x + 10)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .text(ev.label);\n }\n });\n }\n}\n\n// ============================================================\n// Word Cloud Helpers\n// ============================================================\n\nfunction getRotateFn(mode: WordCloudRotate): () => number {\n if (mode === 'mixed') return () => (Math.random() > 0.5 ? 0 : 90);\n if (mode === 'angled') return () => Math.round(Math.random() * 30 - 15);\n return () => 0;\n}\n\n// ============================================================\n// Word Cloud Renderer\n// ============================================================\n\n/**\n * Renders a word cloud into the given container using d3-cloud.\n */\nexport function renderWordCloud(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n _isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { words, title, cloudOptions } = parsed;\n if (words.length === 0) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = title ? 40 : 0;\n const cloudHeight = height - titleHeight;\n\n const textColor = palette.text;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n const { minSize, maxSize } = cloudOptions;\n const weights = words.map((w) => w.weight);\n const minWeight = Math.min(...weights);\n const maxWeight = Math.max(...weights);\n const range = maxWeight - minWeight || 1;\n\n const fontSize = (weight: number): number => {\n const t = (weight - minWeight) / range;\n return minSize + t * (maxSize - minSize);\n };\n\n const rotateFn = getRotateFn(cloudOptions.rotate);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n const g = svg\n .append('g')\n .attr(\n 'transform',\n `translate(${width / 2},${titleHeight + cloudHeight / 2})`\n );\n\n cloud<WordCloudWord & cloud.Word>()\n .size([width, cloudHeight])\n .words(words.map((w) => ({ ...w, size: fontSize(w.weight) })))\n .padding(4)\n .rotate(rotateFn)\n .fontSize((d) => d.size!)\n .font(FONT_FAMILY)\n .on('end', (layoutWords) => {\n g.selectAll('text')\n .data(layoutWords)\n .join('text')\n .style('font-size', (d) => `${d.size}px`)\n .style('font-family', FONT_FAMILY)\n .style('font-weight', '600')\n .style('fill', (_d, i) => colors[i % colors.length])\n .style('cursor', (d) =>\n onClickItem && (d as WordCloudWord).lineNumber ? 'pointer' : 'default'\n )\n .attr('text-anchor', 'middle')\n .attr(\n 'transform',\n (d) => `translate(${d.x},${d.y}) rotate(${d.rotate})`\n )\n .attr('data-line-number', (d) => {\n const ln = (d as WordCloudWord).lineNumber;\n return ln ? String(ln) : null;\n })\n .text((d) => d.text!)\n .on('click', (_event, d) => {\n const ln = (d as WordCloudWord).lineNumber;\n if (onClickItem && ln) onClickItem(ln);\n });\n })\n .start();\n}\n\n// ============================================================\n// Word Cloud Renderer (for export — returns Promise)\n// ============================================================\n\nfunction renderWordCloudAsync(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n _isDark: boolean,\n exportDims?: D3ExportDimensions\n): Promise<void> {\n return new Promise((resolve) => {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { words, title, cloudOptions } = parsed;\n if (words.length === 0) {\n resolve();\n return;\n }\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) {\n resolve();\n return;\n }\n\n const titleHeight = title ? 40 : 0;\n const cloudHeight = height - titleHeight;\n\n const textColor = palette.text;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n const { minSize, maxSize } = cloudOptions;\n const weights = words.map((w) => w.weight);\n const minWeight = Math.min(...weights);\n const maxWeight = Math.max(...weights);\n const range = maxWeight - minWeight || 1;\n\n const fontSize = (weight: number): number => {\n const t = (weight - minWeight) / range;\n return minSize + t * (maxSize - minSize);\n };\n\n const rotateFn = getRotateFn(cloudOptions.rotate);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n }\n }\n\n const g = svg\n .append('g')\n .attr(\n 'transform',\n `translate(${width / 2},${titleHeight + cloudHeight / 2})`\n );\n\n cloud<WordCloudWord & cloud.Word>()\n .size([width, cloudHeight])\n .words(words.map((w) => ({ ...w, size: fontSize(w.weight) })))\n .padding(4)\n .rotate(rotateFn)\n .fontSize((d) => d.size!)\n .font(FONT_FAMILY)\n .on('end', (layoutWords) => {\n g.selectAll('text')\n .data(layoutWords)\n .join('text')\n .style('font-size', (d) => `${d.size}px`)\n .style('font-family', FONT_FAMILY)\n .style('font-weight', '600')\n .style('fill', (_d, i) => colors[i % colors.length])\n .attr('text-anchor', 'middle')\n .attr(\n 'transform',\n (d) => `translate(${d.x},${d.y}) rotate(${d.rotate})`\n )\n .text((d) => d.text!);\n resolve();\n })\n .start();\n });\n}\n\n// ============================================================\n// Venn Diagram Math Helpers\n// ============================================================\n\nfunction radiusFromArea(area: number): number {\n return Math.sqrt(area / Math.PI);\n}\n\nfunction circleOverlapArea(r1: number, r2: number, d: number): number {\n // No overlap\n if (d >= r1 + r2) return 0;\n // Full containment\n if (d + Math.min(r1, r2) <= Math.max(r1, r2)) {\n return Math.PI * Math.min(r1, r2) ** 2;\n }\n const part1 = r1 * r1 * Math.acos((d * d + r1 * r1 - r2 * r2) / (2 * d * r1));\n const part2 = r2 * r2 * Math.acos((d * d + r2 * r2 - r1 * r1) / (2 * d * r2));\n const part3 =\n 0.5 *\n Math.sqrt((-d + r1 + r2) * (d + r1 - r2) * (d - r1 + r2) * (d + r1 + r2));\n return part1 + part2 - part3;\n}\n\nfunction distanceForOverlap(\n r1: number,\n r2: number,\n targetArea: number\n): number {\n if (targetArea <= 0) return r1 + r2;\n const minR = Math.min(r1, r2);\n if (targetArea >= Math.PI * minR * minR) return Math.abs(r1 - r2);\n let lo = Math.abs(r1 - r2);\n let hi = r1 + r2;\n for (let i = 0; i < 64; i++) {\n const mid = (lo + hi) / 2;\n if (circleOverlapArea(r1, r2, mid) > targetArea) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n return (lo + hi) / 2;\n}\n\ninterface Point {\n x: number;\n y: number;\n}\n\ninterface Circle {\n x: number;\n y: number;\n r: number;\n}\n\nfunction thirdCirclePosition(\n ax: number,\n ay: number,\n dAC: number,\n bx: number,\n by: number,\n dBC: number\n): Point {\n const dx = bx - ax;\n const dy = by - ay;\n const dAB = Math.sqrt(dx * dx + dy * dy);\n if (dAB === 0) return { x: ax + dAC, y: ay };\n const cosA = (dAB * dAB + dAC * dAC - dBC * dBC) / (2 * dAB * dAC);\n const sinA = Math.sqrt(Math.max(0, 1 - cosA * cosA));\n const ux = dx / dAB;\n const uy = dy / dAB;\n // Place C above the AB line\n return {\n x: ax + dAC * (cosA * ux - sinA * uy),\n y: ay + dAC * (cosA * uy + sinA * ux),\n };\n}\n\nfunction fitCirclesToContainerAsymmetric(\n circles: Circle[],\n w: number,\n h: number,\n mLeft: number,\n mRight: number,\n mTop: number,\n mBottom: number\n): Circle[] {\n if (circles.length === 0) return [];\n let minX = Infinity,\n maxX = -Infinity,\n minY = Infinity,\n maxY = -Infinity;\n for (const c of circles) {\n minX = Math.min(minX, c.x - c.r);\n maxX = Math.max(maxX, c.x + c.r);\n minY = Math.min(minY, c.y - c.r);\n maxY = Math.max(maxY, c.y + c.r);\n }\n const bw = maxX - minX;\n const bh = maxY - minY;\n const availW = w - mLeft - mRight;\n const availH = h - mTop - mBottom;\n const scale = Math.min(availW / bw, availH / bh);\n const cx = (minX + maxX) / 2;\n const cy = (minY + maxY) / 2;\n const tx = mLeft + availW / 2;\n const ty = mTop + availH / 2;\n return circles.map((c) => ({\n x: (c.x - cx) * scale + tx,\n y: (c.y - cy) * scale + ty,\n r: c.r * scale,\n }));\n}\n\nfunction pointInCircle(p: Point, c: Circle): boolean {\n const dx = p.x - c.x;\n const dy = p.y - c.y;\n return dx * dx + dy * dy <= c.r * c.r + 1e-6;\n}\n\nfunction regionCentroid(circles: Circle[], inside: boolean[]): Point {\n // Deterministic 50×50 grid scan instead of random sampling\n const GRID = 50;\n let minX = Infinity,\n maxX = -Infinity,\n minY = Infinity,\n maxY = -Infinity;\n for (const c of circles) {\n minX = Math.min(minX, c.x - c.r);\n maxX = Math.max(maxX, c.x + c.r);\n minY = Math.min(minY, c.y - c.r);\n maxY = Math.max(maxY, c.y + c.r);\n }\n const stepX = (maxX - minX) / GRID;\n const stepY = (maxY - minY) / GRID;\n let sx = 0,\n sy = 0,\n count = 0;\n for (let gi = 0; gi <= GRID; gi++) {\n const x = minX + gi * stepX;\n for (let gj = 0; gj <= GRID; gj++) {\n const y = minY + gj * stepY;\n let match = true;\n for (let j = 0; j < circles.length; j++) {\n const isIn = pointInCircle({ x, y }, circles[j]);\n if (isIn !== inside[j]) {\n match = false;\n break;\n }\n }\n if (match) {\n sx += x;\n sy += y;\n count++;\n }\n }\n }\n if (count === 0) {\n // Fallback: centroid of the circles that should be \"inside\"\n let fx = 0,\n fy = 0,\n fc = 0;\n for (let j = 0; j < circles.length; j++) {\n if (inside[j]) {\n fx += circles[j].x;\n fy += circles[j].y;\n fc++;\n }\n }\n return { x: fx / (fc || 1), y: fy / (fc || 1) };\n }\n return { x: sx / count, y: sy / count };\n}\n\n// ============================================================\n// Venn Diagram Renderer\n// ============================================================\n\nexport function renderVenn(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { vennSets, vennOverlaps, vennShowValues, title } = parsed;\n if (vennSets.length < 2) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const textColor = palette.text;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n const titleHeight = title ? 40 : 0;\n\n // Compute radii\n const radii = vennSets.map((s) => radiusFromArea(s.size));\n\n // Build overlap map keyed by sorted set names\n const overlapMap = new Map<string, number>();\n for (const ov of vennOverlaps) {\n overlapMap.set(ov.sets.join('&'), ov.size);\n }\n\n // Layout circles\n let rawCircles: Circle[];\n const n = vennSets.length;\n\n if (n === 2) {\n const d = distanceForOverlap(\n radii[0],\n radii[1],\n overlapMap.get([vennSets[0].name, vennSets[1].name].sort().join('&')) ?? 0\n );\n rawCircles = [\n { x: -d / 2, y: 0, r: radii[0] },\n { x: d / 2, y: 0, r: radii[1] },\n ];\n } else {\n // 3 sets: place A and B, then compute C position\n const names = vennSets.map((s) => s.name);\n const pairKey = (i: number, j: number) =>\n [names[i], names[j]].sort().join('&');\n\n const dAB = distanceForOverlap(\n radii[0],\n radii[1],\n overlapMap.get(pairKey(0, 1)) ?? 0\n );\n const dAC = distanceForOverlap(\n radii[0],\n radii[2],\n overlapMap.get(pairKey(0, 2)) ?? 0\n );\n const dBC = distanceForOverlap(\n radii[1],\n radii[2],\n overlapMap.get(pairKey(1, 2)) ?? 0\n );\n\n const ax = -dAB / 2;\n const bx = dAB / 2;\n const cPos = thirdCirclePosition(ax, 0, dAC, bx, 0, dBC);\n\n rawCircles = [\n { x: ax, y: 0, r: radii[0] },\n { x: bx, y: 0, r: radii[1] },\n { x: cPos.x, y: cPos.y, r: radii[2] },\n ];\n }\n\n // Resolve colors for each set\n const setColors = vennSets.map(\n (s, i) => s.color ?? colors[i % colors.length]\n );\n\n // ── Layout-aware centering with label space ──\n // Estimate per-side label widths and compute asymmetric margins\n const clusterCx = rawCircles.reduce((s, c) => s + c.x, 0) / n;\n const clusterCy = rawCircles.reduce((s, c) => s + c.y, 0) / n;\n\n // Estimate which side each set label falls on\n let marginLeft = 30,\n marginRight = 30,\n marginTop = 30,\n marginBottom = 30;\n const stubLen = 20;\n const edgePad = 8;\n const labelTextPad = 4;\n\n for (let i = 0; i < n; i++) {\n const displayName = vennSets[i].label ?? vennSets[i].name;\n const estimatedWidth = displayName.length * 8.5 + stubLen + edgePad + labelTextPad;\n const dx = rawCircles[i].x - clusterCx;\n const dy = rawCircles[i].y - clusterCy;\n\n if (Math.abs(dx) >= Math.abs(dy)) {\n // Label exits left or right\n if (dx >= 0) marginRight = Math.max(marginRight, estimatedWidth);\n else marginLeft = Math.max(marginLeft, estimatedWidth);\n } else {\n // Label exits top or bottom\n const halfEstimate = estimatedWidth * 0.5;\n if (dy >= 0) marginBottom = Math.max(marginBottom, halfEstimate + 20);\n else marginTop = Math.max(marginTop, halfEstimate + 20);\n }\n }\n\n const drawH = height - titleHeight;\n const circles = fitCirclesToContainerAsymmetric(\n rawCircles,\n width,\n drawH,\n marginLeft,\n marginRight,\n marginTop,\n marginBottom\n ).map((c) => ({ ...c, y: c.y + titleHeight }));\n\n // SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n // Tooltip\n const tooltip = createTooltip(container, palette, isDark);\n\n // Title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // ── Semi-transparent filled circles ──\n const circleEls: d3Selection.Selection<SVGCircleElement, unknown, null, undefined>[] = [];\n const circleGroup = svg.append('g');\n circles.forEach((c, i) => {\n const el = circleGroup\n .append('circle')\n .attr('cx', c.x)\n .attr('cy', c.y)\n .attr('r', c.r)\n .attr('fill', setColors[i])\n .attr('fill-opacity', 0.35)\n .attr('stroke', setColors[i])\n .attr('stroke-width', 2)\n .style('pointer-events', 'none') as d3Selection.Selection<\n SVGCircleElement,\n unknown,\n null,\n undefined\n >;\n circleEls.push(el);\n });\n\n // ── Labels ──\n // Global center of all circles (for projecting outward)\n const gcx = circles.reduce((s, c) => s + c.x, 0) / n;\n const gcy = circles.reduce((s, c) => s + c.y, 0) / n;\n\n // Helper: ray-circle exit distance (positive = forward along direction)\n function rayCircleExit(\n ox: number,\n oy: number,\n dx: number,\n dy: number,\n c: Circle\n ): number {\n const lx = ox - c.x;\n const ly = oy - c.y;\n const b = lx * dx + ly * dy;\n const det = b * b - (lx * lx + ly * ly - c.r * c.r);\n if (det < 0) return 0;\n return -b + Math.sqrt(det);\n }\n\n const labelGroup = svg.append('g').style('pointer-events', 'none');\n\n // ── Set name labels (inside exclusive region if they fit, else external leader line) ──\n // Helper: measure horizontal clearance at a point inside circle i but outside others\n function exclusiveHSpan(px: number, py: number, ci: number): number {\n // Start with full chord width of circle i at height py\n const dy = py - circles[ci].y;\n const halfChord = Math.sqrt(Math.max(0, circles[ci].r * circles[ci].r - dy * dy));\n let left = circles[ci].x - halfChord;\n let right = circles[ci].x + halfChord;\n // Subtract any overlapping circle chord that covers this y\n for (let j = 0; j < n; j++) {\n if (j === ci) continue;\n const djy = py - circles[j].y;\n if (Math.abs(djy) >= circles[j].r) continue; // circle j doesn't reach this y\n const hc = Math.sqrt(circles[j].r * circles[j].r - djy * djy);\n const jLeft = circles[j].x - hc;\n const jRight = circles[j].x + hc;\n // Clamp our span to exclude the overlap with circle j\n if (jLeft <= left && jRight >= right) return 0; // fully covered\n if (jLeft <= left && jRight > left) left = jRight;\n if (jRight >= right && jLeft < right) right = jLeft;\n }\n return Math.max(0, right - left);\n }\n\n // Font size scaling: 0.6 ch-width per character at a given font size\n const CH_RATIO = 0.6;\n const MIN_FONT = 10;\n const MAX_FONT = 22;\n const INTERNAL_PAD = 12;\n\n circles.forEach((c, i) => {\n const text = vennSets[i].label ?? vennSets[i].name;\n\n // Compute exclusive region centroid\n const inside = circles.map((_, j) => j === i);\n const centroid = regionCentroid(circles, inside);\n\n // Available width at centroid\n const availW = exclusiveHSpan(centroid.x, centroid.y, i);\n // Font size that makes text fill ~80% of available width\n const fitFont = Math.min(MAX_FONT, Math.max(MIN_FONT,\n (availW - INTERNAL_PAD * 2) / (text.length * CH_RATIO)));\n const estTextW = text.length * CH_RATIO * fitFont;\n\n const fitsInside = estTextW + INTERNAL_PAD * 2 < availW &&\n pointInCircle({ x: centroid.x, y: centroid.y - fitFont / 2 }, c) &&\n pointInCircle({ x: centroid.x, y: centroid.y + fitFont / 2 }, c);\n\n if (fitsInside) {\n labelGroup\n .append('text')\n .attr('x', centroid.x)\n .attr('y', centroid.y)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', textColor)\n .attr('font-size', `${Math.round(fitFont)}px`)\n .attr('font-weight', 'bold')\n .text(text);\n } else {\n // External label with leader line\n let dx = c.x - gcx;\n let dy = c.y - gcy;\n const mag = Math.sqrt(dx * dx + dy * dy);\n if (mag < 1e-6) {\n dx = 1;\n dy = 0;\n } else {\n dx /= mag;\n dy /= mag;\n }\n\n const exitX = c.x + dx * c.r;\n const exitY = c.y + dy * c.r;\n const edgeX = exitX + dx * edgePad;\n const edgeY = exitY + dy * edgePad;\n const stubEndX = edgeX + dx * stubLen;\n const stubEndY = edgeY + dy * stubLen;\n\n labelGroup\n .append('line')\n .attr('x1', edgeX)\n .attr('y1', edgeY)\n .attr('x2', stubEndX)\n .attr('y2', stubEndY)\n .attr('stroke', textColor)\n .attr('stroke-width', 1);\n\n const isRight = stubEndX >= gcx;\n const textAnchor = isRight ? 'start' : 'end';\n let textX = stubEndX + (isRight ? labelTextPad : -labelTextPad);\n const textY = stubEndY;\n\n const estW = text.length * 8.5;\n if (isRight) {\n textX = Math.min(textX, width - estW - 4);\n } else {\n textX = Math.max(textX, estW + 4);\n }\n\n labelGroup\n .append('text')\n .attr('x', textX)\n .attr('y', Math.max(14, Math.min(height - 4, textY)))\n .attr('text-anchor', textAnchor)\n .attr('dominant-baseline', 'central')\n .attr('fill', textColor)\n .attr('font-size', '14px')\n .attr('font-weight', 'bold')\n .text(text);\n }\n });\n\n // ── Overlap labels (inline at region centroid, scaled to fit) ──\n // Helper: horizontal span at y inside all circles in idxs, outside others\n function overlapHSpan(py: number, idxs: number[]): number {\n let left = -Infinity, right = Infinity;\n // Intersect chords of all \"inside\" circles\n for (const ci of idxs) {\n const dy = py - circles[ci].y;\n if (Math.abs(dy) >= circles[ci].r) return 0;\n const hc = Math.sqrt(circles[ci].r * circles[ci].r - dy * dy);\n left = Math.max(left, circles[ci].x - hc);\n right = Math.min(right, circles[ci].x + hc);\n }\n if (left >= right) return 0;\n // Subtract any \"outside\" circle that intrudes\n for (let j = 0; j < n; j++) {\n if (idxs.includes(j)) continue;\n const dy = py - circles[j].y;\n if (Math.abs(dy) >= circles[j].r) continue;\n const hc = Math.sqrt(circles[j].r * circles[j].r - dy * dy);\n const jLeft = circles[j].x - hc;\n const jRight = circles[j].x + hc;\n if (jLeft <= left && jRight >= right) return 0;\n if (jLeft <= left && jRight > left) left = jRight;\n if (jRight >= right && jLeft < right) right = jLeft;\n }\n return Math.max(0, right - left);\n }\n\n for (const ov of vennOverlaps) {\n const idxs = ov.sets.map((s) => vennSets.findIndex((vs) => vs.name === s));\n if (idxs.some((idx) => idx < 0)) continue;\n if (!ov.label) continue;\n\n const inside = circles.map((_, j) => idxs.includes(j));\n const centroid = regionCentroid(circles, inside);\n const text = ov.label;\n\n const availW = overlapHSpan(centroid.y, idxs);\n const fitFont = Math.min(MAX_FONT, Math.max(MIN_FONT,\n (availW - INTERNAL_PAD * 2) / (text.length * CH_RATIO)));\n\n labelGroup\n .append('text')\n .attr('x', centroid.x)\n .attr('y', centroid.y)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', textColor)\n .attr('font-size', `${Math.round(fitFont)}px`)\n .attr('font-weight', '600')\n .text(text);\n }\n\n // ── Invisible hover targets (full circles) + interactions ──\n const hoverGroup = svg.append('g');\n circles.forEach((c, i) => {\n const tipName = vennSets[i].label\n ? `${vennSets[i].label} (${vennSets[i].name})`\n : vennSets[i].name;\n const tipHtml = `<strong>${tipName}</strong><br>Size: ${vennSets[i].size}`;\n\n hoverGroup\n .append('circle')\n .attr('cx', c.x)\n .attr('cy', c.y)\n .attr('r', c.r)\n .attr('fill', 'transparent')\n .attr('data-line-number', String(vennSets[i].lineNumber))\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) => {\n circleEls.forEach((el, ci) => {\n el.attr('fill-opacity', ci === i ? 0.5 : 0.1);\n });\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mousemove', (event: MouseEvent) => {\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mouseleave', () => {\n circleEls.forEach((el) => {\n el.attr('fill-opacity', 0.35);\n });\n hideTooltip(tooltip);\n })\n .on('click', () => {\n if (onClickItem && vennSets[i].lineNumber)\n onClickItem(vennSets[i].lineNumber);\n });\n });\n}\n\n// ============================================================\n// Quadrant Chart Renderer\n// ============================================================\n\ntype QuadrantPosition =\n | 'top-right'\n | 'top-left'\n | 'bottom-left'\n | 'bottom-right';\n\n/**\n * Renders a quadrant chart using D3.\n * Displays 4 colored quadrant regions, axis labels, quadrant labels, and data points.\n */\nexport function renderQuadrant(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const {\n title,\n quadrantLabels,\n quadrantPoints,\n quadrantXAxis,\n quadrantYAxis,\n quadrantTitleLineNumber,\n quadrantXAxisLineNumber,\n quadrantYAxisLineNumber,\n } = parsed;\n\n if (quadrantPoints.length === 0) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const textColor = palette.text;\n const mutedColor = palette.textMuted;\n const bgColor = palette.bg;\n const borderColor = palette.border;\n\n // Default quadrant colors with alpha\n const defaultColors = [\n palette.colors.blue,\n palette.colors.green,\n palette.colors.yellow,\n palette.colors.purple,\n ];\n\n // Margins\n const hasXAxis = !!quadrantXAxis;\n const hasYAxis = !!quadrantYAxis;\n const margin = { top: title ? 60 : 30, right: 30, bottom: hasXAxis ? 70 : 40, left: hasYAxis ? 80 : 40 };\n const chartWidth = width - margin.left - margin.right;\n const chartHeight = height - margin.top - margin.bottom;\n\n // Scales: data uses 0-1 range\n const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);\n const yScale = d3Scale.scaleLinear().domain([0, 1]).range([chartHeight, 0]);\n\n // Create SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n // Tooltip\n const tooltip = createTooltip(container, palette, isDark);\n\n // Title\n if (title) {\n const titleText = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style(\n 'cursor',\n onClickItem && quadrantTitleLineNumber ? 'pointer' : 'default'\n )\n .text(title);\n\n if (quadrantTitleLineNumber) {\n titleText.attr('data-line-number', quadrantTitleLineNumber);\n }\n\n if (onClickItem && quadrantTitleLineNumber) {\n titleText\n .on('click', () => onClickItem(quadrantTitleLineNumber))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n }\n }\n\n // Chart group (translated by margins)\n const chartG = svg\n .append('g')\n .attr('transform', `translate(${margin.left}, ${margin.top})`);\n\n // Mix two hex colors: pct=100 → all `a`, pct=0 → all `b`\n const mixHex = (a: string, b: string, pct: number): string => {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n };\n\n // Opaque quadrant fills using the assigned color directly\n const getQuadrantFill = (\n label: QuadrantLabel | null,\n defaultIdx: number\n ): string => {\n return label?.color ?? defaultColors[defaultIdx % defaultColors.length];\n };\n\n // Quadrant definitions: position, rect bounds, label position\n const quadrantDefs: {\n position: QuadrantPosition;\n x: number;\n y: number;\n w: number;\n h: number;\n labelX: number;\n labelY: number;\n label: QuadrantLabel | null;\n colorIdx: number;\n }[] = [\n {\n position: 'top-left',\n x: 0,\n y: 0,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: chartWidth / 4,\n labelY: chartHeight / 4,\n label: quadrantLabels.topLeft,\n colorIdx: 1, // green\n },\n {\n position: 'top-right',\n x: chartWidth / 2,\n y: 0,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: (chartWidth * 3) / 4,\n labelY: chartHeight / 4,\n label: quadrantLabels.topRight,\n colorIdx: 0, // blue\n },\n {\n position: 'bottom-left',\n x: 0,\n y: chartHeight / 2,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: chartWidth / 4,\n labelY: (chartHeight * 3) / 4,\n label: quadrantLabels.bottomLeft,\n colorIdx: 2, // yellow\n },\n {\n position: 'bottom-right',\n x: chartWidth / 2,\n y: chartHeight / 2,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: (chartWidth * 3) / 4,\n labelY: (chartHeight * 3) / 4,\n label: quadrantLabels.bottomRight,\n colorIdx: 3, // purple\n },\n ];\n\n // Draw quadrant rectangles\n const quadrantRects = chartG\n .selectAll('rect.quadrant')\n .data(quadrantDefs)\n .enter()\n .append('rect')\n .attr('class', 'quadrant')\n .attr('x', (d) => d.x)\n .attr('y', (d) => d.y)\n .attr('width', (d) => d.w)\n .attr('height', (d) => d.h)\n .attr('fill', (d) => getQuadrantFill(d.label, d.colorIdx))\n .attr('stroke', borderColor)\n .attr('stroke-width', 0.5);\n\n // White text for points; quadrant labels use a darkened shade of their fill\n const contrastColor = '#ffffff';\n const shadowColor = 'rgba(0,0,0,0.4)';\n\n // Darken the quadrant fill to create a watermark-style label color\n const getQuadrantLabelColor = (d: (typeof quadrantDefs)[number]): string => {\n const fill = getQuadrantFill(d.label, d.colorIdx);\n return mixHex('#000000', fill, 40);\n };\n\n // Scale label font size to fit within quadrant bounds, wrapping into multiple lines if needed\n const LABEL_MAX_FONT = 48;\n const LABEL_MIN_FONT = 14;\n const LABEL_PAD = 40;\n const CHAR_WIDTH_RATIO = 0.6;\n\n const estTextWidth = (text: string, fontSize: number): number =>\n text.length * fontSize * CHAR_WIDTH_RATIO;\n\n interface QuadrantLabelLayout {\n lines: string[];\n fontSize: number;\n }\n\n const quadrantLabelLayout = (text: string, qw: number, qh: number): QuadrantLabelLayout => {\n const availW = qw - LABEL_PAD;\n const availH = qh - LABEL_PAD;\n const words = text.split(/\\s+/);\n\n // Try single line first\n if (estTextWidth(text, LABEL_MAX_FONT) <= availW) {\n const fs = Math.min(LABEL_MAX_FONT, availH);\n return { lines: [text], fontSize: Math.max(LABEL_MIN_FONT, Math.round(fs)) };\n }\n\n // Try wrapping into 2+ lines: greedily pack words so each line fits availW\n const wrapLines = (fs: number): string[] => {\n const result: string[] = [];\n let cur = '';\n for (const w of words) {\n const trial = cur ? `${cur} ${w}` : w;\n if (estTextWidth(trial, fs) > availW && cur) {\n result.push(cur);\n cur = w;\n } else {\n cur = trial;\n }\n }\n if (cur) result.push(cur);\n return result;\n };\n\n // Binary-search for largest font size where wrapped text fits both width and height\n let lo = LABEL_MIN_FONT;\n let hi = LABEL_MAX_FONT;\n let bestLines = wrapLines(lo);\n let bestFs = lo;\n while (lo <= hi) {\n const mid = Math.round((lo + hi) / 2);\n const lines = wrapLines(mid);\n const totalH = lines.length * mid * 1.2; // line height ~1.2em\n const maxLineW = Math.max(...lines.map((l) => estTextWidth(l, mid)));\n if (maxLineW <= availW && totalH <= availH) {\n bestFs = mid;\n bestLines = lines;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return { lines: bestLines, fontSize: Math.max(LABEL_MIN_FONT, bestFs) };\n };\n\n // Draw quadrant labels (large, centered, darkened shade of fill — recedes behind points)\n // Pre-compute layout (lines + font size) for each quadrant label\n const qw = chartWidth / 2;\n const qh = chartHeight / 2;\n const quadrantDefsWithLabel = quadrantDefs.filter((d) => d.label !== null);\n const labelLayouts = new Map(\n quadrantDefsWithLabel.map((d) => [d.label!.text, quadrantLabelLayout(d.label!.text, qw, qh)])\n );\n\n const quadrantLabelTexts = chartG\n .selectAll('text.quadrant-label')\n .data(quadrantDefsWithLabel)\n .enter()\n .append('text')\n .attr('class', 'quadrant-label')\n .attr('x', (d) => d.labelX)\n .attr('y', (d) => d.labelY)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', (d) => getQuadrantLabelColor(d))\n .attr('font-size', (d) => `${labelLayouts.get(d.label!.text)!.fontSize}px`)\n .attr('font-weight', '700')\n .attr('data-line-number', (d) =>\n d.label?.lineNumber ? String(d.label.lineNumber) : null\n )\n .style('cursor', (d) =>\n onClickItem && d.label?.lineNumber ? 'pointer' : 'default'\n )\n .each(function (d) {\n const layout = labelLayouts.get(d.label!.text)!;\n const el = d3Selection.select(this);\n if (layout.lines.length === 1) {\n el.text(layout.lines[0]);\n } else {\n // Multi-line: use tspan elements, offset from center\n const lineH = layout.fontSize * 1.2;\n const totalH = layout.lines.length * lineH;\n const startY = -totalH / 2 + lineH / 2;\n layout.lines.forEach((line, i) => {\n el.append('tspan')\n .attr('x', d.labelX)\n .attr('dy', i === 0 ? `${startY}px` : `${lineH}px`)\n .text(line);\n });\n }\n });\n\n if (onClickItem) {\n quadrantLabelTexts\n .on('click', (_, d) => {\n if (d.label?.lineNumber) onClickItem(d.label.lineNumber);\n })\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n }\n\n // X-axis labels — centered on left/right halves\n if (quadrantXAxis) {\n // Low label (centered on left half)\n const xLowLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', margin.left + chartWidth / 4)\n .attr('y', height - 20)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('data-line-number', quadrantXAxisLineNumber ? String(quadrantXAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantXAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantXAxis[0]);\n\n // High label (centered on right half)\n const xHighLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', margin.left + (chartWidth * 3) / 4)\n .attr('y', height - 20)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('data-line-number', quadrantXAxisLineNumber ? String(quadrantXAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantXAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantXAxis[1]);\n\n if (onClickItem && quadrantXAxisLineNumber) {\n [xLowLabel, xHighLabel].forEach((label) => {\n label\n .on('click', () => onClickItem(quadrantXAxisLineNumber))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n });\n }\n }\n\n // Y-axis labels — centered on top/bottom halves\n if (quadrantYAxis) {\n const yMidBottom = margin.top + (chartHeight * 3) / 4;\n const yMidTop = margin.top + chartHeight / 4;\n\n // Low label (centered on bottom half)\n const yLowLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', 22)\n .attr('y', yMidBottom)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('transform', `rotate(-90, 22, ${yMidBottom})`)\n .attr('data-line-number', quadrantYAxisLineNumber ? String(quadrantYAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantYAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantYAxis[0]);\n\n // High label (centered on top half)\n const yHighLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', 22)\n .attr('y', yMidTop)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('transform', `rotate(-90, 22, ${yMidTop})`)\n .attr('data-line-number', quadrantYAxisLineNumber ? String(quadrantYAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantYAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantYAxis[1]);\n\n if (onClickItem && quadrantYAxisLineNumber) {\n [yLowLabel, yHighLabel].forEach((label) => {\n label\n .on('click', () => onClickItem(quadrantYAxisLineNumber))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n });\n }\n }\n\n // Draw center cross lines\n chartG\n .append('line')\n .attr('x1', chartWidth / 2)\n .attr('y1', 0)\n .attr('x2', chartWidth / 2)\n .attr('y2', chartHeight)\n .attr('stroke', borderColor)\n .attr('stroke-width', 1);\n\n chartG\n .append('line')\n .attr('x1', 0)\n .attr('y1', chartHeight / 2)\n .attr('x2', chartWidth)\n .attr('y2', chartHeight / 2)\n .attr('stroke', borderColor)\n .attr('stroke-width', 1);\n\n // Get which quadrant a point belongs to\n const getPointQuadrant = (x: number, y: number): QuadrantPosition => {\n if (x >= 0.5 && y >= 0.5) return 'top-right';\n if (x < 0.5 && y >= 0.5) return 'top-left';\n if (x < 0.5 && y < 0.5) return 'bottom-left';\n return 'bottom-right';\n };\n\n // Draw data points (circles and labels)\n const pointsG = chartG.append('g').attr('class', 'points');\n\n quadrantPoints.forEach((point) => {\n const cx = xScale(point.x);\n const cy = yScale(point.y);\n const quadrant = getPointQuadrant(point.x, point.y);\n const quadDef = quadrantDefs.find((d) => d.position === quadrant);\n const pointColor =\n quadDef?.label?.color ?? defaultColors[quadDef?.colorIdx ?? 0];\n\n const pointG = pointsG.append('g').attr('class', 'point-group')\n .attr('data-line-number', String(point.lineNumber));\n\n // Circle with white fill and colored border for visibility on opaque quadrants\n pointG\n .append('circle')\n .attr('cx', cx)\n .attr('cy', cy)\n .attr('r', 6)\n .attr('fill', '#ffffff')\n .attr('stroke', pointColor)\n .attr('stroke-width', 2);\n\n // Label (contrasting color with shadow for readability)\n pointG\n .append('text')\n .attr('x', cx)\n .attr('y', cy - 10)\n .attr('text-anchor', 'middle')\n .attr('fill', contrastColor)\n .attr('font-size', '12px')\n .attr('font-weight', '700')\n .style('text-shadow', `0 1px 2px ${shadowColor}`)\n .text(point.label);\n\n // Interactivity\n const tipHtml = `<strong>${point.label}</strong><br>x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`;\n\n pointG\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) => {\n showTooltip(tooltip, tipHtml, event);\n pointG.select('circle').attr('r', 8);\n })\n .on('mousemove', (event: MouseEvent) => {\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mouseleave', () => {\n hideTooltip(tooltip);\n pointG.select('circle').attr('r', 6);\n })\n .on('click', () => {\n if (onClickItem && point.lineNumber) onClickItem(point.lineNumber);\n });\n });\n\n // Quadrant highlighting on hover and click-to-navigate\n quadrantRects\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', function (_, d) {\n // Dim other quadrants\n quadrantRects.attr('opacity', (qd) =>\n qd.position === d.position ? 1 : 0.3\n );\n quadrantLabelTexts.attr('opacity', (qd) =>\n qd.position === d.position ? 1 : 0.3\n );\n // Dim points not in this quadrant\n pointsG.selectAll('g.point-group').each(function (_, i) {\n const pt = quadrantPoints[i];\n const ptQuad = getPointQuadrant(pt.x, pt.y);\n d3Selection\n .select(this)\n .attr('opacity', ptQuad === d.position ? 1 : 0.2);\n });\n })\n .on('mouseleave', () => {\n quadrantRects.attr('opacity', 1);\n quadrantLabelTexts.attr('opacity', 1);\n pointsG.selectAll('g.point-group').attr('opacity', 1);\n })\n .on('click', (_, d) => {\n // Navigate to the quadrant label's line in the source\n if (onClickItem && d.label?.lineNumber) {\n onClickItem(d.label.lineNumber);\n }\n });\n}\n\n// ============================================================\n// Export Renderer\n// ============================================================\n\nconst EXPORT_WIDTH = 1200;\nconst EXPORT_HEIGHT = 800;\n\n/**\n * Renders a D3 chart to an SVG string for export.\n * Creates a detached DOM element, renders into it, extracts the SVG, then cleans up.\n */\nexport async function renderD3ForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette?: PaletteColors,\n orgExportState?: {\n collapsedNodes?: Set<string>;\n activeTagGroup?: string | null;\n hiddenAttributes?: Set<string>;\n },\n options?: { branding?: boolean }\n): Promise<string> {\n // Flowchart and org chart use their own parser pipelines — intercept before parseD3()\n const { parseDgmoChartType } = await import('./dgmo-router');\n const detectedType = parseDgmoChartType(content);\n\n if (detectedType === 'org') {\n const { parseOrg } = await import('./org/parser');\n const { layoutOrg } = await import('./org/layout');\n const { collapseOrgTree } = await import('./org/collapse');\n const { renderOrg } = await import('./org/renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const orgParsed = parseOrg(content, effectivePalette);\n if (orgParsed.error || orgParsed.roots.length === 0) return '';\n\n // Apply interactive collapse state when provided\n const collapsedNodes = orgExportState?.collapsedNodes;\n const activeTagGroup = orgExportState?.activeTagGroup ?? null;\n const hiddenAttributes = orgExportState?.hiddenAttributes;\n\n const { parsed: effectiveParsed, hiddenCounts } =\n collapsedNodes && collapsedNodes.size > 0\n ? collapseOrgTree(orgParsed, collapsedNodes)\n : { parsed: orgParsed, hiddenCounts: new Map<string, number>() };\n\n const orgLayout = layoutOrg(\n effectiveParsed,\n hiddenCounts.size > 0 ? hiddenCounts : undefined,\n activeTagGroup,\n hiddenAttributes\n );\n\n // Size container to fit the diagram content\n const PADDING = 20;\n const titleOffset = effectiveParsed.title ? 30 : 0;\n const exportWidth = orgLayout.width + PADDING * 2;\n const exportHeight = orgLayout.height + PADDING * 2 + titleOffset;\n\n const container = document.createElement('div');\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderOrg(\n container,\n effectiveParsed,\n orgLayout,\n effectivePalette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight },\n activeTagGroup,\n hiddenAttributes\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n if (detectedType === 'class') {\n const { parseClassDiagram } = await import('./class/parser');\n const { layoutClassDiagram } = await import('./class/layout');\n const { renderClassDiagram } = await import('./class/renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const classParsed = parseClassDiagram(content, effectivePalette);\n if (classParsed.error || classParsed.classes.length === 0) return '';\n\n const classLayout = layoutClassDiagram(classParsed);\n const PADDING = 20;\n const titleOffset = classParsed.title ? 40 : 0;\n const exportWidth = classLayout.width + PADDING * 2;\n const exportHeight = classLayout.height + PADDING * 2 + titleOffset;\n\n const container = document.createElement('div');\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderClassDiagram(\n container,\n classParsed,\n classLayout,\n effectivePalette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n if (detectedType === 'er') {\n const { parseERDiagram } = await import('./er/parser');\n const { layoutERDiagram } = await import('./er/layout');\n const { renderERDiagram } = await import('./er/renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const erParsed = parseERDiagram(content, effectivePalette);\n if (erParsed.error || erParsed.tables.length === 0) return '';\n\n const erLayout = layoutERDiagram(erParsed);\n const PADDING = 20;\n const titleOffset = erParsed.title ? 40 : 0;\n const exportWidth = erLayout.width + PADDING * 2;\n const exportHeight = erLayout.height + PADDING * 2 + titleOffset;\n\n const container = document.createElement('div');\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderERDiagram(\n container,\n erParsed,\n erLayout,\n effectivePalette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n if (detectedType === 'flowchart') {\n const { parseFlowchart } = await import('./graph/flowchart-parser');\n const { layoutGraph } = await import('./graph/layout');\n const { renderFlowchart } = await import('./graph/flowchart-renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const fcParsed = parseFlowchart(content, effectivePalette);\n if (fcParsed.error || fcParsed.nodes.length === 0) return '';\n\n const layout = layoutGraph(fcParsed);\n const container = document.createElement('div');\n container.style.width = `${EXPORT_WIDTH}px`;\n container.style.height = `${EXPORT_HEIGHT}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderFlowchart(container, fcParsed, layout, effectivePalette, isDark, undefined, {\n width: EXPORT_WIDTH,\n height: EXPORT_HEIGHT,\n });\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n const parsed = parseD3(content, palette);\n // Allow sequence diagrams through even if parseD3 errors —\n // sequence is parsed by its own dedicated parser (parseSequenceDgmo)\n // and may not have a \"chart:\" line (auto-detected from arrow syntax).\n if (parsed.error && parsed.type !== 'sequence') {\n // Check if content looks like a sequence diagram (has arrows but no chart: line)\n const looksLikeSequence = /->|~>|<-/.test(content);\n if (!looksLikeSequence) return '';\n parsed.type = 'sequence';\n }\n if (parsed.type === 'wordcloud' && parsed.words.length === 0) return '';\n if (parsed.type === 'slope' && parsed.data.length === 0) return '';\n if (parsed.type === 'arc' && parsed.links.length === 0) return '';\n if (parsed.type === 'timeline' && parsed.timelineEvents.length === 0)\n return '';\n if (parsed.type === 'venn' && parsed.vennSets.length < 2) return '';\n if (parsed.type === 'quadrant' && parsed.quadrantPoints.length === 0)\n return '';\n\n const isDark = theme === 'dark';\n\n // Fall back to Nord palette if none provided\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n // Create a temporary offscreen container\n const container = document.createElement('div');\n container.style.width = `${EXPORT_WIDTH}px`;\n container.style.height = `${EXPORT_HEIGHT}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n const dims: D3ExportDimensions = { width: EXPORT_WIDTH, height: EXPORT_HEIGHT };\n\n try {\n if (parsed.type === 'sequence') {\n const { parseSequenceDgmo } = await import('./sequence/parser');\n const { renderSequenceDiagram } = await import('./sequence/renderer');\n const seqParsed = parseSequenceDgmo(content);\n if (seqParsed.error || seqParsed.participants.length === 0) return '';\n renderSequenceDiagram(container, seqParsed, effectivePalette, isDark, undefined, {\n exportWidth: EXPORT_WIDTH,\n });\n } else if (parsed.type === 'wordcloud') {\n await renderWordCloudAsync(container, parsed, effectivePalette, isDark, dims);\n } else if (parsed.type === 'arc') {\n renderArcDiagram(container, parsed, effectivePalette, isDark, undefined, dims);\n } else if (parsed.type === 'timeline') {\n renderTimeline(container, parsed, effectivePalette, isDark, undefined, dims);\n } else if (parsed.type === 'venn') {\n renderVenn(container, parsed, effectivePalette, isDark, undefined, dims);\n } else if (parsed.type === 'quadrant') {\n renderQuadrant(container, parsed, effectivePalette, isDark, undefined, dims);\n } else {\n renderSlopeChart(container, parsed, effectivePalette, isDark, undefined, dims);\n }\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n // Ensure all chart types have a consistent background\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n // Add xmlns for standalone SVG\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n}\n","import { FONT_FAMILY } from './fonts';\n\nconst BRANDING_HEIGHT = 20;\n\n/**\n * Injects `diagrammo.app` branding text into an SVG string.\n * Extends the SVG height by 20px and places the text at the bottom-right.\n */\nexport function injectBranding(svgHtml: string, mutedColor: string): string {\n if (!svgHtml) return svgHtml;\n\n const brandingText = `<text x=\"0\" y=\"0\" font-size=\"10\" font-family=\"${FONT_FAMILY}\" fill=\"${mutedColor}\" opacity=\"0.5\" text-anchor=\"end\">diagrammo.app</text>`;\n\n // Parse viewBox\n const vbMatch = svgHtml.match(/viewBox=\"([^\"]+)\"/);\n const heightAttrMatch = svgHtml.match(/height=\"([^\"]+)\"/);\n\n if (vbMatch) {\n const parts = vbMatch[1].split(/\\s+/).map(Number);\n if (parts.length === 4) {\n const [vx, vy, vw, vh] = parts;\n const newVh = vh + BRANDING_HEIGHT;\n const textX = vx + vw - 4;\n const textY = vy + vh + BRANDING_HEIGHT - 6;\n const positioned = brandingText.replace('x=\"0\" y=\"0\"', `x=\"${textX}\" y=\"${textY}\"`);\n\n let result = svgHtml.replace(\n /viewBox=\"[^\"]+\"/,\n `viewBox=\"${vx} ${vy} ${vw} ${newVh}\"`\n );\n\n // Update height attribute if present\n if (heightAttrMatch) {\n const oldH = parseFloat(heightAttrMatch[1]);\n if (!isNaN(oldH)) {\n result = result.replace(\n `height=\"${heightAttrMatch[1]}\"`,\n `height=\"${oldH + BRANDING_HEIGHT}\"`\n );\n }\n }\n\n result = result.replace('</svg>', `${positioned}</svg>`);\n return result;\n }\n }\n\n // Fallback: no viewBox, try width/height attributes\n if (heightAttrMatch) {\n const widthMatch = svgHtml.match(/width=\"([^\"]+)\"/);\n const w = widthMatch ? parseFloat(widthMatch[1]) : 800;\n const h = parseFloat(heightAttrMatch[1]);\n if (!isNaN(h) && !isNaN(w)) {\n const textX = w - 4;\n const textY = h + BRANDING_HEIGHT - 6;\n const positioned = brandingText.replace('x=\"0\" y=\"0\"', `x=\"${textX}\" y=\"${textY}\"`);\n let result = svgHtml.replace(\n `height=\"${heightAttrMatch[1]}\"`,\n `height=\"${h + BRANDING_HEIGHT}\"`\n );\n result = result.replace('</svg>', `${positioned}</svg>`);\n return result;\n }\n }\n\n return svgHtml;\n}\n","import * as echarts from 'echarts';\nimport type { EChartsOption } from 'echarts';\nimport { FONT_FAMILY } from './fonts';\nimport { injectBranding } from './branding';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport type EChartsChartType =\n | 'sankey'\n | 'chord'\n | 'function'\n | 'scatter'\n | 'heatmap'\n | 'funnel';\n\nexport interface EChartsDataPoint {\n label: string;\n value: number;\n color?: string;\n lineNumber: number;\n}\n\nexport interface ParsedSankeyLink {\n source: string;\n target: string;\n value: number;\n lineNumber: number;\n}\n\nexport interface ParsedFunction {\n name: string;\n expression: string;\n color?: string;\n lineNumber: number;\n}\n\nexport interface ParsedScatterPoint {\n name: string;\n x: number;\n y: number;\n size?: number;\n color?: string;\n category?: string;\n lineNumber: number;\n}\n\nexport interface ParsedHeatmapRow {\n label: string;\n values: number[];\n lineNumber: number;\n}\n\nexport interface ParsedEChart {\n type: EChartsChartType;\n title?: string;\n titleLineNumber?: number;\n series?: string;\n seriesNames?: string[];\n seriesNameColors?: (string | undefined)[];\n data: EChartsDataPoint[];\n links?: ParsedSankeyLink[];\n functions?: ParsedFunction[];\n scatterPoints?: ParsedScatterPoint[];\n heatmapRows?: ParsedHeatmapRow[];\n columns?: string[];\n rows?: string[];\n xRange?: { min: number; max: number };\n xlabel?: string;\n ylabel?: string;\n sizelabel?: string;\n showLabels?: boolean;\n categoryColors?: Record<string, string>;\n error?: string;\n}\n\n// ============================================================\n// Nord Colors for Charts\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { PaletteColors } from './palettes';\nimport { getSeriesColors, getSegmentColors } from './palettes';\nimport { parseChart } from './chart';\nimport type { ParsedChart } from './chart';\n\n// ============================================================\n// Parser\n// ============================================================\n\n/**\n * Parses the simple echart text format into a structured object.\n *\n * Format:\n * ```\n * chart: bar\n * title: My Chart\n * series: Revenue\n *\n * Jan: 120\n * Feb: 200\n * Mar: 150\n * ```\n */\nexport function parseEChart(\n content: string,\n palette?: PaletteColors\n): ParsedEChart {\n const lines = content.split('\\n');\n const result: ParsedEChart = {\n type: 'scatter',\n data: [],\n };\n\n // Track current category for grouped scatter charts\n let currentCategory = 'Default';\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Check for markdown-style category header: ## Category Name or ## Category Name(color)\n const mdCategoryMatch = trimmed.match(/^#{2,}\\s+(.+)$/);\n if (mdCategoryMatch) {\n let catName = mdCategoryMatch[1].trim();\n const catColorMatch = catName.match(/\\(([^)]+)\\)\\s*$/);\n if (catColorMatch) {\n const resolved = resolveColor(catColorMatch[1].trim(), palette);\n if (!result.categoryColors) result.categoryColors = {};\n catName = catName.substring(0, catColorMatch.index!).trim();\n result.categoryColors[catName] = resolved;\n }\n currentCategory = catName;\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('#') || trimmed.startsWith('//')) continue;\n\n // Check for category header: [Category Name]\n const categoryMatch = trimmed.match(/^\\[(.+)\\]$/);\n if (categoryMatch) {\n currentCategory = categoryMatch[1].trim();\n continue;\n }\n\n // Parse key: value pairs\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = trimmed.substring(0, colonIndex).trim().toLowerCase();\n const value = trimmed.substring(colonIndex + 1).trim();\n\n // Handle metadata\n if (key === 'chart') {\n const chartType = value.toLowerCase();\n if (\n chartType === 'sankey' ||\n chartType === 'chord' ||\n chartType === 'function' ||\n chartType === 'scatter' ||\n chartType === 'heatmap' ||\n chartType === 'funnel'\n ) {\n result.type = chartType;\n } else {\n result.error = `Unsupported chart type: ${value}. Supported types: scatter, sankey, chord, function, heatmap, funnel.`;\n return result;\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'series') {\n result.series = value;\n const rawNames = value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const names: string[] = [];\n const nameColors: (string | undefined)[] = [];\n for (const raw of rawNames) {\n const colorMatch = raw.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n nameColors.push(resolveColor(colorMatch[1].trim(), palette));\n names.push(raw.substring(0, colorMatch.index!).trim());\n } else {\n nameColors.push(undefined);\n names.push(raw);\n }\n }\n if (names.length === 1) {\n result.series = names[0];\n }\n if (nameColors.some(Boolean)) result.seriesNameColors = nameColors;\n continue;\n }\n\n // Axis labels\n if (key === 'xlabel') {\n result.xlabel = value;\n continue;\n }\n\n if (key === 'ylabel') {\n result.ylabel = value;\n continue;\n }\n\n if (key === 'sizelabel') {\n result.sizelabel = value;\n continue;\n }\n\n if (key === 'labels') {\n result.showLabels =\n value.toLowerCase() === 'on' || value.toLowerCase() === 'true';\n continue;\n }\n\n // Heatmap columns and rows headers\n if (key === 'columns') {\n result.columns = value.split(',').map((s) => s.trim());\n continue;\n }\n\n if (key === 'rows') {\n result.rows = value.split(',').map((s) => s.trim());\n continue;\n }\n\n // Check for x range: \"x: min to max\"\n if (key === 'x') {\n const rangeMatch = value.match(/^(-?[\\d.]+)\\s+to\\s+(-?[\\d.]+)$/);\n if (rangeMatch) {\n result.xRange = {\n min: parseFloat(rangeMatch[1]),\n max: parseFloat(rangeMatch[2]),\n };\n }\n continue;\n }\n\n // Check for Sankey arrow syntax: Source -> Target: Value\n const arrowMatch = trimmed.match(/^(.+?)\\s*->\\s*(.+?):\\s*(\\d+(?:\\.\\d+)?)$/);\n if (arrowMatch) {\n const [, source, target, val] = arrowMatch;\n if (!result.links) result.links = [];\n result.links.push({\n source: source.trim(),\n target: target.trim(),\n value: parseFloat(val),\n lineNumber,\n });\n continue;\n }\n\n // For function charts, treat non-numeric values as function expressions\n if (result.type === 'function') {\n let fnName = trimmed.substring(0, colonIndex).trim();\n let fnColor: string | undefined;\n const colorMatch = fnName.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n fnColor = resolveColor(colorMatch[1].trim(), palette);\n fnName = fnName.substring(0, colorMatch.index!).trim();\n }\n if (!result.functions) result.functions = [];\n result.functions.push({\n name: fnName,\n expression: value,\n ...(fnColor && { color: fnColor }),\n lineNumber,\n });\n continue;\n }\n\n // For scatter charts, parse \"Name: x, y\" or \"Name: x, y, size\"\n if (result.type === 'scatter') {\n const scatterMatch = value.match(\n /^(-?[\\d.]+)\\s*,\\s*(-?[\\d.]+)(?:\\s*,\\s*(-?[\\d.]+))?$/\n );\n if (scatterMatch) {\n let scatterName = trimmed.substring(0, colonIndex).trim();\n let scatterColor: string | undefined;\n const colorMatch = scatterName.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n scatterColor = resolveColor(colorMatch[1].trim(), palette);\n scatterName = scatterName.substring(0, colorMatch.index!).trim();\n }\n if (!result.scatterPoints) result.scatterPoints = [];\n result.scatterPoints.push({\n name: scatterName,\n x: parseFloat(scatterMatch[1]),\n y: parseFloat(scatterMatch[2]),\n size: scatterMatch[3] ? parseFloat(scatterMatch[3]) : undefined,\n ...(scatterColor && { color: scatterColor }),\n ...(currentCategory !== 'Default' && { category: currentCategory }),\n lineNumber,\n });\n }\n continue;\n }\n\n // For heatmap, parse \"RowLabel: val1, val2, val3, ...\"\n if (result.type === 'heatmap') {\n const values = value.split(',').map((v) => parseFloat(v.trim()));\n if (values.length > 0 && values.every((v) => !isNaN(v))) {\n const originalKey = trimmed.substring(0, colonIndex).trim();\n if (!result.heatmapRows) result.heatmapRows = [];\n result.heatmapRows.push({ label: originalKey, values, lineNumber });\n }\n continue;\n }\n\n // Otherwise treat as data point (label: value)\n const numValue = parseFloat(value);\n if (!isNaN(numValue)) {\n // Use the original case for the label (before lowercasing)\n let rawLabel = trimmed.substring(0, colonIndex).trim();\n let pointColor: string | undefined;\n const colorMatch = rawLabel.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n pointColor = resolveColor(colorMatch[1].trim(), palette);\n rawLabel = rawLabel.substring(0, colorMatch.index!).trim();\n }\n result.data.push({\n label: rawLabel,\n value: numValue,\n ...(pointColor && { color: pointColor }),\n lineNumber,\n });\n }\n }\n\n if (!result.error) {\n if (result.type === 'sankey') {\n if (!result.links || result.links.length === 0) {\n result.error =\n 'No links found. Add links in format: Source -> Target: 123';\n }\n } else if (result.type === 'chord') {\n if (!result.links || result.links.length === 0) {\n result.error =\n 'No links found. Add links in format: Source -> Target: 123';\n }\n } else if (result.type === 'function') {\n if (!result.functions || result.functions.length === 0) {\n result.error =\n 'No functions found. Add functions in format: Name: expression';\n }\n if (!result.xRange) {\n result.xRange = { min: -10, max: 10 }; // Default range\n }\n } else if (result.type === 'scatter') {\n if (!result.scatterPoints || result.scatterPoints.length === 0) {\n result.error =\n 'No scatter points found. Add points in format: Name: x, y or Name: x, y, size';\n }\n } else if (result.type === 'heatmap') {\n if (!result.heatmapRows || result.heatmapRows.length === 0) {\n result.error =\n 'No heatmap data found. Add data in format: RowLabel: val1, val2, val3';\n }\n if (!result.columns || result.columns.length === 0) {\n result.error =\n 'No columns defined. Add columns in format: columns: Col1, Col2, Col3';\n }\n } else if (result.type === 'funnel') {\n if (result.data.length === 0) {\n result.error = 'No data found. Add data in format: Label: value';\n }\n }\n }\n\n return result;\n}\n\n// ============================================================\n// ECharts Option Builder\n// ============================================================\n\n/**\n * Converts parsed echart data to ECharts option object.\n */\nexport function buildEChartsOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n isDark: boolean\n): EChartsOption {\n const textColor = palette.text;\n const axisLineColor = palette.border;\n const gridOpacity = isDark ? 0.7 : 0.55;\n const colors = getSeriesColors(palette);\n\n if (parsed.error) {\n // Return empty option, error will be shown separately\n return {};\n }\n\n // Common title configuration\n const titleConfig = parsed.title\n ? {\n text: parsed.title,\n left: 'center' as const,\n top: 8,\n textStyle: {\n color: textColor,\n fontSize: 20,\n fontWeight: 'bold' as const,\n fontFamily: FONT_FAMILY,\n },\n }\n : undefined;\n\n // Shared tooltip theme so tooltips match light/dark mode\n const tooltipTheme = {\n backgroundColor: palette.surface,\n borderColor: palette.border,\n textStyle: { color: palette.text },\n };\n\n // Sankey chart has different structure\n if (parsed.type === 'sankey') {\n return buildSankeyOption(\n parsed,\n textColor,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Chord diagram\n if (parsed.type === 'chord') {\n return buildChordOption(\n parsed,\n textColor,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Function plot\n if (parsed.type === 'function') {\n return buildFunctionOption(\n parsed,\n palette,\n textColor,\n axisLineColor,\n gridOpacity,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Scatter plot\n if (parsed.type === 'scatter') {\n return buildScatterOption(\n parsed,\n palette,\n textColor,\n axisLineColor,\n gridOpacity,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Funnel chart\n if (parsed.type === 'funnel') {\n return buildFunnelOption(\n parsed,\n textColor,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Heatmap\n return buildHeatmapOption(\n parsed,\n palette,\n textColor,\n axisLineColor,\n titleConfig,\n tooltipTheme\n );\n}\n\n/**\n * Builds ECharts option for sankey diagrams.\n */\nfunction buildSankeyOption(\n parsed: ParsedEChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n // Extract unique nodes from links\n const nodeSet = new Set<string>();\n if (parsed.links) {\n for (const link of parsed.links) {\n nodeSet.add(link.source);\n nodeSet.add(link.target);\n }\n }\n\n const nodes = Array.from(nodeSet).map((name, index) => ({\n name,\n itemStyle: {\n color: colors[index % colors.length],\n },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n show: false,\n ...tooltipTheme,\n },\n series: [\n {\n type: 'sankey',\n emphasis: {\n focus: 'adjacency',\n blurScope: 'global' as const,\n },\n nodeAlign: 'left',\n nodeGap: 12,\n nodeWidth: 20,\n data: nodes,\n links: parsed.links ?? [],\n lineStyle: {\n color: 'gradient',\n curveness: 0.5,\n },\n label: {\n color: textColor,\n fontSize: 12,\n },\n },\n ],\n };\n}\n\n/**\n * Builds ECharts option for chord diagrams.\n */\nfunction buildChordOption(\n parsed: ParsedEChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n // Extract unique nodes from links\n const nodeSet = new Set<string>();\n if (parsed.links) {\n for (const link of parsed.links) {\n nodeSet.add(link.source);\n nodeSet.add(link.target);\n }\n }\n\n const nodeNames = Array.from(nodeSet);\n const nodeCount = nodeNames.length;\n\n // Build adjacency matrix\n const matrix: number[][] = Array(nodeCount)\n .fill(null)\n .map(() => Array(nodeCount).fill(0));\n\n if (parsed.links) {\n for (const link of parsed.links) {\n const sourceIndex = nodeNames.indexOf(link.source);\n const targetIndex = nodeNames.indexOf(link.target);\n if (sourceIndex !== -1 && targetIndex !== -1) {\n matrix[sourceIndex][targetIndex] = link.value;\n }\n }\n }\n\n // Create category data for nodes with colors\n const categories = nodeNames.map((name, index) => ({\n name,\n itemStyle: {\n color: colors[index % colors.length],\n },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as {\n data?: { source: string; target: string; value: number };\n };\n if (p.data && p.data.source && p.data.target) {\n return `${p.data.source} → ${p.data.target}: ${p.data.value}`;\n }\n return '';\n },\n },\n legend: {\n data: nodeNames,\n bottom: 10,\n textStyle: {\n color: textColor,\n },\n },\n series: [\n {\n type: 'graph',\n layout: 'circular',\n circular: {\n rotateLabel: true,\n },\n center: ['50%', '55%'],\n width: '60%',\n height: '60%',\n data: categories.map((cat) => ({\n name: cat.name,\n symbolSize: 20,\n itemStyle: cat.itemStyle,\n label: {\n show: true,\n color: textColor,\n },\n })),\n links: (parsed.links ?? []).map((link) => ({\n source: link.source,\n target: link.target,\n value: link.value,\n lineStyle: {\n width: Math.max(1, Math.min(link.value / 20, 10)),\n color: colors[nodeNames.indexOf(link.source) % colors.length],\n curveness: 0.3,\n opacity: 0.6,\n },\n })),\n roam: true,\n label: {\n position: 'right',\n formatter: '{b}',\n },\n emphasis: {\n focus: 'adjacency',\n lineStyle: {\n width: 5,\n opacity: 1,\n },\n },\n },\n ],\n };\n}\n\n/**\n * Evaluates a mathematical expression for a given x value.\n * Supports: +, -, *, /, ^, sin, cos, tan, log, ln, exp, sqrt, abs, pi, e\n */\nfunction evaluateExpression(expr: string, x: number): number {\n try {\n // Replace mathematical constants and functions\n const processed = expr\n .replace(/\\bpi\\b/gi, String(Math.PI))\n .replace(/\\be\\b/g, String(Math.E))\n .replace(/\\bsin\\s*\\(/gi, 'Math.sin(')\n .replace(/\\bcos\\s*\\(/gi, 'Math.cos(')\n .replace(/\\btan\\s*\\(/gi, 'Math.tan(')\n .replace(/\\bln\\s*\\(/gi, 'Math.log(')\n .replace(/\\blog\\s*\\(/gi, 'Math.log10(')\n .replace(/\\bexp\\s*\\(/gi, 'Math.exp(')\n .replace(/\\bsqrt\\s*\\(/gi, 'Math.sqrt(')\n .replace(/\\babs\\s*\\(/gi, 'Math.abs(')\n .replace(/\\bx\\b/gi, `(${x})`)\n .replace(/\\^/g, '**');\n\n // Evaluate the expression\n const result = new Function(`return ${processed}`)() as unknown;\n return typeof result === 'number' && isFinite(result) ? result : NaN;\n } catch {\n return NaN;\n }\n}\n\n/**\n * Builds ECharts option for function plots.\n */\nfunction buildFunctionOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const xRange = parsed.xRange ?? { min: -10, max: 10 };\n const samples = 200;\n const step = (xRange.max - xRange.min) / samples;\n\n // Generate x values\n const xValues: number[] = [];\n for (let i = 0; i <= samples; i++) {\n xValues.push(xRange.min + i * step);\n }\n\n // Generate series for each function\n const series = (parsed.functions ?? []).map((fn, index) => {\n const data = xValues.map((x) => {\n const y = evaluateExpression(fn.expression, x);\n return [x, y];\n });\n\n const fnColor = fn.color ?? colors[index % colors.length];\n return {\n name: fn.name,\n type: 'line' as const,\n showSymbol: false,\n smooth: true,\n data,\n lineStyle: {\n width: 2,\n color: fnColor,\n },\n itemStyle: {\n color: fnColor,\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n };\n });\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: {\n type: 'cross',\n },\n },\n legend: {\n data: (parsed.functions ?? []).map((fn) => fn.name),\n bottom: 10,\n textStyle: {\n color: textColor,\n },\n },\n grid: {\n left: '4%',\n right: '4%',\n bottom: '15%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: {\n type: 'value',\n min: xRange.min,\n max: xRange.max,\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n yAxis: {\n type: 'value',\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n series,\n };\n}\n\n/**\n * Builds ECharts option for scatter plots.\n * Auto-detects categories and size from point data:\n * - hasCategories → multi-series with legend (one per category)\n * - hasSize → dynamic symbol sizing from 3rd value\n */\nfunction buildScatterOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const points = parsed.scatterPoints ?? [];\n const defaultSize = 15;\n\n const hasCategories = points.some((p) => p.category !== undefined);\n const hasSize = points.some((p) => p.size !== undefined);\n\n const labelConfig = {\n show: parsed.showLabels ?? false,\n formatter: '{b}',\n position: 'top' as const,\n color: textColor,\n fontSize: 11,\n };\n\n const emphasisConfig = {\n focus: 'self' as const,\n itemStyle: {\n shadowBlur: 10,\n shadowColor: 'rgba(0, 0, 0, 0.3)',\n },\n };\n\n // Build series based on whether categories are present\n let series;\n let legendData: string[] | undefined;\n\n if (hasCategories) {\n const categories = [\n ...new Set(points.map((p) => p.category).filter(Boolean)),\n ] as string[];\n legendData = categories;\n\n series = categories.map((category, catIndex) => {\n const categoryPoints = points.filter((p) => p.category === category);\n const catColor =\n parsed.categoryColors?.[category] ?? colors[catIndex % colors.length];\n\n const data = categoryPoints.map((p) => ({\n name: p.name,\n value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],\n ...(p.color && { itemStyle: { color: p.color } }),\n }));\n\n return {\n name: category,\n type: 'scatter' as const,\n data,\n ...(hasSize\n ? { symbolSize: (val: number[]) => val[2] }\n : { symbolSize: defaultSize }),\n itemStyle: { color: catColor },\n label: labelConfig,\n emphasis: emphasisConfig,\n };\n });\n } else {\n // Single series — per-point colors\n const data = points.map((p, index) => ({\n name: p.name,\n value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],\n ...(hasSize\n ? { symbolSize: p.size ?? defaultSize }\n : { symbolSize: defaultSize }),\n itemStyle: {\n color: p.color ?? colors[index % colors.length],\n },\n }));\n\n series = [\n {\n type: 'scatter' as const,\n data,\n label: labelConfig,\n emphasis: emphasisConfig,\n },\n ];\n }\n\n // Tooltip adapts to available data\n const tooltip = {\n trigger: 'item' as const,\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as {\n seriesName: string;\n name: string;\n value: number[];\n };\n const xLabel = parsed.xlabel || 'x';\n const yLabel = parsed.ylabel || 'y';\n let html = `<strong>${p.name}</strong>`;\n if (hasCategories) html += `<br/>${p.seriesName}`;\n html += `<br/>${xLabel}: ${p.value[0]}<br/>${yLabel}: ${p.value[1]}`;\n if (hasSize) html += `<br/>${parsed.sizelabel || 'size'}: ${p.value[2]}`;\n return html;\n },\n };\n\n // Auto-fit axes to data range with ~10% padding\n const xValues = points.map((p) => p.x);\n const yValues = points.map((p) => p.y);\n const xMin = Math.min(...xValues);\n const xMax = Math.max(...xValues);\n const yMin = Math.min(...yValues);\n const yMax = Math.max(...yValues);\n const xPad = (xMax - xMin) * 0.1 || 1;\n const yPad = (yMax - yMin) * 0.1 || 1;\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip,\n ...(legendData && {\n legend: {\n data: legendData,\n bottom: 10,\n textStyle: { color: textColor },\n },\n }),\n grid: {\n left: parsed.ylabel ? '5%' : '3%',\n right: '4%',\n bottom: hasCategories ? '15%' : parsed.xlabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: {\n type: 'value',\n name: parsed.xlabel,\n nameLocation: 'middle',\n nameGap: 40,\n nameTextStyle: {\n color: textColor,\n fontSize: 18,\n },\n min: Math.floor(xMin - xPad),\n max: Math.ceil(xMax + xPad),\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n yAxis: {\n type: 'value',\n name: parsed.ylabel,\n nameLocation: 'middle',\n nameGap: 50,\n nameTextStyle: {\n color: textColor,\n fontSize: 18,\n },\n min: Math.floor(yMin - yPad),\n max: Math.ceil(yMax + yPad),\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n series,\n };\n}\n\n/**\n * Builds ECharts option for heatmap charts.\n */\nfunction buildHeatmapOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const heatmapRows = parsed.heatmapRows ?? [];\n const columns = parsed.columns ?? [];\n const rowLabels = heatmapRows.map((r) => r.label);\n\n // Convert row data to [colIndex, rowIndex, value] format\n const data: [number, number, number][] = [];\n let minValue = Infinity;\n let maxValue = -Infinity;\n\n heatmapRows.forEach((row, rowIndex) => {\n row.values.forEach((value, colIndex) => {\n data.push([colIndex, rowIndex, value]);\n minValue = Math.min(minValue, value);\n maxValue = Math.max(maxValue, value);\n });\n });\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as { data: [number, number, number] };\n const colName = columns[p.data[0]] ?? p.data[0];\n const rowName = rowLabels[p.data[1]] ?? p.data[1];\n return `${rowName} / ${colName}: <strong>${p.data[2]}</strong>`;\n },\n },\n grid: {\n left: '3%',\n right: '10%',\n bottom: '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: {\n type: 'category',\n data: columns,\n splitArea: {\n show: true,\n },\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n },\n yAxis: {\n type: 'category',\n data: rowLabels,\n splitArea: {\n show: true,\n },\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n },\n visualMap: {\n min: minValue,\n max: maxValue,\n calculable: true,\n orient: 'vertical',\n right: '2%',\n top: 'center',\n inRange: {\n color: [\n palette.primary,\n palette.colors.cyan,\n palette.colors.yellow,\n palette.colors.orange,\n ],\n },\n textStyle: {\n color: textColor,\n },\n },\n series: [\n {\n type: 'heatmap',\n data,\n label: {\n show: true,\n color: '#ffffff',\n fontSize: 14,\n fontWeight: 'bold' as const,\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n itemStyle: {\n shadowBlur: 10,\n shadowColor: 'rgba(0, 0, 0, 0.5)',\n },\n },\n },\n ],\n };\n}\n\n/**\n * Builds ECharts option for funnel charts.\n */\nfunction buildFunnelOption(\n parsed: ParsedEChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n // Sort data descending by value for funnel ordering\n const sorted = [...parsed.data].sort((a, b) => b.value - a.value);\n const topValue = sorted.length > 0 ? sorted[0].value : 1;\n\n const data = sorted.map((d) => ({\n name: d.label,\n value: d.value,\n itemStyle: {\n color: d.color ?? colors[parsed.data.indexOf(d) % colors.length],\n borderWidth: 0,\n },\n }));\n\n // Build lookup for tooltip: previous step value (in sorted order)\n const prevValueMap = new Map<string, number>();\n for (let i = 0; i < sorted.length; i++) {\n prevValueMap.set(\n sorted[i].label,\n i > 0 ? sorted[i - 1].value : sorted[i].value\n );\n }\n\n const funnelTop = parsed.title ? 60 : 20;\n const funnelLayout = {\n left: '20%',\n top: funnelTop,\n bottom: 20,\n width: '60%',\n sort: 'descending' as const,\n gap: 2,\n minSize: '8%',\n };\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as { name: string; value: number; dataIndex: number };\n const val = p.value;\n const prev = prevValueMap.get(p.name) ?? val;\n const isFirst = p.dataIndex === 0;\n let html = `<strong>${p.name}</strong>: ${val}`;\n if (!isFirst) {\n const stepDrop = ((1 - val / prev) * 100).toFixed(1);\n html += `<br/>Step drop-off: ${stepDrop}%`;\n }\n if (!isFirst && topValue > 0) {\n const totalDrop = ((1 - val / topValue) * 100).toFixed(1);\n html += `<br/>Overall drop-off: ${totalDrop}%`;\n }\n return html;\n },\n },\n series: [\n {\n type: 'funnel',\n ...funnelLayout,\n label: {\n show: true,\n position: 'left',\n formatter: '{b}',\n color: textColor,\n fontSize: 13,\n },\n labelLine: {\n show: true,\n length: 10,\n lineStyle: { color: textColor, opacity: 0.3 },\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n label: {\n fontSize: 15,\n },\n },\n data,\n },\n {\n type: 'funnel',\n ...funnelLayout,\n silent: true,\n itemStyle: { color: 'transparent', borderWidth: 0 },\n label: {\n show: true,\n position: 'right',\n formatter: '{c}',\n color: textColor,\n fontSize: 13,\n },\n labelLine: {\n show: true,\n length: 10,\n lineStyle: { color: textColor, opacity: 0.3 },\n },\n emphasis: { disabled: true },\n data: data.map((d) => ({\n ...d,\n itemStyle: { color: 'transparent', borderWidth: 0 },\n })),\n },\n ],\n };\n}\n\n// ============================================================\n// Standard Chart → ECharts Option Builder\n// ============================================================\n\n/**\n * Resolves axis labels from parsed chart orientation/xlabel/ylabel/label.\n */\nfunction resolveAxisLabels(parsed: ParsedChart): {\n xLabel?: string;\n yLabel?: string;\n} {\n const isHorizontal = parsed.orientation === 'horizontal';\n return {\n xLabel: parsed.xlabel ?? (isHorizontal ? parsed.label : undefined),\n yLabel: parsed.ylabel ?? (isHorizontal ? undefined : parsed.label),\n };\n}\n\n/**\n * Produces a reusable axis config object for category or value axes.\n */\nfunction makeGridAxis(\n type: 'category' | 'value',\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n label?: string,\n data?: string[]\n): Record<string, unknown> {\n return {\n type,\n ...(data && { data }),\n axisLine: { lineStyle: { color: axisLineColor } },\n axisLabel: { color: textColor, fontSize: 16, fontFamily: FONT_FAMILY },\n splitLine: { lineStyle: { color: splitLineColor, opacity: gridOpacity } },\n ...(label && {\n name: label,\n nameLocation: 'middle',\n nameGap: 40,\n nameTextStyle: { color: textColor, fontSize: 18, fontFamily: FONT_FAMILY },\n }),\n };\n}\n\n/**\n * Converts a ParsedChart into an EChartsOption.\n * Renders standard chart types (bar, line, pie, etc.) with ECharts.\n */\nexport function buildEChartsOptionFromChart(\n parsed: ParsedChart,\n palette: PaletteColors,\n isDark: boolean\n): EChartsOption {\n if (parsed.error) return {};\n\n const textColor = palette.text;\n const axisLineColor = palette.border;\n const splitLineColor = palette.border;\n const gridOpacity = isDark ? 0.7 : 0.55;\n const colors = getSeriesColors(palette);\n\n const titleConfig = parsed.title\n ? {\n text: parsed.title,\n left: 'center' as const,\n top: 8,\n textStyle: {\n color: textColor,\n fontSize: 20,\n fontWeight: 'bold' as const,\n fontFamily: FONT_FAMILY,\n },\n }\n : undefined;\n\n const tooltipTheme = {\n backgroundColor: palette.surface,\n borderColor: palette.border,\n textStyle: { color: palette.text },\n };\n\n switch (parsed.type) {\n case 'bar':\n return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);\n case 'bar-stacked':\n return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);\n case 'line':\n return parsed.seriesNames\n ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme)\n : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);\n case 'area':\n return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);\n case 'pie':\n return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, false);\n case 'doughnut':\n return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, true);\n case 'radar':\n return buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme);\n case 'polar-area':\n return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme);\n }\n}\n\n// ── Bar ──────────────────────────────────────────────────────\n\nfunction buildBarOption(\n parsed: ParsedChart,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const isHorizontal = parsed.orientation === 'horizontal';\n const labels = parsed.data.map((d) => d.label);\n const data = parsed.data.map((d, i) => ({\n value: d.value,\n itemStyle: { color: d.color ?? colors[i % colors.length] },\n }));\n\n const categoryAxis = makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);\n const valueAxis = makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);\n\n // xAxis is always the bottom axis, yAxis is always the left axis in ECharts\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'shadow' },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: xLabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: isHorizontal ? valueAxis : categoryAxis,\n yAxis: isHorizontal ? categoryAxis : valueAxis,\n series: [\n {\n type: 'bar',\n data,\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Line ─────────────────────────────────────────────────────\n\nfunction buildLineOption(\n parsed: ParsedChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n const labels = parsed.data.map((d) => d.label);\n const values = parsed.data.map((d) => d.value);\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'line' },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: xLabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),\n yAxis: makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),\n series: [\n {\n type: 'line',\n data: values,\n smooth: false,\n symbolSize: 8,\n lineStyle: { color: lineColor, width: 3 },\n itemStyle: { color: lineColor },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Multi-line ───────────────────────────────────────────────\n\nfunction buildMultiLineOption(\n parsed: ParsedChart,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const seriesNames = parsed.seriesNames ?? [];\n const labels = parsed.data.map((d) => d.label);\n\n const series = seriesNames.map((name, idx) => {\n const color = parsed.seriesNameColors?.[idx] ?? colors[idx % colors.length];\n const data = parsed.data.map((dp) =>\n idx === 0 ? dp.value : (dp.extraValues?.[idx - 1] ?? 0)\n );\n return {\n name,\n type: 'line' as const,\n data,\n smooth: false,\n symbolSize: 8,\n lineStyle: { color, width: 3 },\n itemStyle: { color },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n };\n });\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'line' },\n },\n legend: {\n data: seriesNames,\n bottom: 10,\n textStyle: { color: textColor },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: '15%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),\n yAxis: makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),\n series,\n };\n}\n\n// ── Area ─────────────────────────────────────────────────────\n\nfunction buildAreaOption(\n parsed: ParsedChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n const labels = parsed.data.map((d) => d.label);\n const values = parsed.data.map((d) => d.value);\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'line' },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: xLabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),\n yAxis: makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),\n series: [\n {\n type: 'line',\n data: values,\n smooth: false,\n symbolSize: 8,\n lineStyle: { color: lineColor, width: 3 },\n itemStyle: { color: lineColor },\n areaStyle: { opacity: 0.25 },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Segment label formatter ──────────────────────────────────\n\nfunction segmentLabelFormatter(mode: ParsedChart['labels']): string {\n switch (mode) {\n case 'name': return '{b}';\n case 'value': return '{b} — {c}';\n case 'percent': return '{b} — {d}%';\n default: return '{b} — {c} ({d}%)';\n }\n}\n\n// ── Pie / Doughnut ───────────────────────────────────────────\n\nfunction buildPieOption(\n parsed: ParsedChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>,\n isDoughnut: boolean\n): EChartsOption {\n const data = parsed.data.map((d, i) => ({\n name: d.label,\n value: d.value,\n itemStyle: { color: d.color ?? colors[i % colors.length] },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n },\n series: [\n {\n type: 'pie',\n radius: isDoughnut ? ['40%', '70%'] : ['0%', '70%'],\n data,\n label: {\n position: 'outside',\n formatter: segmentLabelFormatter(parsed.labels),\n color: textColor,\n fontFamily: FONT_FAMILY,\n },\n labelLine: { show: true },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Radar ────────────────────────────────────────────────────\n\nfunction buildRadarOption(\n parsed: ParsedChart,\n palette: PaletteColors,\n textColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const radarColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n const values = parsed.data.map((d) => d.value);\n const maxValue = Math.max(...values) * 1.15;\n\n const indicator = parsed.data.map((d) => ({\n name: d.label,\n max: maxValue,\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n },\n radar: {\n indicator,\n axisName: {\n color: textColor,\n fontFamily: FONT_FAMILY,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: { color: palette.border, opacity: gridOpacity },\n },\n axisLine: {\n lineStyle: { color: palette.border, opacity: gridOpacity },\n },\n splitArea: { show: false },\n },\n series: [\n {\n type: 'radar',\n data: [\n {\n value: values,\n name: parsed.series ?? 'Value',\n areaStyle: { color: radarColor, opacity: 0.25 },\n lineStyle: { color: radarColor },\n itemStyle: { color: radarColor },\n symbol: 'circle',\n symbolSize: 8,\n label: {\n show: true,\n formatter: '{c}',\n color: textColor,\n fontSize: 11,\n fontFamily: FONT_FAMILY,\n },\n },\n ],\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Polar Area ───────────────────────────────────────────────\n\nfunction buildPolarAreaOption(\n parsed: ParsedChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const data = parsed.data.map((d, i) => ({\n name: d.label,\n value: d.value,\n itemStyle: { color: d.color ?? colors[i % colors.length] },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n },\n series: [\n {\n type: 'pie',\n roseType: 'radius',\n radius: ['10%', '70%'],\n data,\n label: {\n position: 'outside',\n formatter: segmentLabelFormatter(parsed.labels),\n color: textColor,\n fontFamily: FONT_FAMILY,\n },\n labelLine: { show: true },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Bar Stacked ──────────────────────────────────────────────\n\nfunction buildBarStackedOption(\n parsed: ParsedChart,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const isHorizontal = parsed.orientation === 'horizontal';\n const seriesNames = parsed.seriesNames ?? [];\n const labels = parsed.data.map((d) => d.label);\n\n const series = seriesNames.map((name, idx) => {\n const color = parsed.seriesNameColors?.[idx] ?? colors[idx % colors.length];\n const data = parsed.data.map((dp) =>\n idx === 0 ? dp.value : (dp.extraValues?.[idx - 1] ?? 0)\n );\n return {\n name,\n type: 'bar' as const,\n stack: 'total',\n data,\n itemStyle: { color },\n label: {\n show: true,\n position: 'inside' as const,\n formatter: '{c}',\n color: '#ffffff',\n fontSize: 14,\n fontWeight: 'bold' as const,\n fontFamily: FONT_FAMILY,\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n };\n });\n\n const categoryAxis = makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);\n const valueAxis = makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'shadow' },\n },\n legend: {\n data: seriesNames,\n bottom: 10,\n textStyle: { color: textColor },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: '15%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: isHorizontal ? valueAxis : categoryAxis,\n yAxis: isHorizontal ? categoryAxis : valueAxis,\n series,\n };\n}\n\n// ============================================================\n// ECharts SSR Export\n// ============================================================\n\nconst ECHART_EXPORT_WIDTH = 1200;\nconst ECHART_EXPORT_HEIGHT = 800;\n\nconst STANDARD_CHART_TYPES = new Set([\n 'bar',\n 'line',\n 'multi-line',\n 'area',\n 'pie',\n 'doughnut',\n 'radar',\n 'polar-area',\n 'bar-stacked',\n]);\n\n/**\n * Renders an ECharts diagram to SVG using server-side rendering.\n * Mirrors the `renderD3ForExport` API — returns an SVG string or empty string on failure.\n */\nexport async function renderEChartsForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette?: PaletteColors,\n options?: { branding?: boolean }\n): Promise<string> {\n const isDark = theme === 'dark';\n\n // Fall back to Nord palette if none provided\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n // Detect chart type to dispatch to the right parser/builder\n const chartLine = content.match(/^chart\\s*:\\s*(.+)/im);\n const chartType = chartLine?.[1]?.trim().toLowerCase();\n\n let option: EChartsOption;\n if (chartType && STANDARD_CHART_TYPES.has(chartType)) {\n const parsed = parseChart(content, effectivePalette);\n if (parsed.error) return '';\n option = buildEChartsOptionFromChart(parsed, effectivePalette, isDark);\n } else {\n const parsed = parseEChart(content, effectivePalette);\n if (parsed.error) return '';\n option = buildEChartsOption(parsed, effectivePalette, isDark);\n }\n if (!option || Object.keys(option).length === 0) return '';\n\n const chart = echarts.init(null, null, {\n renderer: 'svg',\n ssr: true,\n width: ECHART_EXPORT_WIDTH,\n height: ECHART_EXPORT_HEIGHT,\n });\n\n try {\n chart.setOption(option);\n const svgString = chart.renderToSVGString();\n if (!svgString) return '';\n\n // The SSR output already includes xmlns, width, height, and viewBox.\n // Inject font-family and background on the root <svg> element.\n const bgStyle = theme !== 'transparent' ? `background: ${effectivePalette.bg}; ` : '';\n let result = svgString.replace(\n /^<svg /,\n `<svg style=\"${bgStyle}font-family: ${FONT_FAMILY}\" `\n );\n\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n result = injectBranding(result, brandColor);\n }\n\n return result;\n } finally {\n chart.dispose();\n }\n}\n","// ============================================================\n// Types\n// ============================================================\n\nexport type ChartType =\n | 'bar'\n | 'line'\n | 'pie'\n | 'doughnut'\n | 'area'\n | 'polar-area'\n | 'radar'\n | 'bar-stacked';\n\nexport interface ChartDataPoint {\n label: string;\n value: number;\n extraValues?: number[];\n color?: string;\n lineNumber: number;\n}\n\nexport interface ParsedChart {\n type: ChartType;\n title?: string;\n titleLineNumber?: number;\n series?: string;\n xlabel?: string;\n ylabel?: string;\n seriesNames?: string[];\n seriesNameColors?: (string | undefined)[];\n orientation?: 'horizontal' | 'vertical';\n color?: string;\n label?: string;\n labels?: 'name' | 'value' | 'percent' | 'full';\n data: ChartDataPoint[];\n error?: string;\n}\n\n// ============================================================\n// Colors\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { PaletteColors } from './palettes';\n\n// ============================================================\n// Parser\n// ============================================================\n\nconst VALID_TYPES = new Set<ChartType>([\n 'bar',\n 'line',\n 'pie',\n 'doughnut',\n 'area',\n 'polar-area',\n 'radar',\n 'bar-stacked',\n]);\n\nconst TYPE_ALIASES: Record<string, ChartType> = {\n 'multi-line': 'line',\n};\n\n/**\n * Parses the simple chart text format into a structured object.\n *\n * Format:\n * ```\n * chart: bar\n * title: My Chart\n * series: Revenue\n *\n * Jan: 120\n * Feb: 200\n * Mar: 150\n * ```\n */\nexport function parseChart(\n content: string,\n palette?: PaletteColors\n): ParsedChart {\n const lines = content.split('\\n');\n const result: ParsedChart = {\n type: 'bar',\n data: [],\n };\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Recognize ## section headers (skip, but don't treat as comments)\n if (/^#{2,}\\s+/.test(trimmed)) continue;\n\n // Skip comments\n if (trimmed.startsWith('#') || trimmed.startsWith('//')) continue;\n\n // Parse key: value pairs\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = trimmed.substring(0, colonIndex).trim().toLowerCase();\n const value = trimmed.substring(colonIndex + 1).trim();\n\n // Handle metadata\n if (key === 'chart') {\n const raw = value.toLowerCase();\n const chartType = (TYPE_ALIASES[raw] ?? raw) as ChartType;\n if (VALID_TYPES.has(chartType)) {\n result.type = chartType;\n } else {\n result.error = `Unsupported chart type: ${value}. Supported types: ${[...VALID_TYPES].join(', ')}.`;\n return result;\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'xlabel') {\n result.xlabel = value;\n continue;\n }\n\n if (key === 'ylabel') {\n result.ylabel = value;\n continue;\n }\n\n if (key === 'label') {\n result.label = value;\n continue;\n }\n\n if (key === 'labels') {\n const v = value.toLowerCase();\n if (v === 'name' || v === 'value' || v === 'percent' || v === 'full') {\n result.labels = v;\n }\n continue;\n }\n\n if (key === 'orientation') {\n const v = value.toLowerCase();\n if (v === 'horizontal' || v === 'vertical') {\n result.orientation = v;\n }\n continue;\n }\n\n if (key === 'color') {\n result.color = resolveColor(value.trim(), palette);\n continue;\n }\n\n if (key === 'series') {\n result.series = value;\n // Parse comma-separated series names for multi-series chart types\n const rawNames = value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const names: string[] = [];\n const nameColors: (string | undefined)[] = [];\n for (const raw of rawNames) {\n const colorMatch = raw.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n const resolved = resolveColor(colorMatch[1].trim(), palette);\n nameColors.push(resolved);\n names.push(raw.substring(0, colorMatch.index!).trim());\n } else {\n nameColors.push(undefined);\n names.push(raw);\n }\n }\n if (names.length === 1) {\n result.series = names[0];\n }\n if (names.length > 1) {\n result.seriesNames = names;\n }\n if (nameColors.some(Boolean)) result.seriesNameColors = nameColors;\n continue;\n }\n\n // Data point: Label: value or Label: v1, v2, ...\n const parts = value.split(',').map((s) => s.trim());\n const numValue = parseFloat(parts[0]);\n if (!isNaN(numValue)) {\n let rawLabel = trimmed.substring(0, colonIndex).trim();\n let pointColor: string | undefined;\n const colorMatch = rawLabel.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n const resolved = resolveColor(colorMatch[1].trim(), palette);\n pointColor = resolved;\n rawLabel = rawLabel.substring(0, colorMatch.index!).trim();\n }\n const extra = parts\n .slice(1)\n .map((s) => parseFloat(s))\n .filter((n) => !isNaN(n));\n result.data.push({\n label: rawLabel,\n value: numValue,\n ...(extra.length > 0 && { extraValues: extra }),\n ...(pointColor && { color: pointColor }),\n lineNumber,\n });\n }\n }\n\n // Validation\n if (!result.error && result.data.length === 0) {\n result.error = 'No data points found. Add data in format: Label: 123';\n }\n\n if (!result.error && result.type === 'bar-stacked' && !result.seriesNames) {\n result.error = `Chart type \"bar-stacked\" requires multiple series names. Use: series: Name1, Name2, Name3`;\n }\n\n if (!result.error && result.seriesNames) {\n const expectedCount = result.seriesNames.length;\n for (const dp of result.data) {\n const actualCount = 1 + (dp.extraValues?.length ?? 0);\n if (actualCount !== expectedCount) {\n result.error = `Data point \"${dp.label}\" has ${actualCount} value(s), but ${expectedCount} series defined. Each row must have ${expectedCount} comma-separated values.`;\n break;\n }\n }\n }\n\n return result;\n}\n","import { renderD3ForExport } from './d3';\nimport { renderEChartsForExport } from './echarts';\nimport { parseDgmoChartType, getDgmoFramework } from './dgmo-router';\nimport { getPalette } from './palettes/registry';\n\n/**\n * Ensures DOM globals are available for D3 renderers.\n * No-ops in browser environments where `document` already exists.\n * Dynamically imports jsdom only in Node.js to avoid bundling it for browsers.\n */\nasync function ensureDom(): Promise<void> {\n if (typeof document !== 'undefined') return;\n\n const { JSDOM } = await import('jsdom');\n const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>');\n const win = dom.window;\n\n Object.defineProperty(globalThis, 'document', { value: win.document, configurable: true });\n Object.defineProperty(globalThis, 'window', { value: win, configurable: true });\n Object.defineProperty(globalThis, 'navigator', { value: win.navigator, configurable: true });\n Object.defineProperty(globalThis, 'HTMLElement', { value: win.HTMLElement, configurable: true });\n Object.defineProperty(globalThis, 'SVGElement', { value: win.SVGElement, configurable: true });\n}\n\n/**\n * Render DGMO source to an SVG string.\n *\n * Automatically detects the chart type, selects the appropriate renderer,\n * and returns a complete SVG document string.\n *\n * @param content - DGMO source text\n * @param options - Optional theme and palette settings\n * @returns SVG string, or empty string on error\n *\n * @example\n * ```ts\n * import { render } from '@diagrammo/dgmo';\n *\n * const svg = await render(`chart: pie\n * title: Languages\n * TypeScript: 45\n * Python: 30\n * Rust: 25`);\n * ```\n */\nexport async function render(\n content: string,\n options?: {\n theme?: 'light' | 'dark' | 'transparent';\n palette?: string;\n branding?: boolean;\n },\n): Promise<string> {\n const theme = options?.theme ?? 'light';\n const paletteName = options?.palette ?? 'nord';\n const branding = options?.branding ?? true;\n\n const paletteColors = getPalette(paletteName)[theme === 'dark' ? 'dark' : 'light'];\n\n const chartType = parseDgmoChartType(content);\n const framework = chartType ? getDgmoFramework(chartType) : null;\n\n if (framework === 'echart') {\n return renderEChartsForExport(content, theme, paletteColors, { branding });\n }\n\n // D3 and unknown/null frameworks both go through D3 renderer\n await ensureDom();\n return renderD3ForExport(content, theme, paletteColors, undefined, { branding });\n}\n","// ============================================================\n// .dgmo → Mermaid Translation Layer\n// Parses dgmo quadrant syntax and generates valid Mermaid code.\n// ============================================================\n\nimport { resolveColor } from './colors';\n\n// ============================================================\n// Types\n// ============================================================\n\ninterface QuadrantLabel {\n text: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface ParsedQuadrant {\n title: string | null;\n titleLineNumber: number | null;\n xAxis: [string, string] | null;\n xAxisLineNumber: number | null;\n yAxis: [string, string] | null;\n yAxisLineNumber: number | null;\n quadrants: {\n topRight: QuadrantLabel | null;\n topLeft: QuadrantLabel | null;\n bottomLeft: QuadrantLabel | null;\n bottomRight: QuadrantLabel | null;\n };\n points: { label: string; x: number; y: number; lineNumber: number }[];\n error: string | null;\n}\n\n// ============================================================\n// Parser\n// ============================================================\n\n/** Regex for quadrant label lines: `top-right: Promote (green)` */\nconst QUADRANT_LABEL_RE = /^(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/;\n\n/** Regex for data point lines: `Label: 0.9, 0.5` */\nconst DATA_POINT_RE = /^(.+?):\\s*([0-9]*\\.?[0-9]+)\\s*,\\s*([0-9]*\\.?[0-9]+)\\s*$/;\n\nconst QUADRANT_POSITIONS = new Set([\n 'top-right',\n 'top-left',\n 'bottom-left',\n 'bottom-right',\n]);\n\n/**\n * Parses a .dgmo quadrant document into a structured object.\n * Lines are processed sequentially; unknown lines are silently skipped.\n */\nexport function parseQuadrant(content: string): ParsedQuadrant {\n const result: ParsedQuadrant = {\n title: null,\n titleLineNumber: null,\n xAxis: null,\n xAxisLineNumber: null,\n yAxis: null,\n yAxisLineNumber: null,\n quadrants: {\n topRight: null,\n topLeft: null,\n bottomLeft: null,\n bottomRight: null,\n },\n points: [],\n error: null,\n };\n\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n const lineNumber = i + 1; // 1-indexed for editor\n\n // Skip empty lines and comments\n if (!line || line.startsWith('#') || line.startsWith('//')) continue;\n\n // Skip the chart: directive (already consumed by router)\n if (/^chart\\s*:/i.test(line)) continue;\n\n // title: <text>\n const titleMatch = line.match(/^title\\s*:\\s*(.+)/i);\n if (titleMatch) {\n result.title = titleMatch[1].trim();\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n // x-axis: Low, High\n const xMatch = line.match(/^x-axis\\s*:\\s*(.+)/i);\n if (xMatch) {\n const parts = xMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.xAxis = [parts[0], parts[1]];\n result.xAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // y-axis: Low, High\n const yMatch = line.match(/^y-axis\\s*:\\s*(.+)/i);\n if (yMatch) {\n const parts = yMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.yAxis = [parts[0], parts[1]];\n result.yAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // Quadrant position labels: top-right: Label (color)\n const posMatch = line.match(\n /^(top-right|top-left|bottom-left|bottom-right)\\s*:\\s*(.+)/i\n );\n if (posMatch) {\n const position = posMatch[1].toLowerCase();\n const labelMatch = posMatch[2].match(QUADRANT_LABEL_RE);\n if (labelMatch) {\n const label: QuadrantLabel = {\n text: labelMatch[1].trim(),\n color: labelMatch[2] ? resolveColor(labelMatch[2].trim()) : null,\n lineNumber,\n };\n if (position === 'top-right') result.quadrants.topRight = label;\n else if (position === 'top-left') result.quadrants.topLeft = label;\n else if (position === 'bottom-left')\n result.quadrants.bottomLeft = label;\n else if (position === 'bottom-right')\n result.quadrants.bottomRight = label;\n }\n continue;\n }\n\n // Data points: Label: x, y\n const pointMatch = line.match(DATA_POINT_RE);\n if (pointMatch) {\n // Make sure this isn't a quadrant position keyword\n const key = pointMatch[1].trim().toLowerCase();\n if (!QUADRANT_POSITIONS.has(key)) {\n result.points.push({\n label: pointMatch[1].trim(),\n x: parseFloat(pointMatch[2]),\n y: parseFloat(pointMatch[3]),\n lineNumber,\n });\n }\n continue;\n }\n }\n\n if (result.points.length === 0) {\n result.error = 'No data points found. Add lines like: Label: 0.5, 0.7';\n }\n\n return result;\n}\n\n// ============================================================\n// Mermaid Builder\n// ============================================================\n\n/**\n * Generates valid Mermaid quadrantChart syntax from a parsed quadrant.\n * Returns a string ready for the Mermaid renderer.\n */\nexport function buildMermaidQuadrant(\n parsed: ParsedQuadrant,\n options: {\n isDark?: boolean;\n textColor?: string;\n mutedTextColor?: string;\n } = {}\n): string {\n const { isDark = false, textColor, mutedTextColor } = options;\n const lines: string[] = [];\n\n // %%{init}%% block — fill colors with reduced opacity + text color overrides\n const fillAlpha = isDark ? '30' : '55';\n const primaryText = textColor ?? (isDark ? '#d0d0d0' : '#333333');\n const quadrantLabelText = mutedTextColor ?? (isDark ? '#888888' : '#666666');\n\n const colorMap: Record<string, string> = {};\n if (parsed.quadrants.topRight?.color)\n colorMap.quadrant1Fill = parsed.quadrants.topRight.color + fillAlpha;\n if (parsed.quadrants.topLeft?.color)\n colorMap.quadrant2Fill = parsed.quadrants.topLeft.color + fillAlpha;\n if (parsed.quadrants.bottomLeft?.color)\n colorMap.quadrant3Fill = parsed.quadrants.bottomLeft.color + fillAlpha;\n if (parsed.quadrants.bottomRight?.color)\n colorMap.quadrant4Fill = parsed.quadrants.bottomRight.color + fillAlpha;\n\n // Quadrant labels use muted color, points use primary text color\n colorMap.quadrant1TextFill = quadrantLabelText;\n colorMap.quadrant2TextFill = quadrantLabelText;\n colorMap.quadrant3TextFill = quadrantLabelText;\n colorMap.quadrant4TextFill = quadrantLabelText;\n colorMap.quadrantPointTextFill = primaryText;\n colorMap.quadrantXAxisTextFill = primaryText;\n colorMap.quadrantYAxisTextFill = primaryText;\n colorMap.quadrantTitleFill = primaryText;\n\n const vars = JSON.stringify(colorMap);\n lines.push(`%%{init: {\"themeVariables\": ${vars}}}%%`);\n\n lines.push('quadrantChart');\n\n if (parsed.title) {\n lines.push(` title ${parsed.title}`);\n }\n\n if (parsed.xAxis) {\n lines.push(` x-axis ${parsed.xAxis[0]} --> ${parsed.xAxis[1]}`);\n }\n\n if (parsed.yAxis) {\n lines.push(` y-axis ${parsed.yAxis[0]} --> ${parsed.yAxis[1]}`);\n }\n\n // Helper to quote labels that need it (contain spaces or special chars)\n const quote = (s: string): string => (/[\\s,:[\\]]/.test(s) ? `\"${s}\"` : s);\n\n // Quadrant labels: 1=top-right, 2=top-left, 3=bottom-left, 4=bottom-right\n if (parsed.quadrants.topRight) {\n lines.push(` quadrant-1 ${quote(parsed.quadrants.topRight.text)}`);\n }\n if (parsed.quadrants.topLeft) {\n lines.push(` quadrant-2 ${quote(parsed.quadrants.topLeft.text)}`);\n }\n if (parsed.quadrants.bottomLeft) {\n lines.push(` quadrant-3 ${quote(parsed.quadrants.bottomLeft.text)}`);\n }\n if (parsed.quadrants.bottomRight) {\n lines.push(` quadrant-4 ${quote(parsed.quadrants.bottomRight.text)}`);\n }\n\n // Data points\n for (const point of parsed.points) {\n lines.push(` ${quote(point.label)}: [${point.x}, ${point.y}]`);\n }\n\n return lines.join('\\n');\n}\n","import {\n compressToEncodedURIComponent,\n decompressFromEncodedURIComponent,\n} from 'lz-string';\n\nconst DEFAULT_BASE_URL = 'https://diagrammo.app/view';\nconst COMPRESSED_SIZE_LIMIT = 8192; // 8 KB\n\nexport interface DiagramViewState {\n activeTagGroup?: string;\n}\n\nexport interface DecodedDiagramUrl {\n dsl: string;\n viewState: DiagramViewState;\n}\n\nexport interface EncodeDiagramUrlOptions {\n baseUrl?: string;\n viewState?: DiagramViewState;\n}\n\nexport type EncodeDiagramUrlResult =\n | { url: string; error?: undefined }\n | { url?: undefined; error: 'too-large'; compressedSize: number; limit: number };\n\n/**\n * Compress a DGMO DSL string into a shareable URL.\n * Returns `{ url }` on success, or `{ error: 'too-large', compressedSize, limit }` if the\n * compressed payload exceeds the 8 KB limit.\n */\nexport function encodeDiagramUrl(\n dsl: string,\n options?: EncodeDiagramUrlOptions,\n): EncodeDiagramUrlResult {\n const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;\n const compressed = compressToEncodedURIComponent(dsl);\n const byteSize = new TextEncoder().encode(compressed).byteLength;\n\n if (byteSize > COMPRESSED_SIZE_LIMIT) {\n return { error: 'too-large', compressedSize: byteSize, limit: COMPRESSED_SIZE_LIMIT };\n }\n\n let hash = `dgmo=${compressed}`;\n\n if (options?.viewState?.activeTagGroup) {\n hash += `&tag=${encodeURIComponent(options.viewState.activeTagGroup)}`;\n }\n\n return { url: `${baseUrl}#${hash}` };\n}\n\n/**\n * Decode a DGMO DSL string and view state from a URL hash.\n * Accepts any of:\n * - `#dgmo=<payload>&tag=<name>`\n * - `dgmo=<payload>`\n * - `<bare payload>`\n *\n * Returns `{ dsl, viewState }`. The DSL is empty string on invalid input.\n */\nexport function decodeDiagramUrl(hash: string): DecodedDiagramUrl {\n const empty: DecodedDiagramUrl = { dsl: '', viewState: {} };\n if (!hash) return empty;\n\n let raw = hash;\n\n // Strip leading '#'\n if (raw.startsWith('#')) {\n raw = raw.slice(1);\n }\n\n // Split on '&' to separate dgmo payload from extra params.\n // lz-string's compressToEncodedURIComponent alphabet (A-Za-z0-9+-$) never\n // produces '&', so this split is safe.\n const parts = raw.split('&');\n let payload = parts[0];\n\n // Parse extra params (e.g. tag=Location)\n const viewState: DiagramViewState = {};\n for (let i = 1; i < parts.length; i++) {\n const eq = parts[i].indexOf('=');\n if (eq === -1) continue;\n const key = parts[i].slice(0, eq);\n const val = decodeURIComponent(parts[i].slice(eq + 1));\n if (key === 'tag' && val) {\n viewState.activeTagGroup = val;\n }\n }\n\n // Strip 'dgmo=' prefix\n if (payload.startsWith('dgmo=')) {\n payload = payload.slice(5);\n }\n\n if (!payload) return { dsl: '', viewState };\n\n try {\n const result = decompressFromEncodedURIComponent(payload);\n return { dsl: result ?? '', viewState };\n } catch {\n return { dsl: '', viewState };\n }\n}\n"],"mappings":"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AO,MAAM,iBAAiB,OAAO,QAAQ,MAAM;AACxG,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAMA,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;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,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,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,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,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,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,qBAAqB,MAA+B;AAC3D,QAAM,SAAS,oBAAI,IAAoB;AAGvC,QAAM,SAAS,KACZ,YAAY,EACZ,MAAM,aAAa,EACnB,OAAO,OAAO;AAEjB,aAAW,OAAO,QAAQ;AAExB,UAAM,OAAO,IAAI,QAAQ,YAAY,EAAE;AACvC,QAAI,KAAK,SAAS,KAAK,WAAW,IAAI,IAAI,EAAG;AAC7C,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EAC9C;AAEA,SAAO,MAAM,KAAK,OAAO,QAAQ,CAAC,EAC/B,IAAI,CAAC,CAACC,OAAM,KAAK,OAAO,EAAE,MAAAA,OAAM,QAAQ,OAAO,YAAY,EAAE,EAAE,EAC/D,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACvC;AAMA,IAAM,eAAe,EAAE,KAAK,IAAI,QAAQ,IAAI,MAAM,GAAG;AACrD,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AAKlB,SAAS,iBACd,WACA,QACA,SACA,QACA,aACA,YACM;AAEN,EAAY,oBAAO,SAAS,EAAE,UAAU,yBAAyB,EAAE,OAAO;AAE1E,QAAM,EAAE,SAAS,MAAM,MAAM,IAAI;AACjC,MAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,EAAG;AAE7C,QAAM,QAAQ,YAAY,SAAS,UAAU;AAC7C,QAAM,SAAS,YAAY,UAAU,UAAU;AAC/C,MAAI,SAAS,KAAK,UAAU,EAAG;AAG/B,QAAM,eAAe,KAAK,OAAO,CAAC,SAAS,SAAS;AAClD,UAAM,OAAO,GAAG,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC,CAAC,WAAM,KAAK,KAAK;AACnE,WAAO,KAAK,SAAS,QAAQ,SAAS,OAAO;AAAA,EAC/C,GAAG,EAAE;AACL,QAAM,sBAAsB,aAAa,SAAS;AAClD,QAAM,iBAAiB,KAAK,MAAM,QAAQ,IAAI;AAC9C,QAAM,cAAc,KAAK;AAAA,IACvB,KAAK,IAAI,sBAAsB,IAAI,GAAG;AAAA,IACtC;AAAA,EACF;AAEA,QAAM,aAAa,QAAQ,aAAa,OAAO;AAC/C,QAAM,cAAc,SAAS,aAAa,MAAM,aAAa;AAG7D,QAAM,YAAY,QAAQ;AAC1B,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ;AACxB,QAAM,SAAS,gBAAgB,OAAO;AAGtC,QAAM,YAAY,KAAK,QAAQ,CAAC,MAAM,EAAE,MAAM;AAC9C,QAAM,CAAC,QAAQ,MAAM,IAAY,eAAO,SAAS;AACjD,QAAM,gBAAgB,SAAS,UAAU,OAAO;AAEhD,QAAM,SACH,oBAAY,EACZ,OAAO,CAAC,SAAS,cAAc,SAAS,YAAY,CAAC,EACrD,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,QAAM,SACH,mBAAmB,EACnB,OAAO,OAAO,EACd,MAAM,CAAC,GAAG,UAAU,CAAC,EACrB,QAAQ,CAAC;AAGZ,QAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,QAAM,IAAI,IACP,OAAO,GAAG,EACV,KAAK,aAAa,aAAa,aAAa,IAAI,IAAI,aAAa,GAAG,GAAG;AAG1E,QAAM,UAAU,cAAc,WAAW,SAAS,MAAM;AAGxD,MAAI,OAAO;AACT,UAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,QAAI,OAAO,iBAAiB;AAC1B,cAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,UAAI,aAAa;AACf,gBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,QAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,QAAG,CAAC;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAGA,aAAW,UAAU,SAAS;AAC5B,UAAM,IAAI,OAAO,MAAM;AACvB,MAAE,OAAO,MAAM,EACZ,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,GAAG,EACb,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,MAAM;AAGd,MAAE,OAAO,MAAM,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,CAAC,EACtB,KAAK,oBAAoB,KAAK;AAAA,EACnC;AAGA,QAAM,UACH,cAAa,EACb,EAAE,CAAC,IAAI,MAAM,OAAO,QAAQ,CAAC,CAAC,CAAE,EAChC,EAAE,CAAC,MAAM,OAAO,CAAC,CAAC;AAGrB,OAAK,QAAQ,CAAC,MAAM,QAAQ;AAC1B,UAAM,QAAQ,KAAK,SAAS,OAAO,MAAM,OAAO,MAAM;AAGtD,UAAM,UAAU,EACb,OAAO,GAAG,EACV,KAAK,SAAS,cAAc,EAC5B,KAAK,oBAAoB,OAAO,KAAK,UAAU,CAAC;AAGnD,UAAM,WAAW,KAAK,OAAO,CAAC;AAC9B,UAAM,UAAU,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC;AAClD,UAAM,YAAY,UAAU;AAC5B,UAAM,YAAY,aAAa,IAAK,YAAY,WAAY,MAAM;AAClE,UAAM,OAAO,YAAY,IAAI,MAAM;AACnC,UAAM,UACJ,cAAc,OAAO,KAAK,IAAI,GAAG,UAAU,QAAQ,CAAC,CAAC,OAAO;AAC9D,UAAM,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE;AACvC,QAAI,cAAc,KAAM,UAAS,KAAK,GAAG,IAAI,GAAG,UAAU,QAAQ,CAAC,CAAC,GAAG;AACvE,UAAM,UAAU,SAAS,KAAK,MAAM;AAGpC,YAAQ,OAAO,MAAM,EAClB,MAAM,KAAK,MAAM,EACjB,KAAK,QAAQ,MAAM,EACnB,KAAK,UAAU,KAAK,EACpB,KAAK,gBAAgB,GAAG,EACxB,KAAK,KAAK,OAAO;AAGpB,YAAQ,OAAO,MAAM,EAClB,MAAM,KAAK,MAAM,EACjB,KAAK,QAAQ,MAAM,EACnB,KAAK,UAAU,aAAa,EAC5B,KAAK,gBAAgB,EAAE,EACvB,KAAK,KAAK,OAAO,EACjB,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD;AAAA,MAAG;AAAA,MAAc,CAAC,UACjB,YAAY,SAAS,SAAS,KAAK;AAAA,IACrC,EACC;AAAA,MAAG;AAAA,MAAa,CAAC,UAChB,YAAY,SAAS,SAAS,KAAK;AAAA,IACrC,EACC,GAAG,cAAc,MAAM,YAAY,OAAO,CAAC,EAC3C,GAAG,SAAS,MAAM;AACjB,UAAI,eAAe,KAAK,WAAY,aAAY,KAAK,UAAU;AAAA,IACjE,CAAC;AAGH,SAAK,OAAO,QAAQ,CAAC,KAAK,MAAM;AAC9B,YAAM,IAAI,OAAO,QAAQ,CAAC,CAAC;AAC3B,YAAM,IAAI,OAAO,GAAG;AAGpB,cAAQ,OAAO,QAAQ,EACpB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,KAAK,EAClB,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,GAAG,EACxB,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD;AAAA,QAAG;AAAA,QAAc,CAAC,UACjB,YAAY,SAAS,SAAS,KAAK;AAAA,MACrC,EACC;AAAA,QAAG;AAAA,QAAa,CAAC,UAChB,YAAY,SAAS,SAAS,KAAK;AAAA,MACrC,EACC,GAAG,cAAc,MAAM,YAAY,OAAO,CAAC,EAC3C,GAAG,SAAS,MAAM;AACjB,YAAI,eAAe,KAAK,WAAY,aAAY,KAAK,UAAU;AAAA,MACjE,CAAC;AAGH,YAAM,UAAU,MAAM;AACtB,YAAM,SAAS,MAAM,QAAQ,SAAS;AACtC,UAAI,CAAC,QAAQ;AACX,gBAAQ,OAAO,MAAM,EAClB,KAAK,KAAK,UAAU,IAAI,KAAK,CAAC,EAC9B,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,UAAU,QAAQ,QAAQ,EAC9C,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,IAAI,SAAS,CAAC;AAAA,MACxB;AAAA,IACF,CAAC;AAGD,UAAM,QAAQ,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAChD,UAAM,QAAQ,OAAO,OAAO;AAC5B,UAAM,YAAY,GAAG,OAAO,WAAM,KAAK,KAAK;AAC5C,UAAM,iBAAiB,cAAc;AACrC,UAAM,WAAW,KAAK,MAAM,iBAAiB,gBAAgB;AAE7D,UAAM,UAAU,QACb,OAAO,MAAM,EACb,KAAK,KAAK,QAAQ,EAAE,EACpB,KAAK,KAAK,KAAK,EACf,KAAK,eAAe,OAAO,EAC3B,KAAK,QAAQ,KAAK,EAClB,KAAK,aAAa,GAAG,qBAAqB,IAAI,EAC9C,KAAK,eAAe,KAAK;AAE5B,QAAI,UAAU,UAAU,UAAU;AAChC,cAAQ,KAAK,MAAM,QAAQ,EAAE,KAAK,SAAS;AAAA,IAC7C,OAAO;AAEL,YAAM,QAAQ,UAAU,MAAM,KAAK;AACnC,YAAM,QAAkB,CAAC;AACzB,UAAI,UAAU;AACd,iBAAW,QAAQ,OAAO;AACxB,cAAM,OAAO,UAAU,GAAG,OAAO,IAAI,IAAI,KAAK;AAC9C,YAAI,KAAK,SAAS,YAAY,SAAS;AACrC,gBAAM,KAAK,OAAO;AAClB,oBAAU;AAAA,QACZ,OAAO;AACL,oBAAU;AAAA,QACZ;AAAA,MACF;AACA,UAAI,QAAS,OAAM,KAAK,OAAO;AAE/B,YAAM,aAAa,wBAAwB;AAC3C,YAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAM,UAAU,CAAC,cAAc;AAE/B,YAAM,QAAQ,CAACD,OAAM,OAAO;AAC1B,gBACG,OAAO,OAAO,EACd,KAAK,KAAK,QAAQ,EAAE,EACpB;AAAA,UACC;AAAA,UACA,OAAO,IACH,GAAG,UAAU,wBAAwB,IAAI,OACzC,GAAG,UAAU;AAAA,QACnB,EACC,KAAKA,KAAI;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;AASO,SAAS,cACd,OACA,OACA,QACU;AAEV,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,QAAQ,OAAO;AACxB,YAAQ,IAAI,KAAK,MAAM;AACvB,YAAQ,IAAI,KAAK,MAAM;AAAA,EACzB;AACA,QAAM,WAAW,MAAM,KAAK,OAAO;AAEnC,MAAI,UAAU,QAAQ;AACpB,WAAO,SAAS,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAAA,EAC3D;AAEA,MAAI,UAAU,UAAU;AACtB,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,QAAQ,SAAU,QAAO,IAAI,MAAM,CAAC;AAC/C,eAAW,QAAQ,OAAO;AACxB,aAAO,IAAI,KAAK,QAAQ,OAAO,IAAI,KAAK,MAAM,IAAK,KAAK,KAAK;AAC7D,aAAO,IAAI,KAAK,QAAQ,OAAO,IAAI,KAAK,MAAM,IAAK,KAAK,KAAK;AAAA,IAC/D;AACA,WAAO,SAAS,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM;AACrC,YAAM,OAAO,OAAO,IAAI,CAAC,IAAK,OAAO,IAAI,CAAC;AAC1C,aAAO,SAAS,IAAI,OAAO,EAAE,cAAc,CAAC;AAAA,IAC9C,CAAC;AAAA,EACH;AAEA,MAAI,UAAU,SAAS;AACrB,QAAI,OAAO,SAAS,GAAG;AAErB,YAAM,UAAoB,CAAC;AAC3B,YAAM,SAAS,oBAAI,IAAY;AAC/B,iBAAW,SAAS,QAAQ;AAC1B,mBAAW,QAAQ,MAAM,OAAO;AAC9B,cAAI,CAAC,OAAO,IAAI,IAAI,GAAG;AACrB,oBAAQ,KAAK,IAAI;AACjB,mBAAO,IAAI,IAAI;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAEA,iBAAW,QAAQ,UAAU;AAC3B,YAAI,CAAC,OAAO,IAAI,IAAI,GAAG;AACrB,kBAAQ,KAAK,IAAI;AACjB,iBAAO,IAAI,IAAI;AAAA,QACjB;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,oBAAI,IAAyB;AACzC,eAAW,QAAQ,SAAU,KAAI,IAAI,MAAM,oBAAI,IAAI,CAAC;AACpD,eAAW,QAAQ,OAAO;AACxB,UAAI,IAAI,KAAK,MAAM,EAAG,IAAI,KAAK,MAAM;AACrC,UAAI,IAAI,KAAK,MAAM,EAAG,IAAI,KAAK,MAAM;AAAA,IACvC;AAEA,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,QAAQ,SAAU,QAAO,IAAI,MAAM,CAAC;AAC/C,eAAW,QAAQ,OAAO;AACxB,aAAO,IAAI,KAAK,QAAQ,OAAO,IAAI,KAAK,MAAM,IAAK,KAAK,KAAK;AAC7D,aAAO,IAAI,KAAK,QAAQ,OAAO,IAAI,KAAK,MAAM,IAAK,KAAK,KAAK;AAAA,IAC/D;AAEA,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,aAAyB,CAAC;AAEhC,UAAM,YAAY,IAAI,IAAI,QAAQ;AAClC,WAAO,UAAU,OAAO,GAAG;AAEzB,UAAI,OAAO;AACX,UAAI,SAAS;AACb,iBAAW,QAAQ,WAAW;AAC5B,YAAI,OAAO,IAAI,IAAI,IAAK,QAAQ;AAC9B,mBAAS,OAAO,IAAI,IAAI;AACxB,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,YAAM,YAAsB,CAAC;AAC7B,YAAM,QAAQ,CAAC,IAAI;AACnB,cAAQ,IAAI,IAAI;AAChB,gBAAU,OAAO,IAAI;AACrB,aAAO,MAAM,SAAS,GAAG;AACvB,cAAM,OAAO,MAAM,MAAM;AACzB,kBAAU,KAAK,IAAI;AACnB,mBAAW,YAAY,IAAI,IAAI,IAAI,GAAI;AACrC,cAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG;AAC1B,oBAAQ,IAAI,QAAQ;AACpB,sBAAU,OAAO,QAAQ;AACzB,kBAAM,KAAK,QAAQ;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AACA,iBAAW,KAAK,SAAS;AAAA,IAC3B;AAEA,eAAW,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AAC7C,WAAO,WAAW,KAAK;AAAA,EACzB;AAGA,SAAO;AACT;AAMA,IAAM,aAAa,EAAE,KAAK,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM,GAAG;AAKvD,SAAS,iBACd,WACA,QACA,SACA,SACA,aACA,YACM;AACN,EAAY,oBAAO,SAAS,EAAE,UAAU,yBAAyB,EAAE,OAAO;AAE1E,QAAM,EAAE,OAAO,OAAO,aAAa,UAAU,cAAc,IAAI;AAC/D,MAAI,MAAM,WAAW,EAAG;AAExB,QAAM,QAAQ,YAAY,SAAS,UAAU;AAC7C,QAAM,SAAS,YAAY,UAAU,UAAU;AAC/C,MAAI,SAAS,KAAK,UAAU,EAAG;AAE/B,QAAM,aAAa,gBAAgB;AACnC,QAAM,SAAS,aACX;AAAA,IACE,KAAK,WAAW;AAAA,IAChB,OAAO,WAAW;AAAA,IAClB,QAAQ,WAAW;AAAA,IACnB,MAAM;AAAA,EACR,IACA;AAEJ,QAAM,aAAa,QAAQ,OAAO,OAAO,OAAO;AAChD,QAAM,cAAc,SAAS,OAAO,MAAM,OAAO;AAGjD,QAAM,YAAY,QAAQ;AAC1B,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ;AACxB,QAAM,SAAS,gBAAgB,OAAO;AAGtC,QAAM,QAAQ,cAAc,OAAO,UAAU,aAAa;AAG1D,QAAM,eAAe,oBAAI,IAAoB;AAC7C,aAAW,SAAS,eAAe;AACjC,QAAI,MAAM,OAAO;AACf,iBAAW,QAAQ,MAAM,OAAO;AAC9B,YAAI,CAAC,aAAa,IAAI,IAAI,GAAG;AAC3B,uBAAa,IAAI,MAAM,MAAM,KAAK;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,oBAAI,IAAyB;AACnD,aAAW,SAAS,eAAe;AACjC,kBAAc,IAAI,MAAM,MAAM,IAAI,IAAI,MAAM,KAAK,CAAC;AAAA,EACpD;AAGA,QAAM,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK;AACvC,QAAM,CAAC,QAAQ,MAAM,IAAY,eAAO,MAAM;AAC9C,QAAM,cACH,oBAAY,EACZ,OAAO,CAAC,QAAQ,MAAM,CAAC,EACvB,MAAM,CAAC,KAAK,CAAC,CAAC;AAGjB,QAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,QAAM,IAAI,IACP,OAAO,GAAG,EACV,KAAK,aAAa,aAAa,OAAO,IAAI,IAAI,OAAO,GAAG,GAAG;AAG9D,MAAI,OAAO;AACT,UAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,QAAI,OAAO,iBAAiB;AAC1B,cAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,UAAI,aAAa;AACf,gBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,QAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,QAAG,CAAC;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,oBAAI,IAAyB;AAC/C,aAAW,QAAQ,MAAO,WAAU,IAAI,MAAM,oBAAI,IAAI,CAAC;AACvD,aAAW,QAAQ,OAAO;AACxB,cAAU,IAAI,KAAK,MAAM,EAAG,IAAI,KAAK,MAAM;AAC3C,cAAU,IAAI,KAAK,MAAM,EAAG,IAAI,KAAK,MAAM;AAAA,EAC7C;AAEA,QAAM,eAAe;AAErB,WAAS,iBAAiB,SAAiB;AACzC,UAAM,YAAY,UAAU,IAAI,OAAO;AAEvC,MAAE,UAAmC,WAAW,EAAE,KAAK,WAAY;AACjE,YAAM,KAAiB,oBAAO,IAAI;AAClC,YAAM,MAAM,GAAG,KAAK,aAAa;AACjC,YAAM,MAAM,GAAG,KAAK,aAAa;AACjC,YAAM,YAAY,QAAQ,WAAW,QAAQ;AAC7C,SAAG,KAAK,kBAAkB,YAAY,OAAO,YAAY;AAAA,IAC3D,CAAC;AAED,MAAE,UAAgC,WAAW,EAAE,KAAK,WAAY;AAC9D,YAAM,KAAiB,oBAAO,IAAI;AAClC,YAAM,OAAO,GAAG,KAAK,WAAW;AAChC,YAAM,YAAY,SAAS,WAAW,UAAU,IAAI,IAAK;AACzD,SAAG,KAAK,WAAW,YAAY,IAAI,YAAY;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,WAAS,mBAAmB;AAC1B,MAAE,UAAmC,WAAW,EAAE;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AACA,MAAE,UAAgC,WAAW,EAAE,KAAK,WAAW,CAAC;AAChE,MAAE,UAAmC,iBAAiB,EAAE;AAAA,MACtD;AAAA,MACA;AAAA,IACF;AACA,MAAE,UAAmC,kBAAkB,EAAE;AAAA,MACvD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,WAAS,iBAAiB,WAAmB;AAC3C,UAAM,UAAU,cAAc,IAAI,SAAS;AAC3C,QAAI,CAAC,QAAS;AAEd,MAAE,UAAmC,WAAW,EAAE,KAAK,WAAY;AACjE,YAAM,KAAiB,oBAAO,IAAI;AAClC,YAAM,YACJ,QAAQ,IAAI,GAAG,KAAK,aAAa,CAAE,KACnC,QAAQ,IAAI,GAAG,KAAK,aAAa,CAAE;AACrC,SAAG,KAAK,kBAAkB,YAAY,OAAO,YAAY;AAAA,IAC3D,CAAC;AAED,MAAE,UAAgC,WAAW,EAAE,KAAK,WAAY;AAC9D,YAAM,KAAiB,oBAAO,IAAI;AAClC,SAAG,KAAK,WAAW,QAAQ,IAAI,GAAG,KAAK,WAAW,CAAE,IAAI,IAAI,YAAY;AAAA,IAC1E,CAAC;AAED,MAAE,UAAmC,iBAAiB,EAAE,KAAK,WAAY;AACvE,YAAM,KAAiB,oBAAO,IAAI;AAClC,SAAG;AAAA,QACD;AAAA,QACA,GAAG,KAAK,YAAY,MAAM,YAAY,OAAO;AAAA,MAC/C;AAAA,IACF,CAAC;AAED,MAAE,UAAmC,kBAAkB,EAAE,KAAK,WAAY;AACxE,YAAM,KAAiB,oBAAO,IAAI;AAClC,SAAG,KAAK,gBAAgB,GAAG,KAAK,YAAY,MAAM,YAAY,IAAI,GAAG;AAAA,IACvE,CAAC;AAAA,EACH;AAEA,MAAI,YAAY;AAEd,UAAM,SACH,mBAAmB,EACnB,OAAO,KAAK,EACZ,MAAM,CAAC,GAAG,WAAW,CAAC,EACtB,QAAQ,GAAG;AAEd,UAAM,QAAQ,aAAa;AAG3B,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM,WAAW,OAAO,OAAO,KAAK,MAAM;AAC1C,YAAM,YAAY;AAClB,iBAAW,SAAS,eAAe;AACjC,cAAM,aAAa,MAAM,MAAM,OAAO,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;AAC9D,YAAI,WAAW,WAAW,EAAG;AAC7B,cAAM,YAAY,WAAW,IAAI,CAAC,MAAM,OAAO,CAAC,CAAE;AAClD,cAAM,OAAO,KAAK,IAAI,GAAG,SAAS,IAAI;AACtC,cAAM,OAAO,KAAK,IAAI,GAAG,SAAS,IAAI;AACtC,cAAM,YAAY,MAAM,SAAS;AAEjC,UAAE,OAAO,MAAM,EACZ,KAAK,SAAS,gBAAgB,EAC9B,KAAK,cAAc,MAAM,IAAI,EAC7B,KAAK,oBAAoB,OAAO,MAAM,UAAU,CAAC,EACjD,KAAK,KAAK,QAAQ,SAAS,EAC3B,KAAK,KAAK,IAAI,EACd,KAAK,SAAS,YAAY,CAAC,EAC3B,KAAK,UAAU,OAAO,IAAI,EAC1B,KAAK,MAAM,CAAC,EACZ,KAAK,QAAQ,SAAS,EACtB,KAAK,gBAAgB,IAAI,EACzB,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,iBAAiB,MAAM,IAAI,CAAC,EACnD,GAAG,cAAc,gBAAgB,EACjC,GAAG,SAAS,MAAM;AACjB,cAAI,YAAa,aAAY,MAAM,UAAU;AAAA,QAC/C,CAAC;AAEH,UAAE,OAAO,MAAM,EACZ,KAAK,SAAS,iBAAiB,EAC/B,KAAK,cAAc,MAAM,IAAI,EAC7B,KAAK,oBAAoB,OAAO,MAAM,UAAU,CAAC,EACjD,KAAK,KAAK,QAAQ,YAAY,CAAC,EAC/B,KAAK,KAAK,OAAO,EAAE,EACnB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,gBAAgB,GAAG,EACxB,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD,KAAK,MAAM,IAAI,EACf,GAAG,cAAc,MAAM,iBAAiB,MAAM,IAAI,CAAC,EACnD,GAAG,cAAc,gBAAgB,EACjC,GAAG,SAAS,MAAM;AACjB,cAAI,YAAa,aAAY,MAAM,UAAU;AAAA,QAC/C,CAAC;AAAA,MACL;AAAA,IACF;AAGA,MAAE,OAAO,MAAM,EACZ,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,CAAC,EACtB,KAAK,oBAAoB,KAAK;AAGjC,UAAM,QAAQ,CAAC,MAAM,QAAQ;AAC3B,YAAM,KAAK,OAAO,KAAK,MAAM;AAC7B,YAAM,KAAK,OAAO,KAAK,MAAM;AAC7B,YAAM,QAAQ,KAAK,MAAM;AACzB,YAAM,WAAW,KAAK,IAAI,KAAK,EAAE;AACjC,YAAM,WAAW,QAAQ,WAAW;AACpC,YAAM,QAAQ,KAAK,SAAS,OAAO,MAAM,OAAO,MAAM;AAEtD,QAAE,OAAO,MAAM,EACZ,KAAK,SAAS,UAAU,EACxB,KAAK,eAAe,KAAK,MAAM,EAC/B,KAAK,eAAe,KAAK,MAAM,EAC/B,KAAK,oBAAoB,OAAO,KAAK,UAAU,CAAC,EAChD,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE,MAAM,QAAQ,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,EAAE,EACjE,KAAK,QAAQ,MAAM,EACnB,KAAK,UAAU,KAAK,EACpB,KAAK,gBAAgB,YAAY,KAAK,KAAK,CAAC,EAC5C,KAAK,kBAAkB,GAAG,EAC1B,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD,GAAG,SAAS,MAAM;AACjB,YAAI,eAAe,KAAK,WAAY,aAAY,KAAK,UAAU;AAAA,MACjE,CAAC;AAAA,IACL,CAAC;AAGD,eAAW,QAAQ,OAAO;AACxB,YAAM,IAAI,OAAO,IAAI;AACrB,YAAM,YAAY,aAAa,IAAI,IAAI,KAAK;AAE5C,YAAM,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE,WAAW,IAAI;AAEzE,YAAM,QAAQ,EACX,OAAO,GAAG,EACV,KAAK,SAAS,UAAU,EACxB,KAAK,aAAa,IAAI,EACtB,KAAK,oBAAoB,UAAU,aAAa,OAAO,SAAS,UAAU,IAAI,IAAI,EAClF,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,iBAAiB,IAAI,CAAC,EAC7C,GAAG,cAAc,gBAAgB,EACjC,GAAG,SAAS,MAAM;AACjB,YAAI,eAAe,UAAU;AAC3B,sBAAY,SAAS,UAAU;AAAA,MACnC,CAAC;AAEH,YACG,OAAO,QAAQ,EACf,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,CAAC,EACZ,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,SAAS,EACtB,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,GAAG;AAG3B,YACG,OAAO,MAAM,EACb,KAAK,KAAK,QAAQ,EAAE,EACpB,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,KAAK,EACzB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,IAAI;AAAA,IACd;AAAA,EACF,OAAO;AAEL,UAAM,SACH,mBAAmB,EACnB,OAAO,KAAK,EACZ,MAAM,CAAC,GAAG,UAAU,CAAC,EACrB,QAAQ,GAAG;AAEd,UAAM,QAAQ,cAAc;AAG5B,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM,WAAW,OAAO,OAAO,KAAK,MAAM;AAC1C,YAAM,YAAY;AAClB,iBAAW,SAAS,eAAe;AACjC,cAAM,aAAa,MAAM,MAAM,OAAO,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;AAC9D,YAAI,WAAW,WAAW,EAAG;AAC7B,cAAM,YAAY,WAAW,IAAI,CAAC,MAAM,OAAO,CAAC,CAAE;AAClD,cAAM,OAAO,KAAK,IAAI,GAAG,SAAS,IAAI;AACtC,cAAM,OAAO,KAAK,IAAI,GAAG,SAAS,IAAI;AACtC,cAAM,YAAY,MAAM,SAAS;AAEjC,UAAE,OAAO,MAAM,EACZ,KAAK,SAAS,gBAAgB,EAC9B,KAAK,cAAc,MAAM,IAAI,EAC7B,KAAK,oBAAoB,OAAO,MAAM,UAAU,CAAC,EACjD,KAAK,KAAK,IAAI,EACd,KAAK,KAAK,QAAQ,SAAS,EAC3B,KAAK,SAAS,OAAO,IAAI,EACzB,KAAK,UAAU,YAAY,CAAC,EAC5B,KAAK,MAAM,CAAC,EACZ,KAAK,QAAQ,SAAS,EACtB,KAAK,gBAAgB,IAAI,EACzB,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,iBAAiB,MAAM,IAAI,CAAC,EACnD,GAAG,cAAc,gBAAgB,EACjC,GAAG,SAAS,MAAM;AACjB,cAAI,YAAa,aAAY,MAAM,UAAU;AAAA,QAC/C,CAAC;AAEH,UAAE,OAAO,MAAM,EACZ,KAAK,SAAS,iBAAiB,EAC/B,KAAK,cAAc,MAAM,IAAI,EAC7B,KAAK,oBAAoB,OAAO,MAAM,UAAU,CAAC,EACjD,KAAK,MAAM,OAAO,QAAQ,CAAC,EAC3B,KAAK,KAAK,QAAQ,YAAY,CAAC,EAC/B,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,gBAAgB,GAAG,EACxB,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD,KAAK,MAAM,IAAI,EACf,GAAG,cAAc,MAAM,iBAAiB,MAAM,IAAI,CAAC,EACnD,GAAG,cAAc,gBAAgB,EACjC,GAAG,SAAS,MAAM;AACjB,cAAI,YAAa,aAAY,MAAM,UAAU;AAAA,QAC/C,CAAC;AAAA,MACL;AAAA,IACF;AAGA,MAAE,OAAO,MAAM,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,KAAK,EAChB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,CAAC,EACtB,KAAK,oBAAoB,KAAK;AAGjC,UAAM,QAAQ,CAAC,MAAM,QAAQ;AAC3B,YAAM,KAAK,OAAO,KAAK,MAAM;AAC7B,YAAM,KAAK,OAAO,KAAK,MAAM;AAC7B,YAAM,QAAQ,KAAK,MAAM;AACzB,YAAM,WAAW,KAAK,IAAI,KAAK,EAAE;AACjC,YAAM,WAAW,QAAQ,WAAW;AACpC,YAAM,QAAQ,KAAK,SAAS,OAAO,MAAM,OAAO,MAAM;AAEtD,QAAE,OAAO,MAAM,EACZ,KAAK,SAAS,UAAU,EACxB,KAAK,eAAe,KAAK,MAAM,EAC/B,KAAK,eAAe,KAAK,MAAM,EAC/B,KAAK,oBAAoB,OAAO,KAAK,UAAU,CAAC,EAChD,KAAK,KAAK,KAAK,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,QAAQ,IAAI,EAAE,IAAI,KAAK,EAAE,EACjE,KAAK,QAAQ,MAAM,EACnB,KAAK,UAAU,KAAK,EACpB,KAAK,gBAAgB,YAAY,KAAK,KAAK,CAAC,EAC5C,KAAK,kBAAkB,GAAG,EAC1B,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD,GAAG,SAAS,MAAM;AACjB,YAAI,eAAe,KAAK,WAAY,aAAY,KAAK,UAAU;AAAA,MACjE,CAAC;AAAA,IACL,CAAC;AAGD,eAAW,QAAQ,OAAO;AACxB,YAAM,IAAI,OAAO,IAAI;AACrB,YAAM,YAAY,aAAa,IAAI,IAAI,KAAK;AAE5C,YAAM,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE,WAAW,IAAI;AAEzE,YAAM,QAAQ,EACX,OAAO,GAAG,EACV,KAAK,SAAS,UAAU,EACxB,KAAK,aAAa,IAAI,EACtB,KAAK,oBAAoB,UAAU,aAAa,OAAO,SAAS,UAAU,IAAI,IAAI,EAClF,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,iBAAiB,IAAI,CAAC,EAC7C,GAAG,cAAc,gBAAgB,EACjC,GAAG,SAAS,MAAM;AACjB,YAAI,eAAe,UAAU;AAC3B,sBAAY,SAAS,UAAU;AAAA,MACnC,CAAC;AAEH,YACG,OAAO,QAAQ,EACf,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,KAAK,EAChB,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,SAAS,EACtB,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,GAAG;AAG3B,YACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,QAAQ,EAAE,EACpB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,IAAI;AAAA,IACd;AAAA,EACF;AACF;AAMA,SAAS,aAAa,SAAkC;AACtD,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,EACjB;AACF;AAKA,SAAS,WACP,GACA,MACA,OACA,YACA,YACA,aACA,SACA,SACA,WAAoB,OACpB,UAAiC,MACjC,SACM;AACN,QAAM,YAAY,UACd,aAAa,OAAO,IACpB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAC1D,OAAK,QAAQ,CAAC,KAAK,MAAM;AACvB,UAAM,WAAW,kBAAkB,IAAI,SAAS;AAChD,UAAM,SAAS,kBAAkB,IAAI,OAAO;AAC5C,UAAM,QAAQ,MAAM,QAAQ;AAC5B,UAAM,MAAM,MAAM,MAAM;AACxB,UAAM,QAAQ,IAAI,SAAS,UAAU,IAAI,UAAU,MAAM;AAEzD,UAAM,OAAO,EACV,OAAO,GAAG,EACV,KAAK,SAAS,QAAQ,EACtB,KAAK,kBAAkB,OAAO,QAAQ,CAAC,EACvC,KAAK,gBAAgB,OAAO,MAAM,CAAC,EACnC,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,SAAU,OAAmB;AAC7C,cAAQ,UAAU,MAAM;AACxB,UAAI,QAAS,aAAY,SAAS,oBAAoB,GAAG,GAAG,KAAK;AAAA,IACnE,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,cAAQ;AACR,UAAI,QAAS,aAAY,OAAO;AAAA,IAClC,CAAC,EACA,GAAG,aAAa,SAAU,OAAmB;AAC5C,UAAI,QAAS,aAAY,SAAS,oBAAoB,GAAG,GAAG,KAAK;AAAA,IACnE,CAAC;AAEH,QAAI,YAAY;AACd,YAAM,IAAI,KAAK,IAAI,OAAO,GAAG;AAC7B,YAAM,IAAI,KAAK,IAAI,MAAM,KAAK;AAC9B,WACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,UAAU,EACxB,KAAK,UAAU,CAAC,EAChB,KAAK,QAAQ,KAAK,EAClB,KAAK,WAAW,IAAI;AACvB,WACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,IAAI,EAAE,EAChB,KAAK,eAAe,OAAO,EAC3B,KAAK,QAAQ,KAAK,EAClB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,WAAW,GAAG,EACnB,KAAK,IAAI,KAAK;AAAA,IACnB,OAAO;AACL,YAAM,IAAI,KAAK,IAAI,OAAO,GAAG;AAC7B,YAAM,IAAI,KAAK,IAAI,MAAM,KAAK;AAG9B,YAAM,UAAU,WAAW,MAAM;AACjC,WACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,OAAO,EACjB,KAAK,SAAS,CAAC,EACf,KAAK,UAAU,cAAc,OAAO,EACpC,KAAK,QAAQ,KAAK,EAClB,KAAK,WAAW,IAAI;AACvB,WACG,OAAO,MAAM,EACb,KAAK,KAAK,IAAI,IAAI,CAAC,EACnB,KAAK,KAAK,WAAW,MAAM,EAAE,EAC7B,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,KAAK,EAClB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,WAAW,GAAG,EACnB,KAAK,IAAI,KAAK;AAAA,IACnB;AAAA,EACF,CAAC;AACH;AAKA,SAAS,cACP,GACA,SACA,OACA,YACA,YACA,aACA,YAAqB,OACrB,UAAiC,MACjC,SACM;AAEN,QAAM,eAAe,SAAS,UAAU;AAExC,UAAQ,QAAQ,CAAC,WAAW;AAC1B,UAAM,UAAU,kBAAkB,OAAO,IAAI;AAC7C,UAAM,MAAM,MAAM,OAAO;AACzB,UAAM,QAAQ,OAAO,SAAS;AAC9B,UAAM,cAAc;AACpB,UAAM,cAAc;AAEpB,UAAM,UAAU,EACb,OAAO,GAAG,EACV,KAAK,SAAS,WAAW,EACzB,KAAK,oBAAoB,OAAO,OAAO,CAAC,EACxC,KAAK,oBAAoB,OAAO,OAAO,UAAU,CAAC,EAClD,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,SAAU,OAAmB;AAC7C,UAAI,SAAS;AACX,oBAAY,SAAS,gBAAgB,OAAO,IAAI,GAAG,KAAK;AAAA,MAC1D;AAAA,IACF,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,UAAI,QAAS,aAAY,OAAO;AAAA,IAClC,CAAC,EACA,GAAG,aAAa,SAAU,OAAmB;AAC5C,UAAI,SAAS;AACX,oBAAY,SAAS,gBAAgB,OAAO,IAAI,GAAG,KAAK;AAAA,MAC1D;AAAA,IACF,CAAC;AAEH,QAAI,YAAY;AAEd,cACG,OAAO,MAAM,EACb,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,GAAG,EACd,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,GAAG,EACd,KAAK,UAAU,KAAK,EACpB,KAAK,gBAAgB,GAAG,EACxB,KAAK,oBAAoB,KAAK,EAC9B,KAAK,WAAW,WAAW;AAG9B,cACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,cAAc,CAAC,EAC1B,KAAK,KAAK,MAAM,cAAc,CAAC,EAC/B,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,KAAK,EAClB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,OAAO,KAAK;AAGpB,cACG,OAAO,MAAM,EACb;AAAA,QACC;AAAA,QACA,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG,KAAK,WAAW,KAAK,WAAW,KAAK,WAAW,IAAI,WAAW,MAAM,WAAW,IAAI,WAAW;AAAA,MAC5H,EACC,KAAK,QAAQ,KAAK,EAClB,KAAK,WAAW,GAAG;AAAA,IACxB,OAAO;AAGL,YAAM,SAAS;AACf,YAAM,WAAW,SAAS;AAG1B,cACG,OAAO,MAAM,EACb,KAAK,KAAK,GAAG,EACb,KAAK,KAAK,MAAM,EAChB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,KAAK,EAClB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,OAAO,KAAK;AAGpB,cACG,OAAO,MAAM,EACb;AAAA,QACC;AAAA,QACA,IAAI,GAAG,IAAI,WAAW,WAAW,KAAK,WAAW,IAAI,WAAW,MAAM,WAAW,IAAI,WAAW,MAAM,WAAW,KAAK,WAAW;AAAA,MACnI,EACC,KAAK,QAAQ,KAAK,EAClB,KAAK,WAAW,GAAG;AAGtB,cACG,OAAO,MAAM,EACb,KAAK,MAAM,GAAG,EACd,KAAK,MAAM,WAAW,WAAW,EACjC,KAAK,MAAM,GAAG,EACd,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,KAAK,EACpB,KAAK,gBAAgB,GAAG,EACxB,KAAK,oBAAoB,KAAK,EAC9B,KAAK,WAAW,WAAW;AAAA,IAChC;AAAA,EACF,CAAC;AACH;AAMA,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,SAAS,gBAAgB,SAAyB;AACvD,QAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAM,OAAO,MAAM,CAAC;AACpB,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,QAAQ,WAAW,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC;AACnD,MAAI,MAAM,WAAW,EAAG,QAAO,GAAG,KAAK,IAAI,IAAI;AAC/C,QAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AACjC,SAAO,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI;AACjC;AAYO,SAAS,iBACd,WACA,WACA,OACA,eACA,aACA,oBACA,kBACkC;AAClC,QAAM,UAAU,KAAK,MAAM,SAAS;AACpC,QAAM,UAAU,KAAK,MAAM,SAAS;AACpC,QAAM,OAAO,YAAY;AAEzB,MAAI,QAA0C,CAAC;AAG/C,QAAM,YAAY,KAAK,KAAK,SAAS;AACrC,QAAM,WAAW,KAAK,MAAM,SAAS;AACrC,MAAI,YAAY,YAAY,GAAG;AAE7B,UAAM,WAAW,WAAW;AAC5B,QAAI,OAAO;AACX,QAAI,WAAW,GAAI,QAAO;AAAA,aACjB,WAAW,GAAI,QAAO;AAAA,aACtB,WAAW,GAAI,QAAO;AAAA,aACtB,WAAW,GAAI,QAAO;AAG/B,UAAM,eAAe,KAAK,KAAK,YAAY,IAAI,IAAI;AACnD,aAAS,IAAI,cAAc,KAAK,UAAU,KAAK,MAAM;AACnD,YAAM,KAAK,EAAE,KAAK,MAAM,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,CAAC;AAAA,IAChD;AAAA,EACF,WAAW,OAAO,MAAM;AAEtB,UAAM,cAAc,UAAU;AAC9B,aAAS,IAAI,SAAS,KAAK,UAAU,GAAG,KAAK;AAC3C,eAAS,IAAI,GAAG,KAAK,IAAI,KAAK;AAC5B,cAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,YAAI,MAAM,UAAW;AACrB,YAAI,OAAO,WAAW;AACpB,gBAAM,KAAK;AAAA,YACT,KAAK,MAAM,GAAG;AAAA,YACd,OAAO,cACH,GAAG,WAAW,IAAI,CAAC,CAAC,KAAK,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,KAC5C,WAAW,IAAI,CAAC;AAAA,UACtB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AAEL,aAAS,IAAI,SAAS,KAAK,UAAU,GAAG,KAAK;AAC3C,eAAS,IAAI,GAAG,KAAK,IAAI,KAAK;AAC5B,mBAAW,KAAK,CAAC,GAAG,GAAG,IAAI,EAAE,GAAG;AAC9B,gBAAM,MAAM,KAAK,IAAI,KAAK,MAAM,IAAI,KAAK;AACzC,cAAI,MAAM,UAAW;AACrB,cAAI,OAAO,WAAW;AACpB,kBAAM,KAAK;AAAA,cACT,KAAK,MAAM,GAAG;AAAA,cACd,OAAO,GAAG,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC;AAAA,YAClC,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAIA,QAAM,qBAAqB;AAE3B,MAAI,kBAAkB,UAAa,oBAAoB;AACrD,UAAM,cAAc,MAAM,aAAa;AAEvC,YAAQ,MAAM;AAAA,MACZ,CAAC,MAAM,KAAK,IAAI,EAAE,MAAM,WAAW,KAAK;AAAA,IAC1C;AACA,UAAM,QAAQ,EAAE,KAAK,aAAa,OAAO,mBAAmB,CAAC;AAAA,EAC/D;AAEA,MAAI,gBAAgB,UAAa,kBAAkB;AACjD,UAAM,cAAc,MAAM,WAAW;AAErC,YAAQ,MAAM;AAAA,MACZ,CAAC,MAAM,KAAK,IAAI,EAAE,MAAM,WAAW,KAAK;AAAA,IAC1C;AACA,UAAM,KAAK,EAAE,KAAK,aAAa,OAAO,iBAAiB,CAAC;AAAA,EAC1D;AAEA,SAAO;AACT;AAMA,SAAS,gBACP,GACA,OACA,YACA,YACA,aACA,WACA,eACA,aACA,oBACA,kBACM;AACN,QAAM,CAAC,WAAW,SAAS,IAAI,MAAM,OAAO;AAC5C,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM,SAAS,EAAG;AAEtB,QAAM,UAAU;AAChB,QAAM,UAAU;AAEhB,QAAM,eAAe;AAErB,aAAW,QAAQ,OAAO;AACxB,QAAI,YAAY;AAEd,QAAE,OAAO,MAAM,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,UAAU,SAAS,EACxB,KAAK,gBAAgB,CAAC,EACtB,KAAK,oBAAoB,KAAK,EAC9B,KAAK,WAAW,YAAY;AAG/B,QAAE,OAAO,MAAM,EACZ,KAAK,MAAM,CAAC,OAAO,EACnB,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,UAAU,SAAS,EACxB,KAAK,gBAAgB,CAAC,EACtB,KAAK,WAAW,OAAO;AAE1B,QAAE,OAAO,MAAM,EACZ,KAAK,KAAK,CAAC,UAAU,CAAC,EACtB,KAAK,KAAK,KAAK,GAAG,EAClB,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,KAAK,EACzB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,WAAW,OAAO,EACvB,KAAK,KAAK,KAAK;AAGlB,QAAE,OAAO,MAAM,EACZ,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,aAAa,OAAO,EAC/B,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,UAAU,SAAS,EACxB,KAAK,gBAAgB,CAAC,EACtB,KAAK,WAAW,OAAO;AAE1B,QAAE,OAAO,MAAM,EACZ,KAAK,KAAK,aAAa,UAAU,CAAC,EAClC,KAAK,KAAK,KAAK,GAAG,EAClB,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,OAAO,EAC3B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,WAAW,OAAO,EACvB,KAAK,KAAK,KAAK;AAAA,IACpB,OAAO;AAEL,QAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,SAAS,EACxB,KAAK,gBAAgB,CAAC,EACtB,KAAK,oBAAoB,KAAK,EAC9B,KAAK,WAAW,YAAY;AAG/B,QAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,WAAW,EACtB,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,cAAc,OAAO,EAChC,KAAK,UAAU,SAAS,EACxB,KAAK,gBAAgB,CAAC,EACtB,KAAK,WAAW,OAAO;AAE1B,QAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,KAAK,KAAK,GAAG,EAClB,KAAK,KAAK,cAAc,UAAU,EAAE,EACpC,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,WAAW,OAAO,EACvB,KAAK,KAAK,KAAK;AAGlB,QAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,CAAC,OAAO,EACnB,KAAK,MAAM,KAAK,GAAG,EACnB,KAAK,MAAM,CAAC,EACZ,KAAK,UAAU,SAAS,EACxB,KAAK,gBAAgB,CAAC,EACtB,KAAK,WAAW,OAAO;AAE1B,QAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,KAAK,KAAK,GAAG,EAClB,KAAK,KAAK,CAAC,UAAU,CAAC,EACtB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,WAAW,OAAO,EACvB,KAAK,KAAK,KAAK;AAAA,IACpB;AAAA,EACF;AACF;AAUA,SAAS,sBACP,GACA,OACA,WACA,SACA,aACA,aACM;AAEN,IAAE,UAAU,gBAAgB,EAAE,KAAK,WAAW,GAAG;AAEjD,QAAM,UAAU;AAChB,QAAM,WAAW,MAAM,kBAAkB,SAAS,CAAC;AACnD,QAAM,aAAa,gBAAgB,SAAS;AAG5C,IAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,MAAM,QAAQ,EACnB,KAAK,MAAM,CAAC,OAAO,EACnB,KAAK,MAAM,QAAQ,EACnB,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,WAAW,EAC1B,KAAK,gBAAgB,GAAG,EACxB,KAAK,oBAAoB,KAAK,EAC9B,KAAK,WAAW,GAAG;AAEtB,IAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,KAAK,QAAQ,EAClB,KAAK,KAAK,CAAC,UAAU,CAAC,EACtB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,WAAW,EACxB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,UAAU;AAGlB,IAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,KAAK,QAAQ,EAClB,KAAK,KAAK,cAAc,UAAU,EAAE,EACpC,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,WAAW,EACxB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,UAAU;AAElB,MAAI,SAAS;AACX,UAAM,SAAS,MAAM,kBAAkB,OAAO,CAAC;AAC/C,UAAM,WAAW,gBAAgB,OAAO;AAGxC,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,MAAM,MAAM,EACjB,KAAK,MAAM,CAAC,OAAO,EACnB,KAAK,MAAM,MAAM,EACjB,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,WAAW,EAC1B,KAAK,gBAAgB,GAAG,EACxB,KAAK,oBAAoB,KAAK,EAC9B,KAAK,WAAW,GAAG;AAEtB,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,KAAK,MAAM,EAChB,KAAK,KAAK,CAAC,UAAU,CAAC,EACtB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,WAAW,EACxB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,QAAQ;AAGhB,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,eAAe,EAC7B,KAAK,KAAK,MAAM,EAChB,KAAK,KAAK,cAAc,UAAU,EAAE,EACpC,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,WAAW,EACxB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,QAAQ;AAAA,EAClB;AACF;AAKA,SAAS,sBACP,GACM;AAEN,IAAE,UAAU,gBAAgB,EAAE,OAAO;AAGrC,IAAE,UAAU,gBAAgB,EAAE,KAAK,WAAY;AAC7C,UAAM,KAAiB,oBAAO,IAAI;AAElC,UAAM,WAAW,GAAG,KAAK,kBAAkB;AAC3C,OAAG,KAAK,WAAW,WAAW,OAAO,GAAG;AAAA,EAC1C,CAAC;AACH;AAMA,SAAS,cACP,WACA,SACA,QACgB;AAChB,YAAU,MAAM,WAAW;AAG3B,QAAM,WAAW,UAAU,cAA8B,mBAAmB;AAC5E,MAAI,UAAU;AACZ,aAAS,MAAM,UAAU;AACzB,aAAS,MAAM,aAAa,QAAQ;AACpC,aAAS,MAAM,QAAQ,QAAQ;AAC/B,aAAS,MAAM,YAAY,SACvB,8BACA;AACJ,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,SAAS,cAAc,KAAK;AACxC,MAAI,aAAa,mBAAmB,EAAE;AACtC,MAAI,MAAM,WAAW;AACrB,MAAI,MAAM,UAAU;AACpB,MAAI,MAAM,gBAAgB;AAC1B,MAAI,MAAM,aAAa,QAAQ;AAC/B,MAAI,MAAM,QAAQ,QAAQ;AAC1B,MAAI,MAAM,UAAU;AACpB,MAAI,MAAM,eAAe;AACzB,MAAI,MAAM,WAAW;AACrB,MAAI,MAAM,aAAa;AACvB,MAAI,MAAM,aAAa;AACvB,MAAI,MAAM,SAAS;AACnB,MAAI,MAAM,YAAY,SAClB,8BACA;AACJ,YAAU,YAAY,GAAG;AACzB,SAAO;AACT;AAEA,SAAS,YACP,SACA,MACA,OACM;AACN,UAAQ,YAAY;AACpB,UAAQ,MAAM,UAAU;AACxB,QAAM,YAAY,QAAQ;AAC1B,QAAM,OAAO,UAAU,sBAAsB;AAC7C,MAAI,OAAO,MAAM,UAAU,KAAK,OAAO;AACvC,MAAI,MAAM,MAAM,UAAU,KAAK,MAAM;AAErC,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,QAAQ;AACrB,MAAI,OAAO,OAAO,KAAK,MAAO,QAAO,KAAK,QAAQ,OAAO;AACzD,MAAI,MAAM,EAAG,OAAM,MAAM,UAAU,KAAK,MAAM;AAC9C,MAAI,MAAM,OAAO,KAAK,OAAQ,OAAM,KAAK,SAAS,OAAO;AACzD,UAAQ,MAAM,OAAO,GAAG,IAAI;AAC5B,UAAQ,MAAM,MAAM,GAAG,GAAG;AAC5B;AAEA,SAAS,YAAY,SAA+B;AAClD,UAAQ,MAAM,UAAU;AAC1B;AAEA,SAAS,sBAAsB,IAA2B;AACxD,QAAM,WAAW,GAAG,UAChB,GAAG,gBAAgB,GAAG,IAAI,CAAC,WAAM,gBAAgB,GAAG,OAAO,CAAC,KAC5D,gBAAgB,GAAG,IAAI;AAC3B,SAAO,WAAW,GAAG,KAAK,gBAAgB,QAAQ;AACpD;AAEA,SAAS,oBAAoB,KAA0B;AACrD,SAAO,WAAW,IAAI,KAAK,gBAAgB,gBAAgB,IAAI,SAAS,CAAC,WAAM,gBAAgB,IAAI,OAAO,CAAC;AAC7G;AAUO,SAAS,eACd,WACA,QACA,SACA,QACA,aACA,YACM;AACN,EAAY,oBAAO,SAAS,EAAE,UAAU,yBAAyB,EAAE,OAAO;AAE1E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,MAAI,eAAe,WAAW,EAAG;AAEjC,QAAM,UAAU,cAAc,WAAW,SAAS,MAAM;AAExD,QAAM,QAAQ,YAAY,SAAS,UAAU;AAC7C,QAAM,SAAS,YAAY,UAAU,UAAU;AAC/C,MAAI,SAAS,KAAK,UAAU,EAAG;AAE/B,QAAM,aAAa,gBAAgB;AAGnC,QAAM,YAAY,QAAQ;AAC1B,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ;AACxB,QAAM,SAAS,gBAAgB,OAAO;AAGtC,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,iBAAe,QAAQ,CAAC,KAAK,MAAM;AACjC,kBAAc,IAAI,IAAI,MAAM,IAAI,SAAS,OAAO,IAAI,OAAO,MAAM,CAAC;AAAA,EACpE,CAAC;AAED,WAAS,WAAW,IAA2B;AAC7C,QAAI,GAAG,SAAS,cAAc,IAAI,GAAG,KAAK,GAAG;AAC3C,aAAO,cAAc,IAAI,GAAG,KAAK;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAGA,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI,uBAAuB;AAC3B,MAAI,mBAAmB;AAEvB,aAAW,MAAM,gBAAgB;AAC/B,UAAM,WAAW,kBAAkB,GAAG,IAAI;AAC1C,UAAM,SAAS,GAAG,UAAU,kBAAkB,GAAG,OAAO,IAAI;AAE5D,QAAI,WAAW,SAAS;AACtB,gBAAU;AACV,6BAAuB,GAAG;AAAA,IAC5B;AACA,QAAI,SAAS,SAAS;AACpB,gBAAU;AACV,yBAAmB,GAAG,WAAW,GAAG;AAAA,IACtC;AAAA,EACF;AACA,QAAM,eAAe,UAAU,WAAW,QAAQ;AAElD,QAAM,eAAe;AAMrB,WAAS,YACP,GACA,WACA;AACA,MAAE,UAAgC,WAAW,EAAE,KAAK,WAAY;AAC9D,YAAM,KAAiB,oBAAO,IAAI;AAClC,YAAM,UAAU,GAAG,KAAK,YAAY;AACpC,SAAG,KAAK,WAAW,YAAY,YAAY,IAAI,YAAY;AAAA,IAC7D,CAAC;AACD,MAAE,UAAgC,kCAAkC,EAAE;AAAA,MACpE,WAAY;AACV,cAAM,KAAiB,oBAAO,IAAI;AAClC,cAAM,OAAO,GAAG,KAAK,YAAY;AACjC,WAAG,KAAK,WAAW,SAAS,YAAY,IAAI,YAAY;AAAA,MAC1D;AAAA,IACF;AACA,MAAE,UAAgC,YAAY,EAAE;AAAA,MAC9C;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,WAAS,UACP,GACA,UACA,QACA;AACA,MAAE,UAAgC,WAAW,EAAE,KAAK,WAAY;AAC9D,YAAM,KAAiB,oBAAO,IAAI;AAClC,YAAM,OAAO,WAAW,GAAG,KAAK,WAAW,CAAE;AAC7C,YAAM,UAAU,GAAG,KAAK,eAAe;AACvC,YAAM,QAAQ,UAAU,WAAW,OAAO,IAAI;AAC9C,YAAM,SAAS,SAAS,YAAY,QAAQ;AAC5C,SAAG,KAAK,WAAW,SAAS,IAAI,YAAY;AAAA,IAC9C,CAAC;AACD,MAAE,UAAgC,kCAAkC,EAAE;AAAA,MACpE;AAAA,MACA;AAAA,IACF;AACA,MAAE,UAAgC,SAAS,EAAE,KAAK,WAAY;AAC5D,YAAM,KAAiB,oBAAO,IAAI;AAClC,YAAM,IAAI,WAAW,GAAG,KAAK,gBAAgB,CAAE;AAC/C,YAAM,IAAI,WAAW,GAAG,KAAK,cAAc,CAAE;AAC7C,YAAM,SAAS,MAAM,YAAY,MAAM;AACvC,SAAG,KAAK,WAAW,SAAS,IAAI,YAAY;AAAA,IAC9C,CAAC;AACD,MAAE,UAAgC,YAAY,EAAE,KAAK,WAAY;AAC/D,YAAM,KAAiB,oBAAO,IAAI;AAClC,YAAM,OAAO,WAAW,GAAG,KAAK,kBAAkB,CAAE;AACpD,YAAM,SAAS,QAAQ,YAAY,QAAQ;AAC3C,SAAG,KAAK,WAAW,SAAS,IAAI,YAAY;AAAA,IAC9C,CAAC;AAAA,EACH;AAEA,WAAS,UACP,GACA;AACA,MAAE;AAAA,MACA;AAAA,IACF,EAAE,KAAK,WAAW,CAAC;AACnB,MAAE,UAAgC,SAAS,EAAE,KAAK,WAAW,CAAC;AAAA,EAChE;AAKA,MAAI,YAAY;AACd,QAAI,iBAAiB,WAAW,eAAe,SAAS,GAAG;AAEzD,YAAM,aAAa,eAAe,IAAI,CAAC,OAAO,GAAG,IAAI;AACrD,YAAM,kBAAkB,eAAe;AAAA,QACrC,CAAC,OAAO,GAAG,UAAU,QAAQ,CAAC,WAAW,SAAS,GAAG,KAAK;AAAA,MAC5D;AACA,YAAM,YACJ,gBAAgB,SAAS,IAAI,CAAC,GAAG,YAAY,SAAS,IAAI;AAE5D,YAAM,YAAY,UAAU;AAC5B,YAAM,cAAc,gBAAgB,KAAK;AACzC,YAAM,eAAe,gBAAgB,SAAS,IAAI,KAAK;AACvD,YAAM,SAAS;AAAA,QACb,KAAK,MAAM;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,QAAQ;AAAA,QACR,MAAM,KAAK;AAAA,MACb;AACA,YAAM,aAAa,QAAQ,OAAO,OAAO,OAAO;AAChD,YAAM,cAAc,SAAS,OAAO,MAAM,OAAO;AACjD,YAAM,YAAY,aAAa;AAE/B,YAAM,SACH,oBAAY,EACZ,OAAO,CAAC,UAAU,aAAa,UAAU,WAAW,CAAC,EACrD,MAAM,CAAC,GAAG,WAAW,CAAC;AAEzB,YAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,YAAM,IAAI,IACP,OAAO,GAAG,EACV,KAAK,aAAa,aAAa,OAAO,IAAI,IAAI,OAAO,GAAG,GAAG;AAE9D,UAAI,OAAO;AACT,cAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,YAAI,OAAO,iBAAiB;AAC1B,kBAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,cAAI,aAAa;AACf,oBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,cAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,YAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,cAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,YAAG,CAAC;AAAA,UAClF;AAAA,QACF;AAAA,MACF;AAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,GAAG,MAAM,UAAU,GAAG,GAAG,CAAC;AAAA,QAC3B,MAAM,UAAU,CAAC;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,eAAe;AACjB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,gBAAgB,oBAAoB;AAAA,UACpC,gBAAgB,gBAAgB;AAAA,QAClC;AAAA,MACF;AAEA,gBAAU,QAAQ,CAAC,UAAU,YAAY;AACvC,cAAM,QAAQ,UAAU;AACxB,cAAM,YAAY,cAAc,IAAI,QAAQ,KAAK;AACjD,cAAM,aAAa,QAAQ,YAAY;AAEvC,cAAM,UAAU,EACb,OAAO,GAAG,EACV,KAAK,SAAS,gBAAgB,EAC9B,KAAK,cAAc,QAAQ,EAC3B,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,YAAY,GAAG,QAAQ,CAAC,EAC/C,GAAG,cAAc,MAAM,UAAU,CAAC,CAAC;AAEtC,gBACG,OAAO,MAAM,EACb,KAAK,KAAK,UAAU,EACpB,KAAK,KAAK,GAAG,EACb,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,QAAQ;AAEhB,UAAE,OAAO,MAAM,EACZ,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,CAAC,EACtB,KAAK,oBAAoB,KAAK;AAEjC,cAAM,aAAa,eAAe;AAAA,UAAO,CAAC,OACxC,aAAa,YACT,GAAG,UAAU,QAAQ,CAAC,WAAW,SAAS,GAAG,KAAK,IAClD,GAAG,UAAU;AAAA,QACnB;AAEA,mBAAW,MAAM,YAAY;AAC3B,gBAAM,IAAI,OAAO,kBAAkB,GAAG,IAAI,CAAC;AAC3C,gBAAM,MAAM,EACT,OAAO,GAAG,EACV,KAAK,SAAS,UAAU,EACxB,KAAK,cAAc,QAAQ,EAC3B,KAAK,oBAAoB,OAAO,GAAG,UAAU,CAAC,EAC9C,KAAK,aAAa,OAAO,kBAAkB,GAAG,IAAI,CAAC,CAAC,EACpD;AAAA,YACC;AAAA,YACA,GAAG,UAAU,OAAO,kBAAkB,GAAG,OAAO,CAAC,IAAI;AAAA,UACvD,EACC,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,SAAU,OAAmB;AAC7C,wBAAY,GAAG,QAAQ;AACvB,wBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,UACvD,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,sBAAU,CAAC;AACX,wBAAY,OAAO;AAAA,UACrB,CAAC,EACA,GAAG,aAAa,SAAU,OAAmB;AAC5C,wBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,UACvD,CAAC,EACA,GAAG,SAAS,MAAM;AACjB,gBAAI,eAAe,GAAG,WAAY,aAAY,GAAG,UAAU;AAAA,UAC7D,CAAC;AAEH,cAAI,GAAG,SAAS;AACd,kBAAM,KAAK,OAAO,kBAAkB,GAAG,OAAO,CAAC;AAC/C,kBAAM,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC;AAChC,gBACG,OAAO,MAAM,EACb,KAAK,KAAK,aAAa,CAAC,EACxB,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,EAAE,EAChB,KAAK,UAAU,KAAK,EACpB,KAAK,MAAM,CAAC,EACZ,KAAK,QAAQ,SAAS;AACzB,gBACG,OAAO,MAAM,EACb,KAAK,KAAK,aAAa,EAAE,EACzB,KAAK,KAAK,IAAI,QAAQ,CAAC,EACvB,KAAK,MAAM,QAAQ,EACnB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,UAClB,OAAO;AACL,gBACG,OAAO,QAAQ,EACf,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,CAAC,EACZ,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,SAAS,EACtB,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,GAAG;AAC3B,gBACG,OAAO,MAAM,EACb,KAAK,KAAK,aAAa,EAAE,EACzB,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,UAClB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AAEL,YAAM,cAAc,gBAAgB,KAAK;AACzC,YAAM,eAAe,gBAAgB,SAAS,IAAI,KAAK;AACvD,YAAM,SAAS;AAAA,QACb,KAAK,MAAM;AAAA,QACX,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM,KAAK;AAAA,MACb;AACA,YAAM,aAAa,QAAQ,OAAO,OAAO,OAAO;AAChD,YAAM,cAAc,SAAS,OAAO,MAAM,OAAO;AACjD,YAAM,QAAQ;AAEd,YAAM,SACH,oBAAY,EACZ,OAAO,CAAC,UAAU,aAAa,UAAU,WAAW,CAAC,EACrD,MAAM,CAAC,GAAG,WAAW,CAAC;AAEzB,YAAM,SAAS,eACZ,MAAM,EACN,KAAK,CAAC,GAAG,MAAM,kBAAkB,EAAE,IAAI,IAAI,kBAAkB,EAAE,IAAI,CAAC;AAEvE,YAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,YAAM,IAAI,IACP,OAAO,GAAG,EACV,KAAK,aAAa,aAAa,OAAO,IAAI,IAAI,OAAO,GAAG,GAAG;AAE9D,UAAI,OAAO;AACT,cAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,YAAI,OAAO,iBAAiB;AAC1B,kBAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,cAAI,aAAa;AACf,oBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,cAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,YAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,cAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,YAAG,CAAC;AAAA,UAClF;AAAA,QACF;AAAA,MACF;AAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,GAAG,MAAM,UAAU,GAAG,GAAG,CAAC;AAAA,QAC3B,MAAM,UAAU,CAAC;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,eAAe;AACjB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,gBAAgB,oBAAoB;AAAA,UACpC,gBAAgB,gBAAgB;AAAA,QAClC;AAAA,MACF;AAGA,UAAI,eAAe,SAAS,GAAG;AAC7B,YAAI,UAAU;AACd,cAAM,UAAU;AAChB,mBAAW,OAAO,gBAAgB;AAChC,gBAAM,QAAQ,cAAc,IAAI,IAAI,IAAI,KAAK;AAC7C,gBAAM,QAAQ,EACX,OAAO,GAAG,EACV,KAAK,SAAS,gBAAgB,EAC9B,KAAK,cAAc,IAAI,IAAI,EAC3B,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,EAC/C,GAAG,cAAc,MAAM,UAAU,CAAC,CAAC;AAEtC,gBACG,OAAO,QAAQ,EACf,KAAK,MAAM,OAAO,EAClB,KAAK,MAAM,OAAO,EAClB,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,KAAK;AAErB,gBACG,OAAO,MAAM,EACb,KAAK,KAAK,UAAU,EAAE,EACtB,KAAK,KAAK,OAAO,EACjB,KAAK,MAAM,QAAQ,EACnB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,IAAI,IAAI;AAEhB,qBAAW,IAAI,KAAK,SAAS,IAAI;AAAA,QACnC;AAAA,MACF;AAEA,QAAE,OAAO,MAAM,EACZ,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,CAAC,EACtB,KAAK,oBAAoB,KAAK;AAEjC,iBAAW,MAAM,QAAQ;AACvB,cAAM,IAAI,OAAO,kBAAkB,GAAG,IAAI,CAAC;AAC3C,cAAM,QAAQ,WAAW,EAAE;AAE3B,cAAM,MAAM,EACT,OAAO,GAAG,EACV,KAAK,SAAS,UAAU,EACxB,KAAK,cAAc,GAAG,SAAS,EAAE,EACjC,KAAK,oBAAoB,OAAO,GAAG,UAAU,CAAC,EAC9C,KAAK,aAAa,OAAO,kBAAkB,GAAG,IAAI,CAAC,CAAC,EACpD;AAAA,UACC;AAAA,UACA,GAAG,UAAU,OAAO,kBAAkB,GAAG,OAAO,CAAC,IAAI;AAAA,QACvD,EACC,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,SAAU,OAAmB;AAC7C,cAAI,GAAG,SAAS,eAAe,SAAS,EAAG,aAAY,GAAG,GAAG,KAAK;AAClE,sBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,QACvD,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,oBAAU,CAAC;AACX,sBAAY,OAAO;AAAA,QACrB,CAAC,EACA,GAAG,aAAa,SAAU,OAAmB;AAC5C,sBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,QACvD,CAAC,EACA,GAAG,SAAS,MAAM;AACjB,cAAI,eAAe,GAAG,WAAY,aAAY,GAAG,UAAU;AAAA,QAC7D,CAAC;AAEH,YAAI,GAAG,SAAS;AACd,gBAAM,KAAK,OAAO,kBAAkB,GAAG,OAAO,CAAC;AAC/C,gBAAM,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC;AAChC,cACG,OAAO,MAAM,EACb,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,EAAE,EAChB,KAAK,UAAU,KAAK,EACpB,KAAK,MAAM,CAAC,EACZ,KAAK,QAAQ,KAAK;AACrB,cACG,OAAO,MAAM,EACb,KAAK,KAAK,QAAQ,EAAE,EACpB,KAAK,KAAK,IAAI,QAAQ,CAAC,EACvB,KAAK,MAAM,QAAQ,EACnB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,QAClB,OAAO;AACL,cACG,OAAO,QAAQ,EACf,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,CAAC,EACZ,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,KAAK,EAClB,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,GAAG;AAC3B,cACG,OAAO,MAAM,EACb,KAAK,KAAK,QAAQ,EAAE,EACpB,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,QAClB;AAGA,YACG,OAAO,MAAM,EACb,KAAK,KAAK,QAAQ,EAAE,EACpB;AAAA,UACC;AAAA,UACA,GAAG,UACC,OAAO,kBAAkB,GAAG,IAAI,CAAC,IAC/B,KAAK;AAAA,YACH,OAAO,kBAAkB,GAAG,OAAO,CAAC,IAClC,OAAO,kBAAkB,GAAG,IAAI,CAAC;AAAA,YACnC;AAAA,UACF,IACE,IACJ;AAAA,QACN,EACC,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,KAAK,EACzB,KAAK,QAAQ,UAAU,EACvB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,QAAQ,GAAG,UAAU,SAAI,GAAG,OAAO,KAAK,GAAG;AAAA,MACxD;AAAA,IACF;AAEA;AAAA,EACF;AAOA,QAAM,QAAQ;AACd,QAAM,YAAY;AAElB,MAAI,iBAAiB,WAAW,eAAe,SAAS,GAAG;AAEzD,UAAM,aAAa,eAAe,IAAI,CAAC,OAAO,GAAG,IAAI;AACrD,UAAM,kBAAkB,eAAe;AAAA,MACrC,CAAC,OAAO,GAAG,UAAU,QAAQ,CAAC,WAAW,SAAS,GAAG,KAAK;AAAA,IAC5D;AACA,UAAM,YACJ,gBAAgB,SAAS,IAAI,CAAC,GAAG,YAAY,SAAS,IAAI;AAG5D,UAAM,QAAQ,UAAU,IAAI,CAAC,UAAU;AAAA,MACrC;AAAA,MACA,QAAQ,eAAe;AAAA,QAAO,CAAC,OAC7B,SAAS,YACL,GAAG,UAAU,QAAQ,CAAC,WAAW,SAAS,GAAG,KAAK,IAClD,GAAG,UAAU;AAAA,MACnB;AAAA,IACF,EAAE;AAEF,UAAM,iBAAiB,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AACpE,UAAM,cAAc,gBAAgB,KAAK;AACzC,UAAM,eAAe,gBAAgB,SAAS,IAAI,KAAK;AAEvD,UAAM,kBAAkB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AACnE,UAAM,oBAAoB,KAAK,IAAI,KAAK,kBAAkB,IAAI,EAAE;AAEhE,UAAM,gBAAgB,QAAQ,KAAK;AACnC,UAAM,SAAS;AAAA,MACb,KAAK,iBAAiB,gBAAgB,KAAK,KAAK;AAAA,MAChD,OAAO;AAAA,MACP,QAAQ,KAAK;AAAA,MACb,MAAM;AAAA,IACR;AACA,UAAM,aAAa,QAAQ,OAAO,OAAO,OAAO;AAChD,UAAM,cAAc,SAAS,OAAO,MAAM,OAAO;AACjD,UAAM,aAAa,MAAM,SAAS,KAAK;AACvC,UAAM,OAAO,KAAK,IAAI,KAAK,cAAc,aAAa,cAAc;AAEpE,UAAM,SACH,oBAAY,EACZ,OAAO,CAAC,UAAU,aAAa,UAAU,WAAW,CAAC,EACrD,MAAM,CAAC,GAAG,UAAU,CAAC;AAExB,UAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,UAAM,IAAI,IACP,OAAO,GAAG,EACV,KAAK,aAAa,aAAa,OAAO,IAAI,IAAI,OAAO,GAAG,GAAG;AAE9D,QAAI,OAAO;AACT,YAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,UAAI,OAAO,iBAAiB;AAC1B,gBAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,YAAI,aAAa;AACf,kBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,YAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,UAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,YAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,UAAG,CAAC;AAAA,QAClF;AAAA,MACF;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,GAAG,MAAM,UAAU,GAAG,GAAG,CAAC;AAAA,MAC3B,MAAM,UAAU,CAAC;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,eAAe;AACjB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,oBAAoB;AAAA,QACpC,gBAAgB,gBAAgB;AAAA,MAClC;AAAA,IACF;AAGA,QAAI,OAAO;AAIX,QAAI,mBAAmB;AACrB,UAAI,QAAQ;AACZ,YAAM,QAAQ,CAAC,MAAM,QAAQ;AAC3B,cAAM,WAAW,KAAK,OAAO,SAAS;AAEtC,cAAM,YAAY,MAAM,MAAM,IAAI,YAAY;AAC9C,UAAE,OAAO,MAAM,EACZ,KAAK,SAAS,aAAa,EAC3B,KAAK,cAAc,KAAK,IAAI,EAC5B,KAAK,KAAK,CAAC,OAAO,IAAI,EACtB,KAAK,KAAK,KAAK,EACf,KAAK,SAAS,aAAa,OAAO,IAAI,EACtC,KAAK,UAAU,YAAY,MAAM,MAAM,SAAS,IAAI,YAAY,EAAE,EAClE,KAAK,QAAQ,SAAS,EACtB,KAAK,WAAW,IAAI;AACvB,iBAAS,WAAW;AAAA,MACtB,CAAC;AAAA,IACH;AAEA,eAAW,QAAQ,OAAO;AACxB,YAAM,YAAY,cAAc,IAAI,KAAK,IAAI,KAAK;AAClD,YAAM,WAAW,KAAK,OAAO,SAAS;AAGtC,YAAM,QAAQ,eAAe,KAAK,CAAC,QAAQ,IAAI,SAAS,KAAK,IAAI;AACjE,YAAM,UAAU,EACb,OAAO,GAAG,EACV,KAAK,SAAS,gBAAgB,EAC9B,KAAK,cAAc,KAAK,IAAI,EAC5B,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,YAAY,GAAG,KAAK,IAAI,CAAC,EAChD,GAAG,cAAc,MAAM,UAAU,CAAC,CAAC,EACnC,GAAG,SAAS,MAAM;AACjB,YAAI,eAAe,OAAO,WAAY,aAAY,MAAM,UAAU;AAAA,MACpE,CAAC;AAEH,cACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,OAAO,OAAO,EAAE,EAC3B,KAAK,KAAK,OAAO,WAAW,CAAC,EAC7B,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,OAAO,EAC3B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,KAAK,IAAI;AAEjB,WAAK,OAAO,QAAQ,CAAC,IAAI,MAAM;AAC7B,cAAM,IAAI,OAAO,IAAI,OAAO,OAAO;AACnC,cAAM,IAAI,OAAO,kBAAkB,GAAG,IAAI,CAAC;AAE3C,cAAM,MAAM,EACT,OAAO,GAAG,EACV,KAAK,SAAS,UAAU,EACxB,KAAK,cAAc,KAAK,IAAI,EAC5B,KAAK,oBAAoB,OAAO,GAAG,UAAU,CAAC,EAC9C,KAAK,aAAa,OAAO,kBAAkB,GAAG,IAAI,CAAC,CAAC,EACpD;AAAA,UACC;AAAA,UACA,GAAG,UAAU,OAAO,kBAAkB,GAAG,OAAO,CAAC,IAAI;AAAA,QACvD,EACC,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,SAAU,OAAmB;AAC7C,sBAAY,GAAG,KAAK,IAAI;AACxB,cAAI,eAAe;AACjB;AAAA,cACE;AAAA,cACA;AAAA,cACA,GAAG;AAAA,cACH,GAAG;AAAA,cACH;AAAA,cACA;AAAA,YACF;AAAA,UACF,OAAO;AACL,wBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,UACvD;AAAA,QACF,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,oBAAU,CAAC;AACX,cAAI,eAAe;AACjB,kCAAsB,CAAC;AAAA,UACzB,OAAO;AACL,wBAAY,OAAO;AAAA,UACrB;AAAA,QACF,CAAC,EACA,GAAG,aAAa,SAAU,OAAmB;AAC5C,cAAI,CAAC,eAAe;AAClB,wBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,UACvD;AAAA,QACF,CAAC,EACA,GAAG,SAAS,MAAM;AACjB,cAAI,eAAe,GAAG,WAAY,aAAY,GAAG,UAAU;AAAA,QAC7D,CAAC;AAEH,YAAI,GAAG,SAAS;AACd,gBAAM,KAAK,OAAO,kBAAkB,GAAG,OAAO,CAAC;AAC/C,gBAAM,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC;AAEhC,gBAAM,gBAAgB,GAAG,MAAM,SAAS,IAAI;AAC5C,gBAAM,kBAAkB,SAAS;AAEjC,cAAIE,QAAe;AACnB,cAAI,GAAG,WAAW;AAEhB,kBAAM,aAAa,aAAa,GAAG,UAAU;AAC7C,kBAAM,OAAO,IAAI,OAAO,MAAM,EAAE,KAAK,KAAK,IAAI,OAAO,MAAM,EAAE,KAAK;AAClE,YACG,oBAAO,IAAe,EACtB,OAAO,gBAAgB,EACvB,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,IAAI,EACf,KAAK,MAAM,IAAI,EACf,KAAK,MAAM,MAAM,EACjB,KAAK,MAAM,IAAI,EACf,UAAU,MAAM,EAChB,KAAK;AAAA,cACJ,EAAE,QAAQ,MAAM,SAAS,EAAE;AAAA,cAC3B,EAAE,QAAQ,OAAO,SAAS,EAAE;AAAA,cAC5B,EAAE,QAAQ,QAAQ,SAAS,EAAE;AAAA,YAC/B,CAAC,EACA,MAAM,EACN,OAAO,MAAM,EACb,KAAK,UAAU,CAAC,MAAM,EAAE,MAAM,EAC9B,KAAK,cAAc,SAAS,EAC5B,KAAK,gBAAgB,CAAC,MAAM,EAAE,OAAO;AACxC,YAAAA,QAAO,QAAQ,UAAU;AAAA,UAC3B;AAEA,cACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,IAAI,QAAQ,CAAC,EACvB,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,KAAK,EACpB,KAAK,MAAM,CAAC,EACZ,KAAK,QAAQA,KAAI;AAEpB,cAAI,iBAAiB;AAEnB,gBACG,OAAO,MAAM,EACb,KAAK,KAAK,IAAI,CAAC,EACf,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,OAAO,EAC3B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,GAAG,KAAK;AAAA,UAClB,OAAO;AAEL,kBAAM,gBAAgB,IAAI,QAAQ,aAAa;AAC/C,kBAAM,gBAAgB,IAAI,IAAI,gBAAgB;AAC9C,kBAAM,WAAW,iBAAiB;AAClC,gBACG,OAAO,MAAM,EACb,KAAK,KAAK,WAAW,IAAI,IAAI,IAAI,QAAQ,CAAC,EAC1C,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,WAAW,QAAQ,OAAO,EAC9C,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,UAClB;AAAA,QACF,OAAO;AAEL,gBAAM,gBAAgB,GAAG,MAAM,SAAS;AAExC,gBAAM,gBAAgB,IAAI,aAAa;AACvC,gBAAM,gBAAgB,IAAI,KAAK,gBAAgB;AAC/C,gBAAM,WAAW,iBAAiB;AAClC,cACG,OAAO,QAAQ,EACf,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,SAAS,EACtB,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,GAAG;AAC3B,cACG,OAAO,MAAM,EACb,KAAK,KAAK,WAAW,IAAI,KAAK,IAAI,EAAE,EACpC,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,WAAW,QAAQ,OAAO,EAC9C,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,QAClB;AAAA,MACF,CAAC;AAED,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,OAAO;AAEL,UAAM,SAAS,eACZ,MAAM,EACN,KAAK,CAAC,GAAG,MAAM,kBAAkB,EAAE,IAAI,IAAI,kBAAkB,EAAE,IAAI,CAAC;AAEvE,UAAM,cAAc,gBAAgB,KAAK;AACzC,UAAM,eAAe,gBAAgB,SAAS,IAAI,KAAK;AACvD,UAAM,SAAS;AAAA,MACb,KAAK,OAAO,gBAAgB,KAAK,KAAK;AAAA,MACtC,OAAO;AAAA,MACP,QAAQ,KAAK;AAAA,MACb,MAAM;AAAA,IACR;AACA,UAAM,aAAa,QAAQ,OAAO,OAAO,OAAO;AAChD,UAAM,cAAc,SAAS,OAAO,MAAM,OAAO;AACjD,UAAM,OAAO,KAAK,IAAI,IAAI,cAAc,OAAO,MAAM;AAErD,UAAM,SACH,oBAAY,EACZ,OAAO,CAAC,UAAU,aAAa,UAAU,WAAW,CAAC,EACrD,MAAM,CAAC,GAAG,UAAU,CAAC;AAExB,UAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,UAAM,IAAI,IACP,OAAO,GAAG,EACV,KAAK,aAAa,aAAa,OAAO,IAAI,IAAI,OAAO,GAAG,GAAG;AAE9D,QAAI,OAAO;AACT,YAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,UAAI,OAAO,iBAAiB;AAC1B,gBAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,YAAI,aAAa;AACf,kBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,YAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,UAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,YAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,UAAG,CAAC;AAAA,QAClF;AAAA,MACF;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,GAAG,MAAM,UAAU,GAAG,GAAG,CAAC;AAAA,MAC3B,MAAM,UAAU,CAAC;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,eAAe;AACjB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,oBAAoB;AAAA,QACpC,gBAAgB,gBAAgB;AAAA,MAClC;AAAA,IACF;AAGA,QAAI,eAAe,SAAS,GAAG;AAC7B,UAAI,UAAU;AACd,YAAM,UAAU,gBAAgB,MAAM;AACtC,iBAAW,OAAO,gBAAgB;AAChC,cAAM,QAAQ,cAAc,IAAI,IAAI,IAAI,KAAK;AAC7C,cAAM,QAAQ,EACX,OAAO,GAAG,EACV,KAAK,SAAS,gBAAgB,EAC9B,KAAK,cAAc,IAAI,IAAI,EAC3B,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,EAC/C,GAAG,cAAc,MAAM,UAAU,CAAC,CAAC;AAEtC,cACG,OAAO,QAAQ,EACf,KAAK,MAAM,OAAO,EAClB,KAAK,MAAM,OAAO,EAClB,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,KAAK;AAErB,cACG,OAAO,MAAM,EACb,KAAK,KAAK,UAAU,EAAE,EACtB,KAAK,KAAK,OAAO,EACjB,KAAK,MAAM,QAAQ,EACnB,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,IAAI,IAAI;AAEhB,mBAAW,IAAI,KAAK,SAAS,IAAI;AAAA,MACnC;AAAA,IACF;AAEA,WAAO,QAAQ,CAAC,IAAI,MAAM;AAExB,YAAM,IAAI,eAAe,IAAI,OAAO,OAAO;AAC3C,YAAM,IAAI,OAAO,kBAAkB,GAAG,IAAI,CAAC;AAC3C,YAAM,QAAQ,WAAW,EAAE;AAE3B,YAAM,MAAM,EACT,OAAO,GAAG,EACV,KAAK,SAAS,UAAU,EACxB,KAAK,cAAc,GAAG,SAAS,EAAE,EACjC,KAAK,oBAAoB,OAAO,GAAG,UAAU,CAAC,EAC9C,KAAK,aAAa,OAAO,kBAAkB,GAAG,IAAI,CAAC,CAAC,EACpD;AAAA,QACC;AAAA,QACA,GAAG,UAAU,OAAO,kBAAkB,GAAG,OAAO,CAAC,IAAI;AAAA,MACvD,EACC,MAAM,UAAU,SAAS,EACzB,GAAG,cAAc,SAAU,OAAmB;AAC7C,YAAI,GAAG,SAAS,eAAe,SAAS,EAAG,aAAY,GAAG,GAAG,KAAK;AAClE,YAAI,eAAe;AACjB;AAAA,YACE;AAAA,YACA;AAAA,YACA,GAAG;AAAA,YACH,GAAG;AAAA,YACH;AAAA,YACA;AAAA,UACF;AAAA,QACF,OAAO;AACL,sBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,QACvD;AAAA,MACF,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,kBAAU,CAAC;AACX,YAAI,eAAe;AACjB,gCAAsB,CAAC;AAAA,QACzB,OAAO;AACL,sBAAY,OAAO;AAAA,QACrB;AAAA,MACF,CAAC,EACA,GAAG,aAAa,SAAU,OAAmB;AAC5C,YAAI,CAAC,eAAe;AAClB,sBAAY,SAAS,sBAAsB,EAAE,GAAG,KAAK;AAAA,QACvD;AAAA,MACF,CAAC,EACA,GAAG,SAAS,MAAM;AACjB,YAAI,eAAe,GAAG,WAAY,aAAY,GAAG,UAAU;AAAA,MAC7D,CAAC;AAEH,UAAI,GAAG,SAAS;AACd,cAAM,KAAK,OAAO,kBAAkB,GAAG,OAAO,CAAC;AAC/C,cAAM,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC;AAEhC,cAAM,gBAAgB,GAAG,MAAM,SAAS,IAAI;AAC5C,cAAM,kBAAkB,SAAS;AAEjC,YAAIA,QAAe;AACnB,YAAI,GAAG,WAAW;AAEhB,gBAAM,aAAa,gBAAgB,GAAG,UAAU;AAChD,gBAAM,OAAO,IAAI,OAAO,MAAM,EAAE,KAAK,KAAK,IAAI,OAAO,MAAM,EAAE,KAAK;AAClE,UACG,oBAAO,IAAe,EACtB,OAAO,gBAAgB,EACvB,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,IAAI,EACf,KAAK,MAAM,IAAI,EACf,KAAK,MAAM,MAAM,EACjB,KAAK,MAAM,IAAI,EACf,UAAU,MAAM,EAChB,KAAK;AAAA,YACJ,EAAE,QAAQ,MAAM,SAAS,EAAE;AAAA,YAC3B,EAAE,QAAQ,OAAO,SAAS,EAAE;AAAA,YAC5B,EAAE,QAAQ,QAAQ,SAAS,EAAE;AAAA,UAC/B,CAAC,EACA,MAAM,EACN,OAAO,MAAM,EACb,KAAK,UAAU,CAAC,MAAM,EAAE,MAAM,EAC9B,KAAK,cAAc,KAAK,EACxB,KAAK,gBAAgB,CAAC,MAAM,EAAE,OAAO;AACxC,UAAAA,QAAO,QAAQ,UAAU;AAAA,QAC3B;AAEA,YACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,IAAI,QAAQ,CAAC,EACvB,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,KAAK,EACpB,KAAK,MAAM,CAAC,EACZ,KAAK,QAAQA,KAAI;AAEpB,YAAI,iBAAiB;AAEnB,cACG,OAAO,MAAM,EACb,KAAK,KAAK,IAAI,CAAC,EACf,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,OAAO,EAC3B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,GAAG,KAAK;AAAA,QAClB,OAAO;AAEL,gBAAM,gBAAgB,IAAI,QAAQ,aAAa;AAC/C,gBAAM,gBAAgB,IAAI,IAAI,gBAAgB;AAC9C,gBAAM,WAAW,iBAAiB;AAClC,cACG,OAAO,MAAM,EACb,KAAK,KAAK,WAAW,IAAI,IAAI,IAAI,QAAQ,CAAC,EAC1C,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,WAAW,QAAQ,OAAO,EAC9C,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,QAClB;AAAA,MACF,OAAO;AAEL,cAAM,gBAAgB,GAAG,MAAM,SAAS;AAExC,cAAM,gBAAgB,IAAI,aAAa;AACvC,cAAM,gBAAgB,IAAI,KAAK,gBAAgB;AAC/C,cAAM,WAAW,iBAAiB;AAClC,YACG,OAAO,QAAQ,EACf,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,KAAK,EAClB,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,GAAG;AAC3B,YACG,OAAO,MAAM,EACb,KAAK,KAAK,WAAW,IAAI,KAAK,IAAI,EAAE,EACpC,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,QAAQ,EACnB,KAAK,eAAe,WAAW,QAAQ,OAAO,EAC9C,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,GAAG,KAAK;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAMA,SAAS,YAAY,MAAqC;AACxD,MAAI,SAAS,QAAS,QAAO,MAAO,KAAK,OAAO,IAAI,MAAM,IAAI;AAC9D,MAAI,SAAS,SAAU,QAAO,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,EAAE;AACtE,SAAO,MAAM;AACf;AASO,SAAS,gBACd,WACA,QACA,SACA,SACA,aACA,YACM;AACN,EAAY,oBAAO,SAAS,EAAE,UAAU,yBAAyB,EAAE,OAAO;AAE1E,QAAM,EAAE,OAAO,OAAO,aAAa,IAAI;AACvC,MAAI,MAAM,WAAW,EAAG;AAExB,QAAM,QAAQ,YAAY,SAAS,UAAU;AAC7C,QAAM,SAAS,YAAY,UAAU,UAAU;AAC/C,MAAI,SAAS,KAAK,UAAU,EAAG;AAE/B,QAAM,cAAc,QAAQ,KAAK;AACjC,QAAM,cAAc,SAAS;AAE7B,QAAM,YAAY,QAAQ;AAC1B,QAAM,UAAU,QAAQ;AACxB,QAAM,SAAS,gBAAgB,OAAO;AAEtC,QAAM,EAAE,SAAS,QAAQ,IAAI;AAC7B,QAAM,UAAU,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM;AACzC,QAAM,YAAY,KAAK,IAAI,GAAG,OAAO;AACrC,QAAM,YAAY,KAAK,IAAI,GAAG,OAAO;AACrC,QAAM,QAAQ,YAAY,aAAa;AAEvC,QAAM,WAAW,CAAC,WAA2B;AAC3C,UAAM,KAAK,SAAS,aAAa;AACjC,WAAO,UAAU,KAAK,UAAU;AAAA,EAClC;AAEA,QAAM,WAAW,YAAY,aAAa,MAAM;AAEhD,QAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,MAAI,OAAO;AACT,UAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,QAAI,OAAO,iBAAiB;AAC1B,cAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,UAAI,aAAa;AACf,gBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,QAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,QAAG,CAAC;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,IACP,OAAO,GAAG,EACV;AAAA,IACC;AAAA,IACA,aAAa,QAAQ,CAAC,IAAI,cAAc,cAAc,CAAC;AAAA,EACzD;AAEF,sBAAAC,SAAkC,EAC/B,KAAK,CAAC,OAAO,WAAW,CAAC,EACzB,MAAM,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAC5D,QAAQ,CAAC,EACT,OAAO,QAAQ,EACf,SAAS,CAAC,MAAM,EAAE,IAAK,EACvB,KAAK,WAAW,EAChB,GAAG,OAAO,CAAC,gBAAgB;AAC1B,MAAE,UAAU,MAAM,EACf,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,MAAM,aAAa,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,EACvC,MAAM,eAAe,WAAW,EAChC,MAAM,eAAe,KAAK,EAC1B,MAAM,QAAQ,CAAC,IAAI,MAAM,OAAO,IAAI,OAAO,MAAM,CAAC,EAClD;AAAA,MAAM;AAAA,MAAU,CAAC,MAChB,eAAgB,EAAoB,aAAa,YAAY;AAAA,IAC/D,EACC,KAAK,eAAe,QAAQ,EAC5B;AAAA,MACC;AAAA,MACA,CAAC,MAAM,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM;AAAA,IACpD,EACC,KAAK,oBAAoB,CAAC,MAAM;AAC/B,YAAM,KAAM,EAAoB;AAChC,aAAO,KAAK,OAAO,EAAE,IAAI;AAAA,IAC3B,CAAC,EACA,KAAK,CAAC,MAAM,EAAE,IAAK,EACnB,GAAG,SAAS,CAAC,QAAQ,MAAM;AAC1B,YAAM,KAAM,EAAoB;AAChC,UAAI,eAAe,GAAI,aAAY,EAAE;AAAA,IACvC,CAAC;AAAA,EACL,CAAC,EACA,MAAM;AACX;AAMA,SAAS,qBACP,WACA,QACA,SACA,SACA,YACe;AACf,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,IAAY,oBAAO,SAAS,EAAE,UAAU,yBAAyB,EAAE,OAAO;AAE1E,UAAM,EAAE,OAAO,OAAO,aAAa,IAAI;AACvC,QAAI,MAAM,WAAW,GAAG;AACtB,cAAQ;AACR;AAAA,IACF;AAEA,UAAM,QAAQ,YAAY,SAAS,UAAU;AAC7C,UAAM,SAAS,YAAY,UAAU,UAAU;AAC/C,QAAI,SAAS,KAAK,UAAU,GAAG;AAC7B,cAAQ;AACR;AAAA,IACF;AAEA,UAAM,cAAc,QAAQ,KAAK;AACjC,UAAM,cAAc,SAAS;AAE7B,UAAM,YAAY,QAAQ;AAC1B,UAAM,UAAU,QAAQ;AACxB,UAAM,SAAS,gBAAgB,OAAO;AAEtC,UAAM,EAAE,SAAS,QAAQ,IAAI;AAC7B,UAAM,UAAU,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM;AACzC,UAAM,YAAY,KAAK,IAAI,GAAG,OAAO;AACrC,UAAM,YAAY,KAAK,IAAI,GAAG,OAAO;AACrC,UAAM,QAAQ,YAAY,aAAa;AAEvC,UAAM,WAAW,CAAC,WAA2B;AAC3C,YAAM,KAAK,SAAS,aAAa;AACjC,aAAO,UAAU,KAAK,UAAU;AAAA,IAClC;AAEA,UAAM,WAAW,YAAY,aAAa,MAAM;AAEhD,UAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAE9B,QAAI,OAAO;AACT,YAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,KAAK,KAAK;AAEb,UAAI,OAAO,iBAAiB;AAC1B,gBAAQ,KAAK,oBAAoB,OAAO,eAAe;AAAA,MACzD;AAAA,IACF;AAEA,UAAM,IAAI,IACP,OAAO,GAAG,EACV;AAAA,MACC;AAAA,MACA,aAAa,QAAQ,CAAC,IAAI,cAAc,cAAc,CAAC;AAAA,IACzD;AAEF,wBAAAA,SAAkC,EAC/B,KAAK,CAAC,OAAO,WAAW,CAAC,EACzB,MAAM,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAC5D,QAAQ,CAAC,EACT,OAAO,QAAQ,EACf,SAAS,CAAC,MAAM,EAAE,IAAK,EACvB,KAAK,WAAW,EAChB,GAAG,OAAO,CAAC,gBAAgB;AAC1B,QAAE,UAAU,MAAM,EACf,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,MAAM,aAAa,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,EACvC,MAAM,eAAe,WAAW,EAChC,MAAM,eAAe,KAAK,EAC1B,MAAM,QAAQ,CAAC,IAAI,MAAM,OAAO,IAAI,OAAO,MAAM,CAAC,EAClD,KAAK,eAAe,QAAQ,EAC5B;AAAA,QACC;AAAA,QACA,CAAC,MAAM,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM;AAAA,MACpD,EACC,KAAK,CAAC,MAAM,EAAE,IAAK;AACtB,cAAQ;AAAA,IACV,CAAC,EACA,MAAM;AAAA,EACX,CAAC;AACH;AAMA,SAAS,eAAe,MAAsB;AAC5C,SAAO,KAAK,KAAK,OAAO,KAAK,EAAE;AACjC;AAEA,SAAS,kBAAkB,IAAY,IAAY,GAAmB;AAEpE,MAAI,KAAK,KAAK,GAAI,QAAO;AAEzB,MAAI,IAAI,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG;AAC5C,WAAO,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,KAAK;AAAA,EACvC;AACA,QAAM,QAAQ,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,KAAK,OAAO,IAAI,IAAI,GAAG;AAC5E,QAAM,QAAQ,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,KAAK,OAAO,IAAI,IAAI,GAAG;AAC5E,QAAM,QACJ,MACA,KAAK,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,OAAO,IAAI,KAAK,OAAO,IAAI,KAAK,GAAG;AAC1E,SAAO,QAAQ,QAAQ;AACzB;AAEA,SAAS,mBACP,IACA,IACA,YACQ;AACR,MAAI,cAAc,EAAG,QAAO,KAAK;AACjC,QAAM,OAAO,KAAK,IAAI,IAAI,EAAE;AAC5B,MAAI,cAAc,KAAK,KAAK,OAAO,KAAM,QAAO,KAAK,IAAI,KAAK,EAAE;AAChE,MAAI,KAAK,KAAK,IAAI,KAAK,EAAE;AACzB,MAAI,KAAK,KAAK;AACd,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,OAAO,KAAK,MAAM;AACxB,QAAI,kBAAkB,IAAI,IAAI,GAAG,IAAI,YAAY;AAC/C,WAAK;AAAA,IACP,OAAO;AACL,WAAK;AAAA,IACP;AAAA,EACF;AACA,UAAQ,KAAK,MAAM;AACrB;AAaA,SAAS,oBACP,IACA,IACA,KACA,IACA,IACA,KACO;AACP,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACvC,MAAI,QAAQ,EAAG,QAAO,EAAE,GAAG,KAAK,KAAK,GAAG,GAAG;AAC3C,QAAM,QAAQ,MAAM,MAAM,MAAM,MAAM,MAAM,QAAQ,IAAI,MAAM;AAC9D,QAAM,OAAO,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,OAAO,IAAI,CAAC;AACnD,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAEhB,SAAO;AAAA,IACL,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO;AAAA,IAClC,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO;AAAA,EACpC;AACF;AAEA,SAAS,gCACP,SACA,GACA,GACA,OACA,QACA,MACA,SACU;AACV,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,MAAI,OAAO,UACT,OAAO,WACP,OAAO,UACP,OAAO;AACT,aAAW,KAAK,SAAS;AACvB,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,EACjC;AACA,QAAM,KAAK,OAAO;AAClB,QAAM,KAAK,OAAO;AAClB,QAAM,SAAS,IAAI,QAAQ;AAC3B,QAAM,SAAS,IAAI,OAAO;AAC1B,QAAM,QAAQ,KAAK,IAAI,SAAS,IAAI,SAAS,EAAE;AAC/C,QAAM,MAAM,OAAO,QAAQ;AAC3B,QAAM,MAAM,OAAO,QAAQ;AAC3B,QAAM,KAAK,QAAQ,SAAS;AAC5B,QAAM,KAAK,OAAO,SAAS;AAC3B,SAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,IACzB,IAAI,EAAE,IAAI,MAAM,QAAQ;AAAA,IACxB,IAAI,EAAE,IAAI,MAAM,QAAQ;AAAA,IACxB,GAAG,EAAE,IAAI;AAAA,EACX,EAAE;AACJ;AAEA,SAAS,cAAc,GAAU,GAAoB;AACnD,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,SAAO,KAAK,KAAK,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI;AAC1C;AAEA,SAAS,eAAe,SAAmB,QAA0B;AAEnE,QAAM,OAAO;AACb,MAAI,OAAO,UACT,OAAO,WACP,OAAO,UACP,OAAO;AACT,aAAW,KAAK,SAAS;AACvB,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAC/B,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,EACjC;AACA,QAAM,SAAS,OAAO,QAAQ;AAC9B,QAAM,SAAS,OAAO,QAAQ;AAC9B,MAAI,KAAK,GACP,KAAK,GACL,QAAQ;AACV,WAAS,KAAK,GAAG,MAAM,MAAM,MAAM;AACjC,UAAM,IAAI,OAAO,KAAK;AACtB,aAAS,KAAK,GAAG,MAAM,MAAM,MAAM;AACjC,YAAM,IAAI,OAAO,KAAK;AACtB,UAAI,QAAQ;AACZ,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAM,OAAO,cAAc,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC;AAC/C,YAAI,SAAS,OAAO,CAAC,GAAG;AACtB,kBAAQ;AACR;AAAA,QACF;AAAA,MACF;AACA,UAAI,OAAO;AACT,cAAM;AACN,cAAM;AACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,UAAU,GAAG;AAEf,QAAI,KAAK,GACP,KAAK,GACL,KAAK;AACP,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAI,OAAO,CAAC,GAAG;AACb,cAAM,QAAQ,CAAC,EAAE;AACjB,cAAM,QAAQ,CAAC,EAAE;AACjB;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,GAAG,MAAM,MAAM,IAAI,GAAG,MAAM,MAAM,GAAG;AAAA,EAChD;AACA,SAAO,EAAE,GAAG,KAAK,OAAO,GAAG,KAAK,MAAM;AACxC;AAMO,SAAS,WACd,WACA,QACA,SACA,QACA,aACA,YACM;AACN,EAAY,oBAAO,SAAS,EAAE,UAAU,yBAAyB,EAAE,OAAO;AAE1E,QAAM,EAAE,UAAU,cAAc,gBAAgB,MAAM,IAAI;AAC1D,MAAI,SAAS,SAAS,EAAG;AAEzB,QAAM,QAAQ,YAAY,SAAS,UAAU;AAC7C,QAAM,SAAS,YAAY,UAAU,UAAU;AAC/C,MAAI,SAAS,KAAK,UAAU,EAAG;AAE/B,QAAM,YAAY,QAAQ;AAC1B,QAAM,UAAU,QAAQ;AACxB,QAAM,SAAS,gBAAgB,OAAO;AACtC,QAAM,cAAc,QAAQ,KAAK;AAGjC,QAAM,QAAQ,SAAS,IAAI,CAAC,MAAM,eAAe,EAAE,IAAI,CAAC;AAGxD,QAAM,aAAa,oBAAI,IAAoB;AAC3C,aAAW,MAAM,cAAc;AAC7B,eAAW,IAAI,GAAG,KAAK,KAAK,GAAG,GAAG,GAAG,IAAI;AAAA,EAC3C;AAGA,MAAI;AACJ,QAAM,IAAI,SAAS;AAEnB,MAAI,MAAM,GAAG;AACX,UAAM,IAAI;AAAA,MACR,MAAM,CAAC;AAAA,MACP,MAAM,CAAC;AAAA,MACP,WAAW,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,KAAK;AAAA,IAC3E;AACA,iBAAa;AAAA,MACX,EAAE,GAAG,CAAC,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC,EAAE;AAAA,MAC/B,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC,EAAE;AAAA,IAChC;AAAA,EACF,OAAO;AAEL,UAAM,QAAQ,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI;AACxC,UAAM,UAAU,CAAC,GAAW,MAC1B,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG;AAEtC,UAAM,MAAM;AAAA,MACV,MAAM,CAAC;AAAA,MACP,MAAM,CAAC;AAAA,MACP,WAAW,IAAI,QAAQ,GAAG,CAAC,CAAC,KAAK;AAAA,IACnC;AACA,UAAM,MAAM;AAAA,MACV,MAAM,CAAC;AAAA,MACP,MAAM,CAAC;AAAA,MACP,WAAW,IAAI,QAAQ,GAAG,CAAC,CAAC,KAAK;AAAA,IACnC;AACA,UAAM,MAAM;AAAA,MACV,MAAM,CAAC;AAAA,MACP,MAAM,CAAC;AAAA,MACP,WAAW,IAAI,QAAQ,GAAG,CAAC,CAAC,KAAK;AAAA,IACnC;AAEA,UAAM,KAAK,CAAC,MAAM;AAClB,UAAM,KAAK,MAAM;AACjB,UAAM,OAAO,oBAAoB,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG;AAEvD,iBAAa;AAAA,MACX,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,EAAE;AAAA,MAC3B,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,EAAE;AAAA,MAC3B,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,GAAG,MAAM,CAAC,EAAE;AAAA,IACtC;AAAA,EACF;AAGA,QAAM,YAAY,SAAS;AAAA,IACzB,CAAC,GAAG,MAAM,EAAE,SAAS,OAAO,IAAI,OAAO,MAAM;AAAA,EAC/C;AAIA,QAAM,YAAY,WAAW,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,GAAG,CAAC,IAAI;AAC5D,QAAM,YAAY,WAAW,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,GAAG,CAAC,IAAI;AAG5D,MAAI,aAAa,IACf,cAAc,IACd,YAAY,IACZ,eAAe;AACjB,QAAM,UAAU;AAChB,QAAM,UAAU;AAChB,QAAM,eAAe;AAErB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,cAAc,SAAS,CAAC,EAAE,SAAS,SAAS,CAAC,EAAE;AACrD,UAAM,iBAAiB,YAAY,SAAS,MAAM,UAAU,UAAU;AACtE,UAAM,KAAK,WAAW,CAAC,EAAE,IAAI;AAC7B,UAAM,KAAK,WAAW,CAAC,EAAE,IAAI;AAE7B,QAAI,KAAK,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,GAAG;AAEhC,UAAI,MAAM,EAAG,eAAc,KAAK,IAAI,aAAa,cAAc;AAAA,UAC1D,cAAa,KAAK,IAAI,YAAY,cAAc;AAAA,IACvD,OAAO;AAEL,YAAM,eAAe,iBAAiB;AACtC,UAAI,MAAM,EAAG,gBAAe,KAAK,IAAI,cAAc,eAAe,EAAE;AAAA,UAC/D,aAAY,KAAK,IAAI,WAAW,eAAe,EAAE;AAAA,IACxD;AAAA,EACF;AAEA,QAAM,QAAQ,SAAS;AACvB,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,YAAY,EAAE;AAG7C,QAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAG9B,QAAM,UAAU,cAAc,WAAW,SAAS,MAAM;AAGxD,MAAI,OAAO;AACT,UAAM,UAAU,IACb,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,UAAU,eAAe,OAAO,kBAAkB,YAAY,SAAS,EAC7E,KAAK,KAAK;AAEb,QAAI,OAAO,iBAAiB;AAC1B,cAAQ,KAAK,oBAAoB,OAAO,eAAe;AACvD,UAAI,aAAa;AACf,gBACG,GAAG,SAAS,MAAM,YAAY,OAAO,eAAgB,CAAC,EACtD,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,QAAG,CAAC,EAC/E,GAAG,cAAc,WAAY;AAAE,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,QAAG,CAAC;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAiF,CAAC;AACxF,QAAM,cAAc,IAAI,OAAO,GAAG;AAClC,UAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,UAAM,KAAK,YACR,OAAO,QAAQ,EACf,KAAK,MAAM,EAAE,CAAC,EACd,KAAK,MAAM,EAAE,CAAC,EACd,KAAK,KAAK,EAAE,CAAC,EACb,KAAK,QAAQ,UAAU,CAAC,CAAC,EACzB,KAAK,gBAAgB,IAAI,EACzB,KAAK,UAAU,UAAU,CAAC,CAAC,EAC3B,KAAK,gBAAgB,CAAC,EACtB,MAAM,kBAAkB,MAAM;AAMjC,cAAU,KAAK,EAAE;AAAA,EACnB,CAAC;AAID,QAAM,MAAM,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,GAAG,CAAC,IAAI;AACnD,QAAM,MAAM,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,GAAG,CAAC,IAAI;AAGnD,WAAS,cACP,IACA,IACA,IACA,IACA,GACQ;AACR,UAAM,KAAK,KAAK,EAAE;AAClB,UAAM,KAAK,KAAK,EAAE;AAClB,UAAM,IAAI,KAAK,KAAK,KAAK;AACzB,UAAM,MAAM,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE,IAAI,EAAE;AACjD,QAAI,MAAM,EAAG,QAAO;AACpB,WAAO,CAAC,IAAI,KAAK,KAAK,GAAG;AAAA,EAC3B;AAEA,QAAM,aAAa,IAAI,OAAO,GAAG,EAAE,MAAM,kBAAkB,MAAM;AAIjE,WAAS,eAAe,IAAY,IAAY,IAAoB;AAElE,UAAM,KAAK,KAAK,QAAQ,EAAE,EAAE;AAC5B,UAAM,YAAY,KAAK,KAAK,KAAK,IAAI,GAAG,QAAQ,EAAE,EAAE,IAAI,QAAQ,EAAE,EAAE,IAAI,KAAK,EAAE,CAAC;AAChF,QAAI,OAAO,QAAQ,EAAE,EAAE,IAAI;AAC3B,QAAI,QAAQ,QAAQ,EAAE,EAAE,IAAI;AAE5B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,MAAM,GAAI;AACd,YAAM,MAAM,KAAK,QAAQ,CAAC,EAAE;AAC5B,UAAI,KAAK,IAAI,GAAG,KAAK,QAAQ,CAAC,EAAE,EAAG;AACnC,YAAM,KAAK,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,IAAI,MAAM,GAAG;AAC5D,YAAM,QAAQ,QAAQ,CAAC,EAAE,IAAI;AAC7B,YAAM,SAAS,QAAQ,CAAC,EAAE,IAAI;AAE9B,UAAI,SAAS,QAAQ,UAAU,MAAO,QAAO;AAC7C,UAAI,SAAS,QAAQ,SAAS,KAAM,QAAO;AAC3C,UAAI,UAAU,SAAS,QAAQ,MAAO,SAAQ;AAAA,IAChD;AACA,WAAO,KAAK,IAAI,GAAG,QAAQ,IAAI;AAAA,EACjC;AAGA,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,eAAe;AAErB,UAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,UAAM,OAAO,SAAS,CAAC,EAAE,SAAS,SAAS,CAAC,EAAE;AAG9C,UAAM,SAAS,QAAQ,IAAI,CAAC,GAAG,MAAM,MAAM,CAAC;AAC5C,UAAM,WAAW,eAAe,SAAS,MAAM;AAG/C,UAAM,SAAS,eAAe,SAAS,GAAG,SAAS,GAAG,CAAC;AAEvD,UAAM,UAAU,KAAK,IAAI,UAAU,KAAK;AAAA,MAAI;AAAA,OACzC,SAAS,eAAe,MAAM,KAAK,SAAS;AAAA,IAAS,CAAC;AACzD,UAAM,WAAW,KAAK,SAAS,WAAW;AAE1C,UAAM,aAAa,WAAW,eAAe,IAAI,UAC/C,cAAc,EAAE,GAAG,SAAS,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,GAAG,CAAC,KAC/D,cAAc,EAAE,GAAG,SAAS,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,GAAG,CAAC;AAEjE,QAAI,YAAY;AACd,iBACG,OAAO,MAAM,EACb,KAAK,KAAK,SAAS,CAAC,EACpB,KAAK,KAAK,SAAS,CAAC,EACpB,KAAK,eAAe,QAAQ,EAC5B,KAAK,qBAAqB,SAAS,EACnC,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,GAAG,KAAK,MAAM,OAAO,CAAC,IAAI,EAC5C,KAAK,eAAe,MAAM,EAC1B,KAAK,IAAI;AAAA,IACd,OAAO;AAEL,UAAI,KAAK,EAAE,IAAI;AACf,UAAI,KAAK,EAAE,IAAI;AACf,YAAM,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACvC,UAAI,MAAM,MAAM;AACd,aAAK;AACL,aAAK;AAAA,MACP,OAAO;AACL,cAAM;AACN,cAAM;AAAA,MACR;AAEA,YAAM,QAAQ,EAAE,IAAI,KAAK,EAAE;AAC3B,YAAM,QAAQ,EAAE,IAAI,KAAK,EAAE;AAC3B,YAAM,QAAQ,QAAQ,KAAK;AAC3B,YAAM,QAAQ,QAAQ,KAAK;AAC3B,YAAM,WAAW,QAAQ,KAAK;AAC9B,YAAM,WAAW,QAAQ,KAAK;AAE9B,iBACG,OAAO,MAAM,EACb,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,KAAK,EAChB,KAAK,MAAM,QAAQ,EACnB,KAAK,MAAM,QAAQ,EACnB,KAAK,UAAU,SAAS,EACxB,KAAK,gBAAgB,CAAC;AAEzB,YAAM,UAAU,YAAY;AAC5B,YAAM,aAAa,UAAU,UAAU;AACvC,UAAI,QAAQ,YAAY,UAAU,eAAe,CAAC;AAClD,YAAM,QAAQ;AAEd,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,SAAS;AACX,gBAAQ,KAAK,IAAI,OAAO,QAAQ,OAAO,CAAC;AAAA,MAC1C,OAAO;AACL,gBAAQ,KAAK,IAAI,OAAO,OAAO,CAAC;AAAA,MAClC;AAEA,iBACG,OAAO,MAAM,EACb,KAAK,KAAK,KAAK,EACf,KAAK,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,SAAS,GAAG,KAAK,CAAC,CAAC,EACnD,KAAK,eAAe,UAAU,EAC9B,KAAK,qBAAqB,SAAS,EACnC,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,MAAM,EAC1B,KAAK,IAAI;AAAA,IACd;AAAA,EACF,CAAC;AAID,WAAS,aAAa,IAAY,MAAwB;AACxD,QAAI,OAAO,WAAW,QAAQ;AAE9B,eAAW,MAAM,MAAM;AACrB,YAAM,KAAK,KAAK,QAAQ,EAAE,EAAE;AAC5B,UAAI,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,EAAE,EAAG,QAAO;AAC1C,YAAM,KAAK,KAAK,KAAK,QAAQ,EAAE,EAAE,IAAI,QAAQ,EAAE,EAAE,IAAI,KAAK,EAAE;AAC5D,aAAO,KAAK,IAAI,MAAM,QAAQ,EAAE,EAAE,IAAI,EAAE;AACxC,cAAQ,KAAK,IAAI,OAAO,QAAQ,EAAE,EAAE,IAAI,EAAE;AAAA,IAC5C;AACA,QAAI,QAAQ,MAAO,QAAO;AAE1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,KAAK,SAAS,CAAC,EAAG;AACtB,YAAM,KAAK,KAAK,QAAQ,CAAC,EAAE;AAC3B,UAAI,KAAK,IAAI,EAAE,KAAK,QAAQ,CAAC,EAAE,EAAG;AAClC,YAAM,KAAK,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,IAAI,KAAK,EAAE;AAC1D,YAAM,QAAQ,QAAQ,CAAC,EAAE,IAAI;AAC7B,YAAM,SAAS,QAAQ,CAAC,EAAE,IAAI;AAC9B,UAAI,SAAS,QAAQ,UAAU,MAAO,QAAO;AAC7C,UAAI,SAAS,QAAQ,SAAS,KAAM,QAAO;AAC3C,UAAI,UAAU,SAAS,QAAQ,MAAO,SAAQ;AAAA,IAChD;AACA,WAAO,KAAK,IAAI,GAAG,QAAQ,IAAI;AAAA,EACjC;AAEA,aAAW,MAAM,cAAc;AAC7B,UAAM,OAAO,GAAG,KAAK,IAAI,CAAC,MAAM,SAAS,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;AACzE,QAAI,KAAK,KAAK,CAAC,QAAQ,MAAM,CAAC,EAAG;AACjC,QAAI,CAAC,GAAG,MAAO;AAEf,UAAM,SAAS,QAAQ,IAAI,CAAC,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC;AACrD,UAAM,WAAW,eAAe,SAAS,MAAM;AAC/C,UAAM,OAAO,GAAG;AAEhB,UAAM,SAAS,aAAa,SAAS,GAAG,IAAI;AAC5C,UAAM,UAAU,KAAK,IAAI,UAAU,KAAK;AAAA,MAAI;AAAA,OACzC,SAAS,eAAe,MAAM,KAAK,SAAS;AAAA,IAAS,CAAC;AAEzD,eACG,OAAO,MAAM,EACb,KAAK,KAAK,SAAS,CAAC,EACpB,KAAK,KAAK,SAAS,CAAC,EACpB,KAAK,eAAe,QAAQ,EAC5B,KAAK,qBAAqB,SAAS,EACnC,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,GAAG,KAAK,MAAM,OAAO,CAAC,IAAI,EAC5C,KAAK,eAAe,KAAK,EACzB,KAAK,IAAI;AAAA,EACd;AAGA,QAAM,aAAa,IAAI,OAAO,GAAG;AACjC,UAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,UAAM,UAAU,SAAS,CAAC,EAAE,QACxB,GAAG,SAAS,CAAC,EAAE,KAAK,KAAK,SAAS,CAAC,EAAE,IAAI,MACzC,SAAS,CAAC,EAAE;AAChB,UAAM,UAAU,WAAW,OAAO,sBAAsB,SAAS,CAAC,EAAE,IAAI;AAExE,eACG,OAAO,QAAQ,EACf,KAAK,MAAM,EAAE,CAAC,EACd,KAAK,MAAM,EAAE,CAAC,EACd,KAAK,KAAK,EAAE,CAAC,EACb,KAAK,QAAQ,aAAa,EAC1B,KAAK,oBAAoB,OAAO,SAAS,CAAC,EAAE,UAAU,CAAC,EACvD,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD,GAAG,cAAc,CAAC,UAAsB;AACvC,gBAAU,QAAQ,CAAC,IAAI,OAAO;AAC5B,WAAG,KAAK,gBAAgB,OAAO,IAAI,MAAM,GAAG;AAAA,MAC9C,CAAC;AACD,kBAAY,SAAS,SAAS,KAAK;AAAA,IACrC,CAAC,EACA,GAAG,aAAa,CAAC,UAAsB;AACtC,kBAAY,SAAS,SAAS,KAAK;AAAA,IACrC,CAAC,EACA,GAAG,cAAc,MAAM;AACtB,gBAAU,QAAQ,CAAC,OAAO;AACxB,WAAG,KAAK,gBAAgB,IAAI;AAAA,MAC9B,CAAC;AACD,kBAAY,OAAO;AAAA,IACrB,CAAC,EACA,GAAG,SAAS,MAAM;AACjB,UAAI,eAAe,SAAS,CAAC,EAAE;AAC7B,oBAAY,SAAS,CAAC,EAAE,UAAU;AAAA,IACtC,CAAC;AAAA,EACL,CAAC;AACH;AAgBO,SAAS,eACd,WACA,QACA,SACA,QACA,aACA,YACM;AACN,EAAY,oBAAO,SAAS,EAAE,UAAU,yBAAyB,EAAE,OAAO;AAE1E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,eAAe,WAAW,EAAG;AAEjC,QAAM,QAAQ,YAAY,SAAS,UAAU;AAC7C,QAAM,SAAS,YAAY,UAAU,UAAU;AAC/C,MAAI,SAAS,KAAK,UAAU,EAAG;AAE/B,QAAM,YAAY,QAAQ;AAC1B,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ;AACxB,QAAM,cAAc,QAAQ;AAG5B,QAAM,gBAAgB;AAAA,IACpB,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,EACjB;AAGA,QAAM,WAAW,CAAC,CAAC;AACnB,QAAM,WAAW,CAAC,CAAC;AACnB,QAAM,SAAS,EAAE,KAAK,QAAQ,KAAK,IAAI,OAAO,IAAI,QAAQ,WAAW,KAAK,IAAI,MAAM,WAAW,KAAK,GAAG;AACvG,QAAM,aAAa,QAAQ,OAAO,OAAO,OAAO;AAChD,QAAM,cAAc,SAAS,OAAO,MAAM,OAAO;AAGjD,QAAM,SAAiB,oBAAY,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC;AACzE,QAAM,SAAiB,oBAAY,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;AAG1E,QAAM,MACH,oBAAO,SAAS,EAChB,OAAO,KAAK,EACZ,KAAK,SAAS,KAAK,EACnB,KAAK,UAAU,MAAM,EACrB,MAAM,cAAc,OAAO;AAG9B,QAAM,UAAU,cAAc,WAAW,SAAS,MAAM;AAGxD,MAAI,OAAO;AACT,UAAM,YAAY,IACf,OAAO,MAAM,EACb,KAAK,SAAS,aAAa,EAC3B,KAAK,KAAK,QAAQ,CAAC,EACnB,KAAK,KAAK,EAAE,EACZ,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB;AAAA,MACC;AAAA,MACA,eAAe,0BAA0B,YAAY;AAAA,IACvD,EACC,KAAK,KAAK;AAEb,QAAI,yBAAyB;AAC3B,gBAAU,KAAK,oBAAoB,uBAAuB;AAAA,IAC5D;AAEA,QAAI,eAAe,yBAAyB;AAC1C,gBACG,GAAG,SAAS,MAAM,YAAY,uBAAuB,CAAC,EACtD,GAAG,cAAc,WAAY;AAC5B,QAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,MAC9C,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,QAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,MAC5C,CAAC;AAAA,IACL;AAAA,EACF;AAGA,QAAM,SAAS,IACZ,OAAO,GAAG,EACV,KAAK,aAAa,aAAa,OAAO,IAAI,KAAK,OAAO,GAAG,GAAG;AAG/D,QAAM,SAAS,CAAC,GAAW,GAAW,QAAwB;AAC5D,UAAM,QAAQ,CAAC,MAAc;AAC3B,YAAM,IAAI,EAAE,QAAQ,KAAK,EAAE;AAC3B,YAAM,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAI;AAC3D,aAAO,CAAC,SAAS,EAAE,UAAU,GAAE,CAAC,GAAE,EAAE,GAAG,SAAS,EAAE,UAAU,GAAE,CAAC,GAAE,EAAE,GAAG,SAAS,EAAE,UAAU,GAAE,CAAC,GAAE,EAAE,CAAC;AAAA,IACrG;AACA,UAAM,CAAC,IAAG,IAAG,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,IAAG,IAAG,EAAE,IAAI,MAAM,CAAC,GAAG,IAAI,MAAI;AAC5D,UAAM,IAAI,CAAC,GAAW,MAAc,KAAK,MAAM,IAAE,IAAI,KAAG,IAAE,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,GAAE,GAAG;AACzF,WAAO,IAAI,EAAE,IAAG,EAAE,CAAC,GAAG,EAAE,IAAG,EAAE,CAAC,GAAG,EAAE,IAAG,EAAE,CAAC;AAAA,EAC3C;AAGA,QAAM,kBAAkB,CACtB,OACA,eACW;AACX,WAAO,OAAO,SAAS,cAAc,aAAa,cAAc,MAAM;AAAA,EACxE;AAGA,QAAM,eAUA;AAAA,IACJ;AAAA,MACE,UAAU;AAAA,MACV,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG,aAAa;AAAA,MAChB,GAAG,cAAc;AAAA,MACjB,QAAQ,aAAa;AAAA,MACrB,QAAQ,cAAc;AAAA,MACtB,OAAO,eAAe;AAAA,MACtB,UAAU;AAAA;AAAA,IACZ;AAAA,IACA;AAAA,MACE,UAAU;AAAA,MACV,GAAG,aAAa;AAAA,MAChB,GAAG;AAAA,MACH,GAAG,aAAa;AAAA,MAChB,GAAG,cAAc;AAAA,MACjB,QAAS,aAAa,IAAK;AAAA,MAC3B,QAAQ,cAAc;AAAA,MACtB,OAAO,eAAe;AAAA,MACtB,UAAU;AAAA;AAAA,IACZ;AAAA,IACA;AAAA,MACE,UAAU;AAAA,MACV,GAAG;AAAA,MACH,GAAG,cAAc;AAAA,MACjB,GAAG,aAAa;AAAA,MAChB,GAAG,cAAc;AAAA,MACjB,QAAQ,aAAa;AAAA,MACrB,QAAS,cAAc,IAAK;AAAA,MAC5B,OAAO,eAAe;AAAA,MACtB,UAAU;AAAA;AAAA,IACZ;AAAA,IACA;AAAA,MACE,UAAU;AAAA,MACV,GAAG,aAAa;AAAA,MAChB,GAAG,cAAc;AAAA,MACjB,GAAG,aAAa;AAAA,MAChB,GAAG,cAAc;AAAA,MACjB,QAAS,aAAa,IAAK;AAAA,MAC3B,QAAS,cAAc,IAAK;AAAA,MAC5B,OAAO,eAAe;AAAA,MACtB,UAAU;AAAA;AAAA,IACZ;AAAA,EACF;AAGA,QAAM,gBAAgB,OACnB,UAAU,eAAe,EACzB,KAAK,YAAY,EACjB,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,UAAU,EACxB,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,EACpB,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,EACpB,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC,EACxB,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC,EACzB,KAAK,QAAQ,CAAC,MAAM,gBAAgB,EAAE,OAAO,EAAE,QAAQ,CAAC,EACxD,KAAK,UAAU,WAAW,EAC1B,KAAK,gBAAgB,GAAG;AAG3B,QAAM,gBAAgB;AACtB,QAAM,cAAc;AAGpB,QAAM,wBAAwB,CAAC,MAA6C;AAC1E,UAAMD,QAAO,gBAAgB,EAAE,OAAO,EAAE,QAAQ;AAChD,WAAO,OAAO,WAAWA,OAAM,EAAE;AAAA,EACnC;AAGA,QAAM,iBAAiB;AACvB,QAAM,iBAAiB;AACvB,QAAM,YAAY;AAClB,QAAM,mBAAmB;AAEzB,QAAM,eAAe,CAAC,MAAc,aAClC,KAAK,SAAS,WAAW;AAO3B,QAAM,sBAAsB,CAAC,MAAcE,KAAYC,QAAoC;AACzF,UAAM,SAASD,MAAK;AACpB,UAAM,SAASC,MAAK;AACpB,UAAM,QAAQ,KAAK,MAAM,KAAK;AAG9B,QAAI,aAAa,MAAM,cAAc,KAAK,QAAQ;AAChD,YAAM,KAAK,KAAK,IAAI,gBAAgB,MAAM;AAC1C,aAAO,EAAE,OAAO,CAAC,IAAI,GAAG,UAAU,KAAK,IAAI,gBAAgB,KAAK,MAAM,EAAE,CAAC,EAAE;AAAA,IAC7E;AAGA,UAAM,YAAY,CAAC,OAAyB;AAC1C,YAAM,SAAmB,CAAC;AAC1B,UAAI,MAAM;AACV,iBAAW,KAAK,OAAO;AACrB,cAAM,QAAQ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK;AACpC,YAAI,aAAa,OAAO,EAAE,IAAI,UAAU,KAAK;AAC3C,iBAAO,KAAK,GAAG;AACf,gBAAM;AAAA,QACR,OAAO;AACL,gBAAM;AAAA,QACR;AAAA,MACF;AACA,UAAI,IAAK,QAAO,KAAK,GAAG;AACxB,aAAO;AAAA,IACT;AAGA,QAAI,KAAK;AACT,QAAI,KAAK;AACT,QAAI,YAAY,UAAU,EAAE;AAC5B,QAAI,SAAS;AACb,WAAO,MAAM,IAAI;AACf,YAAM,MAAM,KAAK,OAAO,KAAK,MAAM,CAAC;AACpC,YAAM,QAAQ,UAAU,GAAG;AAC3B,YAAM,SAAS,MAAM,SAAS,MAAM;AACpC,YAAM,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC;AACnE,UAAI,YAAY,UAAU,UAAU,QAAQ;AAC1C,iBAAS;AACT,oBAAY;AACZ,aAAK,MAAM;AAAA,MACb,OAAO;AACL,aAAK,MAAM;AAAA,MACb;AAAA,IACF;AACA,WAAO,EAAE,OAAO,WAAW,UAAU,KAAK,IAAI,gBAAgB,MAAM,EAAE;AAAA,EACxE;AAIA,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,cAAc;AACzB,QAAM,wBAAwB,aAAa,OAAO,CAAC,MAAM,EAAE,UAAU,IAAI;AACzE,QAAM,eAAe,IAAI;AAAA,IACvB,sBAAsB,IAAI,CAAC,MAAM,CAAC,EAAE,MAAO,MAAM,oBAAoB,EAAE,MAAO,MAAM,IAAI,EAAE,CAAC,CAAC;AAAA,EAC9F;AAEA,QAAM,qBAAqB,OACxB,UAAU,qBAAqB,EAC/B,KAAK,qBAAqB,EAC1B,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,gBAAgB,EAC9B,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM,EACzB,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM,EACzB,KAAK,eAAe,QAAQ,EAC5B,KAAK,qBAAqB,SAAS,EACnC,KAAK,QAAQ,CAAC,MAAM,sBAAsB,CAAC,CAAC,EAC5C,KAAK,aAAa,CAAC,MAAM,GAAG,aAAa,IAAI,EAAE,MAAO,IAAI,EAAG,QAAQ,IAAI,EACzE,KAAK,eAAe,KAAK,EACzB;AAAA,IAAK;AAAA,IAAoB,CAAC,MACzB,EAAE,OAAO,aAAa,OAAO,EAAE,MAAM,UAAU,IAAI;AAAA,EACrD,EACC;AAAA,IAAM;AAAA,IAAU,CAAC,MAChB,eAAe,EAAE,OAAO,aAAa,YAAY;AAAA,EACnD,EACC,KAAK,SAAU,GAAG;AACjB,UAAM,SAAS,aAAa,IAAI,EAAE,MAAO,IAAI;AAC7C,UAAM,KAAiB,oBAAO,IAAI;AAClC,QAAI,OAAO,MAAM,WAAW,GAAG;AAC7B,SAAG,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IACzB,OAAO;AAEL,YAAM,QAAQ,OAAO,WAAW;AAChC,YAAM,SAAS,OAAO,MAAM,SAAS;AACrC,YAAM,SAAS,CAAC,SAAS,IAAI,QAAQ;AACrC,aAAO,MAAM,QAAQ,CAACL,OAAM,MAAM;AAChC,WAAG,OAAO,OAAO,EACd,KAAK,KAAK,EAAE,MAAM,EAClB,KAAK,MAAM,MAAM,IAAI,GAAG,MAAM,OAAO,GAAG,KAAK,IAAI,EACjD,KAAKA,KAAI;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAEH,MAAI,aAAa;AACf,uBACG,GAAG,SAAS,CAAC,GAAG,MAAM;AACrB,UAAI,EAAE,OAAO,WAAY,aAAY,EAAE,MAAM,UAAU;AAAA,IACzD,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,MAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,IAC9C,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,MAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,IAC5C,CAAC;AAAA,EACL;AAGA,MAAI,eAAe;AAEjB,UAAM,YAAY,IACf,OAAO,MAAM,EACb,KAAK,SAAS,qBAAqB,EACnC,KAAK,KAAK,OAAO,OAAO,aAAa,CAAC,EACtC,KAAK,KAAK,SAAS,EAAE,EACrB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,oBAAoB,0BAA0B,OAAO,uBAAuB,IAAI,IAAI,EACzF;AAAA,MACC;AAAA,MACA,eAAe,0BAA0B,YAAY;AAAA,IACvD,EACC,KAAK,cAAc,CAAC,CAAC;AAGxB,UAAM,aAAa,IAChB,OAAO,MAAM,EACb,KAAK,SAAS,qBAAqB,EACnC,KAAK,KAAK,OAAO,OAAQ,aAAa,IAAK,CAAC,EAC5C,KAAK,KAAK,SAAS,EAAE,EACrB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,oBAAoB,0BAA0B,OAAO,uBAAuB,IAAI,IAAI,EACzF;AAAA,MACC;AAAA,MACA,eAAe,0BAA0B,YAAY;AAAA,IACvD,EACC,KAAK,cAAc,CAAC,CAAC;AAExB,QAAI,eAAe,yBAAyB;AAC1C,OAAC,WAAW,UAAU,EAAE,QAAQ,CAAC,UAAU;AACzC,cACG,GAAG,SAAS,MAAM,YAAY,uBAAuB,CAAC,EACtD,GAAG,cAAc,WAAY;AAC5B,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,QAC9C,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,QAC5C,CAAC;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,eAAe;AACjB,UAAM,aAAa,OAAO,MAAO,cAAc,IAAK;AACpD,UAAM,UAAU,OAAO,MAAM,cAAc;AAG3C,UAAM,YAAY,IACf,OAAO,MAAM,EACb,KAAK,SAAS,qBAAqB,EACnC,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,UAAU,EACpB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,aAAa,mBAAmB,UAAU,GAAG,EAClD,KAAK,oBAAoB,0BAA0B,OAAO,uBAAuB,IAAI,IAAI,EACzF;AAAA,MACC;AAAA,MACA,eAAe,0BAA0B,YAAY;AAAA,IACvD,EACC,KAAK,cAAc,CAAC,CAAC;AAGxB,UAAM,aAAa,IAChB,OAAO,MAAM,EACb,KAAK,SAAS,qBAAqB,EACnC,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,OAAO,EACjB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,SAAS,EACtB,KAAK,aAAa,MAAM,EACxB,KAAK,aAAa,mBAAmB,OAAO,GAAG,EAC/C,KAAK,oBAAoB,0BAA0B,OAAO,uBAAuB,IAAI,IAAI,EACzF;AAAA,MACC;AAAA,MACA,eAAe,0BAA0B,YAAY;AAAA,IACvD,EACC,KAAK,cAAc,CAAC,CAAC;AAExB,QAAI,eAAe,yBAAyB;AAC1C,OAAC,WAAW,UAAU,EAAE,QAAQ,CAAC,UAAU;AACzC,cACG,GAAG,SAAS,MAAM,YAAY,uBAAuB,CAAC,EACtD,GAAG,cAAc,WAAY;AAC5B,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,GAAG;AAAA,QAC9C,CAAC,EACA,GAAG,cAAc,WAAY;AAC5B,UAAY,oBAAO,IAAI,EAAE,KAAK,WAAW,CAAC;AAAA,QAC5C,CAAC;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAGA,SACG,OAAO,MAAM,EACb,KAAK,MAAM,aAAa,CAAC,EACzB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,aAAa,CAAC,EACzB,KAAK,MAAM,WAAW,EACtB,KAAK,UAAU,WAAW,EAC1B,KAAK,gBAAgB,CAAC;AAEzB,SACG,OAAO,MAAM,EACb,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,cAAc,CAAC,EAC1B,KAAK,MAAM,UAAU,EACrB,KAAK,MAAM,cAAc,CAAC,EAC1B,KAAK,UAAU,WAAW,EAC1B,KAAK,gBAAgB,CAAC;AAGzB,QAAM,mBAAmB,CAAC,GAAW,MAAgC;AACnE,QAAI,KAAK,OAAO,KAAK,IAAK,QAAO;AACjC,QAAI,IAAI,OAAO,KAAK,IAAK,QAAO;AAChC,QAAI,IAAI,OAAO,IAAI,IAAK,QAAO;AAC/B,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,OAAO,OAAO,GAAG,EAAE,KAAK,SAAS,QAAQ;AAEzD,iBAAe,QAAQ,CAAC,UAAU;AAChC,UAAM,KAAK,OAAO,MAAM,CAAC;AACzB,UAAM,KAAK,OAAO,MAAM,CAAC;AACzB,UAAM,WAAW,iBAAiB,MAAM,GAAG,MAAM,CAAC;AAClD,UAAM,UAAU,aAAa,KAAK,CAAC,MAAM,EAAE,aAAa,QAAQ;AAChE,UAAM,aACJ,SAAS,OAAO,SAAS,cAAc,SAAS,YAAY,CAAC;AAE/D,UAAM,SAAS,QAAQ,OAAO,GAAG,EAAE,KAAK,SAAS,aAAa,EAC3D,KAAK,oBAAoB,OAAO,MAAM,UAAU,CAAC;AAGpD,WACG,OAAO,QAAQ,EACf,KAAK,MAAM,EAAE,EACb,KAAK,MAAM,EAAE,EACb,KAAK,KAAK,CAAC,EACX,KAAK,QAAQ,SAAS,EACtB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,CAAC;AAGzB,WACG,OAAO,MAAM,EACb,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,KAAK,EAAE,EACjB,KAAK,eAAe,QAAQ,EAC5B,KAAK,QAAQ,aAAa,EAC1B,KAAK,aAAa,MAAM,EACxB,KAAK,eAAe,KAAK,EACzB,MAAM,eAAe,aAAa,WAAW,EAAE,EAC/C,KAAK,MAAM,KAAK;AAGnB,UAAM,UAAU,WAAW,MAAM,KAAK,mBAAmB,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC;AAErG,WACG,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD,GAAG,cAAc,CAAC,UAAsB;AACvC,kBAAY,SAAS,SAAS,KAAK;AACnC,aAAO,OAAO,QAAQ,EAAE,KAAK,KAAK,CAAC;AAAA,IACrC,CAAC,EACA,GAAG,aAAa,CAAC,UAAsB;AACtC,kBAAY,SAAS,SAAS,KAAK;AAAA,IACrC,CAAC,EACA,GAAG,cAAc,MAAM;AACtB,kBAAY,OAAO;AACnB,aAAO,OAAO,QAAQ,EAAE,KAAK,KAAK,CAAC;AAAA,IACrC,CAAC,EACA,GAAG,SAAS,MAAM;AACjB,UAAI,eAAe,MAAM,WAAY,aAAY,MAAM,UAAU;AAAA,IACnE,CAAC;AAAA,EACL,CAAC;AAGD,gBACG,MAAM,UAAU,cAAc,YAAY,SAAS,EACnD,GAAG,cAAc,SAAU,GAAG,GAAG;AAEhC,kBAAc;AAAA,MAAK;AAAA,MAAW,CAAC,OAC7B,GAAG,aAAa,EAAE,WAAW,IAAI;AAAA,IACnC;AACA,uBAAmB;AAAA,MAAK;AAAA,MAAW,CAAC,OAClC,GAAG,aAAa,EAAE,WAAW,IAAI;AAAA,IACnC;AAEA,YAAQ,UAAU,eAAe,EAAE,KAAK,SAAUM,IAAG,GAAG;AACtD,YAAM,KAAK,eAAe,CAAC;AAC3B,YAAM,SAAS,iBAAiB,GAAG,GAAG,GAAG,CAAC;AAC1C,MACG,oBAAO,IAAI,EACX,KAAK,WAAW,WAAW,EAAE,WAAW,IAAI,GAAG;AAAA,IACpD,CAAC;AAAA,EACH,CAAC,EACA,GAAG,cAAc,MAAM;AACtB,kBAAc,KAAK,WAAW,CAAC;AAC/B,uBAAmB,KAAK,WAAW,CAAC;AACpC,YAAQ,UAAU,eAAe,EAAE,KAAK,WAAW,CAAC;AAAA,EACtD,CAAC,EACA,GAAG,SAAS,CAAC,GAAG,MAAM;AAErB,QAAI,eAAe,EAAE,OAAO,YAAY;AACtC,kBAAY,EAAE,MAAM,UAAU;AAAA,IAChC;AAAA,EACF,CAAC;AACL;AAMA,IAAM,eAAe;AACrB,IAAM,gBAAgB;AAMtB,eAAsB,kBACpB,SACA,OACA,SACA,gBAKA,SACiB;AAEjB,QAAM,EAAE,oBAAAC,oBAAmB,IAAI,MAAM;AACrC,QAAM,eAAeA,oBAAmB,OAAO;AAE/C,MAAI,iBAAiB,OAAO;AAC1B,UAAM,EAAE,UAAAC,UAAS,IAAI,MAAM;AAC3B,UAAM,EAAE,WAAAC,WAAU,IAAI,MAAM;AAC5B,UAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAClC,UAAM,EAAE,WAAAC,WAAU,IAAI,MAAM;AAE5B,UAAMC,UAAS,UAAU;AACzB,UAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,UAAMC,oBACJ,YAAYF,UAASC,YAAW,MAAM,EAAE,OAAOA,YAAW,MAAM,EAAE;AAEpE,UAAM,YAAYL,UAAS,SAASM,iBAAgB;AACpD,QAAI,UAAU,SAAS,UAAU,MAAM,WAAW,EAAG,QAAO;AAG5D,UAAM,iBAAiB,gBAAgB;AACvC,UAAM,iBAAiB,gBAAgB,kBAAkB;AACzD,UAAM,mBAAmB,gBAAgB;AAEzC,UAAM,EAAE,QAAQ,iBAAiB,aAAa,IAC5C,kBAAkB,eAAe,OAAO,IACpCJ,iBAAgB,WAAW,cAAc,IACzC,EAAE,QAAQ,WAAW,cAAc,oBAAI,IAAoB,EAAE;AAEnE,UAAM,YAAYD;AAAA,MAChB;AAAA,MACA,aAAa,OAAO,IAAI,eAAe;AAAA,MACvC;AAAA,MACA;AAAA,IACF;AAGA,UAAM,UAAU;AAChB,UAAM,cAAc,gBAAgB,QAAQ,KAAK;AACjD,UAAM,cAAc,UAAU,QAAQ,UAAU;AAChD,UAAM,eAAe,UAAU,SAAS,UAAU,IAAI;AAEtD,UAAMM,aAAY,SAAS,cAAc,KAAK;AAC9C,IAAAA,WAAU,MAAM,QAAQ,GAAG,WAAW;AACtC,IAAAA,WAAU,MAAM,SAAS,GAAG,YAAY;AACxC,IAAAA,WAAU,MAAM,WAAW;AAC3B,IAAAA,WAAU,MAAM,OAAO;AACvB,aAAS,KAAK,YAAYA,UAAS;AAEnC,QAAI;AACF,MAAAJ;AAAA,QACEI;AAAA,QACA;AAAA,QACA;AAAA,QACAD;AAAA,QACAF;AAAA,QACA;AAAA,QACA,EAAE,OAAO,aAAa,QAAQ,aAAa;AAAA,QAC3C;AAAA,QACA;AAAA,MACF;AAEA,YAAM,QAAQG,WAAU,cAAc,KAAK;AAC3C,UAAI,CAAC,MAAO,QAAO;AAEnB,UAAI,UAAU,eAAe;AAC3B,cAAM,MAAM,aAAa;AAAA,MAC3B,WAAW,CAAC,MAAM,MAAM,YAAY;AAClC,cAAM,MAAM,aAAaD,kBAAiB;AAAA,MAC5C;AAEA,YAAM,aAAa,SAAS,4BAA4B;AACxD,YAAM,MAAM,aAAa;AAEzB,YAAM,UAAU,MAAM;AACtB,UAAI,SAAS,aAAa,OAAO;AAC/B,cAAM,aAAa,UAAU,gBAAgB,SAASA,kBAAiB;AACvE,eAAO,eAAe,SAAS,UAAU;AAAA,MAC3C;AACA,aAAO;AAAA,IACT,UAAE;AACA,eAAS,KAAK,YAAYC,UAAS;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,iBAAiB,SAAS;AAC5B,UAAM,EAAE,mBAAAC,mBAAkB,IAAI,MAAM;AACpC,UAAM,EAAE,oBAAAC,oBAAmB,IAAI,MAAM;AACrC,UAAM,EAAE,oBAAAC,oBAAmB,IAAI,MAAM;AAErC,UAAMN,UAAS,UAAU;AACzB,UAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,UAAMC,oBACJ,YAAYF,UAASC,YAAW,MAAM,EAAE,OAAOA,YAAW,MAAM,EAAE;AAEpE,UAAM,cAAcG,mBAAkB,SAASF,iBAAgB;AAC/D,QAAI,YAAY,SAAS,YAAY,QAAQ,WAAW,EAAG,QAAO;AAElE,UAAM,cAAcG,oBAAmB,WAAW;AAClD,UAAM,UAAU;AAChB,UAAM,cAAc,YAAY,QAAQ,KAAK;AAC7C,UAAM,cAAc,YAAY,QAAQ,UAAU;AAClD,UAAM,eAAe,YAAY,SAAS,UAAU,IAAI;AAExD,UAAMF,aAAY,SAAS,cAAc,KAAK;AAC9C,IAAAA,WAAU,MAAM,QAAQ,GAAG,WAAW;AACtC,IAAAA,WAAU,MAAM,SAAS,GAAG,YAAY;AACxC,IAAAA,WAAU,MAAM,WAAW;AAC3B,IAAAA,WAAU,MAAM,OAAO;AACvB,aAAS,KAAK,YAAYA,UAAS;AAEnC,QAAI;AACF,MAAAG;AAAA,QACEH;AAAA,QACA;AAAA,QACA;AAAA,QACAD;AAAA,QACAF;AAAA,QACA;AAAA,QACA,EAAE,OAAO,aAAa,QAAQ,aAAa;AAAA,MAC7C;AAEA,YAAM,QAAQG,WAAU,cAAc,KAAK;AAC3C,UAAI,CAAC,MAAO,QAAO;AAEnB,UAAI,UAAU,eAAe;AAC3B,cAAM,MAAM,aAAa;AAAA,MAC3B,WAAW,CAAC,MAAM,MAAM,YAAY;AAClC,cAAM,MAAM,aAAaD,kBAAiB;AAAA,MAC5C;AAEA,YAAM,aAAa,SAAS,4BAA4B;AACxD,YAAM,MAAM,aAAa;AAEzB,YAAM,UAAU,MAAM;AACtB,UAAI,SAAS,aAAa,OAAO;AAC/B,cAAM,aAAa,UAAU,gBAAgB,SAASA,kBAAiB;AACvE,eAAO,eAAe,SAAS,UAAU;AAAA,MAC3C;AACA,aAAO;AAAA,IACT,UAAE;AACA,eAAS,KAAK,YAAYC,UAAS;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,iBAAiB,MAAM;AACzB,UAAM,EAAE,gBAAAI,gBAAe,IAAI,MAAM;AACjC,UAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAClC,UAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAElC,UAAMT,UAAS,UAAU;AACzB,UAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,UAAMC,oBACJ,YAAYF,UAASC,YAAW,MAAM,EAAE,OAAOA,YAAW,MAAM,EAAE;AAEpE,UAAM,WAAWM,gBAAe,SAASL,iBAAgB;AACzD,QAAI,SAAS,SAAS,SAAS,OAAO,WAAW,EAAG,QAAO;AAE3D,UAAM,WAAWM,iBAAgB,QAAQ;AACzC,UAAM,UAAU;AAChB,UAAM,cAAc,SAAS,QAAQ,KAAK;AAC1C,UAAM,cAAc,SAAS,QAAQ,UAAU;AAC/C,UAAM,eAAe,SAAS,SAAS,UAAU,IAAI;AAErD,UAAML,aAAY,SAAS,cAAc,KAAK;AAC9C,IAAAA,WAAU,MAAM,QAAQ,GAAG,WAAW;AACtC,IAAAA,WAAU,MAAM,SAAS,GAAG,YAAY;AACxC,IAAAA,WAAU,MAAM,WAAW;AAC3B,IAAAA,WAAU,MAAM,OAAO;AACvB,aAAS,KAAK,YAAYA,UAAS;AAEnC,QAAI;AACF,MAAAM;AAAA,QACEN;AAAA,QACA;AAAA,QACA;AAAA,QACAD;AAAA,QACAF;AAAA,QACA;AAAA,QACA,EAAE,OAAO,aAAa,QAAQ,aAAa;AAAA,MAC7C;AAEA,YAAM,QAAQG,WAAU,cAAc,KAAK;AAC3C,UAAI,CAAC,MAAO,QAAO;AAEnB,UAAI,UAAU,eAAe;AAC3B,cAAM,MAAM,aAAa;AAAA,MAC3B,WAAW,CAAC,MAAM,MAAM,YAAY;AAClC,cAAM,MAAM,aAAaD,kBAAiB;AAAA,MAC5C;AAEA,YAAM,aAAa,SAAS,4BAA4B;AACxD,YAAM,MAAM,aAAa;AAEzB,YAAM,UAAU,MAAM;AACtB,UAAI,SAAS,aAAa,OAAO;AAC/B,cAAM,aAAa,UAAU,gBAAgB,SAASA,kBAAiB;AACvE,eAAO,eAAe,SAAS,UAAU;AAAA,MAC3C;AACA,aAAO;AAAA,IACT,UAAE;AACA,eAAS,KAAK,YAAYC,UAAS;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,iBAAiB,aAAa;AAChC,UAAM,EAAE,gBAAAO,gBAAe,IAAI,MAAM;AACjC,UAAM,EAAE,aAAAC,aAAY,IAAI,MAAM;AAC9B,UAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAElC,UAAMZ,UAAS,UAAU;AACzB,UAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,UAAMC,oBACJ,YAAYF,UAASC,YAAW,MAAM,EAAE,OAAOA,YAAW,MAAM,EAAE;AAEpE,UAAM,WAAWS,gBAAe,SAASR,iBAAgB;AACzD,QAAI,SAAS,SAAS,SAAS,MAAM,WAAW,EAAG,QAAO;AAE1D,UAAM,SAASS,aAAY,QAAQ;AACnC,UAAMR,aAAY,SAAS,cAAc,KAAK;AAC9C,IAAAA,WAAU,MAAM,QAAQ,GAAG,YAAY;AACvC,IAAAA,WAAU,MAAM,SAAS,GAAG,aAAa;AACzC,IAAAA,WAAU,MAAM,WAAW;AAC3B,IAAAA,WAAU,MAAM,OAAO;AACvB,aAAS,KAAK,YAAYA,UAAS;AAEnC,QAAI;AACF,MAAAS,iBAAgBT,YAAW,UAAU,QAAQD,mBAAkBF,SAAQ,QAAW;AAAA,QAChF,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,QAAQG,WAAU,cAAc,KAAK;AAC3C,UAAI,CAAC,MAAO,QAAO;AAEnB,UAAI,UAAU,eAAe;AAC3B,cAAM,MAAM,aAAa;AAAA,MAC3B,WAAW,CAAC,MAAM,MAAM,YAAY;AAClC,cAAM,MAAM,aAAaD,kBAAiB;AAAA,MAC5C;AAEA,YAAM,aAAa,SAAS,4BAA4B;AACxD,YAAM,MAAM,aAAa;AAEzB,YAAM,UAAU,MAAM;AACtB,UAAI,SAAS,aAAa,OAAO;AAC/B,cAAM,aAAa,UAAU,gBAAgB,SAASA,kBAAiB;AACvE,eAAO,eAAe,SAAS,UAAU;AAAA,MAC3C;AACA,aAAO;AAAA,IACT,UAAE;AACA,eAAS,KAAK,YAAYC,UAAS;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,SAAS,OAAO;AAIvC,MAAI,OAAO,SAAS,OAAO,SAAS,YAAY;AAE9C,UAAMU,qBAAoB,WAAW,KAAK,OAAO;AACjD,QAAI,CAACA,mBAAmB,QAAO;AAC/B,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,OAAO,SAAS,eAAe,OAAO,MAAM,WAAW,EAAG,QAAO;AACrE,MAAI,OAAO,SAAS,WAAW,OAAO,KAAK,WAAW,EAAG,QAAO;AAChE,MAAI,OAAO,SAAS,SAAS,OAAO,MAAM,WAAW,EAAG,QAAO;AAC/D,MAAI,OAAO,SAAS,cAAc,OAAO,eAAe,WAAW;AACjE,WAAO;AACT,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,SAAS,EAAG,QAAO;AACjE,MAAI,OAAO,SAAS,cAAc,OAAO,eAAe,WAAW;AACjE,WAAO;AAET,QAAM,SAAS,UAAU;AAGzB,QAAM,EAAE,YAAAZ,YAAW,IAAI,MAAM;AAC7B,QAAM,mBACJ,YAAY,SAASA,YAAW,MAAM,EAAE,OAAOA,YAAW,MAAM,EAAE;AAGpE,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,MAAM,QAAQ,GAAG,YAAY;AACvC,YAAU,MAAM,SAAS,GAAG,aAAa;AACzC,YAAU,MAAM,WAAW;AAC3B,YAAU,MAAM,OAAO;AACvB,WAAS,KAAK,YAAY,SAAS;AAEnC,QAAM,OAA2B,EAAE,OAAO,cAAc,QAAQ,cAAc;AAE9E,MAAI;AACF,QAAI,OAAO,SAAS,YAAY;AAC9B,YAAM,EAAE,mBAAAa,mBAAkB,IAAI,MAAM;AACpC,YAAM,EAAE,uBAAAC,uBAAsB,IAAI,MAAM;AACxC,YAAM,YAAYD,mBAAkB,OAAO;AAC3C,UAAI,UAAU,SAAS,UAAU,aAAa,WAAW,EAAG,QAAO;AACnE,MAAAC,uBAAsB,WAAW,WAAW,kBAAkB,QAAQ,QAAW;AAAA,QAC/E,aAAa;AAAA,MACf,CAAC;AAAA,IACH,WAAW,OAAO,SAAS,aAAa;AACtC,YAAM,qBAAqB,WAAW,QAAQ,kBAAkB,QAAQ,IAAI;AAAA,IAC9E,WAAW,OAAO,SAAS,OAAO;AAChC,uBAAiB,WAAW,QAAQ,kBAAkB,QAAQ,QAAW,IAAI;AAAA,IAC/E,WAAW,OAAO,SAAS,YAAY;AACrC,qBAAe,WAAW,QAAQ,kBAAkB,QAAQ,QAAW,IAAI;AAAA,IAC7E,WAAW,OAAO,SAAS,QAAQ;AACjC,iBAAW,WAAW,QAAQ,kBAAkB,QAAQ,QAAW,IAAI;AAAA,IACzE,WAAW,OAAO,SAAS,YAAY;AACrC,qBAAe,WAAW,QAAQ,kBAAkB,QAAQ,QAAW,IAAI;AAAA,IAC7E,OAAO;AACL,uBAAiB,WAAW,QAAQ,kBAAkB,QAAQ,QAAW,IAAI;AAAA,IAC/E;AAEA,UAAM,QAAQ,UAAU,cAAc,KAAK;AAC3C,QAAI,CAAC,MAAO,QAAO;AAGnB,QAAI,UAAU,eAAe;AAC3B,YAAM,MAAM,aAAa;AAAA,IAC3B,WAAW,CAAC,MAAM,MAAM,YAAY;AAClC,YAAM,MAAM,aAAa,iBAAiB;AAAA,IAC5C;AAGA,UAAM,aAAa,SAAS,4BAA4B;AACxD,UAAM,MAAM,aAAa;AAEzB,UAAM,UAAU,MAAM;AACtB,QAAI,SAAS,aAAa,OAAO;AAC/B,YAAM,aAAa,UAAU,gBAAgB,SAAS,iBAAiB;AACvE,aAAO,eAAe,SAAS,UAAU;AAAA,IAC3C;AACA,WAAO;AAAA,EACT,UAAE;AACA,aAAS,KAAK,YAAY,SAAS;AAAA,EACrC;AACF;;;AE/5KA,cAAyB;AAEzB;AA+EA;AAEA;;;ACxCA;AAOA,IAAM,cAAc,oBAAI,IAAe;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,eAA0C;AAAA,EAC9C,cAAc;AAChB;AAgBO,SAAS,WACd,SACA,SACa;AACb,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,SAAsB;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM,CAAC;AAAA,EACT;AAEA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,UAAU,MAAM,CAAC,EAAE,KAAK;AAC9B,UAAM,aAAa,IAAI;AAGvB,QAAI,CAAC,QAAS;AAGd,QAAI,YAAY,KAAK,OAAO,EAAG;AAG/B,QAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,IAAI,EAAG;AAGzD,UAAM,aAAa,QAAQ,QAAQ,GAAG;AACtC,QAAI,eAAe,GAAI;AAEvB,UAAM,MAAM,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK,EAAE,YAAY;AAChE,UAAM,QAAQ,QAAQ,UAAU,aAAa,CAAC,EAAE,KAAK;AAGrD,QAAI,QAAQ,SAAS;AACnB,YAAM,MAAM,MAAM,YAAY;AAC9B,YAAM,YAAa,aAAa,GAAG,KAAK;AACxC,UAAI,YAAY,IAAI,SAAS,GAAG;AAC9B,eAAO,OAAO;AAAA,MAChB,OAAO;AACL,eAAO,QAAQ,2BAA2B,KAAK,sBAAsB,CAAC,GAAG,WAAW,EAAE,KAAK,IAAI,CAAC;AAChG,eAAO;AAAA,MACT;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS;AACnB,aAAO,QAAQ;AACf,aAAO,kBAAkB;AACzB;AAAA,IACF;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS;AAChB;AAAA,IACF;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS;AAChB;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS;AACnB,aAAO,QAAQ;AACf;AAAA,IACF;AAEA,QAAI,QAAQ,UAAU;AACpB,YAAM,IAAI,MAAM,YAAY;AAC5B,UAAI,MAAM,UAAU,MAAM,WAAW,MAAM,aAAa,MAAM,QAAQ;AACpE,eAAO,SAAS;AAAA,MAClB;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,eAAe;AACzB,YAAM,IAAI,MAAM,YAAY;AAC5B,UAAI,MAAM,gBAAgB,MAAM,YAAY;AAC1C,eAAO,cAAc;AAAA,MACvB;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS;AACnB,aAAO,QAAQ,aAAa,MAAM,KAAK,GAAG,OAAO;AACjD;AAAA,IACF;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS;AAEhB,YAAM,WAAW,MACd,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AACjB,YAAM,QAAkB,CAAC;AACzB,YAAM,aAAqC,CAAC;AAC5C,iBAAW,OAAO,UAAU;AAC1B,cAAM,aAAa,IAAI,MAAM,iBAAiB;AAC9C,YAAI,YAAY;AACd,gBAAM,WAAW,aAAa,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO;AAC3D,qBAAW,KAAK,QAAQ;AACxB,gBAAM,KAAK,IAAI,UAAU,GAAG,WAAW,KAAM,EAAE,KAAK,CAAC;AAAA,QACvD,OAAO;AACL,qBAAW,KAAK,MAAS;AACzB,gBAAM,KAAK,GAAG;AAAA,QAChB;AAAA,MACF;AACA,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO,SAAS,MAAM,CAAC;AAAA,MACzB;AACA,UAAI,MAAM,SAAS,GAAG;AACpB,eAAO,cAAc;AAAA,MACvB;AACA,UAAI,WAAW,KAAK,OAAO,EAAG,QAAO,mBAAmB;AACxD;AAAA,IACF;AAGA,UAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAClD,UAAM,WAAW,WAAW,MAAM,CAAC,CAAC;AACpC,QAAI,CAAC,MAAM,QAAQ,GAAG;AACpB,UAAI,WAAW,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK;AACrD,UAAI;AACJ,YAAM,aAAa,SAAS,MAAM,iBAAiB;AACnD,UAAI,YAAY;AACd,cAAM,WAAW,aAAa,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO;AAC3D,qBAAa;AACb,mBAAW,SAAS,UAAU,GAAG,WAAW,KAAM,EAAE,KAAK;AAAA,MAC3D;AACA,YAAM,QAAQ,MACX,MAAM,CAAC,EACP,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,EACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1B,aAAO,KAAK,KAAK;AAAA,QACf,OAAO;AAAA,QACP,OAAO;AAAA,QACP,GAAI,MAAM,SAAS,KAAK,EAAE,aAAa,MAAM;AAAA,QAC7C,GAAI,cAAc,EAAE,OAAO,WAAW;AAAA,QACtC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,GAAG;AAC7C,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,CAAC,OAAO,SAAS,OAAO,SAAS,iBAAiB,CAAC,OAAO,aAAa;AACzE,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,CAAC,OAAO,SAAS,OAAO,aAAa;AACvC,UAAM,gBAAgB,OAAO,YAAY;AACzC,eAAW,MAAM,OAAO,MAAM;AAC5B,YAAM,cAAc,KAAK,GAAG,aAAa,UAAU;AACnD,UAAI,gBAAgB,eAAe;AACjC,eAAO,QAAQ,eAAe,GAAG,KAAK,SAAS,WAAW,kBAAkB,aAAa,uCAAuC,aAAa;AAC7I;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ADxIO,SAAS,YACd,SACA,SACc;AACd,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,SAAuB;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM,CAAC;AAAA,EACT;AAGA,MAAI,kBAAkB;AAEtB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,UAAU,MAAM,CAAC,EAAE,KAAK;AAC9B,UAAM,aAAa,IAAI;AAGvB,QAAI,CAAC,QAAS;AAGd,UAAM,kBAAkB,QAAQ,MAAM,gBAAgB;AACtD,QAAI,iBAAiB;AACnB,UAAI,UAAU,gBAAgB,CAAC,EAAE,KAAK;AACtC,YAAM,gBAAgB,QAAQ,MAAM,iBAAiB;AACrD,UAAI,eAAe;AACjB,cAAM,WAAW,aAAa,cAAc,CAAC,EAAE,KAAK,GAAG,OAAO;AAC9D,YAAI,CAAC,OAAO,eAAgB,QAAO,iBAAiB,CAAC;AACrD,kBAAU,QAAQ,UAAU,GAAG,cAAc,KAAM,EAAE,KAAK;AAC1D,eAAO,eAAe,OAAO,IAAI;AAAA,MACnC;AACA,wBAAkB;AAClB;AAAA,IACF;AAGA,QAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,IAAI,EAAG;AAGzD,UAAM,gBAAgB,QAAQ,MAAM,YAAY;AAChD,QAAI,eAAe;AACjB,wBAAkB,cAAc,CAAC,EAAE,KAAK;AACxC;AAAA,IACF;AAGA,UAAM,aAAa,QAAQ,QAAQ,GAAG;AACtC,QAAI,eAAe,GAAI;AAEvB,UAAM,MAAM,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK,EAAE,YAAY;AAChE,UAAM,QAAQ,QAAQ,UAAU,aAAa,CAAC,EAAE,KAAK;AAGrD,QAAI,QAAQ,SAAS;AACnB,YAAM,YAAY,MAAM,YAAY;AACpC,UACE,cAAc,YACd,cAAc,WACd,cAAc,cACd,cAAc,aACd,cAAc,aACd,cAAc,UACd;AACA,eAAO,OAAO;AAAA,MAChB,OAAO;AACL,eAAO,QAAQ,2BAA2B,KAAK;AAC/C,eAAO;AAAA,MACT;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS;AACnB,aAAO,QAAQ;AACf,aAAO,kBAAkB;AACzB;AAAA,IACF;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS;AAChB,YAAM,WAAW,MACd,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AACjB,YAAM,QAAkB,CAAC;AACzB,YAAM,aAAqC,CAAC;AAC5C,iBAAW,OAAO,UAAU;AAC1B,cAAM,aAAa,IAAI,MAAM,iBAAiB;AAC9C,YAAI,YAAY;AACd,qBAAW,KAAK,aAAa,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;AAC3D,gBAAM,KAAK,IAAI,UAAU,GAAG,WAAW,KAAM,EAAE,KAAK,CAAC;AAAA,QACvD,OAAO;AACL,qBAAW,KAAK,MAAS;AACzB,gBAAM,KAAK,GAAG;AAAA,QAChB;AAAA,MACF;AACA,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO,SAAS,MAAM,CAAC;AAAA,MACzB;AACA,UAAI,WAAW,KAAK,OAAO,EAAG,QAAO,mBAAmB;AACxD;AAAA,IACF;AAGA,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS;AAChB;AAAA,IACF;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS;AAChB;AAAA,IACF;AAEA,QAAI,QAAQ,aAAa;AACvB,aAAO,YAAY;AACnB;AAAA,IACF;AAEA,QAAI,QAAQ,UAAU;AACpB,aAAO,aACL,MAAM,YAAY,MAAM,QAAQ,MAAM,YAAY,MAAM;AAC1D;AAAA,IACF;AAGA,QAAI,QAAQ,WAAW;AACrB,aAAO,UAAU,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACrD;AAAA,IACF;AAEA,QAAI,QAAQ,QAAQ;AAClB,aAAO,OAAO,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAClD;AAAA,IACF;AAGA,QAAI,QAAQ,KAAK;AACf,YAAM,aAAa,MAAM,MAAM,gCAAgC;AAC/D,UAAI,YAAY;AACd,eAAO,SAAS;AAAA,UACd,KAAK,WAAW,WAAW,CAAC,CAAC;AAAA,UAC7B,KAAK,WAAW,WAAW,CAAC,CAAC;AAAA,QAC/B;AAAA,MACF;AACA;AAAA,IACF;AAGA,UAAM,aAAa,QAAQ,MAAM,yCAAyC;AAC1E,QAAI,YAAY;AACd,YAAM,CAAC,EAAE,QAAQ,QAAQ,GAAG,IAAI;AAChC,UAAI,CAAC,OAAO,MAAO,QAAO,QAAQ,CAAC;AACnC,aAAO,MAAM,KAAK;AAAA,QAChB,QAAQ,OAAO,KAAK;AAAA,QACpB,QAAQ,OAAO,KAAK;AAAA,QACpB,OAAO,WAAW,GAAG;AAAA,QACrB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,YAAY;AAC9B,UAAI,SAAS,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK;AACnD,UAAI;AACJ,YAAM,aAAa,OAAO,MAAM,iBAAiB;AACjD,UAAI,YAAY;AACd,kBAAU,aAAa,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO;AACpD,iBAAS,OAAO,UAAU,GAAG,WAAW,KAAM,EAAE,KAAK;AAAA,MACvD;AACA,UAAI,CAAC,OAAO,UAAW,QAAO,YAAY,CAAC;AAC3C,aAAO,UAAU,KAAK;AAAA,QACpB,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,GAAI,WAAW,EAAE,OAAO,QAAQ;AAAA,QAChC;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,WAAW;AAC7B,YAAM,eAAe,MAAM;AAAA,QACzB;AAAA,MACF;AACA,UAAI,cAAc;AAChB,YAAI,cAAc,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK;AACxD,YAAI;AACJ,cAAM,aAAa,YAAY,MAAM,iBAAiB;AACtD,YAAI,YAAY;AACd,yBAAe,aAAa,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO;AACzD,wBAAc,YAAY,UAAU,GAAG,WAAW,KAAM,EAAE,KAAK;AAAA,QACjE;AACA,YAAI,CAAC,OAAO,cAAe,QAAO,gBAAgB,CAAC;AACnD,eAAO,cAAc,KAAK;AAAA,UACxB,MAAM;AAAA,UACN,GAAG,WAAW,aAAa,CAAC,CAAC;AAAA,UAC7B,GAAG,WAAW,aAAa,CAAC,CAAC;AAAA,UAC7B,MAAM,aAAa,CAAC,IAAI,WAAW,aAAa,CAAC,CAAC,IAAI;AAAA,UACtD,GAAI,gBAAgB,EAAE,OAAO,aAAa;AAAA,UAC1C,GAAI,oBAAoB,aAAa,EAAE,UAAU,gBAAgB;AAAA,UACjE;AAAA,QACF,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,WAAW;AAC7B,YAAM,SAAS,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,WAAW,EAAE,KAAK,CAAC,CAAC;AAC/D,UAAI,OAAO,SAAS,KAAK,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG;AACvD,cAAM,cAAc,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK;AAC1D,YAAI,CAAC,OAAO,YAAa,QAAO,cAAc,CAAC;AAC/C,eAAO,YAAY,KAAK,EAAE,OAAO,aAAa,QAAQ,WAAW,CAAC;AAAA,MACpE;AACA;AAAA,IACF;AAGA,UAAM,WAAW,WAAW,KAAK;AACjC,QAAI,CAAC,MAAM,QAAQ,GAAG;AAEpB,UAAI,WAAW,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK;AACrD,UAAI;AACJ,YAAM,aAAa,SAAS,MAAM,iBAAiB;AACnD,UAAI,YAAY;AACd,qBAAa,aAAa,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO;AACvD,mBAAW,SAAS,UAAU,GAAG,WAAW,KAAM,EAAE,KAAK;AAAA,MAC3D;AACA,aAAO,KAAK,KAAK;AAAA,QACf,OAAO;AAAA,QACP,OAAO;AAAA,QACP,GAAI,cAAc,EAAE,OAAO,WAAW;AAAA,QACtC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,OAAO;AACjB,QAAI,OAAO,SAAS,UAAU;AAC5B,UAAI,CAAC,OAAO,SAAS,OAAO,MAAM,WAAW,GAAG;AAC9C,eAAO,QACL;AAAA,MACJ;AAAA,IACF,WAAW,OAAO,SAAS,SAAS;AAClC,UAAI,CAAC,OAAO,SAAS,OAAO,MAAM,WAAW,GAAG;AAC9C,eAAO,QACL;AAAA,MACJ;AAAA,IACF,WAAW,OAAO,SAAS,YAAY;AACrC,UAAI,CAAC,OAAO,aAAa,OAAO,UAAU,WAAW,GAAG;AACtD,eAAO,QACL;AAAA,MACJ;AACA,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO,SAAS,EAAE,KAAK,KAAK,KAAK,GAAG;AAAA,MACtC;AAAA,IACF,WAAW,OAAO,SAAS,WAAW;AACpC,UAAI,CAAC,OAAO,iBAAiB,OAAO,cAAc,WAAW,GAAG;AAC9D,eAAO,QACL;AAAA,MACJ;AAAA,IACF,WAAW,OAAO,SAAS,WAAW;AACpC,UAAI,CAAC,OAAO,eAAe,OAAO,YAAY,WAAW,GAAG;AAC1D,eAAO,QACL;AAAA,MACJ;AACA,UAAI,CAAC,OAAO,WAAW,OAAO,QAAQ,WAAW,GAAG;AAClD,eAAO,QACL;AAAA,MACJ;AAAA,IACF,WAAW,OAAO,SAAS,UAAU;AACnC,UAAI,OAAO,KAAK,WAAW,GAAG;AAC5B,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,mBACd,QACA,SACA,QACe;AACf,QAAM,YAAY,QAAQ;AAC1B,QAAM,gBAAgB,QAAQ;AAC9B,QAAM,cAAc,SAAS,MAAM;AACnC,QAAM,SAAS,gBAAgB,OAAO;AAEtC,MAAI,OAAO,OAAO;AAEhB,WAAO,CAAC;AAAA,EACV;AAGA,QAAM,cAAc,OAAO,QACvB;AAAA,IACE,MAAM,OAAO;AAAA,IACb,MAAM;AAAA,IACN,KAAK;AAAA,IACL,WAAW;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AAAA,EACF,IACA;AAGJ,QAAM,eAAe;AAAA,IACnB,iBAAiB,QAAQ;AAAA,IACzB,aAAa,QAAQ;AAAA,IACrB,WAAW,EAAE,OAAO,QAAQ,KAAK;AAAA,EACnC;AAGA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,SAAS;AAC3B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,YAAY;AAC9B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKA,SAAS,kBACP,QACA,WACA,QACA,aACA,cACe;AAEf,QAAM,UAAU,oBAAI,IAAY;AAChC,MAAI,OAAO,OAAO;AAChB,eAAW,QAAQ,OAAO,OAAO;AAC/B,cAAQ,IAAI,KAAK,MAAM;AACvB,cAAQ,IAAI,KAAK,MAAM;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,KAAK,OAAO,EAAE,IAAI,CAAC,MAAM,WAAW;AAAA,IACtD;AAAA,IACA,WAAW;AAAA,MACT,OAAO,OAAO,QAAQ,OAAO,MAAM;AAAA,IACrC;AAAA,EACF,EAAE;AAEF,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,MAAM;AAAA,MACN,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,QACA,WAAW;AAAA,QACX,SAAS;AAAA,QACT,WAAW;AAAA,QACX,MAAM;AAAA,QACN,OAAO,OAAO,SAAS,CAAC;AAAA,QACxB,WAAW;AAAA,UACT,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,QACA,OAAO;AAAA,UACL,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,iBACP,QACA,WACA,QACA,aACA,cACe;AAEf,QAAM,UAAU,oBAAI,IAAY;AAChC,MAAI,OAAO,OAAO;AAChB,eAAW,QAAQ,OAAO,OAAO;AAC/B,cAAQ,IAAI,KAAK,MAAM;AACvB,cAAQ,IAAI,KAAK,MAAM;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,KAAK,OAAO;AACpC,QAAM,YAAY,UAAU;AAG5B,QAAM,SAAqB,MAAM,SAAS,EACvC,KAAK,IAAI,EACT,IAAI,MAAM,MAAM,SAAS,EAAE,KAAK,CAAC,CAAC;AAErC,MAAI,OAAO,OAAO;AAChB,eAAW,QAAQ,OAAO,OAAO;AAC/B,YAAM,cAAc,UAAU,QAAQ,KAAK,MAAM;AACjD,YAAM,cAAc,UAAU,QAAQ,KAAK,MAAM;AACjD,UAAI,gBAAgB,MAAM,gBAAgB,IAAI;AAC5C,eAAO,WAAW,EAAE,WAAW,IAAI,KAAK;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAGA,QAAM,aAAa,UAAU,IAAI,CAAC,MAAM,WAAW;AAAA,IACjD;AAAA,IACA,WAAW;AAAA,MACT,OAAO,OAAO,QAAQ,OAAO,MAAM;AAAA,IACrC;AAAA,EACF,EAAE;AAEF,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,WAAW,CAAC,WAAoB;AAC9B,cAAM,IAAI;AAGV,YAAI,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ;AAC5C,iBAAO,GAAG,EAAE,KAAK,MAAM,WAAM,EAAE,KAAK,MAAM,KAAK,EAAE,KAAK,KAAK;AAAA,QAC7D;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,UAAU;AAAA,UACR,aAAa;AAAA,QACf;AAAA,QACA,QAAQ,CAAC,OAAO,KAAK;AAAA,QACrB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM,WAAW,IAAI,CAAC,SAAS;AAAA,UAC7B,MAAM,IAAI;AAAA,UACV,YAAY;AAAA,UACZ,WAAW,IAAI;AAAA,UACf,OAAO;AAAA,YACL,MAAM;AAAA,YACN,OAAO;AAAA,UACT;AAAA,QACF,EAAE;AAAA,QACF,QAAQ,OAAO,SAAS,CAAC,GAAG,IAAI,CAAC,UAAU;AAAA,UACzC,QAAQ,KAAK;AAAA,UACb,QAAQ,KAAK;AAAA,UACb,OAAO,KAAK;AAAA,UACZ,WAAW;AAAA,YACT,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,QAAQ,IAAI,EAAE,CAAC;AAAA,YAChD,OAAO,OAAO,UAAU,QAAQ,KAAK,MAAM,IAAI,OAAO,MAAM;AAAA,YAC5D,WAAW;AAAA,YACX,SAAS;AAAA,UACX;AAAA,QACF,EAAE;AAAA,QACF,MAAM;AAAA,QACN,OAAO;AAAA,UACL,UAAU;AAAA,UACV,WAAW;AAAA,QACb;AAAA,QACA,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,YACT,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,mBAAmB,MAAc,GAAmB;AAC3D,MAAI;AAEF,UAAM,YAAY,KACf,QAAQ,YAAY,OAAO,KAAK,EAAE,CAAC,EACnC,QAAQ,UAAU,OAAO,KAAK,CAAC,CAAC,EAChC,QAAQ,gBAAgB,WAAW,EACnC,QAAQ,gBAAgB,WAAW,EACnC,QAAQ,gBAAgB,WAAW,EACnC,QAAQ,eAAe,WAAW,EAClC,QAAQ,gBAAgB,aAAa,EACrC,QAAQ,gBAAgB,WAAW,EACnC,QAAQ,iBAAiB,YAAY,EACrC,QAAQ,gBAAgB,WAAW,EACnC,QAAQ,WAAW,IAAI,CAAC,GAAG,EAC3B,QAAQ,OAAO,IAAI;AAGtB,UAAM,SAAS,IAAI,SAAS,UAAU,SAAS,EAAE,EAAE;AACnD,WAAO,OAAO,WAAW,YAAY,SAAS,MAAM,IAAI,SAAS;AAAA,EACnE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,oBACP,QACA,SACA,WACA,eACA,aACA,QACA,aACA,cACe;AACf,QAAM,SAAS,OAAO,UAAU,EAAE,KAAK,KAAK,KAAK,GAAG;AACpD,QAAM,UAAU;AAChB,QAAM,QAAQ,OAAO,MAAM,OAAO,OAAO;AAGzC,QAAM,UAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,KAAK,SAAS,KAAK;AACjC,YAAQ,KAAK,OAAO,MAAM,IAAI,IAAI;AAAA,EACpC;AAGA,QAAM,UAAU,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,IAAI,UAAU;AACzD,UAAM,OAAO,QAAQ,IAAI,CAAC,MAAM;AAC9B,YAAM,IAAI,mBAAmB,GAAG,YAAY,CAAC;AAC7C,aAAO,CAAC,GAAG,CAAC;AAAA,IACd,CAAC;AAED,UAAM,UAAU,GAAG,SAAS,OAAO,QAAQ,OAAO,MAAM;AACxD,WAAO;AAAA,MACL,MAAM,GAAG;AAAA,MACT,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,MACT;AAAA,MACA,UAAU;AAAA,QACR,OAAO;AAAA,QACP,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,aAAa;AAAA,QACX,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,OAAO,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI;AAAA,MAClD,QAAQ;AAAA,MACR,WAAW;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO;AAAA,MACZ,UAAU;AAAA,QACR,WAAW,EAAE,OAAO,cAAc;AAAA,MACpC;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,MACA,WAAW;AAAA,QACT,WAAW;AAAA,UACT,OAAO,QAAQ;AAAA,UACf,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,QACR,WAAW,EAAE,OAAO,cAAc;AAAA,MACpC;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,MACA,WAAW;AAAA,QACT,WAAW;AAAA,UACT,OAAO,QAAQ;AAAA,UACf,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAQA,SAAS,mBACP,QACA,SACA,WACA,eACA,aACA,QACA,aACA,cACe;AACf,QAAM,SAAS,OAAO,iBAAiB,CAAC;AACxC,QAAM,cAAc;AAEpB,QAAM,gBAAgB,OAAO,KAAK,CAAC,MAAM,EAAE,aAAa,MAAS;AACjE,QAAM,UAAU,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,MAAS;AAEvD,QAAM,cAAc;AAAA,IAClB,MAAM,OAAO,cAAc;AAAA,IAC3B,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAEA,QAAM,iBAAiB;AAAA,IACrB,OAAO;AAAA,IACP,WAAW;AAAA,MACT,YAAY;AAAA,MACZ,aAAa;AAAA,IACf;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AAEJ,MAAI,eAAe;AACjB,UAAM,aAAa;AAAA,MACjB,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,OAAO,CAAC;AAAA,IAC1D;AACA,iBAAa;AAEb,aAAS,WAAW,IAAI,CAAC,UAAU,aAAa;AAC9C,YAAM,iBAAiB,OAAO,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AACnE,YAAM,WACJ,OAAO,iBAAiB,QAAQ,KAAK,OAAO,WAAW,OAAO,MAAM;AAEtE,YAAM,OAAO,eAAe,IAAI,CAAC,OAAO;AAAA,QACtC,MAAM,EAAE;AAAA,QACR,OAAO,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;AAAA,QACpD,GAAI,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE;AAAA,MACjD,EAAE;AAEF,aAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,GAAI,UACA,EAAE,YAAY,CAAC,QAAkB,IAAI,CAAC,EAAE,IACxC,EAAE,YAAY,YAAY;AAAA,QAC9B,WAAW,EAAE,OAAO,SAAS;AAAA,QAC7B,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AAEL,UAAM,OAAO,OAAO,IAAI,CAAC,GAAG,WAAW;AAAA,MACrC,MAAM,EAAE;AAAA,MACR,OAAO,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;AAAA,MACpD,GAAI,UACA,EAAE,YAAY,EAAE,QAAQ,YAAY,IACpC,EAAE,YAAY,YAAY;AAAA,MAC9B,WAAW;AAAA,QACT,OAAO,EAAE,SAAS,OAAO,QAAQ,OAAO,MAAM;AAAA,MAChD;AAAA,IACF,EAAE;AAEF,aAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UAAU;AAAA,IACd,SAAS;AAAA,IACT,GAAG;AAAA,IACH,WAAW,CAAC,WAAoB;AAC9B,YAAM,IAAI;AAKV,YAAM,SAAS,OAAO,UAAU;AAChC,YAAM,SAAS,OAAO,UAAU;AAChC,UAAI,OAAO,WAAW,EAAE,IAAI;AAC5B,UAAI,cAAe,SAAQ,QAAQ,EAAE,UAAU;AAC/C,cAAQ,QAAQ,MAAM,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,MAAM,KAAK,EAAE,MAAM,CAAC,CAAC;AAClE,UAAI,QAAS,SAAQ,QAAQ,OAAO,aAAa,MAAM,KAAK,EAAE,MAAM,CAAC,CAAC;AACtE,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,UAAU,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;AACrC,QAAM,UAAU,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;AACrC,QAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,QAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,QAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,QAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,QAAM,QAAQ,OAAO,QAAQ,OAAO;AACpC,QAAM,QAAQ,OAAO,QAAQ,OAAO;AAEpC,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP;AAAA,IACA,GAAI,cAAc;AAAA,MAChB,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,WAAW,EAAE,OAAO,UAAU;AAAA,MAChC;AAAA,IACF;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,OAAO,SAAS,OAAO;AAAA,MAC7B,OAAO;AAAA,MACP,QAAQ,gBAAgB,QAAQ,OAAO,SAAS,QAAQ;AAAA,MACxD,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,OAAO;AAAA,MACb,cAAc;AAAA,MACd,SAAS;AAAA,MACT,eAAe;AAAA,QACb,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,MACA,KAAK,KAAK,MAAM,OAAO,IAAI;AAAA,MAC3B,KAAK,KAAK,KAAK,OAAO,IAAI;AAAA,MAC1B,UAAU;AAAA,QACR,WAAW,EAAE,OAAO,cAAc;AAAA,MACpC;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,MACA,WAAW;AAAA,QACT,WAAW;AAAA,UACT,OAAO,QAAQ;AAAA,UACf,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,OAAO;AAAA,MACb,cAAc;AAAA,MACd,SAAS;AAAA,MACT,eAAe;AAAA,QACb,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,MACA,KAAK,KAAK,MAAM,OAAO,IAAI;AAAA,MAC3B,KAAK,KAAK,KAAK,OAAO,IAAI;AAAA,MAC1B,UAAU;AAAA,QACR,WAAW,EAAE,OAAO,cAAc;AAAA,MACpC;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,MACA,WAAW;AAAA,QACT,WAAW;AAAA,UACT,OAAO,QAAQ;AAAA,UACf,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAKA,SAAS,mBACP,QACA,SACA,WACA,eACA,aACA,cACe;AACf,QAAM,cAAc,OAAO,eAAe,CAAC;AAC3C,QAAM,UAAU,OAAO,WAAW,CAAC;AACnC,QAAM,YAAY,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK;AAGhD,QAAM,OAAmC,CAAC;AAC1C,MAAI,WAAW;AACf,MAAI,WAAW;AAEf,cAAY,QAAQ,CAAC,KAAK,aAAa;AACrC,QAAI,OAAO,QAAQ,CAAC,OAAO,aAAa;AACtC,WAAK,KAAK,CAAC,UAAU,UAAU,KAAK,CAAC;AACrC,iBAAW,KAAK,IAAI,UAAU,KAAK;AACnC,iBAAW,KAAK,IAAI,UAAU,KAAK;AAAA,IACrC,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,WAAW,CAAC,WAAoB;AAC9B,cAAM,IAAI;AACV,cAAM,UAAU,QAAQ,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC;AAC9C,cAAM,UAAU,UAAU,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC;AAChD,eAAO,GAAG,OAAO,MAAM,OAAO,aAAa,EAAE,KAAK,CAAC,CAAC;AAAA,MACtD;AAAA,IACF;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,QACT,MAAM;AAAA,MACR;AAAA,MACA,UAAU;AAAA,QACR,WAAW,EAAE,OAAO,cAAc;AAAA,MACpC;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,QACT,MAAM;AAAA,MACR;AAAA,MACA,UAAU;AAAA,QACR,WAAW,EAAE,OAAO,cAAc;AAAA,MACpC;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,KAAK;AAAA,MACL,SAAS;AAAA,QACP,OAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,OAAO;AAAA,UACf,QAAQ,OAAO;AAAA,UACf,QAAQ,OAAO;AAAA,QACjB;AAAA,MACF;AAAA,MACA,WAAW;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,UACV,YAAY;AAAA,QACd;AAAA,QACA,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,UACX,WAAW;AAAA,YACT,YAAY;AAAA,YACZ,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,kBACP,QACA,WACA,QACA,aACA,cACe;AAEf,QAAM,SAAS,CAAC,GAAG,OAAO,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAChE,QAAM,WAAW,OAAO,SAAS,IAAI,OAAO,CAAC,EAAE,QAAQ;AAEvD,QAAM,OAAO,OAAO,IAAI,CAAC,OAAO;AAAA,IAC9B,MAAM,EAAE;AAAA,IACR,OAAO,EAAE;AAAA,IACT,WAAW;AAAA,MACT,OAAO,EAAE,SAAS,OAAO,OAAO,KAAK,QAAQ,CAAC,IAAI,OAAO,MAAM;AAAA,MAC/D,aAAa;AAAA,IACf;AAAA,EACF,EAAE;AAGF,QAAM,eAAe,oBAAI,IAAoB;AAC7C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,iBAAa;AAAA,MACX,OAAO,CAAC,EAAE;AAAA,MACV,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,QAAQ,OAAO,CAAC,EAAE;AAAA,IAC1C;AAAA,EACF;AAEA,QAAM,YAAY,OAAO,QAAQ,KAAK;AACtC,QAAM,eAAe;AAAA,IACnB,MAAM;AAAA,IACN,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AAEA,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,WAAW,CAAC,WAAoB;AAC9B,cAAM,IAAI;AACV,cAAM,MAAM,EAAE;AACd,cAAM,OAAO,aAAa,IAAI,EAAE,IAAI,KAAK;AACzC,cAAM,UAAU,EAAE,cAAc;AAChC,YAAI,OAAO,WAAW,EAAE,IAAI,cAAc,GAAG;AAC7C,YAAI,CAAC,SAAS;AACZ,gBAAM,aAAa,IAAI,MAAM,QAAQ,KAAK,QAAQ,CAAC;AACnD,kBAAQ,uBAAuB,QAAQ;AAAA,QACzC;AACA,YAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,gBAAM,cAAc,IAAI,MAAM,YAAY,KAAK,QAAQ,CAAC;AACxD,kBAAQ,0BAA0B,SAAS;AAAA,QAC7C;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,GAAG;AAAA,QACH,OAAO;AAAA,UACL,MAAM;AAAA,UACN,UAAU;AAAA,UACV,WAAW;AAAA,UACX,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,WAAW,EAAE,OAAO,WAAW,SAAS,IAAI;AAAA,QAC9C;AAAA,QACA,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,UACX,OAAO;AAAA,YACL,UAAU;AAAA,UACZ;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,WAAW,EAAE,OAAO,eAAe,aAAa,EAAE;AAAA,QAClD,OAAO;AAAA,UACL,MAAM;AAAA,UACN,UAAU;AAAA,UACV,WAAW;AAAA,UACX,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,WAAW,EAAE,OAAO,WAAW,SAAS,IAAI;AAAA,QAC9C;AAAA,QACA,UAAU,EAAE,UAAU,KAAK;AAAA,QAC3B,MAAM,KAAK,IAAI,CAAC,OAAO;AAAA,UACrB,GAAG;AAAA,UACH,WAAW,EAAE,OAAO,eAAe,aAAa,EAAE;AAAA,QACpD,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AASA,SAAS,kBAAkB,QAGzB;AACA,QAAM,eAAe,OAAO,gBAAgB;AAC5C,SAAO;AAAA,IACL,QAAQ,OAAO,WAAW,eAAe,OAAO,QAAQ;AAAA,IACxD,QAAQ,OAAO,WAAW,eAAe,SAAY,OAAO;AAAA,EAC9D;AACF;AAKA,SAAS,aACP,MACA,WACA,eACA,gBACA,aACA,OACA,MACyB;AACzB,SAAO;AAAA,IACL;AAAA,IACA,GAAI,QAAQ,EAAE,KAAK;AAAA,IACnB,UAAU,EAAE,WAAW,EAAE,OAAO,cAAc,EAAE;AAAA,IAChD,WAAW,EAAE,OAAO,WAAW,UAAU,IAAI,YAAY,YAAY;AAAA,IACrE,WAAW,EAAE,WAAW,EAAE,OAAO,gBAAgB,SAAS,YAAY,EAAE;AAAA,IACxE,GAAI,SAAS;AAAA,MACX,MAAM;AAAA,MACN,cAAc;AAAA,MACd,SAAS;AAAA,MACT,eAAe,EAAE,OAAO,WAAW,UAAU,IAAI,YAAY,YAAY;AAAA,IAC3E;AAAA,EACF;AACF;AAMO,SAAS,4BACd,QACA,SACA,QACe;AACf,MAAI,OAAO,MAAO,QAAO,CAAC;AAE1B,QAAM,YAAY,QAAQ;AAC1B,QAAM,gBAAgB,QAAQ;AAC9B,QAAM,iBAAiB,QAAQ;AAC/B,QAAM,cAAc,SAAS,MAAM;AACnC,QAAM,SAAS,gBAAgB,OAAO;AAEtC,QAAM,cAAc,OAAO,QACvB;AAAA,IACE,MAAM,OAAO;AAAA,IACb,MAAM;AAAA,IACN,KAAK;AAAA,IACL,WAAW;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AAAA,EACF,IACA;AAEJ,QAAM,eAAe;AAAA,IACnB,iBAAiB,QAAQ;AAAA,IACzB,aAAa,QAAQ;AAAA,IACrB,WAAW,EAAE,OAAO,QAAQ,KAAK;AAAA,EACnC;AAEA,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,eAAe,QAAQ,WAAW,eAAe,gBAAgB,aAAa,QAAQ,aAAa,YAAY;AAAA,IACxH,KAAK;AACH,aAAO,sBAAsB,QAAQ,WAAW,eAAe,gBAAgB,aAAa,QAAQ,aAAa,YAAY;AAAA,IAC/H,KAAK;AACH,aAAO,OAAO,cACV,qBAAqB,QAAQ,WAAW,eAAe,gBAAgB,aAAa,QAAQ,aAAa,YAAY,IACrH,gBAAgB,QAAQ,SAAS,WAAW,eAAe,gBAAgB,aAAa,aAAa,YAAY;AAAA,IACvH,KAAK;AACH,aAAO,gBAAgB,QAAQ,SAAS,WAAW,eAAe,gBAAgB,aAAa,aAAa,YAAY;AAAA,IAC1H,KAAK;AACH,aAAO,eAAe,QAAQ,WAAW,iBAAiB,SAAS,OAAO,KAAK,MAAM,GAAG,aAAa,cAAc,KAAK;AAAA,IAC1H,KAAK;AACH,aAAO,eAAe,QAAQ,WAAW,iBAAiB,SAAS,OAAO,KAAK,MAAM,GAAG,aAAa,cAAc,IAAI;AAAA,IACzH,KAAK;AACH,aAAO,iBAAiB,QAAQ,SAAS,WAAW,aAAa,QAAQ,aAAa,YAAY;AAAA,IACpG,KAAK;AACH,aAAO,qBAAqB,QAAQ,WAAW,iBAAiB,SAAS,OAAO,KAAK,MAAM,GAAG,aAAa,YAAY;AAAA,EAC3H;AACF;AAIA,SAAS,eACP,QACA,WACA,eACA,gBACA,aACA,QACA,aACA,cACe;AACf,QAAM,EAAE,QAAQ,OAAO,IAAI,kBAAkB,MAAM;AACnD,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAC7C,QAAM,OAAO,OAAO,KAAK,IAAI,CAAC,GAAG,OAAO;AAAA,IACtC,OAAO,EAAE;AAAA,IACT,WAAW,EAAE,OAAO,EAAE,SAAS,OAAO,IAAI,OAAO,MAAM,EAAE;AAAA,EAC3D,EAAE;AAEF,QAAM,eAAe,aAAa,YAAY,WAAW,eAAe,gBAAgB,aAAa,eAAe,SAAS,QAAQ,MAAM;AAC3I,QAAM,YAAY,aAAa,SAAS,WAAW,eAAe,gBAAgB,aAAa,eAAe,SAAS,MAAM;AAI7H,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,aAAa,EAAE,MAAM,SAAS;AAAA,IAChC;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,SAAS,OAAO;AAAA,MACtB,OAAO;AAAA,MACP,QAAQ,SAAS,QAAQ;AAAA,MACzB,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO,eAAe,YAAY;AAAA,IAClC,OAAO,eAAe,eAAe;AAAA,IACrC,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,gBACP,QACA,SACA,WACA,eACA,gBACA,aACA,aACA,cACe;AACf,QAAM,EAAE,QAAQ,OAAO,IAAI,kBAAkB,MAAM;AACnD,QAAM,YAAY,OAAO,SAAS,OAAO,mBAAmB,CAAC,KAAK,QAAQ;AAC1E,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAC7C,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAE7C,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,aAAa,EAAE,MAAM,OAAO;AAAA,IAC9B;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,SAAS,OAAO;AAAA,MACtB,OAAO;AAAA,MACP,QAAQ,SAAS,QAAQ;AAAA,MACzB,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO,aAAa,YAAY,WAAW,eAAe,gBAAgB,aAAa,QAAQ,MAAM;AAAA,IACrG,OAAO,aAAa,SAAS,WAAW,eAAe,gBAAgB,aAAa,MAAM;AAAA,IAC1F,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,WAAW,EAAE,OAAO,WAAW,OAAO,EAAE;AAAA,QACxC,WAAW,EAAE,OAAO,UAAU;AAAA,QAC9B,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,qBACP,QACA,WACA,eACA,gBACA,aACA,QACA,aACA,cACe;AACf,QAAM,EAAE,QAAQ,OAAO,IAAI,kBAAkB,MAAM;AACnD,QAAM,cAAc,OAAO,eAAe,CAAC;AAC3C,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAE7C,QAAM,SAAS,YAAY,IAAI,CAAC,MAAM,QAAQ;AAC5C,UAAM,QAAQ,OAAO,mBAAmB,GAAG,KAAK,OAAO,MAAM,OAAO,MAAM;AAC1E,UAAM,OAAO,OAAO,KAAK;AAAA,MAAI,CAAC,OAC5B,QAAQ,IAAI,GAAG,QAAS,GAAG,cAAc,MAAM,CAAC,KAAK;AAAA,IACvD;AACA,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,WAAW,EAAE,OAAO,OAAO,EAAE;AAAA,MAC7B,WAAW,EAAE,MAAM;AAAA,MACnB,UAAU;AAAA,QACR,OAAO;AAAA,QACP,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,aAAa,EAAE,MAAM,OAAO;AAAA,IAC9B;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW,EAAE,OAAO,UAAU;AAAA,IAChC;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,SAAS,OAAO;AAAA,MACtB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO,aAAa,YAAY,WAAW,eAAe,gBAAgB,aAAa,QAAQ,MAAM;AAAA,IACrG,OAAO,aAAa,SAAS,WAAW,eAAe,gBAAgB,aAAa,MAAM;AAAA,IAC1F;AAAA,EACF;AACF;AAIA,SAAS,gBACP,QACA,SACA,WACA,eACA,gBACA,aACA,aACA,cACe;AACf,QAAM,EAAE,QAAQ,OAAO,IAAI,kBAAkB,MAAM;AACnD,QAAM,YAAY,OAAO,SAAS,OAAO,mBAAmB,CAAC,KAAK,QAAQ;AAC1E,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAC7C,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAE7C,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,aAAa,EAAE,MAAM,OAAO;AAAA,IAC9B;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,SAAS,OAAO;AAAA,MACtB,OAAO;AAAA,MACP,QAAQ,SAAS,QAAQ;AAAA,MACzB,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO,aAAa,YAAY,WAAW,eAAe,gBAAgB,aAAa,QAAQ,MAAM;AAAA,IACrG,OAAO,aAAa,SAAS,WAAW,eAAe,gBAAgB,aAAa,MAAM;AAAA,IAC1F,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,WAAW,EAAE,OAAO,WAAW,OAAO,EAAE;AAAA,QACxC,WAAW,EAAE,OAAO,UAAU;AAAA,QAC9B,WAAW,EAAE,SAAS,KAAK;AAAA,QAC3B,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,sBAAsB,MAAqC;AAClE,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAW,aAAO;AAAA,IACvB,KAAK;AAAW,aAAO;AAAA,IACvB,KAAK;AAAW,aAAO;AAAA,IACvB;AAAgB,aAAO;AAAA,EACzB;AACF;AAIA,SAAS,eACP,QACA,WACA,QACA,aACA,cACA,YACe;AACf,QAAM,OAAO,OAAO,KAAK,IAAI,CAAC,GAAG,OAAO;AAAA,IACtC,MAAM,EAAE;AAAA,IACR,OAAO,EAAE;AAAA,IACT,WAAW,EAAE,OAAO,EAAE,SAAS,OAAO,IAAI,OAAO,MAAM,EAAE;AAAA,EAC3D,EAAE;AAEF,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,QAAQ,aAAa,CAAC,OAAO,KAAK,IAAI,CAAC,MAAM,KAAK;AAAA,QAClD;AAAA,QACA,OAAO;AAAA,UACL,UAAU;AAAA,UACV,WAAW,sBAAsB,OAAO,MAAM;AAAA,UAC9C,OAAO;AAAA,UACP,YAAY;AAAA,QACd;AAAA,QACA,WAAW,EAAE,MAAM,KAAK;AAAA,QACxB,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,iBACP,QACA,SACA,WACA,aACA,QACA,aACA,cACe;AACf,QAAM,aAAa,OAAO,SAAS,OAAO,mBAAmB,CAAC,KAAK,QAAQ;AAC3E,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAC7C,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI;AAEvC,QAAM,YAAY,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACxC,MAAM,EAAE;AAAA,IACR,KAAK;AAAA,EACP,EAAE;AAEF,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,IACL;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,QACR,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,MACA,WAAW;AAAA,QACT,WAAW,EAAE,OAAO,QAAQ,QAAQ,SAAS,YAAY;AAAA,MAC3D;AAAA,MACA,UAAU;AAAA,QACR,WAAW,EAAE,OAAO,QAAQ,QAAQ,SAAS,YAAY;AAAA,MAC3D;AAAA,MACA,WAAW,EAAE,MAAM,MAAM;AAAA,IAC3B;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,YACE,OAAO;AAAA,YACP,MAAM,OAAO,UAAU;AAAA,YACvB,WAAW,EAAE,OAAO,YAAY,SAAS,KAAK;AAAA,YAC9C,WAAW,EAAE,OAAO,WAAW;AAAA,YAC/B,WAAW,EAAE,OAAO,WAAW;AAAA,YAC/B,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,OAAO;AAAA,cACL,MAAM;AAAA,cACN,WAAW;AAAA,cACX,OAAO;AAAA,cACP,UAAU;AAAA,cACV,YAAY;AAAA,YACd;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,qBACP,QACA,WACA,QACA,aACA,cACe;AACf,QAAM,OAAO,OAAO,KAAK,IAAI,CAAC,GAAG,OAAO;AAAA,IACtC,MAAM,EAAE;AAAA,IACR,OAAO,EAAE;AAAA,IACT,WAAW,EAAE,OAAO,EAAE,SAAS,OAAO,IAAI,OAAO,MAAM,EAAE;AAAA,EAC3D,EAAE;AAEF,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ,CAAC,OAAO,KAAK;AAAA,QACrB;AAAA,QACA,OAAO;AAAA,UACL,UAAU;AAAA,UACV,WAAW,sBAAsB,OAAO,MAAM;AAAA,UAC9C,OAAO;AAAA,UACP,YAAY;AAAA,QACd;AAAA,QACA,WAAW,EAAE,MAAM,KAAK;AAAA,QACxB,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,sBACP,QACA,WACA,eACA,gBACA,aACA,QACA,aACA,cACe;AACf,QAAM,EAAE,QAAQ,OAAO,IAAI,kBAAkB,MAAM;AACnD,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,cAAc,OAAO,eAAe,CAAC;AAC3C,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAE7C,QAAM,SAAS,YAAY,IAAI,CAAC,MAAM,QAAQ;AAC5C,UAAM,QAAQ,OAAO,mBAAmB,GAAG,KAAK,OAAO,MAAM,OAAO,MAAM;AAC1E,UAAM,OAAO,OAAO,KAAK;AAAA,MAAI,CAAC,OAC5B,QAAQ,IAAI,GAAG,QAAS,GAAG,cAAc,MAAM,CAAC,KAAK;AAAA,IACvD;AACA,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,OAAO;AAAA,MACP;AAAA,MACA,WAAW,EAAE,MAAM;AAAA,MACnB,OAAO;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,QACV,WAAW;AAAA,QACX,OAAO;AAAA,QACP,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AAAA,MACA,UAAU;AAAA,QACR,OAAO;AAAA,QACP,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,eAAe,aAAa,YAAY,WAAW,eAAe,gBAAgB,aAAa,eAAe,SAAS,QAAQ,MAAM;AAC3I,QAAM,YAAY,aAAa,SAAS,WAAW,eAAe,gBAAgB,aAAa,eAAe,SAAS,MAAM;AAE7H,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,GAAG;AAAA,MACH,aAAa,EAAE,MAAM,SAAS;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW,EAAE,OAAO,UAAU;AAAA,IAChC;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,SAAS,OAAO;AAAA,MACtB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,KAAK,OAAO,QAAQ,QAAQ;AAAA,MAC5B,cAAc;AAAA,IAChB;AAAA,IACA,OAAO,eAAe,YAAY;AAAA,IAClC,OAAO,eAAe,eAAe;AAAA,IACrC;AAAA,EACF;AACF;AAMA,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAE7B,IAAM,uBAAuB,oBAAI,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMD,eAAsB,uBACpB,SACA,OACA,SACA,SACiB;AACjB,QAAM,SAAS,UAAU;AAGzB,QAAM,EAAE,YAAAC,YAAW,IAAI,MAAM;AAC7B,QAAM,mBACJ,YAAY,SAASA,YAAW,MAAM,EAAE,OAAOA,YAAW,MAAM,EAAE;AAGpE,QAAM,YAAY,QAAQ,MAAM,qBAAqB;AACrD,QAAM,YAAY,YAAY,CAAC,GAAG,KAAK,EAAE,YAAY;AAErD,MAAI;AACJ,MAAI,aAAa,qBAAqB,IAAI,SAAS,GAAG;AACpD,UAAM,SAAS,WAAW,SAAS,gBAAgB;AACnD,QAAI,OAAO,MAAO,QAAO;AACzB,aAAS,4BAA4B,QAAQ,kBAAkB,MAAM;AAAA,EACvE,OAAO;AACL,UAAM,SAAS,YAAY,SAAS,gBAAgB;AACpD,QAAI,OAAO,MAAO,QAAO;AACzB,aAAS,mBAAmB,QAAQ,kBAAkB,MAAM;AAAA,EAC9D;AACA,MAAI,CAAC,UAAU,OAAO,KAAK,MAAM,EAAE,WAAW,EAAG,QAAO;AAExD,QAAM,QAAgB,aAAK,MAAM,MAAM;AAAA,IACrC,UAAU;AAAA,IACV,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,EACV,CAAC;AAED,MAAI;AACF,UAAM,UAAU,MAAM;AACtB,UAAM,YAAY,MAAM,kBAAkB;AAC1C,QAAI,CAAC,UAAW,QAAO;AAIvB,UAAM,UAAU,UAAU,gBAAgB,eAAe,iBAAiB,EAAE,OAAO;AACnF,QAAI,SAAS,UAAU;AAAA,MACrB;AAAA,MACA,eAAe,OAAO,gBAAgB,WAAW;AAAA,IACnD;AAEA,QAAI,SAAS,aAAa,OAAO;AAC/B,YAAM,aAAa,UAAU,gBAAgB,SAAS,iBAAiB;AACvE,eAAS,eAAe,QAAQ,UAAU;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT,UAAE;AACA,UAAM,QAAQ;AAAA,EAChB;AACF;;;AEt3DA;AACA;AAOA,eAAe,YAA2B;AACxC,MAAI,OAAO,aAAa,YAAa;AAErC,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,QAAM,MAAM,IAAI,MAAM,2CAA2C;AACjE,QAAM,MAAM,IAAI;AAEhB,SAAO,eAAe,YAAY,YAAY,EAAE,OAAO,IAAI,UAAU,cAAc,KAAK,CAAC;AACzF,SAAO,eAAe,YAAY,UAAU,EAAE,OAAO,KAAK,cAAc,KAAK,CAAC;AAC9E,SAAO,eAAe,YAAY,aAAa,EAAE,OAAO,IAAI,WAAW,cAAc,KAAK,CAAC;AAC3F,SAAO,eAAe,YAAY,eAAe,EAAE,OAAO,IAAI,aAAa,cAAc,KAAK,CAAC;AAC/F,SAAO,eAAe,YAAY,cAAc,EAAE,OAAO,IAAI,YAAY,cAAc,KAAK,CAAC;AAC/F;AAuBA,eAAsB,OACpB,SACA,SAKiB;AACjB,QAAM,QAAQ,SAAS,SAAS;AAChC,QAAM,cAAc,SAAS,WAAW;AACxC,QAAM,WAAW,SAAS,YAAY;AAEtC,QAAM,gBAAgB,WAAW,WAAW,EAAE,UAAU,SAAS,SAAS,OAAO;AAEjF,QAAM,YAAY,mBAAmB,OAAO;AAC5C,QAAM,YAAY,YAAY,iBAAiB,SAAS,IAAI;AAE5D,MAAI,cAAc,UAAU;AAC1B,WAAO,uBAAuB,SAAS,OAAO,eAAe,EAAE,SAAS,CAAC;AAAA,EAC3E;AAGA,QAAM,UAAU;AAChB,SAAO,kBAAkB,SAAS,OAAO,eAAe,QAAW,EAAE,SAAS,CAAC;AACjF;;;AL3DA;AA+BA;AAmBA;;;AMvDA;AAkCA,IAAM,oBAAoB;AAG1B,IAAM,gBAAgB;AAEtB,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,SAAS,cAAc,SAAiC;AAC7D,QAAM,SAAyB;AAAA,IAC7B,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,WAAW;AAAA,MACT,UAAU;AAAA,MACV,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,aAAa;AAAA,IACf;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,EACT;AAEA,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAEhC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAMC,QAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,UAAM,aAAa,IAAI;AAGvB,QAAI,CAACA,SAAQA,MAAK,WAAW,GAAG,KAAKA,MAAK,WAAW,IAAI,EAAG;AAG5D,QAAI,cAAc,KAAKA,KAAI,EAAG;AAG9B,UAAM,aAAaA,MAAK,MAAM,oBAAoB;AAClD,QAAI,YAAY;AACd,aAAO,QAAQ,WAAW,CAAC,EAAE,KAAK;AAClC,aAAO,kBAAkB;AACzB;AAAA,IACF;AAGA,UAAM,SAASA,MAAK,MAAM,qBAAqB;AAC/C,QAAI,QAAQ;AACV,YAAM,QAAQ,OAAO,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACtD,UAAI,MAAM,UAAU,GAAG;AACrB,eAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAClC,eAAO,kBAAkB;AAAA,MAC3B;AACA;AAAA,IACF;AAGA,UAAM,SAASA,MAAK,MAAM,qBAAqB;AAC/C,QAAI,QAAQ;AACV,YAAM,QAAQ,OAAO,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACtD,UAAI,MAAM,UAAU,GAAG;AACrB,eAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAClC,eAAO,kBAAkB;AAAA,MAC3B;AACA;AAAA,IACF;AAGA,UAAM,WAAWA,MAAK;AAAA,MACpB;AAAA,IACF;AACA,QAAI,UAAU;AACZ,YAAM,WAAW,SAAS,CAAC,EAAE,YAAY;AACzC,YAAM,aAAa,SAAS,CAAC,EAAE,MAAM,iBAAiB;AACtD,UAAI,YAAY;AACd,cAAM,QAAuB;AAAA,UAC3B,MAAM,WAAW,CAAC,EAAE,KAAK;AAAA,UACzB,OAAO,WAAW,CAAC,IAAI,aAAa,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI;AAAA,UAC5D;AAAA,QACF;AACA,YAAI,aAAa,YAAa,QAAO,UAAU,WAAW;AAAA,iBACjD,aAAa,WAAY,QAAO,UAAU,UAAU;AAAA,iBACpD,aAAa;AACpB,iBAAO,UAAU,aAAa;AAAA,iBACvB,aAAa;AACpB,iBAAO,UAAU,cAAc;AAAA,MACnC;AACA;AAAA,IACF;AAGA,UAAM,aAAaA,MAAK,MAAM,aAAa;AAC3C,QAAI,YAAY;AAEd,YAAM,MAAM,WAAW,CAAC,EAAE,KAAK,EAAE,YAAY;AAC7C,UAAI,CAAC,mBAAmB,IAAI,GAAG,GAAG;AAChC,eAAO,OAAO,KAAK;AAAA,UACjB,OAAO,WAAW,CAAC,EAAE,KAAK;AAAA,UAC1B,GAAG,WAAW,WAAW,CAAC,CAAC;AAAA,UAC3B,GAAG,WAAW,WAAW,CAAC,CAAC;AAAA,UAC3B;AAAA,QACF,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,OAAO,WAAW,GAAG;AAC9B,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO;AACT;AAUO,SAAS,qBACd,QACA,UAII,CAAC,GACG;AACR,QAAM,EAAE,SAAS,OAAO,WAAW,eAAe,IAAI;AACtD,QAAM,QAAkB,CAAC;AAGzB,QAAM,YAAY,SAAS,OAAO;AAClC,QAAM,cAAc,cAAc,SAAS,YAAY;AACvD,QAAM,oBAAoB,mBAAmB,SAAS,YAAY;AAElE,QAAM,WAAmC,CAAC;AAC1C,MAAI,OAAO,UAAU,UAAU;AAC7B,aAAS,gBAAgB,OAAO,UAAU,SAAS,QAAQ;AAC7D,MAAI,OAAO,UAAU,SAAS;AAC5B,aAAS,gBAAgB,OAAO,UAAU,QAAQ,QAAQ;AAC5D,MAAI,OAAO,UAAU,YAAY;AAC/B,aAAS,gBAAgB,OAAO,UAAU,WAAW,QAAQ;AAC/D,MAAI,OAAO,UAAU,aAAa;AAChC,aAAS,gBAAgB,OAAO,UAAU,YAAY,QAAQ;AAGhE,WAAS,oBAAoB;AAC7B,WAAS,oBAAoB;AAC7B,WAAS,oBAAoB;AAC7B,WAAS,oBAAoB;AAC7B,WAAS,wBAAwB;AACjC,WAAS,wBAAwB;AACjC,WAAS,wBAAwB;AACjC,WAAS,oBAAoB;AAE7B,QAAM,OAAO,KAAK,UAAU,QAAQ;AACpC,QAAM,KAAK,+BAA+B,IAAI,MAAM;AAEpD,QAAM,KAAK,eAAe;AAE1B,MAAI,OAAO,OAAO;AAChB,UAAM,KAAK,aAAa,OAAO,KAAK,EAAE;AAAA,EACxC;AAEA,MAAI,OAAO,OAAO;AAChB,UAAM,KAAK,cAAc,OAAO,MAAM,CAAC,CAAC,QAAQ,OAAO,MAAM,CAAC,CAAC,EAAE;AAAA,EACnE;AAEA,MAAI,OAAO,OAAO;AAChB,UAAM,KAAK,cAAc,OAAO,MAAM,CAAC,CAAC,QAAQ,OAAO,MAAM,CAAC,CAAC,EAAE;AAAA,EACnE;AAGA,QAAM,QAAQ,CAAC,MAAuB,YAAY,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM;AAGvE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,KAAK,kBAAkB,MAAM,OAAO,UAAU,SAAS,IAAI,CAAC,EAAE;AAAA,EACtE;AACA,MAAI,OAAO,UAAU,SAAS;AAC5B,UAAM,KAAK,kBAAkB,MAAM,OAAO,UAAU,QAAQ,IAAI,CAAC,EAAE;AAAA,EACrE;AACA,MAAI,OAAO,UAAU,YAAY;AAC/B,UAAM,KAAK,kBAAkB,MAAM,OAAO,UAAU,WAAW,IAAI,CAAC,EAAE;AAAA,EACxE;AACA,MAAI,OAAO,UAAU,aAAa;AAChC,UAAM,KAAK,kBAAkB,MAAM,OAAO,UAAU,YAAY,IAAI,CAAC,EAAE;AAAA,EACzE;AAGA,aAAW,SAAS,OAAO,QAAQ;AACjC,UAAM,KAAK,OAAO,MAAM,MAAM,KAAK,CAAC,MAAM,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG;AAAA,EAClE;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ANlLA;AAEAC;AAYAC;AAOAC;AAEAF;AAWAC;AAOAC;AAWAF;AAQA;AAQA;AAEA;AAGAC;AAQA;AAuBAC;AAoBA;AAEA;;;AOlMA,uBAGO;AAEP,IAAM,mBAAmB;AACzB,IAAM,wBAAwB;AAyBvB,SAAS,iBACd,KACA,SACwB;AACxB,QAAM,UAAU,SAAS,WAAW;AACpC,QAAM,iBAAa,gDAA8B,GAAG;AACpD,QAAM,WAAW,IAAI,YAAY,EAAE,OAAO,UAAU,EAAE;AAEtD,MAAI,WAAW,uBAAuB;AACpC,WAAO,EAAE,OAAO,aAAa,gBAAgB,UAAU,OAAO,sBAAsB;AAAA,EACtF;AAEA,MAAI,OAAO,QAAQ,UAAU;AAE7B,MAAI,SAAS,WAAW,gBAAgB;AACtC,YAAQ,QAAQ,mBAAmB,QAAQ,UAAU,cAAc,CAAC;AAAA,EACtE;AAEA,SAAO,EAAE,KAAK,GAAG,OAAO,IAAI,IAAI,GAAG;AACrC;AAWO,SAAS,iBAAiB,MAAiC;AAChE,QAAM,QAA2B,EAAE,KAAK,IAAI,WAAW,CAAC,EAAE;AAC1D,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI,MAAM;AAGV,MAAI,IAAI,WAAW,GAAG,GAAG;AACvB,UAAM,IAAI,MAAM,CAAC;AAAA,EACnB;AAKA,QAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,MAAI,UAAU,MAAM,CAAC;AAGrB,QAAM,YAA8B,CAAC;AACrC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,KAAK,MAAM,CAAC,EAAE,QAAQ,GAAG;AAC/B,QAAI,OAAO,GAAI;AACf,UAAM,MAAM,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE;AAChC,UAAM,MAAM,mBAAmB,MAAM,CAAC,EAAE,MAAM,KAAK,CAAC,CAAC;AACrD,QAAI,QAAQ,SAAS,KAAK;AACxB,gBAAU,iBAAiB;AAAA,IAC7B;AAAA,EACF;AAGA,MAAI,QAAQ,WAAW,OAAO,GAAG;AAC/B,cAAU,QAAQ,MAAM,CAAC;AAAA,EAC3B;AAEA,MAAI,CAAC,QAAS,QAAO,EAAE,KAAK,IAAI,UAAU;AAE1C,MAAI;AACF,UAAM,aAAS,oDAAkC,OAAO;AACxD,WAAO,EAAE,KAAK,UAAU,IAAI,UAAU;AAAA,EACxC,QAAQ;AACN,WAAO,EAAE,KAAK,IAAI,UAAU;AAAA,EAC9B;AACF;","names":["p","q","line","measureIndent","line","parser_exports","measureIndent","line","init_parser","parser_exports","measureIndent","line","REL_KEYWORD_RE","init_parser","line","init_parser","parser_exports","measureIndent","line","extractColor","COLOR_SUFFIX_RE","GROUP_HEADING_RE","indent","init_parser","countDescendants","fill","stroke","CONTAINER_META_LINE_HEIGHT","HEADER_HEIGHT","SEPARATOR_GAP","META_LINE_HEIGHT","LEGEND_PAD","LEGEND_HEADER_H","EYE_ICON_GAP","LEGEND_DOT_R","LEGEND_DOT_TEXT_GAP","LEGEND_MAX_PER_ROW","LEGEND_ENTRY_GAP","LEGEND_ENTRY_H","init_parser","layout_exports","CHAR_WIDTH","dagre","init_layout","renderer_exports","mix","nodeFill","nodeStroke","DIAGRAM_PADDING","EDGE_STROKE_WIDTH","fill","stroke","NODE_STROKE_WIDTH","COMPARTMENT_PADDING_Y","MEMBER_LINE_HEIGHT","d3Selection","init_renderer","init_parser","init_layout","layout_exports","computeNodeDimensions","MIN_WIDTH","CHAR_WIDTH","PADDING_X","HEADER_BASE","COMPARTMENT_PADDING_Y","MEMBER_LINE_HEIGHT","SEPARATOR_HEIGHT","dagre","import_dagre","init_layout","renderer_exports","mix","EDGE_STROKE_WIDTH","EDGE_LABEL_FONT_SIZE","DIAGRAM_PADDING","seriesColors","lineGenerator","fill","stroke","NODE_STROKE_WIDTH","COMPARTMENT_PADDING_Y","MEMBER_PADDING_X","MEMBER_LINE_HEIGHT","d3Selection","d3Shape","init_renderer","init_parser","init_layout","layout_exports","dagre","import_dagre","init_layout","mix","nodeFill","nodeStroke","NODE_STROKE_WIDTH","DIAGRAM_PADDING","lineGenerator","EDGE_STROKE_WIDTH","EDGE_LABEL_FONT_SIZE","d3Selection","d3Shape","init_layout","renderer_exports","line","mix","TITLE_HEIGHT","d3Selection","init_renderer","d3Selection","d3Shape","line","text","fill","cloud","qw","qh","_","parseDgmoChartType","parseOrg","layoutOrg","collapseOrgTree","renderOrg","isDark","getPalette","effectivePalette","container","parseClassDiagram","layoutClassDiagram","renderClassDiagram","parseERDiagram","layoutERDiagram","renderERDiagram","parseFlowchart","layoutGraph","renderFlowchart","looksLikeSequence","parseSequenceDgmo","renderSequenceDiagram","getPalette","line","init_parser","init_layout","init_renderer"]}
1
+ {"version":3,"sources":["../src/diagnostics.ts","../src/fonts.ts","../src/branding.ts","../src/colors.ts","../src/palettes/registry.ts","../src/palettes/color-utils.ts","../src/palettes/nord.ts","../src/palettes/solarized.ts","../src/palettes/catppuccin.ts","../src/palettes/rose-pine.ts","../src/palettes/gruvbox.ts","../src/palettes/tokyo-night.ts","../src/palettes/one-dark.ts","../src/palettes/bold.ts","../src/palettes/mermaid-bridge.ts","../src/palettes/index.ts","../src/sequence/participant-inference.ts","../src/sequence/parser.ts","../src/graph/flowchart-parser.ts","../src/class/parser.ts","../src/er/parser.ts","../src/chart.ts","../src/echarts.ts","../src/org/parser.ts","../src/dgmo-router.ts","../src/org/layout.ts","../src/org/collapse.ts","../src/org/renderer.ts","../src/class/layout.ts","../src/class/renderer.ts","../src/er/layout.ts","../src/er/renderer.ts","../src/graph/layout.ts","../src/graph/flowchart-renderer.ts","../src/sequence/renderer.ts","../src/d3.ts","../src/index.ts","../src/render.ts","../src/dgmo-mermaid.ts","../src/org/resolver.ts","../src/sharing.ts"],"sourcesContent":["// ============================================================\n// Structured Diagnostic Types\n// ============================================================\n\nexport type DgmoSeverity = 'error' | 'warning';\n\nexport interface DgmoError {\n line: number; // 1-based (0 = no line info)\n column?: number; // optional 1-based column\n message: string; // without \"Line N:\" prefix\n severity: DgmoSeverity;\n}\n\nexport function makeDgmoError(\n line: number,\n message: string,\n severity: DgmoSeverity = 'error'\n): DgmoError {\n return { line, message, severity };\n}\n\nexport function formatDgmoError(err: DgmoError): string {\n return err.line > 0 ? `Line ${err.line}: ${err.message}` : err.message;\n}\n\n// ============================================================\n// \"Did you mean?\" Suggestions\n// ============================================================\n\n/**\n * Simple Levenshtein distance between two strings.\n */\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[] = Array(n + 1)\n .fill(0)\n .map((_, i) => i);\n\n for (let i = 1; i <= m; i++) {\n let prev = dp[0];\n dp[0] = i;\n for (let j = 1; j <= n; j++) {\n const tmp = dp[j];\n dp[j] =\n a[i - 1] === b[j - 1]\n ? prev\n : 1 + Math.min(prev, dp[j], dp[j - 1]);\n prev = tmp;\n }\n }\n return dp[n];\n}\n\n/**\n * Returns a \"did you mean 'X'?\" suggestion if the input is close to one of the candidates.\n * Returns null if no good match is found.\n * Threshold: distance ≤ max(2, floor(input.length / 3))\n */\nexport function suggest(input: string, candidates: readonly string[]): string | null {\n if (!input || candidates.length === 0) return null;\n const lower = input.toLowerCase();\n const threshold = Math.max(2, Math.floor(lower.length / 3));\n\n let best: string | null = null;\n let bestDist = Infinity;\n\n for (const c of candidates) {\n const dist = levenshtein(lower, c.toLowerCase());\n if (dist < bestDist && dist <= threshold && dist > 0) {\n bestDist = dist;\n best = c;\n }\n }\n\n return best ? `Did you mean '${best}'?` : null;\n}\n","export const FONT_FAMILY = 'Inter, system-ui, Avenir, Helvetica, Arial, sans-serif';\nexport const DEFAULT_FONT_NAME = 'Helvetica';\n","import { FONT_FAMILY } from './fonts';\n\nconst BRANDING_HEIGHT = 20;\n\n/**\n * Injects `diagrammo.app` branding text into an SVG string.\n * Extends the SVG height by 20px and places the text at the bottom-right.\n */\nexport function injectBranding(svgHtml: string, mutedColor: string): string {\n if (!svgHtml) return svgHtml;\n\n const brandingText = `<text x=\"0\" y=\"0\" font-size=\"10\" font-family=\"${FONT_FAMILY}\" fill=\"${mutedColor}\" opacity=\"0.5\" text-anchor=\"end\">diagrammo.app</text>`;\n\n // Parse viewBox\n const vbMatch = svgHtml.match(/viewBox=\"([^\"]+)\"/);\n const heightAttrMatch = svgHtml.match(/height=\"([^\"]+)\"/);\n\n if (vbMatch) {\n const parts = vbMatch[1].split(/\\s+/).map(Number);\n if (parts.length === 4) {\n const [vx, vy, vw, vh] = parts;\n const newVh = vh + BRANDING_HEIGHT;\n const textX = vx + vw - 4;\n const textY = vy + vh + BRANDING_HEIGHT - 6;\n const positioned = brandingText.replace('x=\"0\" y=\"0\"', `x=\"${textX}\" y=\"${textY}\"`);\n\n let result = svgHtml.replace(\n /viewBox=\"[^\"]+\"/,\n `viewBox=\"${vx} ${vy} ${vw} ${newVh}\"`\n );\n\n // Update height attribute if present\n if (heightAttrMatch) {\n const oldH = parseFloat(heightAttrMatch[1]);\n if (!isNaN(oldH)) {\n result = result.replace(\n `height=\"${heightAttrMatch[1]}\"`,\n `height=\"${oldH + BRANDING_HEIGHT}\"`\n );\n }\n }\n\n result = result.replace('</svg>', `${positioned}</svg>`);\n return result;\n }\n }\n\n // Fallback: no viewBox, try width/height attributes\n if (heightAttrMatch) {\n const widthMatch = svgHtml.match(/width=\"([^\"]+)\"/);\n const w = widthMatch ? parseFloat(widthMatch[1]) : 800;\n const h = parseFloat(heightAttrMatch[1]);\n if (!isNaN(h) && !isNaN(w)) {\n const textX = w - 4;\n const textY = h + BRANDING_HEIGHT - 6;\n const positioned = brandingText.replace('x=\"0\" y=\"0\"', `x=\"${textX}\" y=\"${textY}\"`);\n let result = svgHtml.replace(\n `height=\"${heightAttrMatch[1]}\"`,\n `height=\"${h + BRANDING_HEIGHT}\"`\n );\n result = result.replace('</svg>', `${positioned}</svg>`);\n return result;\n }\n }\n\n return svgHtml;\n}\n","// ============================================================\n// Shared Nord Color Palette\n// ============================================================\n\n/** Complete 16-entry Nord palette. */\nexport const nord = {\n // Polar Night (dark)\n nord0: '#2e3440',\n nord1: '#3b4252',\n nord2: '#434c5e',\n nord3: '#4c566a',\n // Snow Storm (light)\n nord4: '#d8dee9',\n nord5: '#e5e9f0',\n nord6: '#eceff4',\n // Frost (accent blues)\n nord7: '#8fbcbb',\n nord8: '#88c0d0',\n nord9: '#81a1c1',\n nord10: '#5e81ac',\n // Aurora (colors)\n nord11: '#bf616a', // red\n nord12: '#d08770', // orange\n nord13: '#ebcb8b', // yellow\n nord14: '#a3be8c', // green\n nord15: '#b48ead', // purple\n};\n\n/** Color name → Nord hex for inline `(color)` annotations. */\nexport const colorNames: Record<string, string> = {\n red: nord.nord11,\n orange: nord.nord12,\n yellow: nord.nord13,\n green: nord.nord14,\n blue: nord.nord10,\n purple: nord.nord15,\n teal: nord.nord7,\n cyan: nord.nord8,\n lightblue: nord.nord8,\n gray: nord.nord3,\n};\n\n/**\n * Resolves a color name or hex code to a valid CSS color.\n * When a palette is provided, named colors resolve against its color map first.\n * Hex codes (e.g. \"#ff0000\") are passed through regardless of palette (FR8).\n * Unknown names are returned as-is.\n */\nexport function resolveColor(\n color: string,\n palette?: { colors: Record<string, string> }\n): string {\n const lower = color.toLowerCase();\n if (lower.startsWith('#')) return lower;\n\n if (palette) {\n const named = palette.colors[lower];\n if (named) return named;\n }\n\n if (colorNames[lower]) return colorNames[lower];\n return color;\n}\n\n/** @deprecated Use getSeriesColors(palette) from '@/lib/palettes' instead. */\nexport const seriesColors = [\n nord.nord10, // blue\n nord.nord14, // green\n nord.nord13, // yellow\n nord.nord12, // orange\n nord.nord15, // purple\n nord.nord11, // red\n nord.nord7, // teal\n nord.nord8, // light blue\n];\n","import type { PaletteConfig, PaletteColors } from './types';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst PALETTE_REGISTRY = new Map<string, PaletteConfig>();\nconst DEFAULT_PALETTE_ID = 'nord';\n\n// ============================================================\n// Validation\n// ============================================================\n\n/** Validate that a hex string is well-formed (#RGB or #RRGGBB). */\nexport function isValidHex(value: string): boolean {\n return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);\n}\n\n/** Named color keys that must be present in PaletteColors.colors. */\nconst COLOR_KEYS: (keyof PaletteColors['colors'])[] = [\n 'red',\n 'orange',\n 'yellow',\n 'green',\n 'blue',\n 'purple',\n 'teal',\n 'cyan',\n 'gray',\n];\n\n/** Semantic color keys that must be present at the top level of PaletteColors. */\nconst SEMANTIC_KEYS: (keyof Omit<PaletteColors, 'colors'>)[] = [\n 'bg',\n 'surface',\n 'overlay',\n 'border',\n 'text',\n 'textMuted',\n 'primary',\n 'secondary',\n 'accent',\n 'destructive',\n];\n\nfunction validatePaletteColors(\n colors: PaletteColors,\n mode: string,\n paletteId: string\n): void {\n for (const key of SEMANTIC_KEYS) {\n const value = colors[key];\n if (typeof value !== 'string' || !isValidHex(value)) {\n throw new Error(\n `Palette \"${paletteId}\" ${mode}.${key}: invalid hex \"${value}\"`\n );\n }\n }\n for (const key of COLOR_KEYS) {\n const value = colors.colors[key];\n if (typeof value !== 'string' || !isValidHex(value)) {\n throw new Error(\n `Palette \"${paletteId}\" ${mode}.colors.${key}: invalid hex \"${value}\"`\n );\n }\n }\n}\n\n// ============================================================\n// Registry Functions\n// ============================================================\n\n/**\n * Register a palette. Called at module initialization.\n * Validates that all 19 color fields per mode are present and valid hex.\n * Throws on malformed palettes to catch errors at startup, not at render time.\n */\nexport function registerPalette(palette: PaletteConfig): void {\n validatePaletteColors(palette.light, 'light', palette.id);\n validatePaletteColors(palette.dark, 'dark', palette.id);\n PALETTE_REGISTRY.set(palette.id, palette);\n}\n\n/** Get palette by id. Returns Nord if id is unrecognized (FR10). */\nexport function getPalette(id: string): PaletteConfig {\n return PALETTE_REGISTRY.get(id) ?? PALETTE_REGISTRY.get(DEFAULT_PALETTE_ID)!;\n}\n\n/** List all registered palettes (for the selector UI). */\nexport function getAvailablePalettes(): PaletteConfig[] {\n return Array.from(PALETTE_REGISTRY.values());\n}\n","import type { PaletteColors } from './types';\n\n// ============================================================\n// HSL Conversion\n// ============================================================\n\n/** Convert hex (#RRGGBB or #RGB) to { h, s, l } with h in degrees, s/l as percentages. */\nexport function hexToHSL(hex: string): { h: number; s: number; l: number } {\n const raw = hex.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n\n const r = parseInt(full.substring(0, 2), 16) / 255;\n const g = parseInt(full.substring(2, 4), 16) / 255;\n const b = parseInt(full.substring(4, 6), 16) / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l: Math.round(l * 100) };\n }\n\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n let h: number;\n if (max === r) {\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n } else if (max === g) {\n h = ((b - r) / d + 2) / 6;\n } else {\n h = ((r - g) / d + 4) / 6;\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/** Convert { h (degrees), s (%), l (%) } back to #RRGGBB hex string. */\nexport function hslToHex(h: number, s: number, l: number): string {\n const sNorm = s / 100;\n const lNorm = l / 100;\n\n if (sNorm === 0) {\n const v = Math.round(lNorm * 255);\n return `#${v.toString(16).padStart(2, '0')}${v.toString(16).padStart(2, '0')}${v.toString(16).padStart(2, '0')}`;\n }\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n let tNorm = t;\n if (tNorm < 0) tNorm += 1;\n if (tNorm > 1) tNorm -= 1;\n if (tNorm < 1 / 6) return p + (q - p) * 6 * tNorm;\n if (tNorm < 1 / 2) return q;\n if (tNorm < 2 / 3) return p + (q - p) * (2 / 3 - tNorm) * 6;\n return p;\n };\n\n const q = lNorm < 0.5 ? lNorm * (1 + sNorm) : lNorm + sNorm - lNorm * sNorm;\n const p = 2 * lNorm - q;\n const hNorm = h / 360;\n\n const r = Math.round(hue2rgb(p, q, hNorm + 1 / 3) * 255);\n const g = Math.round(hue2rgb(p, q, hNorm) * 255);\n const b = Math.round(hue2rgb(p, q, hNorm - 1 / 3) * 255);\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/** Convert hex to \"H S% L%\" string for CSS custom properties. */\nexport function hexToHSLString(hex: string): string {\n const { h, s, l } = hexToHSL(hex);\n return `${h} ${s}% ${l}%`;\n}\n\n// ============================================================\n// Color Manipulation\n// ============================================================\n\n/**\n * Derive a muted (desaturated, darkened) variant of a color.\n * Used by the Mermaid theme generator for dark-mode fills.\n *\n * Algorithm: cap saturation at 35% and lightness at 36%.\n */\nexport function mute(hex: string): string {\n const { h, s, l } = hexToHSL(hex);\n return hslToHex(h, Math.min(s, 35), Math.min(l, 36));\n}\n\n/**\n * Blend a color toward white (light mode quadrant fills).\n * amount: 0 = original, 1 = white\n */\nexport function tint(hex: string, amount: number): string {\n const raw = hex.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n\n const r = parseInt(full.substring(0, 2), 16);\n const g = parseInt(full.substring(2, 4), 16);\n const b = parseInt(full.substring(4, 6), 16);\n\n const tr = Math.round(r + (255 - r) * amount);\n const tg = Math.round(g + (255 - g) * amount);\n const tb = Math.round(b + (255 - b) * amount);\n\n return `#${tr.toString(16).padStart(2, '0')}${tg.toString(16).padStart(2, '0')}${tb.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Blend a color toward a dark base (dark mode quadrant fills).\n * amount: 0 = original, 1 = base\n */\nexport function shade(hex: string, base: string, amount: number): string {\n const parse = (h: string): [number, number, number] => {\n const raw = h.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n return [\n parseInt(full.substring(0, 2), 16),\n parseInt(full.substring(2, 4), 16),\n parseInt(full.substring(4, 6), 16),\n ];\n };\n\n const [r, g, b] = parse(hex);\n const [br, bg, bb] = parse(base);\n\n const sr = Math.round(r + (br - r) * amount);\n const sg = Math.round(g + (bg - g) * amount);\n const sb = Math.round(b + (bb - b) * amount);\n\n return `#${sr.toString(16).padStart(2, '0')}${sg.toString(16).padStart(2, '0')}${sb.toString(16).padStart(2, '0')}`;\n}\n\n// ============================================================\n// Contrast / Accessibility\n// ============================================================\n\n/** WCAG 2.1 relative luminance (0 = black, 1 = white). */\nexport function relativeLuminance(hex: string): number {\n const raw = hex.replace('#', '');\n const full =\n raw.length === 3\n ? raw[0] + raw[0] + raw[1] + raw[1] + raw[2] + raw[2]\n : raw;\n\n const srgb = [\n parseInt(full.substring(0, 2), 16) / 255,\n parseInt(full.substring(2, 4), 16) / 255,\n parseInt(full.substring(4, 6), 16) / 255,\n ].map((c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4));\n\n return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];\n}\n\n/**\n * Pick a text color that contrasts against `bg`.\n * Returns `darkText` when background is light (luminance > 0.179),\n * `lightText` when background is dark.\n * Threshold 0.179 is the standard WCAG midpoint for the contrast flip.\n */\nexport function contrastText(\n bg: string,\n lightText: string,\n darkText: string\n): string {\n return relativeLuminance(bg) > 0.179 ? darkText : lightText;\n}\n\n// ============================================================\n// Series Colors\n// ============================================================\n\n/** Derive the 8-color series rotation from a palette's named colors. */\nexport function getSeriesColors(palette: PaletteColors): string[] {\n const c = palette.colors;\n return [c.blue, c.green, c.yellow, c.orange, c.purple, c.red, c.teal, c.cyan];\n}\n\n/**\n * Generate `count` visually distinct colors for segment-based charts\n * (pie, doughnut, polar-area).\n *\n * Problem: several palettes have duplicate hex values for different named\n * colors (e.g. Solarized teal===cyan, One Dark orange===yellow), and the\n * 8-color modulo cycle repeats when there are more than 8 segments.\n *\n * Solution: generate evenly-spaced hues using the palette's characteristic\n * saturation and lightness, guaranteeing every segment gets a unique,\n * perceptually distinct color regardless of segment count.\n */\nexport function getSegmentColors(palette: PaletteColors, count: number): string[] {\n const base = getSeriesColors(palette);\n const unique = [...new Set(base)];\n const hsls = unique.map(hexToHSL);\n\n const avgS = Math.round(hsls.reduce((s, c) => s + c.s, 0) / hsls.length);\n const avgL = Math.round(hsls.reduce((s, c) => s + c.l, 0) / hsls.length);\n\n // Start from the palette's blue hue (first in series) for consistency\n const startHue = hsls[0].h;\n const step = 360 / count;\n\n return Array.from({ length: count }, (_, i) =>\n hslToHex(Math.round((startHue + i * step) % 360), avgS, avgL)\n );\n}\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Nord Palette Definition\n// ============================================================\n\nexport const nordPalette: PaletteConfig = {\n id: 'nord',\n name: 'Nord',\n light: {\n bg: '#eceff4', // nord6\n surface: '#e5e9f0', // nord5\n overlay: '#d8dee9', // nord4 (muted/secondary backgrounds)\n border: '#d8dee9', // nord4\n text: '#2e3440', // nord0\n textMuted: '#4c566a', // nord3\n primary: '#5e81ac', // nord10\n secondary: '#81a1c1', // nord9\n accent: '#81a1c1', // nord9\n destructive: '#bf616a', // nord11\n colors: {\n red: '#bf616a', // nord11\n orange: '#d08770', // nord12\n yellow: '#ebcb8b', // nord13\n green: '#a3be8c', // nord14\n blue: '#5e81ac', // nord10\n purple: '#b48ead', // nord15\n teal: '#8fbcbb', // nord7\n cyan: '#88c0d0', // nord8\n gray: '#4c566a', // nord3\n },\n },\n dark: {\n bg: '#2e3440', // nord0\n surface: '#3b4252', // nord1\n overlay: '#434c5e', // nord2\n border: '#4c566a', // nord3\n text: '#eceff4', // nord6\n textMuted: '#d8dee9', // nord4\n primary: '#88c0d0', // nord8 (different from light's nord10)\n secondary: '#81a1c1', // nord9\n accent: '#81a1c1', // nord9\n destructive: '#bf616a', // nord11\n colors: {\n red: '#bf616a', // nord11\n orange: '#d08770', // nord12\n yellow: '#ebcb8b', // nord13\n green: '#a3be8c', // nord14\n blue: '#5e81ac', // nord10\n purple: '#b48ead', // nord15\n teal: '#8fbcbb', // nord7\n cyan: '#88c0d0', // nord8\n gray: '#4c566a', // nord3\n },\n },\n};\n\nregisterPalette(nordPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Solarized Palette Definition\n// ============================================================\n\n// Official Solarized colors: https://ethanschoonover.com/solarized/\n//\n// Base tones:\n// base03 #002b36 | base02 #073642 | base01 #586e75 | base00 #657b83\n// base0 #839496 | base1 #93a1a1 | base2 #eee8d5 | base3 #fdf6e3\n//\n// Accent colors:\n// yellow #b58900 | orange #cb4b16 | red #dc322f | magenta #d33682\n// violet #6c71c4 | blue #268bd2 | cyan #2aa198 | green #859900\n\nexport const solarizedPalette: PaletteConfig = {\n id: 'solarized',\n name: 'Solarized',\n light: {\n bg: '#fdf6e3', // base3\n surface: '#eee8d5', // base2\n overlay: '#eee8d5', // base2 (muted/secondary backgrounds)\n border: '#93a1a1', // base1\n text: '#657b83', // base00\n textMuted: '#93a1a1', // base1\n primary: '#268bd2', // blue\n secondary: '#2aa198', // cyan\n accent: '#6c71c4', // violet\n destructive: '#dc322f', // red\n colors: {\n red: '#dc322f',\n orange: '#cb4b16',\n yellow: '#b58900',\n green: '#859900',\n blue: '#268bd2',\n purple: '#6c71c4',\n teal: '#2aa198',\n cyan: '#2aa198', // Solarized has no separate cyan — reuse teal\n gray: '#586e75', // base01\n },\n },\n dark: {\n bg: '#002b36', // base03\n surface: '#073642', // base02\n overlay: '#073642', // base02 (muted/secondary backgrounds)\n border: '#586e75', // base01\n text: '#839496', // base0\n textMuted: '#586e75', // base01\n primary: '#268bd2', // blue\n secondary: '#2aa198', // cyan\n accent: '#6c71c4', // violet\n destructive: '#dc322f', // red\n colors: {\n red: '#dc322f',\n orange: '#cb4b16',\n yellow: '#b58900',\n green: '#859900',\n blue: '#268bd2',\n purple: '#6c71c4',\n teal: '#2aa198',\n cyan: '#2aa198',\n gray: '#586e75', // base01\n },\n },\n};\n\nregisterPalette(solarizedPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Catppuccin Palette Definition\n// ============================================================\n\n// Official Catppuccin colors: https://catppuccin.com/palette\n//\n// Latte (light):\n// Base #eff1f5 | Mantle #e6e9ef | Crust #dce0e8\n// Surface0 #ccd0da | Text #4c4f69 | Subtext1 #5c5f77 | Overlay0 #9ca0b0\n//\n// Mocha (dark):\n// Base #1e1e2e | Mantle #181825 | Surface0 #313244\n// Surface1 #45475a | Overlay0 #6c7086 | Text #cdd6f4 | Subtext1 #bac2de\n//\n// Accents (Latte / Mocha):\n// Red #d20f39 / #f38ba8 | Peach #fe640b / #fab387\n// Yellow #df8e1d / #f9e2af | Green #40a02b / #a6e3a1\n// Blue #1e66f5 / #89b4fa | Mauve #8839ef / #cba6f7\n// Teal #179299 / #94e2d5 | Sapphire #209fb5 / #74c7ec\n// Lavender #7287fd / #b4befe\n\nexport const catppuccinPalette: PaletteConfig = {\n id: 'catppuccin',\n name: 'Catppuccin',\n light: {\n bg: '#eff1f5', // Latte Base\n surface: '#e6e9ef', // Latte Mantle\n overlay: '#ccd0da', // Latte Surface0\n border: '#dce0e8', // Latte Crust\n text: '#4c4f69', // Latte Text\n textMuted: '#5c5f77', // Latte Subtext1\n primary: '#1e66f5', // Latte Blue\n secondary: '#7287fd', // Latte Lavender\n accent: '#8839ef', // Latte Mauve\n destructive: '#d20f39', // Latte Red\n colors: {\n red: '#d20f39',\n orange: '#fe640b',\n yellow: '#df8e1d',\n green: '#40a02b',\n blue: '#1e66f5',\n purple: '#8839ef',\n teal: '#179299',\n cyan: '#209fb5',\n gray: '#9ca0b0', // Latte Overlay0\n },\n },\n dark: {\n bg: '#1e1e2e', // Mocha Base\n surface: '#313244', // Mocha Surface0\n overlay: '#45475a', // Mocha Surface1\n border: '#6c7086', // Mocha Overlay0\n text: '#cdd6f4', // Mocha Text\n textMuted: '#bac2de', // Mocha Subtext1\n primary: '#89b4fa', // Mocha Blue\n secondary: '#b4befe', // Mocha Lavender\n accent: '#cba6f7', // Mocha Mauve\n destructive: '#f38ba8', // Mocha Red\n colors: {\n red: '#f38ba8',\n orange: '#fab387',\n yellow: '#f9e2af',\n green: '#a6e3a1',\n blue: '#89b4fa',\n purple: '#cba6f7',\n teal: '#94e2d5',\n cyan: '#74c7ec',\n gray: '#6c7086', // Mocha Overlay0\n },\n },\n};\n\nregisterPalette(catppuccinPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Rosé Pine Palette Definition\n// ============================================================\n\n// Official Rosé Pine colors: https://rosepinetheme.com/palette\n//\n// Dawn (light):\n// Base #faf4ed | Surface #fffaf3 | Overlay #f2e9e1\n// Muted #9893a5 | Subtle #797593 | Text #575279\n// Highlight Med #dfdad9\n//\n// Moon (dark):\n// Base #232136 | Surface #2a273f | Overlay #393552\n// Muted #6e6a86 | Subtle #908caa | Text #e0def4\n// Highlight Med #44415a\n//\n// Accents (Dawn / Moon):\n// Love #b4637a / #eb6f92 | Gold #ea9d34 / #f6c177\n// Rose #d7827e / #ea9a97 | Pine #286983 / #3e8fb0\n// Foam #56949f / #9ccfd8 | Iris #907aa9 / #c4a7e7\n\nexport const rosePinePalette: PaletteConfig = {\n id: 'rose-pine',\n name: 'Rosé Pine',\n light: {\n bg: '#faf4ed', // Dawn Base\n surface: '#fffaf3', // Dawn Surface\n overlay: '#f2e9e1', // Dawn Overlay\n border: '#dfdad9', // Dawn Highlight Med\n text: '#575279', // Dawn Text\n textMuted: '#9893a5', // Dawn Muted\n primary: '#286983', // Dawn Pine\n secondary: '#56949f', // Dawn Foam\n accent: '#907aa9', // Dawn Iris\n destructive: '#b4637a', // Dawn Love\n colors: {\n red: '#b4637a', // Love\n orange: '#d7827e', // Rose\n yellow: '#ea9d34', // Gold\n green: '#286983', // Pine\n blue: '#56949f', // Foam\n purple: '#907aa9', // Iris\n teal: '#286983', // Pine\n cyan: '#56949f', // Foam\n gray: '#9893a5', // Muted\n },\n },\n dark: {\n bg: '#232136', // Moon Base\n surface: '#2a273f', // Moon Surface\n overlay: '#393552', // Moon Overlay\n border: '#44415a', // Moon Highlight Med\n text: '#e0def4', // Moon Text\n textMuted: '#908caa', // Moon Subtle\n primary: '#3e8fb0', // Moon Pine\n secondary: '#9ccfd8', // Moon Foam\n accent: '#c4a7e7', // Moon Iris\n destructive: '#eb6f92', // Moon Love\n colors: {\n red: '#eb6f92', // Love\n orange: '#ea9a97', // Rose\n yellow: '#f6c177', // Gold\n green: '#3e8fb0', // Pine\n blue: '#9ccfd8', // Foam\n purple: '#c4a7e7', // Iris\n teal: '#3e8fb0', // Pine\n cyan: '#9ccfd8', // Foam\n gray: '#6e6a86', // Muted\n },\n },\n};\n\nregisterPalette(rosePinePalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Gruvbox Palette Definition\n// ============================================================\n\n// Official Gruvbox colors: https://github.com/morhetz/gruvbox\n//\n// Neutrals:\n// dark0 #282828 | dark1 #3c3836 | dark2 #504945 | dark3 #665c54\n// light0 #fbf1c7 | light1 #ebdbb2 | light2 #d5c4a1 | light3 #bdae93\n// gray #928374\n//\n// Accents (bright / neutral / faded):\n// Red #fb4934 / #cc241d / #9d0006\n// Green #b8bb26 / #98971a / #79740e\n// Yellow #fabd2f / #d79921 / #b57614\n// Blue #83a598 / #458588 / #076678\n// Purple #d3869b / #b16286 / #8f3f71\n// Aqua #8ec07c / #689d6a / #427b58\n// Orange #fe8019 / #d65d0e / #af3a03\n//\n// Light mode uses faded accents, dark mode uses bright accents.\n\nexport const gruvboxPalette: PaletteConfig = {\n id: 'gruvbox',\n name: 'Gruvbox',\n light: {\n bg: '#fbf1c7', // light0\n surface: '#ebdbb2', // light1\n overlay: '#d5c4a1', // light2\n border: '#bdae93', // light3\n text: '#3c3836', // dark1\n textMuted: '#7c6f64', // dark4\n primary: '#076678', // faded blue\n secondary: '#427b58', // faded aqua\n accent: '#8f3f71', // faded purple\n destructive: '#9d0006', // faded red\n colors: {\n red: '#9d0006', // faded\n orange: '#af3a03', // faded\n yellow: '#b57614', // faded\n green: '#79740e', // faded\n blue: '#076678', // faded\n purple: '#8f3f71', // faded\n teal: '#427b58', // faded aqua\n cyan: '#427b58', // faded aqua\n gray: '#928374',\n },\n },\n dark: {\n bg: '#282828', // dark0\n surface: '#3c3836', // dark1\n overlay: '#504945', // dark2\n border: '#665c54', // dark3\n text: '#ebdbb2', // light1\n textMuted: '#a89984', // light4\n primary: '#83a598', // bright blue\n secondary: '#8ec07c', // bright aqua\n accent: '#d3869b', // bright purple\n destructive: '#fb4934', // bright red\n colors: {\n red: '#fb4934', // bright\n orange: '#fe8019', // bright\n yellow: '#fabd2f', // bright\n green: '#b8bb26', // bright\n blue: '#83a598', // bright\n purple: '#d3869b', // bright\n teal: '#8ec07c', // bright aqua\n cyan: '#8ec07c', // bright aqua\n gray: '#928374',\n },\n },\n};\n\nregisterPalette(gruvboxPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Tokyo Night Palette Definition\n// ============================================================\n\n// Official Tokyo Night colors: https://github.com/folke/tokyonight.nvim\n//\n// Night (dark):\n// bg #1a1b26 | bg_highlight #292e42 | terminal_black #414868\n// fg_gutter #3b4261 | fg #c0caf5 | fg_dark #a9b1d6\n// comment #565f89\n//\n// Day (light):\n// bg #e1e2e7 | bg_float #d0d5e3 | bg_highlight #c4c8da\n// fg_gutter #a8aecb | fg #3760bf | fg_dark #6172b0\n// dark3 #8990b3\n//\n// Accents (Day / Night):\n// Red #f52a65 / #f7768e | Orange #b15c00 / #ff9e64\n// Yellow #8c6c3e / #e0af68 | Green #587539 / #9ece6a\n// Blue #2e7de9 / #7aa2f7 | Purple #7847bd / #bb9af7\n// Teal #118c74 / #1abc9c | Cyan #007197 / #7dcfff\n// Magenta #9854f1 / #bb9af7\n\nexport const tokyoNightPalette: PaletteConfig = {\n id: 'tokyo-night',\n name: 'Tokyo Night',\n light: {\n bg: '#e1e2e7', // Day bg\n surface: '#d0d5e3', // Day bg_float\n overlay: '#c4c8da', // Day bg_highlight\n border: '#a8aecb', // Day fg_gutter\n text: '#3760bf', // Day fg\n textMuted: '#6172b0', // Day fg_dark\n primary: '#2e7de9', // Day blue\n secondary: '#007197', // Day cyan\n accent: '#9854f1', // Day magenta\n destructive: '#f52a65', // Day red\n colors: {\n red: '#f52a65',\n orange: '#b15c00',\n yellow: '#8c6c3e',\n green: '#587539',\n blue: '#2e7de9',\n purple: '#7847bd',\n teal: '#118c74',\n cyan: '#007197',\n gray: '#8990b3', // Day dark3\n },\n },\n dark: {\n bg: '#1a1b26', // Night bg\n surface: '#292e42', // Night bg_highlight\n overlay: '#414868', // Night terminal_black\n border: '#3b4261', // Night fg_gutter\n text: '#c0caf5', // Night fg\n textMuted: '#a9b1d6', // Night fg_dark\n primary: '#7aa2f7', // Night blue\n secondary: '#7dcfff', // Night cyan\n accent: '#bb9af7', // Night magenta\n destructive: '#f7768e', // Night red\n colors: {\n red: '#f7768e',\n orange: '#ff9e64',\n yellow: '#e0af68',\n green: '#9ece6a',\n blue: '#7aa2f7',\n purple: '#bb9af7',\n teal: '#1abc9c',\n cyan: '#7dcfff',\n gray: '#565f89', // Night comment\n },\n },\n};\n\nregisterPalette(tokyoNightPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// One Dark Palette Definition\n// Based on Atom's One Dark theme\n// ============================================================\n\nexport const oneDarkPalette: PaletteConfig = {\n id: 'one-dark',\n name: 'One Dark',\n light: {\n // One Light variant (Atom's light counterpart)\n bg: '#fafafa',\n surface: '#f0f0f0',\n overlay: '#e5e5e5',\n border: '#d0d0d0',\n text: '#383a42',\n textMuted: '#696c77',\n primary: '#4078f2',\n secondary: '#a626a4',\n accent: '#0184bc',\n destructive: '#e45649',\n colors: {\n red: '#e45649',\n orange: '#c18401',\n yellow: '#c18401',\n green: '#50a14f',\n blue: '#4078f2',\n purple: '#a626a4',\n teal: '#0184bc',\n cyan: '#0997b3',\n gray: '#696c77',\n },\n },\n dark: {\n // One Dark (Atom's dark theme)\n bg: '#282c34',\n surface: '#21252b',\n overlay: '#2c313a',\n border: '#3e4451',\n text: '#abb2bf',\n textMuted: '#5c6370',\n primary: '#61afef',\n secondary: '#c678dd',\n accent: '#56b6c2',\n destructive: '#e06c75',\n colors: {\n red: '#e06c75',\n orange: '#d19a66',\n yellow: '#e5c07b',\n green: '#98c379',\n blue: '#61afef',\n purple: '#c678dd',\n teal: '#56b6c2',\n cyan: '#56b6c2',\n gray: '#5c6370',\n },\n },\n};\n\nregisterPalette(oneDarkPalette);\n","import type { PaletteConfig } from './types';\nimport { registerPalette } from './registry';\n\n// ============================================================\n// Bold Palette Definition\n// ============================================================\n\nexport const boldPalette: PaletteConfig = {\n id: 'bold',\n name: 'Bold',\n light: {\n bg: '#ffffff',\n surface: '#f0f0f0',\n overlay: '#f0f0f0',\n border: '#cccccc',\n text: '#000000',\n textMuted: '#666666',\n primary: '#0000ff',\n secondary: '#ff00ff',\n accent: '#00cccc',\n destructive: '#ff0000',\n colors: {\n red: '#ff0000',\n orange: '#ff8000',\n yellow: '#ffcc00',\n green: '#00cc00',\n blue: '#0000ff',\n purple: '#cc00cc',\n teal: '#008080',\n cyan: '#00cccc',\n gray: '#808080',\n },\n },\n dark: {\n bg: '#000000',\n surface: '#111111',\n overlay: '#1a1a1a',\n border: '#333333',\n text: '#ffffff',\n textMuted: '#aaaaaa',\n primary: '#00ccff',\n secondary: '#ff00ff',\n accent: '#ffff00',\n destructive: '#ff0000',\n colors: {\n red: '#ff0000',\n orange: '#ff8000',\n yellow: '#ffff00',\n green: '#00ff00',\n blue: '#0066ff',\n purple: '#ff00ff',\n teal: '#00cccc',\n cyan: '#00ffff',\n gray: '#808080',\n },\n },\n};\n\nregisterPalette(boldPalette);\n","import type { PaletteColors } from './types';\nimport { mute, tint, shade, contrastText } from './color-utils';\n\n// ============================================================\n// Mermaid Theme Variable Generator\n// ============================================================\n\n/**\n * Generates ~121 Mermaid theme variables from palette tokens.\n * Replaces the hardcoded lightThemeVars/darkThemeVars objects.\n *\n * Dark mode fills use `mute()` to derive desaturated variants\n * that are readable with light text.\n */\nexport function buildMermaidThemeVars(\n colors: PaletteColors,\n isDark: boolean\n): Record<string, string> {\n const c = colors.colors;\n\n // Ordered accent array for pie/cScale/fillType/actor slots\n const accentOrder = [\n c.blue,\n c.red,\n c.green,\n c.yellow,\n c.purple,\n c.orange,\n c.teal,\n c.cyan,\n colors.secondary,\n ];\n\n // Dark mode fills use muted variants for readability\n const fills = isDark ? accentOrder.map(mute) : accentOrder;\n\n return {\n // ── Backgrounds ──\n background: isDark ? colors.overlay : colors.border,\n mainBkg: colors.surface,\n\n // ── Primary/Secondary/Tertiary nodes ──\n primaryColor: isDark ? colors.primary : colors.surface,\n primaryTextColor: colors.text,\n primaryBorderColor: isDark ? colors.secondary : colors.border,\n secondaryColor: colors.secondary,\n secondaryTextColor: contrastText(colors.secondary, colors.text, colors.bg),\n secondaryBorderColor: colors.primary,\n tertiaryColor: colors.accent,\n tertiaryTextColor: contrastText(colors.accent, colors.text, colors.bg),\n tertiaryBorderColor: colors.border,\n\n // ── Lines & text ──\n lineColor: colors.textMuted,\n textColor: colors.text,\n\n // ── Clusters ──\n clusterBkg: colors.bg,\n clusterBorder: isDark ? colors.border : colors.textMuted,\n titleColor: colors.text,\n\n // ── Labels ──\n edgeLabelBackground: 'transparent',\n\n // ── Notes (sequence diagrams) ──\n noteBkgColor: colors.bg,\n noteTextColor: colors.text,\n noteBorderColor: isDark ? colors.border : colors.textMuted,\n\n // ── Actors (sequence diagrams) ──\n actorBkg: colors.surface,\n actorTextColor: colors.text,\n actorBorder: isDark ? colors.border : colors.textMuted,\n actorLineColor: colors.textMuted,\n\n // ── Signals (sequence diagrams) ──\n signalColor: colors.textMuted,\n signalTextColor: colors.text,\n\n // ── Labels ──\n labelColor: colors.text,\n labelTextColor: colors.text,\n labelBoxBkgColor: colors.surface,\n labelBoxBorderColor: isDark ? colors.border : colors.textMuted,\n\n // ── Loop boxes ──\n loopTextColor: colors.text,\n\n // ── Activation (sequence diagrams) ──\n activationBkgColor: isDark ? colors.overlay : colors.border,\n activationBorderColor: isDark ? colors.border : colors.textMuted,\n\n // ── Sequence numbers ──\n sequenceNumberColor: isDark ? colors.text : colors.bg,\n\n // ── State diagrams ──\n labelBackgroundColor: colors.surface,\n\n // ── Pie chart (9 slices) ──\n // Dark mode: use muted fills so light pieSectionTextColor stays readable\n ...Object.fromEntries(\n (isDark ? fills : accentOrder).map((col, i) => [`pie${i + 1}`, col])\n ),\n pieTitleTextColor: colors.text,\n pieSectionTextColor: isDark ? colors.text : colors.bg,\n pieLegendTextColor: colors.text,\n pieStrokeColor: 'transparent',\n pieOuterStrokeWidth: '0px',\n pieOuterStrokeColor: 'transparent',\n\n // ── cScale (9 tiers) — muted in dark mode ──\n ...Object.fromEntries(fills.map((f, i) => [`cScale${i}`, f])),\n ...Object.fromEntries(\n fills.map((_, i) => [\n `cScaleLabel${i}`,\n isDark ? colors.text : i < 2 || i > 6 ? colors.bg : colors.text,\n ])\n ),\n\n // ── fillType (8 slots) ──\n ...Object.fromEntries(\n [0, 1, 2, 3, 4, 5, 6, 7].map((i) => [\n `fillType${i}`,\n fills[i % fills.length],\n ])\n ),\n\n // ── Journey actors (6 slots) ──\n ...Object.fromEntries(\n [c.red, c.green, c.yellow, c.purple, c.orange, c.teal].map((color, i) => [\n `actor${i}`,\n color,\n ])\n ),\n\n // ── Flowchart ──\n nodeBorder: isDark ? colors.border : colors.textMuted,\n nodeTextColor: colors.text,\n\n // ── Gantt ──\n gridColor: isDark ? colors.textMuted : colors.border,\n doneTaskBkgColor: c.green,\n doneTaskBorderColor: isDark ? colors.border : colors.textMuted,\n activeTaskBkgColor: colors.secondary,\n activeTaskBorderColor: colors.primary,\n critBkgColor: c.orange,\n critBorderColor: c.red,\n taskBkgColor: colors.surface,\n taskBorderColor: isDark ? colors.border : colors.textMuted,\n taskTextColor: contrastText(colors.surface, colors.text, colors.bg),\n taskTextDarkColor: colors.bg,\n taskTextLightColor: colors.text,\n taskTextOutsideColor: colors.text,\n doneTaskTextColor: contrastText(c.green, colors.text, colors.bg),\n activeTaskTextColor: contrastText(colors.secondary, colors.text, colors.bg),\n critTaskTextColor: contrastText(c.orange, colors.text, colors.bg),\n sectionBkgColor: isDark\n ? shade(colors.primary, colors.bg, 0.6)\n : tint(colors.primary, 0.6),\n altSectionBkgColor: colors.bg,\n sectionBkgColor2: isDark\n ? shade(colors.primary, colors.bg, 0.6)\n : tint(colors.primary, 0.6),\n todayLineColor: c.yellow,\n\n // ── Quadrant ──\n quadrant1Fill: isDark\n ? shade(c.green, colors.bg, 0.75)\n : tint(c.green, 0.75),\n quadrant2Fill: isDark ? shade(c.blue, colors.bg, 0.75) : tint(c.blue, 0.75),\n quadrant3Fill: isDark ? shade(c.red, colors.bg, 0.75) : tint(c.red, 0.75),\n quadrant4Fill: isDark\n ? shade(c.yellow, colors.bg, 0.75)\n : tint(c.yellow, 0.75),\n quadrant1TextFill: colors.text,\n quadrant2TextFill: colors.text,\n quadrant3TextFill: colors.text,\n quadrant4TextFill: colors.text,\n quadrantPointFill: isDark ? c.cyan : c.blue,\n quadrantPointTextFill: colors.text,\n quadrantXAxisTextFill: colors.text,\n quadrantYAxisTextFill: colors.text,\n quadrantTitleFill: colors.text,\n quadrantInternalBorderStrokeFill: colors.border,\n quadrantExternalBorderStrokeFill: colors.border,\n };\n}\n\n// ============================================================\n// Mermaid Theme CSS Generator\n// ============================================================\n\n/**\n * Generates custom CSS overrides for Mermaid SVGs.\n * Handles git graph label backgrounds and dark-mode text readability.\n */\nexport function buildThemeCSS(palette: PaletteColors, isDark: boolean): string {\n const base = `\n .branchLabelBkg { fill: transparent !important; stroke: transparent !important; }\n .commit-label-bkg { fill: transparent !important; stroke: transparent !important; }\n .tag-label-bkg { fill: transparent !important; stroke: transparent !important; }\n\n /* GitGraph: ensure commit and branch label text matches palette */\n .commit-label { fill: ${palette.text} !important; }\n .branch-label { fill: ${palette.text} !important; }\n .tag-label { fill: ${palette.text} !important; }\n`;\n\n if (!isDark) return base;\n\n return (\n base +\n `\n /* Flowchart: ensure node and edge label text is readable */\n .nodeLabel, .label { color: ${palette.text} !important; fill: ${palette.text} !important; }\n .edgeLabel { color: ${palette.text} !important; fill: ${palette.text} !important; }\n .edgeLabel .label { color: ${palette.text} !important; fill: ${palette.text} !important; }\n`\n );\n}\n","// Re-export types\nexport type { PaletteConfig, PaletteColors } from './types';\n\n// Re-export registry\nexport {\n getPalette,\n getAvailablePalettes,\n registerPalette,\n isValidHex,\n} from './registry';\n\n// Re-export utilities\nexport {\n hexToHSL,\n hslToHex,\n hexToHSLString,\n mute,\n tint,\n shade,\n getSeriesColors,\n getSegmentColors,\n contrastText,\n} from './color-utils';\n\n// Re-export palette definitions\nexport { nordPalette } from './nord';\nexport { solarizedPalette } from './solarized';\nexport { catppuccinPalette } from './catppuccin';\nexport { rosePinePalette } from './rose-pine';\nexport { gruvboxPalette } from './gruvbox';\nexport { tokyoNightPalette } from './tokyo-night';\nexport { oneDarkPalette } from './one-dark';\nexport { boldPalette } from './bold';\n\n// Re-export Mermaid bridge\nexport { buildMermaidThemeVars, buildThemeCSS } from './mermaid-bridge';\n","// ============================================================\n// Participant Type Inference Engine\n// ============================================================\n//\n// Data-driven rules table that infers participant type from name.\n// First match wins. Infrastructure overrides come before suffix\n// rules to prevent false positives (e.g. \"Router\" → networking,\n// not actor despite the \"-er\" suffix).\n// ============================================================\n\nimport type { ParticipantType } from './parser';\n\n/**\n * A single inference rule: regex pattern → participant type.\n */\ninterface InferenceRule {\n pattern: RegExp;\n type: ParticipantType;\n}\n\n/**\n * Ordered rules table. First match wins.\n *\n * Priority order:\n * 0. Conflict overrides (prevent misclassification by general patterns)\n * 1. Infrastructure overrides (prevent false actor matches)\n * 2. Networking patterns\n * 3. Database patterns\n * 4. Cache patterns\n * 5. Queue/Messaging patterns\n * 6. Actor patterns (suffix + exact)\n * 7. Frontend patterns\n * 8. Service patterns\n * 9. External patterns\n */\nconst PARTICIPANT_RULES: readonly InferenceRule[] = [\n // ── 0. Conflict overrides ────────────────────────────────\n // Names that would incorrectly match general patterns in later groups\n { pattern: /^KeyDB$/i, type: 'cache' }, // not database (DB$ suffix)\n { pattern: /Webhook/i, type: 'external' }, // not frontend (Web contains)\n { pattern: /^Upstream$/i, type: 'external' }, // not queue (Stream$ suffix)\n { pattern: /^Downstream$/i, type: 'external' }, // not queue (Stream$ suffix)\n\n // ── 1. Infrastructure overrides ─────────────────────────\n // These names end in -er/-or but are NOT actors\n { pattern: /^.*Router$/i, type: 'networking' },\n { pattern: /^.*Scheduler$/i, type: 'service' },\n { pattern: /^.*Dispatcher$/i, type: 'service' },\n { pattern: /^.*Balancer$/i, type: 'networking' },\n { pattern: /^.*Controller$/i, type: 'service' },\n { pattern: /^.*Handler$/i, type: 'service' },\n { pattern: /^.*Processor$/i, type: 'service' },\n { pattern: /^.*Connector$/i, type: 'service' },\n { pattern: /^.*Adapter$/i, type: 'service' },\n { pattern: /^.*Provider$/i, type: 'service' },\n { pattern: /^.*Manager$/i, type: 'service' },\n { pattern: /^.*Orchestrator$/i, type: 'service' },\n { pattern: /^.*Monitor$/i, type: 'service' },\n { pattern: /^.*Resolver$/i, type: 'service' },\n { pattern: /^.*Logger$/i, type: 'service' },\n { pattern: /^.*Server$/i, type: 'service' },\n { pattern: /^.*Broker$/i, type: 'queue' },\n { pattern: /^.*Worker$/i, type: 'service' },\n { pattern: /^.*Consumer$/i, type: 'service' },\n { pattern: /^.*Producer$/i, type: 'service' },\n { pattern: /^.*Publisher$/i, type: 'service' },\n { pattern: /^.*Subscriber$/i, type: 'service' },\n { pattern: /^.*Listener$/i, type: 'service' },\n // New -er/-or suffixes that are services, not actors\n { pattern: /^.*Watcher$/i, type: 'service' },\n { pattern: /^.*Executor$/i, type: 'service' },\n { pattern: /^.*Aggregator$/i, type: 'service' },\n { pattern: /^.*Collector$/i, type: 'service' },\n { pattern: /^.*Transformer$/i, type: 'service' },\n { pattern: /^.*Validator$/i, type: 'service' },\n { pattern: /^.*Generator$/i, type: 'service' },\n { pattern: /^.*Indexer$/i, type: 'service' },\n { pattern: /^.*Crawler$/i, type: 'service' },\n { pattern: /^.*Scanner$/i, type: 'service' },\n { pattern: /^.*Parser$/i, type: 'service' },\n { pattern: /^.*Emitter$/i, type: 'service' },\n { pattern: /^.*Exporter$/i, type: 'service' },\n { pattern: /^.*Importer$/i, type: 'service' },\n { pattern: /^.*Loader$/i, type: 'service' },\n { pattern: /^.*Renderer$/i, type: 'service' },\n { pattern: /^.*Checker$/i, type: 'service' },\n { pattern: /^.*Inspector$/i, type: 'service' },\n { pattern: /^.*Encoder$/i, type: 'service' },\n { pattern: /^.*Decoder$/i, type: 'service' },\n { pattern: /^.*Notifier$/i, type: 'service' },\n\n // ── 2. Networking patterns ──────────────────────────────\n { pattern: /Gateway/i, type: 'networking' },\n { pattern: /GW$/i, type: 'networking' },\n { pattern: /Proxy/i, type: 'networking' },\n { pattern: /LB$/i, type: 'networking' },\n { pattern: /LoadBalancer/i, type: 'networking' },\n { pattern: /CDN/i, type: 'networking' },\n { pattern: /Firewall/i, type: 'networking' },\n { pattern: /WAF$/i, type: 'networking' },\n { pattern: /DNS/i, type: 'networking' },\n { pattern: /Ingress/i, type: 'networking' },\n // Named products & patterns\n { pattern: /Nginx/i, type: 'networking' },\n { pattern: /Traefik/i, type: 'networking' },\n { pattern: /Envoy/i, type: 'networking' },\n { pattern: /Istio/i, type: 'networking' },\n { pattern: /Kong/i, type: 'networking' },\n { pattern: /Akamai/i, type: 'networking' },\n { pattern: /Cloudflare/i, type: 'networking' },\n { pattern: /Mesh$/i, type: 'networking' },\n { pattern: /ServiceMesh/i, type: 'networking' },\n\n // ── 3. Database patterns ────────────────────────────────\n { pattern: /DB$/i, type: 'database' },\n { pattern: /Database/i, type: 'database' },\n { pattern: /Datastore/i, type: 'database' },\n { pattern: /Store$/i, type: 'database' },\n { pattern: /Storage/i, type: 'database' },\n { pattern: /Repo$/i, type: 'database' },\n { pattern: /Repository/i, type: 'database' },\n { pattern: /SQL/i, type: 'database' },\n { pattern: /Postgres/i, type: 'database' },\n { pattern: /MySQL/i, type: 'database' },\n { pattern: /Mongo/i, type: 'database' },\n { pattern: /Dynamo/i, type: 'database' },\n // Named products & patterns\n { pattern: /^Aurora$/i, type: 'database' },\n { pattern: /Spanner/i, type: 'database' },\n { pattern: /Supabase/i, type: 'database' },\n { pattern: /Firebase/i, type: 'database' },\n { pattern: /BigQuery/i, type: 'database' },\n { pattern: /Redshift/i, type: 'database' },\n { pattern: /Snowflake/i, type: 'database' },\n { pattern: /Cassandra/i, type: 'database' },\n { pattern: /Neo4j/i, type: 'database' },\n { pattern: /ClickHouse/i, type: 'database' },\n { pattern: /Elastic/i, type: 'database' },\n { pattern: /OpenSearch/i, type: 'database' },\n { pattern: /Druid/i, type: 'database' },\n { pattern: /Trino/i, type: 'database' },\n { pattern: /Pinecone/i, type: 'database' },\n { pattern: /Weaviate/i, type: 'database' },\n { pattern: /Qdrant/i, type: 'database' },\n { pattern: /Milvus/i, type: 'database' },\n { pattern: /Presto/i, type: 'database' },\n { pattern: /Table$/i, type: 'database' },\n\n // ── 4. Cache patterns ──────────────────────────────────\n { pattern: /Cache/i, type: 'cache' },\n { pattern: /Redis/i, type: 'cache' },\n { pattern: /Memcache/i, type: 'cache' },\n // CDN already matched by networking above\n // Named products\n { pattern: /Dragonfly/i, type: 'cache' },\n { pattern: /Hazelcast/i, type: 'cache' },\n { pattern: /Valkey/i, type: 'cache' },\n\n // ── 5. Queue/Messaging patterns ─────────────────────────\n { pattern: /Queue/i, type: 'queue' },\n { pattern: /MQ$/i, type: 'queue' },\n { pattern: /SQS/i, type: 'queue' },\n { pattern: /Kafka/i, type: 'queue' },\n { pattern: /RabbitMQ/i, type: 'queue' },\n { pattern: /EventBus/i, type: 'queue' },\n { pattern: /MessageBus/i, type: 'queue' },\n { pattern: /Bus$/i, type: 'queue' },\n { pattern: /Topic/i, type: 'queue' },\n { pattern: /Stream$/i, type: 'queue' },\n { pattern: /SNS/i, type: 'queue' },\n { pattern: /PubSub/i, type: 'queue' },\n // Named products & patterns\n { pattern: /NATS/i, type: 'queue' },\n { pattern: /Pulsar/i, type: 'queue' },\n { pattern: /Kinesis/i, type: 'queue' },\n { pattern: /EventBridge/i, type: 'queue' },\n { pattern: /CloudEvents/i, type: 'queue' },\n { pattern: /Celery/i, type: 'queue' },\n { pattern: /Sidekiq/i, type: 'queue' },\n { pattern: /EventHub/i, type: 'queue' },\n { pattern: /Channel$/i, type: 'queue' },\n\n // ── 6. Actor patterns ──────────────────────────────────\n // Exact matches first\n { pattern: /^Admin$/i, type: 'actor' },\n { pattern: /^User$/i, type: 'actor' },\n { pattern: /^Customer$/i, type: 'actor' },\n { pattern: /^Client$/i, type: 'actor' },\n { pattern: /^Agent$/i, type: 'actor' },\n { pattern: /^Person$/i, type: 'actor' },\n { pattern: /^Buyer$/i, type: 'actor' },\n { pattern: /^Seller$/i, type: 'actor' },\n { pattern: /^Guest$/i, type: 'actor' },\n { pattern: /^Visitor$/i, type: 'actor' },\n { pattern: /^Operator$/i, type: 'actor' },\n { pattern: /^Alice$/i, type: 'actor' },\n { pattern: /^Bob$/i, type: 'actor' },\n { pattern: /^Charlie$/i, type: 'actor' },\n { pattern: /^Fan$/i, type: 'actor' },\n { pattern: /^Purchaser$/i, type: 'actor' },\n { pattern: /^Reviewer$/i, type: 'actor' },\n // Suffix rules (after infrastructure overrides filtered above)\n { pattern: /User$/i, type: 'actor' },\n { pattern: /Actor$/i, type: 'actor' },\n { pattern: /Analyst$/i, type: 'actor' },\n\n // ── 7. Frontend patterns ────────────────────────────────\n { pattern: /App$/i, type: 'frontend' },\n { pattern: /Application/i, type: 'frontend' },\n { pattern: /Mobile/i, type: 'frontend' },\n { pattern: /iOS/i, type: 'frontend' },\n { pattern: /Android/i, type: 'frontend' },\n { pattern: /Web/i, type: 'frontend' },\n { pattern: /Browser/i, type: 'frontend' },\n { pattern: /Frontend/i, type: 'frontend' },\n { pattern: /UI$/i, type: 'frontend' },\n { pattern: /Dashboard/i, type: 'frontend' },\n { pattern: /CLI$/i, type: 'frontend' },\n { pattern: /Terminal/i, type: 'frontend' },\n // Frameworks & patterns\n { pattern: /React/i, type: 'frontend' },\n { pattern: /^Vue$/i, type: 'frontend' },\n { pattern: /Angular/i, type: 'frontend' },\n { pattern: /Svelte/i, type: 'frontend' },\n { pattern: /NextJS/i, type: 'frontend' },\n { pattern: /Nuxt/i, type: 'frontend' },\n { pattern: /Remix/i, type: 'frontend' },\n { pattern: /Electron/i, type: 'frontend' },\n { pattern: /Tauri/i, type: 'frontend' },\n { pattern: /Widget$/i, type: 'frontend' },\n { pattern: /Portal/i, type: 'frontend' },\n { pattern: /Console$/i, type: 'frontend' },\n { pattern: /^SPA$/i, type: 'frontend' },\n { pattern: /^PWA$/i, type: 'frontend' },\n\n // ── 8. Service patterns ─────────────────────────────────\n { pattern: /Service/i, type: 'service' },\n { pattern: /Svc$/i, type: 'service' },\n { pattern: /API$/i, type: 'service' },\n { pattern: /Lambda/i, type: 'service' },\n { pattern: /Function$/i, type: 'service' },\n { pattern: /Fn$/i, type: 'service' },\n { pattern: /Job$/i, type: 'service' },\n { pattern: /Cron/i, type: 'service' },\n { pattern: /Microservice/i, type: 'service' },\n // Auth\n { pattern: /^Auth$/i, type: 'service' },\n { pattern: /^AuthN$/i, type: 'service' },\n { pattern: /^AuthZ$/i, type: 'service' },\n { pattern: /^SSO$/i, type: 'service' },\n { pattern: /OAuth/i, type: 'service' },\n { pattern: /^OIDC$/i, type: 'service' },\n // SaaS\n { pattern: /Stripe/i, type: 'service' },\n { pattern: /Twilio/i, type: 'service' },\n { pattern: /SendGrid/i, type: 'service' },\n { pattern: /Mailgun/i, type: 'service' },\n // Cloud/infra\n { pattern: /^S3$/i, type: 'service' },\n { pattern: /^Blob$/i, type: 'service' },\n { pattern: /Vercel/i, type: 'service' },\n { pattern: /Netlify/i, type: 'service' },\n { pattern: /Heroku/i, type: 'service' },\n { pattern: /Docker/i, type: 'service' },\n { pattern: /Kubernetes/i, type: 'service' },\n { pattern: /K8s/i, type: 'service' },\n { pattern: /Terraform/i, type: 'service' },\n // Security\n { pattern: /Vault/i, type: 'service' },\n { pattern: /^HSM$/i, type: 'service' },\n { pattern: /KMS/i, type: 'service' },\n { pattern: /^IAM$/i, type: 'service' },\n // AI/ML\n { pattern: /^LLM$/i, type: 'service' },\n { pattern: /GPT/i, type: 'service' },\n { pattern: /^Claude$/i, type: 'service' },\n { pattern: /Embedding/i, type: 'service' },\n { pattern: /Inference/i, type: 'service' },\n // Suffixes & patterns\n { pattern: /Pipeline$/i, type: 'service' },\n { pattern: /Registry/i, type: 'service' },\n { pattern: /Engine$/i, type: 'service' },\n { pattern: /Daemon/i, type: 'service' },\n\n // ── 9. External patterns ────────────────────────────────\n { pattern: /External/i, type: 'external' },\n { pattern: /Ext$/i, type: 'external' },\n { pattern: /ThirdParty/i, type: 'external' },\n { pattern: /3P$/i, type: 'external' },\n { pattern: /Vendor/i, type: 'external' },\n // Named products & patterns\n { pattern: /Callback/i, type: 'external' },\n { pattern: /^AWS$/i, type: 'external' },\n { pattern: /^GCP$/i, type: 'external' },\n { pattern: /Azure/i, type: 'external' },\n];\n\n/**\n * Infer participant type from a name using the ordered rules table.\n * Returns 'default' if no rule matches.\n */\nexport function inferParticipantType(name: string): ParticipantType {\n for (const rule of PARTICIPANT_RULES) {\n if (rule.pattern.test(name)) {\n return rule.type;\n }\n }\n return 'default';\n}\n\n/**\n * Number of rules in the table. Exported for test assertions.\n */\nexport const RULE_COUNT = PARTICIPANT_RULES.length;\n","// ============================================================\n// Sequence Diagram Parser (.dgmo format)\n// ============================================================\n\nimport { inferParticipantType } from './participant-inference';\nimport type { DgmoError } from '../diagnostics';\nimport { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';\n\n/**\n * Participant types that can be declared via \"Name is a type\" syntax.\n */\nexport type ParticipantType =\n | 'default'\n | 'service'\n | 'database'\n | 'actor'\n | 'queue'\n | 'cache'\n | 'gateway'\n | 'external'\n | 'networking'\n | 'frontend';\n\nconst VALID_PARTICIPANT_TYPES: ReadonlySet<string> = new Set([\n 'service',\n 'database',\n 'actor',\n 'queue',\n 'cache',\n 'gateway',\n 'external',\n 'networking',\n 'frontend',\n]);\n\n/**\n * A declared or inferred participant in the sequence diagram.\n */\nexport interface SequenceParticipant {\n /** Internal identifier (e.g. \"AuthService\") */\n id: string;\n /** Display label — uses aka alias if provided, otherwise id */\n label: string;\n /** Participant shape type */\n type: ParticipantType;\n /** Source line number (1-based) */\n lineNumber: number;\n /** Explicit layout position override (0-based from left, negative from right) */\n position?: number;\n}\n\n/**\n * A message between two participants.\n * Placeholder for future stories — included in the interface now for completeness.\n */\nexport interface SequenceMessage {\n from: string;\n to: string;\n label: string;\n returnLabel?: string;\n lineNumber: number;\n async?: boolean;\n}\n\n/**\n * A conditional or loop block in the sequence diagram.\n */\nexport interface ElseIfBranch {\n label: string;\n children: SequenceElement[];\n}\n\nexport interface SequenceBlock {\n kind: 'block';\n type: 'if' | 'loop' | 'parallel';\n label: string;\n children: SequenceElement[];\n elseChildren: SequenceElement[];\n elseIfBranches?: ElseIfBranch[];\n lineNumber: number;\n}\n\n/**\n * A labeled horizontal divider between message phases.\n */\nexport interface SequenceSection {\n kind: 'section';\n label: string;\n color?: string;\n lineNumber: number;\n}\n\n/**\n * An annotation attached to a message, rendered as a folded-corner box.\n */\nexport interface SequenceNote {\n kind: 'note';\n text: string;\n position: 'right' | 'left';\n participantId: string;\n lineNumber: number;\n endLineNumber: number;\n}\n\nexport type SequenceElement =\n | SequenceMessage\n | SequenceBlock\n | SequenceSection\n | SequenceNote;\n\nexport function isSequenceBlock(el: SequenceElement): el is SequenceBlock {\n return 'kind' in el && (el as SequenceBlock).kind === 'block';\n}\n\nexport function isSequenceSection(el: SequenceElement): el is SequenceSection {\n return 'kind' in el && (el as SequenceSection).kind === 'section';\n}\n\nexport function isSequenceNote(el: SequenceElement): el is SequenceNote {\n return 'kind' in el && (el as SequenceNote).kind === 'note';\n}\n\n/**\n * A named group of participants rendered as a labeled box.\n */\nexport interface SequenceGroup {\n name: string;\n color?: string;\n participantIds: string[];\n lineNumber: number;\n}\n\n/**\n * Parsed result from a .dgmo sequence diagram.\n */\nexport interface ParsedSequenceDgmo {\n title: string | null;\n titleLineNumber: number | null;\n participants: SequenceParticipant[];\n messages: SequenceMessage[];\n elements: SequenceElement[];\n groups: SequenceGroup[];\n sections: SequenceSection[];\n options: Record<string, string>;\n diagnostics: DgmoError[];\n error: string | null;\n}\n\n// \"Name is a type\" pattern — e.g. \"AuthService is a service\"\n// Remainder after type is parsed separately for aka/position modifiers\nconst IS_A_PATTERN = /^(\\S+)\\s+is\\s+an?\\s+(\\w+)(?:\\s+(.+))?$/i;\n\n// Standalone \"Name position N\" pattern — e.g. \"DB position -1\"\nconst POSITION_ONLY_PATTERN = /^(\\S+)\\s+position\\s+(-?\\d+)$/i;\n\n// Group heading pattern — \"## Backend\", \"## API Services(blue)\", \"## Backend(#hex)\"\nconst GROUP_HEADING_PATTERN = /^##\\s+(.+?)(?:\\(([^)]+)\\))?\\s*$/;\n\n// Section divider pattern — \"== Label ==\", \"== Label(color) ==\", or \"== Label\" (trailing == optional)\nconst SECTION_PATTERN = /^==\\s+(.+?)(?:\\s*==)?\\s*$/;\n\n// Arrow pattern for sequence inference — \"A -> B: message\" or \"A ~> B: message\"\nconst ARROW_PATTERN = /\\S+\\s*(?:->|~>)\\s*\\S+/;\n\n// <- return syntax: \"Login <- 200 OK\"\nconst ARROW_RETURN_PATTERN = /^(.+?)\\s*<-\\s*(.+)$/;\n\n// UML method(args): returnType syntax: \"getUser(id): UserObj\"\nconst UML_RETURN_PATTERN = /^(\\w+\\([^)]*\\))\\s*:\\s*(.+)$/;\n\n// Note patterns — \"note: text\", \"note right of API: text\", \"note left of User\"\nconst NOTE_SINGLE = /^note(?:\\s+(right|left)\\s+of\\s+(\\S+))?\\s*:\\s*(.+)$/i;\nconst NOTE_MULTI = /^note(?:\\s+(right|left)\\s+of\\s+([^\\s:]+))?\\s*:?\\s*$/i;\n\n/**\n * Extract return label from a message label string.\n * Priority: `<-` syntax first, then UML `method(): return` syntax,\n * then shorthand ` : ` separator (splits on last occurrence).\n */\nfunction parseReturnLabel(rawLabel: string): {\n label: string;\n returnLabel?: string;\n} {\n if (!rawLabel) return { label: '' };\n\n // Check <- syntax first\n const arrowReturn = rawLabel.match(ARROW_RETURN_PATTERN);\n if (arrowReturn) {\n return { label: arrowReturn[1].trim(), returnLabel: arrowReturn[2].trim() };\n }\n\n // Check UML method(args): returnType syntax\n const umlReturn = rawLabel.match(UML_RETURN_PATTERN);\n if (umlReturn) {\n return { label: umlReturn[1].trim(), returnLabel: umlReturn[2].trim() };\n }\n\n // Shorthand colon return syntax (split on last \":\")\n // Skip if the colon is part of a URL scheme (followed by //)\n const lastColon = rawLabel.lastIndexOf(':');\n if (lastColon > 0 && lastColon < rawLabel.length - 1) {\n const afterColon = rawLabel.substring(lastColon + 1);\n if (!afterColon.startsWith('//')) {\n const reqPart = rawLabel.substring(0, lastColon).trim();\n const resPart = afterColon.trim();\n if (reqPart && resPart) {\n return { label: reqPart, returnLabel: resPart };\n }\n }\n }\n\n return { label: rawLabel };\n}\n\n/**\n * Measure leading whitespace of a line, normalizing tabs to 4 spaces.\n */\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\n/**\n * Parse a .dgmo file with `chart: sequence` into a structured representation.\n */\nexport function parseSequenceDgmo(content: string): ParsedSequenceDgmo {\n const result: ParsedSequenceDgmo = {\n title: null,\n titleLineNumber: null,\n participants: [],\n messages: [],\n elements: [],\n groups: [],\n sections: [],\n options: {},\n diagnostics: [],\n error: null,\n };\n\n const fail = (line: number, message: string): ParsedSequenceDgmo => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n };\n\n /** Push a recoverable error and continue parsing. */\n const pushError = (line: number, message: string): void => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n if (!result.error) result.error = formatDgmoError(diag);\n };\n\n if (!content || !content.trim()) {\n return fail(0, 'Empty content');\n }\n\n const lines = content.split('\\n');\n let hasExplicitChart = false;\n let contentStarted = false;\n\n // Group parsing state — tracks the active ## group heading\n let activeGroup: SequenceGroup | null = null;\n\n // Track participant → group name for duplicate membership detection\n const participantGroupMap = new Map<string, string>();\n\n // Block parsing state\n const blockStack: {\n block: SequenceBlock;\n indent: number;\n inElse: boolean;\n activeElseIfBranch?: ElseIfBranch;\n }[] = [];\n const currentContainer = (): SequenceElement[] => {\n if (blockStack.length === 0) return result.elements;\n const top = blockStack[blockStack.length - 1];\n if (top.activeElseIfBranch) return top.activeElseIfBranch.children;\n return top.inElse ? top.block.elseChildren : top.block.children;\n };\n\n // Track last message sender for default note positioning\n let lastMsgFrom: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!trimmed) {\n activeGroup = null;\n continue;\n }\n\n // Parse group heading — must be checked before comment skip since ## starts with #\n const groupMatch = trimmed.match(GROUP_HEADING_PATTERN);\n if (groupMatch) {\n const groupColor = groupMatch[2]?.trim();\n if (groupColor && groupColor.startsWith('#')) {\n pushError(lineNumber, 'Use a named color instead of hex (e.g., blue, red, teal)');\n continue;\n }\n contentStarted = true;\n activeGroup = {\n name: groupMatch[1].trim(),\n color: groupColor || undefined,\n participantIds: [],\n lineNumber,\n };\n result.groups.push(activeGroup);\n continue;\n }\n\n // Close active group on non-indented, non-group lines\n if (activeGroup && measureIndent(raw) === 0) {\n activeGroup = null;\n }\n\n // Skip comments — only // is supported\n if (trimmed.startsWith('//')) continue;\n\n // Reject # as comment syntax (## is for group headings, handled above)\n if (trimmed.startsWith('#') && !trimmed.startsWith('##')) {\n pushError(lineNumber, 'Use // for comments. # is reserved for group headings (##)');\n continue;\n }\n\n // Parse section dividers — \"== Label ==\" or \"== Label(color) ==\"\n // Close blocks first — sections at indent 0 should not nest inside blocks\n const sectionMatch = trimmed.match(SECTION_PATTERN);\n if (sectionMatch) {\n const sectionIndent = measureIndent(raw);\n while (blockStack.length > 0) {\n const top = blockStack[blockStack.length - 1];\n if (sectionIndent > top.indent) break;\n blockStack.pop();\n }\n const labelRaw = sectionMatch[1].trim();\n const colorMatch = labelRaw.match(/^(.+?)\\(([^)]+)\\)$/);\n if (colorMatch && colorMatch[2].trim().startsWith('#')) {\n pushError(lineNumber, 'Use a named color instead of hex (e.g., blue, red, teal)');\n continue;\n }\n contentStarted = true;\n const section: SequenceSection = {\n kind: 'section',\n label: colorMatch ? colorMatch[1].trim() : labelRaw,\n color: colorMatch ? colorMatch[2].trim() : undefined,\n lineNumber,\n };\n result.sections.push(section);\n currentContainer().push(section);\n continue;\n }\n\n // Parse header key: value lines (always top-level)\n // Skip 'note' lines — parsed in the indent-aware section below\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex > 0 && !trimmed.includes('->') && !trimmed.includes('~>')) {\n const key = trimmed.substring(0, colonIndex).trim().toLowerCase();\n if (key === 'note' || key.startsWith('note ')) {\n // Fall through to indent-aware note parsing below\n } else {\n const value = trimmed.substring(colonIndex + 1).trim();\n\n if (key === 'chart') {\n hasExplicitChart = true;\n if (value.toLowerCase() !== 'sequence') {\n return fail(lineNumber, `Expected chart type \"sequence\", got \"${value}\"`);\n }\n continue;\n }\n\n // Enforce headers-before-content\n if (contentStarted) {\n pushError(lineNumber, `Options like '${key}: ${value}' must appear before the first message or declaration`);\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n // Store other options\n result.options[key] = value;\n continue;\n }\n }\n\n // Parse \"Name is a type [aka Alias]\" declarations (always top-level)\n const isAMatch = trimmed.match(IS_A_PATTERN);\n if (isAMatch) {\n contentStarted = true;\n const id = isAMatch[1];\n const typeStr = isAMatch[2].toLowerCase();\n const remainder = isAMatch[3]?.trim() || '';\n\n const participantType: ParticipantType = VALID_PARTICIPANT_TYPES.has(\n typeStr\n )\n ? (typeStr as ParticipantType)\n : 'default';\n\n // Parse modifiers from remainder: aka ALIAS, position N\n const akaMatch = remainder.match(\n /\\baka\\s+(.+?)(?:\\s+position\\s+-?\\d+\\s*$|$)/i\n );\n const posMatch = remainder.match(/\\bposition\\s+(-?\\d+)/i);\n const alias = akaMatch ? akaMatch[1].trim() : null;\n const position = posMatch ? parseInt(posMatch[1], 10) : undefined;\n\n // Avoid duplicate participant declarations\n if (!result.participants.some((p) => p.id === id)) {\n result.participants.push({\n id,\n label: alias || id,\n type: participantType,\n lineNumber,\n ...(position !== undefined ? { position } : {}),\n });\n }\n // Track group membership\n if (activeGroup && !activeGroup.participantIds.includes(id)) {\n const existingGroup = participantGroupMap.get(id);\n if (existingGroup) {\n pushError(lineNumber, `Participant '${id}' is already in group '${existingGroup}' — participants can only belong to one group`);\n } else {\n activeGroup.participantIds.push(id);\n participantGroupMap.set(id, activeGroup.name);\n }\n }\n continue;\n }\n\n // Parse standalone \"Name position N\" (no \"is a\" type)\n const posOnlyMatch = trimmed.match(POSITION_ONLY_PATTERN);\n if (posOnlyMatch) {\n contentStarted = true;\n const id = posOnlyMatch[1];\n const position = parseInt(posOnlyMatch[2], 10);\n\n if (!result.participants.some((p) => p.id === id)) {\n result.participants.push({\n id,\n label: id,\n type: inferParticipantType(id),\n lineNumber,\n position,\n });\n }\n // Track group membership\n if (activeGroup && !activeGroup.participantIds.includes(id)) {\n const existingGroup = participantGroupMap.get(id);\n if (existingGroup) {\n pushError(lineNumber, `Participant '${id}' is already in group '${existingGroup}' — participants can only belong to one group`);\n } else {\n activeGroup.participantIds.push(id);\n participantGroupMap.set(id, activeGroup.name);\n }\n }\n continue;\n }\n\n // Bare participant name inside an active group (single identifier on an indented line)\n if (activeGroup && measureIndent(raw) > 0 && /^\\S+$/.test(trimmed)) {\n contentStarted = true;\n const id = trimmed;\n if (!result.participants.some((p) => p.id === id)) {\n result.participants.push({\n id,\n label: id,\n type: inferParticipantType(id),\n lineNumber,\n });\n }\n if (!activeGroup.participantIds.includes(id)) {\n const existingGroup = participantGroupMap.get(id);\n if (existingGroup) {\n pushError(lineNumber, `Participant '${id}' is already in group '${existingGroup}' — participants can only belong to one group`);\n } else {\n activeGroup.participantIds.push(id);\n participantGroupMap.set(id, activeGroup.name);\n }\n }\n continue;\n }\n\n // ---- Indent-aware parsing for messages and block keywords ----\n const indent = measureIndent(raw);\n\n // Close blocks whose scope has ended (indent decreased)\n while (blockStack.length > 0) {\n const top = blockStack[blockStack.length - 1];\n if (indent > top.indent) break;\n // Keep block on stack when 'else' or 'else if' matches current indent — handled below\n if (\n indent === top.indent &&\n (top.block.type === 'if' || top.block.type === 'parallel')\n ) {\n const lower = trimmed.toLowerCase();\n if (lower === 'else' || lower.startsWith('else if ')) break;\n }\n blockStack.pop();\n }\n\n // Parse message lines first — arrows take priority over keywords\n // Reject \"async\" keyword prefix — use ~> instead\n const asyncPrefixMatch = trimmed.match(/^async\\s+(.+)$/i);\n if (asyncPrefixMatch && ARROW_PATTERN.test(asyncPrefixMatch[1])) {\n pushError(lineNumber, 'Use ~> for async messages: A ~> B: message');\n continue;\n }\n\n // Match ~> (async arrow) or -> (sync arrow)\n let isAsync = false;\n const asyncArrowMatch = trimmed.match(\n /^(\\S+)\\s*~>\\s*([^\\s:]+)\\s*(?::\\s*(.+))?$/\n );\n const syncArrowMatch = trimmed.match(\n /^(\\S+)\\s*->\\s*([^\\s:]+)\\s*(?::\\s*(.+))?$/\n );\n const arrowMatch = asyncArrowMatch || syncArrowMatch;\n if (asyncArrowMatch) isAsync = true;\n\n if (arrowMatch) {\n contentStarted = true;\n const from = arrowMatch[1];\n const to = arrowMatch[2];\n lastMsgFrom = from;\n const rawLabel = arrowMatch[3]?.trim() || '';\n\n // Extract return label — skip for async messages\n const { label, returnLabel } = isAsync\n ? { label: rawLabel, returnLabel: undefined }\n : parseReturnLabel(rawLabel);\n\n const msg: SequenceMessage = {\n from,\n to,\n label,\n returnLabel,\n lineNumber,\n ...(isAsync ? { async: true } : {}),\n };\n result.messages.push(msg);\n currentContainer().push(msg);\n\n // Auto-register participants from message usage with type inference\n if (!result.participants.some((p) => p.id === from)) {\n result.participants.push({\n id: from,\n label: from,\n type: inferParticipantType(from),\n lineNumber,\n });\n }\n if (!result.participants.some((p) => p.id === to)) {\n result.participants.push({\n id: to,\n label: to,\n type: inferParticipantType(to),\n lineNumber,\n });\n }\n continue;\n }\n\n // Parse 'if <label>' block keyword\n const ifMatch = trimmed.match(/^if\\s+(.+)$/i);\n if (ifMatch) {\n contentStarted = true;\n const block: SequenceBlock = {\n kind: 'block',\n type: 'if',\n label: ifMatch[1].trim(),\n children: [],\n elseChildren: [],\n lineNumber,\n };\n currentContainer().push(block);\n blockStack.push({ block, indent, inElse: false });\n continue;\n }\n\n // Parse 'loop <label>' block keyword\n const loopMatch = trimmed.match(/^loop\\s+(.+)$/i);\n if (loopMatch) {\n contentStarted = true;\n const block: SequenceBlock = {\n kind: 'block',\n type: 'loop',\n label: loopMatch[1].trim(),\n children: [],\n elseChildren: [],\n lineNumber,\n };\n currentContainer().push(block);\n blockStack.push({ block, indent, inElse: false });\n continue;\n }\n\n // Parse 'parallel [label]' block keyword\n const parallelMatch = trimmed.match(/^parallel(?:\\s+(.+))?$/i);\n if (parallelMatch) {\n contentStarted = true;\n const block: SequenceBlock = {\n kind: 'block',\n type: 'parallel',\n label: parallelMatch[1]?.trim() || '',\n children: [],\n elseChildren: [],\n lineNumber,\n };\n currentContainer().push(block);\n blockStack.push({ block, indent, inElse: false });\n continue;\n }\n\n // Parse 'else if <label>' keyword (must come before bare 'else')\n const elseIfMatch = trimmed.match(/^else\\s+if\\s+(.+)$/i);\n if (elseIfMatch) {\n if (blockStack.length > 0 && blockStack[blockStack.length - 1].indent === indent) {\n const top = blockStack[blockStack.length - 1];\n if (top.block.type === 'parallel') {\n pushError(lineNumber, \"parallel blocks don't support else if — list all concurrent messages directly inside the block\");\n continue;\n }\n if (top.block.type === 'if') {\n const branch: ElseIfBranch = { label: elseIfMatch[1].trim(), children: [] };\n if (!top.block.elseIfBranches) top.block.elseIfBranches = [];\n top.block.elseIfBranches.push(branch);\n top.activeElseIfBranch = branch;\n top.inElse = false;\n }\n }\n continue;\n }\n\n // Parse 'else' keyword (only applies to 'if' blocks)\n if (trimmed.toLowerCase() === 'else') {\n if (blockStack.length > 0 && blockStack[blockStack.length - 1].indent === indent) {\n const top = blockStack[blockStack.length - 1];\n if (top.block.type === 'parallel') {\n pushError(lineNumber, \"parallel blocks don't support else — list all concurrent messages directly inside the block\");\n continue;\n }\n if (top.block.type === 'if') {\n top.inElse = true;\n top.activeElseIfBranch = undefined;\n }\n }\n continue;\n }\n\n // Parse single-line note — \"note: text\" or \"note right of API: text\"\n const noteSingleMatch = trimmed.match(NOTE_SINGLE);\n if (noteSingleMatch) {\n const notePosition =\n (noteSingleMatch[1]?.toLowerCase() as 'right' | 'left') || 'right';\n let noteParticipant = noteSingleMatch[2] || null;\n if (!noteParticipant) {\n if (!lastMsgFrom) continue; // incomplete — skip during live typing\n noteParticipant = lastMsgFrom;\n }\n if (!result.participants.some((p) => p.id === noteParticipant)) {\n continue; // unknown participant — skip during live typing\n }\n const note: SequenceNote = {\n kind: 'note',\n text: noteSingleMatch[3].trim(),\n position: notePosition,\n participantId: noteParticipant,\n lineNumber,\n endLineNumber: lineNumber,\n };\n currentContainer().push(note);\n continue;\n }\n\n // Parse multi-line note — \"note\" or \"note right of API\" (no colon, body indented below)\n const noteMultiMatch = trimmed.match(NOTE_MULTI);\n if (noteMultiMatch) {\n const notePosition =\n (noteMultiMatch[1]?.toLowerCase() as 'right' | 'left') || 'right';\n let noteParticipant = noteMultiMatch[2] || null;\n if (!noteParticipant) {\n if (!lastMsgFrom) continue; // incomplete — skip during live typing\n noteParticipant = lastMsgFrom;\n }\n if (!result.participants.some((p) => p.id === noteParticipant)) {\n continue; // unknown participant — skip during live typing\n }\n // Collect indented body lines\n const noteLines: string[] = [];\n while (i + 1 < lines.length) {\n const nextRaw = lines[i + 1];\n const nextTrimmed = nextRaw.trim();\n if (!nextTrimmed) break;\n const nextIndent = measureIndent(nextRaw);\n if (nextIndent <= indent) break;\n noteLines.push(nextTrimmed);\n i++;\n }\n if (noteLines.length === 0) continue; // no body yet — skip during live typing\n const note: SequenceNote = {\n kind: 'note',\n text: noteLines.join('\\n'),\n position: notePosition,\n participantId: noteParticipant,\n lineNumber,\n endLineNumber: i + 1, // i has advanced past the body lines (1-based)\n };\n currentContainer().push(note);\n continue;\n }\n }\n\n // Validate: if no explicit chart line, check for arrow-based inference\n if (!hasExplicitChart && result.messages.length === 0) {\n // Check if raw content has arrow patterns for inference\n const hasArrows = lines.some((line) => ARROW_PATTERN.test(line.trim()));\n if (!hasArrows) {\n return fail(1, 'No \"chart: sequence\" header and no sequence content detected');\n }\n }\n\n const warn = (line: number, message: string): void => {\n result.diagnostics.push(makeDgmoError(line, message, 'warning'));\n };\n\n // Warn about unused participants (only when the diagram has messages)\n if (result.messages.length > 0) {\n const usedIds = new Set<string>();\n for (const msg of result.messages) {\n usedIds.add(msg.from);\n usedIds.add(msg.to);\n }\n // Walk elements recursively to find note participant references\n const walkElements = (elements: SequenceElement[]): void => {\n for (const el of elements) {\n if (isSequenceNote(el)) {\n usedIds.add(el.participantId);\n } else if (isSequenceBlock(el)) {\n walkElements(el.children);\n walkElements(el.elseChildren);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n walkElements(branch.children);\n }\n }\n }\n }\n };\n walkElements(result.elements);\n\n for (const p of result.participants) {\n if (!usedIds.has(p.id)) {\n warn(p.lineNumber, `Participant \"${p.label}\" is declared but never used in any message or note`);\n }\n }\n }\n\n // Warn about empty groups\n for (const group of result.groups) {\n if (group.participantIds.length === 0) {\n warn(group.lineNumber, `Group \"${group.name}\" has no participants`);\n }\n }\n\n return result;\n}\n\n/**\n * Detect whether raw content looks like a sequence diagram.\n * Used by the chart type inference logic.\n */\nexport function looksLikeSequence(content: string): boolean {\n if (!content) return false;\n const lines = content.split('\\n');\n return lines.some((line) => {\n const trimmed = line.trim();\n if (trimmed.startsWith('//')) return false;\n return ARROW_PATTERN.test(trimmed);\n });\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\nimport { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';\nimport type {\n ParsedGraph,\n GraphNode,\n GraphEdge,\n GraphGroup,\n GraphShape,\n GraphDirection,\n} from './types';\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nfunction nodeId(shape: GraphShape, label: string): string {\n return `${shape}:${label.toLowerCase().trim()}`;\n}\n\ninterface NodeRef {\n id: string;\n label: string;\n shape: GraphShape;\n color?: string;\n}\n\nconst COLOR_SUFFIX_RE = /\\(([^)]+)\\)\\s*$/;\n\nfunction extractColor(\n label: string,\n palette?: PaletteColors\n): { label: string; color?: string } {\n const m = label.match(COLOR_SUFFIX_RE);\n if (!m) return { label };\n const colorName = m[1].trim();\n return {\n label: label.substring(0, m.index!).trim(),\n color: resolveColor(colorName, palette),\n };\n}\n\n/**\n * Try to parse a node reference from a text fragment.\n * Order matters: subroutine & document before process.\n */\nfunction parseNodeRef(\n text: string,\n palette?: PaletteColors\n): NodeRef | null {\n const t = text.trim();\n if (!t) return null;\n\n // Subroutine: [[Label]]\n let m = t.match(/^\\[\\[([^\\]]+)\\]\\]$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('subroutine', label), label, shape: 'subroutine', color };\n }\n\n // Document: [Label~]\n m = t.match(/^\\[([^\\]]+)~\\]$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('document', label), label, shape: 'document', color };\n }\n\n // Process: [Label]\n m = t.match(/^\\[([^\\]]+)\\]$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('process', label), label, shape: 'process', color };\n }\n\n // Terminal: (Label) — use .+ (greedy) so (Label(color)) matches outermost parens\n m = t.match(/^\\((.+)\\)$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('terminal', label), label, shape: 'terminal', color };\n }\n\n // Decision: <Label>\n m = t.match(/^<([^>]+)>$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('decision', label), label, shape: 'decision', color };\n }\n\n // I/O: /Label/\n m = t.match(/^\\/([^/]+)\\/$/);\n if (m) {\n const { label, color } = extractColor(m[1].trim(), palette);\n return { id: nodeId('io', label), label, shape: 'io', color };\n }\n\n return null;\n}\n\n/**\n * Split a line into segments around arrow tokens.\n * Arrows: `->`, `-label->`, `-(color)->`, `-label(color)->`\n *\n * Returns alternating: [nodeText, arrowText, nodeText, arrowText, nodeText, ...]\n * Where arrowText is the full arrow token like `-yes->` or `->`.\n */\nfunction splitArrows(line: string): string[] {\n const segments: string[] = [];\n // Match: optional `-label(color)->` or just `->`\n // We scan left to right looking for `->` and work backwards to find the `-` start.\n const arrowRe = /(?:^|\\s)-([^>\\s(][^(>]*?)?\\s*(?:\\(([^)]+)\\))?\\s*->|(?:^|\\s)->/g;\n\n let lastIndex = 0;\n // Simpler approach: find all `->` positions, then determine if there's a label prefix\n const arrowPositions: { start: number; end: number; label?: string; color?: string }[] = [];\n\n // Find all -> occurrences\n let searchFrom = 0;\n while (searchFrom < line.length) {\n const idx = line.indexOf('->', searchFrom);\n if (idx === -1) break;\n\n // Look backwards from idx to find the start of the arrow (the `-` that starts the label)\n let arrowStart = idx;\n let label: string | undefined;\n let color: string | undefined;\n\n // Check if there's content between a preceding `-` and this `->` (e.g., `-yes->`)\n // Walk backwards from idx-1 to find another `-` that could be the arrow start\n if (idx > 0 && line[idx - 1] !== ' ' && line[idx - 1] !== '\\t') {\n // There might be label/color content attached: e.g. `-yes->` or `-(blue)->`\n // The arrow token starts with `-` followed by optional label, optional (color), then `->`\n // We need to find the opening `-` before any label text\n // Scan backwards to find a `-` preceded by whitespace or start-of-line\n let scanBack = idx - 1;\n while (scanBack > 0 && line[scanBack] !== '-') {\n scanBack--;\n }\n // Check if this `-` could be the start of the arrow\n if (line[scanBack] === '-' && (scanBack === 0 || /\\s/.test(line[scanBack - 1]))) {\n // Content between opening `-` and `->` (strip trailing `-` that is part of `->`)\n let arrowContent = line.substring(scanBack + 1, idx);\n if (arrowContent.endsWith('-')) arrowContent = arrowContent.slice(0, -1);\n // Parse label and color from arrow content\n const colorMatch = arrowContent.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n color = colorMatch[1].trim();\n const labelPart = arrowContent.substring(0, colorMatch.index!).trim();\n if (labelPart) label = labelPart;\n } else {\n const labelPart = arrowContent.trim();\n if (labelPart) label = labelPart;\n }\n arrowStart = scanBack;\n }\n }\n\n arrowPositions.push({ start: arrowStart, end: idx + 2, label, color });\n searchFrom = idx + 2;\n }\n\n if (arrowPositions.length === 0) {\n return [line];\n }\n\n // Build segments\n for (let i = 0; i < arrowPositions.length; i++) {\n const arrow = arrowPositions[i];\n const beforeText = line.substring(lastIndex, arrow.start).trim();\n if (beforeText || i === 0) {\n segments.push(beforeText);\n }\n // Arrow marker\n let arrowToken = '->';\n if (arrow.label && arrow.color) arrowToken = `-${arrow.label}(${arrow.color})->`;\n else if (arrow.label) arrowToken = `-${arrow.label}->`;\n else if (arrow.color) arrowToken = `-(${arrow.color})->`;\n segments.push(arrowToken);\n lastIndex = arrow.end;\n }\n // Remaining text after last arrow\n const remaining = line.substring(lastIndex).trim();\n if (remaining) {\n segments.push(remaining);\n }\n\n return segments;\n}\n\ninterface ArrowInfo {\n label?: string;\n color?: string;\n}\n\nfunction parseArrowToken(token: string, palette?: PaletteColors): ArrowInfo {\n if (token === '->') return {};\n // Color-only: -(color)->\n const colorOnly = token.match(/^-\\(([^)]+)\\)->$/);\n if (colorOnly) {\n return { color: resolveColor(colorOnly[1].trim(), palette) };\n }\n // -label(color)-> or -label->\n const m = token.match(/^-(.+?)(?:\\(([^)]+)\\))?->$/);\n if (m) {\n const label = m[1]?.trim() || undefined;\n const color = m[2] ? resolveColor(m[2].trim(), palette) : undefined;\n return { label, color };\n }\n return {};\n}\n\n// ============================================================\n// Group heading pattern\n// ============================================================\nconst GROUP_HEADING_RE = /^##\\s+(.+?)(?:\\(([^)]+)\\))?\\s*$/;\n\n// ============================================================\n// Main parser\n// ============================================================\n\nexport function parseFlowchart(\n content: string,\n palette?: PaletteColors\n): ParsedGraph {\n const lines = content.split('\\n');\n const result: ParsedGraph = {\n type: 'flowchart',\n direction: 'TB',\n nodes: [],\n edges: [],\n options: {},\n diagnostics: [],\n };\n\n const fail = (line: number, message: string): ParsedGraph => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n };\n\n const nodeMap = new Map<string, GraphNode>();\n const indentStack: { nodeId: string; indent: number }[] = [];\n let currentGroup: GraphGroup | null = null;\n const groups: GraphGroup[] = [];\n let contentStarted = false;\n\n function getOrCreateNode(ref: NodeRef, lineNumber: number): GraphNode {\n const existing = nodeMap.get(ref.id);\n if (existing) return existing;\n\n const node: GraphNode = {\n id: ref.id,\n label: ref.label,\n shape: ref.shape,\n lineNumber,\n ...(ref.color && { color: ref.color }),\n ...(currentGroup && { group: currentGroup.id }),\n };\n nodeMap.set(ref.id, node);\n result.nodes.push(node);\n\n // Add to current group\n if (currentGroup && !currentGroup.nodeIds.includes(ref.id)) {\n currentGroup.nodeIds.push(ref.id);\n }\n\n return node;\n }\n\n function addEdge(\n sourceId: string,\n targetId: string,\n lineNumber: number,\n label?: string,\n color?: string\n ): void {\n const edge: GraphEdge = {\n source: sourceId,\n target: targetId,\n lineNumber,\n ...(label && { label }),\n ...(color && { color }),\n };\n result.edges.push(edge);\n }\n\n /**\n * Process a content line that may contain nodes and arrows.\n * Returns the last node ID encountered (for indent stack tracking).\n */\n function processContentLine(\n trimmed: string,\n lineNumber: number,\n indent: number\n ): string | null {\n contentStarted = true;\n\n // Determine implicit source from indent stack\n // Pop stack entries that are at same or deeper indent level\n while (indentStack.length > 0) {\n const top = indentStack[indentStack.length - 1];\n if (top.indent >= indent) {\n indentStack.pop();\n } else {\n break;\n }\n }\n\n const implicitSourceId =\n indentStack.length > 0\n ? indentStack[indentStack.length - 1].nodeId\n : null;\n\n // Split line into segments around arrows\n const segments = splitArrows(trimmed);\n\n if (segments.length === 1) {\n // Single node reference, no arrows\n const ref = parseNodeRef(segments[0], palette);\n if (ref) {\n const node = getOrCreateNode(ref, lineNumber);\n indentStack.push({ nodeId: node.id, indent });\n return node.id;\n }\n return null;\n }\n\n // Process chain: alternating nodeText / arrowToken / nodeText / ...\n let lastNodeId: string | null = null;\n let pendingArrow: ArrowInfo | null = null;\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n\n // Check if this is an arrow token\n if (seg === '->' || /^-.+->$/.test(seg)) {\n pendingArrow = parseArrowToken(seg, palette);\n continue;\n }\n\n // This is a node text segment\n const ref = parseNodeRef(seg, palette);\n if (!ref) continue;\n\n const node = getOrCreateNode(ref, lineNumber);\n\n if (pendingArrow !== null) {\n const sourceId = lastNodeId ?? implicitSourceId;\n if (sourceId) {\n addEdge(\n sourceId,\n node.id,\n lineNumber,\n pendingArrow.label,\n pendingArrow.color\n );\n }\n pendingArrow = null;\n } else if (lastNodeId === null && implicitSourceId === null) {\n // First node in chain, no arrow yet — just register\n }\n\n lastNodeId = node.id;\n }\n\n // If we ended with a pending arrow but no target node, that's an edge-only line\n // handled by: the arrow was at the start with implicit source\n if (pendingArrow !== null && lastNodeId === null && implicitSourceId) {\n // Edge-only line like ` -> ` with no target — ignore\n }\n\n // If line started with an arrow and we have an implicit source\n // but no explicit first node, the first segment was empty\n if (\n segments.length >= 2 &&\n segments[0] === '' &&\n implicitSourceId &&\n lastNodeId\n ) {\n // Already handled above — the implicit source was used\n }\n\n if (lastNodeId) {\n indentStack.push({ nodeId: lastNodeId, indent });\n }\n\n return lastNodeId;\n }\n\n // === Main loop ===\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n const indent = measureIndent(raw);\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // Group headings\n const groupMatch = trimmed.match(GROUP_HEADING_RE);\n if (groupMatch) {\n const groupLabel = groupMatch[1].trim();\n const groupColorName = groupMatch[2]?.trim();\n const groupColor = groupColorName\n ? resolveColor(groupColorName, palette)\n : undefined;\n\n currentGroup = {\n id: `group:${groupLabel.toLowerCase()}`,\n label: groupLabel,\n nodeIds: [],\n lineNumber,\n ...(groupColor && { color: groupColor }),\n };\n groups.push(currentGroup);\n continue;\n }\n\n // Metadata directives (before content)\n if (!contentStarted && trimmed.includes(':') && !trimmed.includes('->')) {\n const colonIdx = trimmed.indexOf(':');\n const key = trimmed.substring(0, colonIdx).trim().toLowerCase();\n const value = trimmed.substring(colonIdx + 1).trim();\n\n if (key === 'chart') {\n if (value.toLowerCase() !== 'flowchart') {\n const allTypes = ['flowchart', 'sequence', 'class', 'er', 'org', 'bar', 'line', 'pie', 'scatter', 'sankey', 'venn', 'timeline', 'arc', 'slope'];\n let msg = `Expected chart type \"flowchart\", got \"${value}\"`;\n const hint = suggest(value.toLowerCase(), allTypes);\n if (hint) msg += `. ${hint}`;\n return fail(lineNumber, msg);\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'direction') {\n const dir = value.toUpperCase() as GraphDirection;\n if (dir === 'TB' || dir === 'LR') {\n result.direction = dir;\n }\n continue;\n }\n\n // Store other options (e.g., color: off)\n result.options[key] = value;\n continue;\n }\n\n // Content line (nodes and edges)\n processContentLine(trimmed, lineNumber, indent);\n }\n\n if (groups.length > 0) result.groups = groups;\n\n // Validation: no nodes found\n if (result.nodes.length === 0 && !result.error) {\n const diag = makeDgmoError(1, 'No nodes found. Add flowchart content with shape syntax like [Process] or (Start).');\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n }\n\n // Warn about orphaned nodes (not referenced in any edge)\n if (result.nodes.length >= 2 && result.edges.length >= 1 && !result.error) {\n const connectedIds = new Set<string>();\n for (const edge of result.edges) {\n connectedIds.add(edge.source);\n connectedIds.add(edge.target);\n }\n for (const node of result.nodes) {\n if (!connectedIds.has(node.id)) {\n result.diagnostics.push(makeDgmoError(node.lineNumber, `Node \"${node.label}\" is not connected to any other node`, 'warning'));\n }\n }\n }\n\n return result;\n}\n\n// ============================================================\n// Detection helper\n// ============================================================\n\n/**\n * Detect if content looks like a flowchart (without explicit `chart: flowchart` header).\n * Checks for shape delimiters combined with `->` arrows.\n * Avoids false-positives on sequence diagrams (which use bare names with `->`)\n */\nexport function looksLikeFlowchart(content: string): boolean {\n // Must have -> arrows\n if (!content.includes('->')) return false;\n\n // Must have at least one shape delimiter pattern\n // Shape delimiters: [...], (...), <...>, /.../, [[...]], [...~]\n // Sequence diagrams use bare names like \"Alice -> Bob: msg\" — no delimiters around names\n const hasShapeDelimiter =\n /\\[[^\\]]+\\]/.test(content) ||\n /\\([^)]+\\)/.test(content) ||\n /<[^>]+>/.test(content) ||\n /\\/[^/]+\\//.test(content);\n\n if (!hasShapeDelimiter) return false;\n\n // Check that shape delimiters appear near arrows (not just random brackets)\n // Look for patterns like `[X] ->` or `-> [X]` or `(X) ->` etc.\n const shapeNearArrow =\n /[\\])][ \\t]*-.*->/.test(content) || // shape ] or ) followed by arrow\n /->[ \\t]*[\\[(<\\/]/.test(content); // arrow followed by shape opener\n\n return shapeNearArrow;\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\nimport { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';\nimport type {\n ParsedClassDiagram,\n ClassNode,\n ClassMember,\n ClassRelationship,\n ClassModifier,\n MemberVisibility,\n RelationshipType,\n} from './types';\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nfunction classId(name: string): string {\n return name.toLowerCase().trim();\n}\n\n// ============================================================\n// Regex patterns\n// ============================================================\n\n// Class declaration: ClassName [modifier] (color)\nconst CLASS_DECL_RE =\n /^([A-Z][A-Za-z0-9_]*)(?:\\s+\\[(abstract|interface|enum)\\])?(?:\\s+\\(([^)]+)\\))?\\s*$/;\n\n// Relationship — keyword syntax:\n// ClassName extends|implements|contains|has|uses TargetClass : label\nconst REL_KEYWORD_RE =\n /^([A-Z][A-Za-z0-9_]*)\\s+(extends|implements|contains|has|uses)\\s+([A-Z][A-Za-z0-9_]*)(?:\\s*:\\s*(.+))?$/;\n\n// Relationship — arrow syntax:\n// ClassName --|> TargetClass : label\n// Arrows: --|> ..|> *-- o-- ..> ->\nconst REL_ARROW_RE =\n /^([A-Z][A-Za-z0-9_]*)\\s+(--\\|>|\\.\\.\\|>|\\*--|o--|\\.\\.\\>|->)\\s+([A-Z][A-Za-z0-9_]*)(?:\\s*:\\s*(.+))?$/;\n\n// Member line patterns\nconst VISIBILITY_RE = /^([+\\-#])\\s*/;\nconst STATIC_SUFFIX_RE = /\\{static\\}\\s*$/;\nconst METHOD_RE = /^(.+?)\\(([^)]*)\\)(?:\\s*:\\s*(.+))?$/;\nconst FIELD_RE = /^(.+?)\\s*:\\s*(.+)$/;\n\nconst KEYWORD_TO_TYPE: Record<string, RelationshipType> = {\n extends: 'extends',\n implements: 'implements',\n contains: 'composes',\n has: 'aggregates',\n uses: 'depends',\n};\n\nconst ARROW_TO_TYPE: Record<string, RelationshipType> = {\n '--|>': 'extends',\n '..|>': 'implements',\n '*--': 'composes',\n 'o--': 'aggregates',\n '..>': 'depends',\n '->': 'associates',\n};\n\nfunction parseVisibility(prefix: string): MemberVisibility {\n switch (prefix) {\n case '-':\n return 'private';\n case '#':\n return 'protected';\n default:\n return 'public';\n }\n}\n\n// ============================================================\n// Member parser\n// ============================================================\n\nfunction parseMember(\n line: string,\n lineNumber: number,\n isEnum: boolean\n): ClassMember | null {\n let text = line.trim();\n if (!text) return null;\n\n // Enum values: plain text, no colon, no parens needed\n if (isEnum) {\n return {\n name: text,\n visibility: 'public',\n isStatic: false,\n isMethod: false,\n lineNumber,\n };\n }\n\n // Extract visibility prefix\n let visibility: MemberVisibility = 'public';\n const visMatch = text.match(VISIBILITY_RE);\n if (visMatch) {\n visibility = parseVisibility(visMatch[1]);\n text = text.substring(visMatch[0].length);\n }\n\n // Check for {static} suffix\n let isStatic = false;\n if (STATIC_SUFFIX_RE.test(text)) {\n isStatic = true;\n text = text.replace(STATIC_SUFFIX_RE, '').trim();\n }\n\n // Method: name(params) : returnType\n const methodMatch = text.match(METHOD_RE);\n if (methodMatch) {\n return {\n name: methodMatch[1].trim(),\n params: methodMatch[2].trim(),\n type: methodMatch[3]?.trim(),\n visibility,\n isStatic,\n isMethod: true,\n lineNumber,\n };\n }\n\n // Field: name : type\n const fieldMatch = text.match(FIELD_RE);\n if (fieldMatch) {\n return {\n name: fieldMatch[1].trim(),\n type: fieldMatch[2].trim(),\n visibility,\n isStatic,\n isMethod: false,\n lineNumber,\n };\n }\n\n // Plain name (field with no type)\n return {\n name: text,\n visibility,\n isStatic,\n isMethod: false,\n lineNumber,\n };\n}\n\n// ============================================================\n// Main parser\n// ============================================================\n\nexport function parseClassDiagram(\n content: string,\n palette?: PaletteColors\n): ParsedClassDiagram {\n const lines = content.split('\\n');\n const result: ParsedClassDiagram = {\n type: 'class',\n classes: [],\n relationships: [],\n options: {},\n diagnostics: [],\n };\n\n const fail = (line: number, message: string): ParsedClassDiagram => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n };\n\n const classMap = new Map<string, ClassNode>();\n let currentClass: ClassNode | null = null;\n let contentStarted = false;\n\n function getOrCreateClass(name: string, lineNumber: number): ClassNode {\n const id = classId(name);\n const existing = classMap.get(id);\n if (existing) return existing;\n\n const node: ClassNode = {\n id,\n name,\n members: [],\n lineNumber,\n };\n classMap.set(id, node);\n result.classes.push(node);\n return node;\n }\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n const indent = measureIndent(raw);\n\n // Skip empty lines\n if (!trimmed) {\n // Empty line ends current class context\n if (indent === 0) currentClass = null;\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // Metadata directives (before content) — only simple keys (no spaces)\n if (!contentStarted && indent === 0 && /^[a-z][a-z0-9-]*\\s*:/i.test(trimmed)) {\n const colonIdx = trimmed.indexOf(':');\n const key = trimmed.substring(0, colonIdx).trim().toLowerCase();\n const value = trimmed.substring(colonIdx + 1).trim();\n\n // Only recognize known metadata keys\n if (key === 'chart') {\n if (value.toLowerCase() !== 'class') {\n const allTypes = ['class', 'flowchart', 'sequence', 'er', 'org', 'bar', 'line', 'pie', 'scatter', 'sankey', 'venn', 'timeline', 'arc', 'slope'];\n let msg = `Expected chart type \"class\", got \"${value}\"`;\n const hint = suggest(value.toLowerCase(), allTypes);\n if (hint) msg += `. ${hint}`;\n return fail(lineNumber, msg);\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n // Store diagram-level options (e.g., color: off)\n if (!/\\s/.test(key)) {\n result.options[key] = value;\n continue;\n }\n }\n\n // Indented lines = members of current class\n if (indent > 0 && currentClass) {\n const member = parseMember(\n trimmed,\n lineNumber,\n currentClass.modifier === 'enum'\n );\n if (member) {\n currentClass.members.push(member);\n }\n continue;\n }\n\n // At indent 0 — this ends any previous class context\n currentClass = null;\n contentStarted = true;\n\n // Try relationship — keyword syntax\n const relKeyword = trimmed.match(REL_KEYWORD_RE);\n if (relKeyword) {\n const sourceName = relKeyword[1];\n const keyword = relKeyword[2].toLowerCase();\n const targetName = relKeyword[3];\n const label = relKeyword[4]?.trim();\n\n // Ensure both classes exist\n getOrCreateClass(sourceName, lineNumber);\n getOrCreateClass(targetName, lineNumber);\n\n result.relationships.push({\n source: classId(sourceName),\n target: classId(targetName),\n type: KEYWORD_TO_TYPE[keyword],\n ...(label && { label }),\n lineNumber,\n });\n continue;\n }\n\n // Try relationship — arrow syntax\n const relArrow = trimmed.match(REL_ARROW_RE);\n if (relArrow) {\n const sourceName = relArrow[1];\n const arrow = relArrow[2];\n const targetName = relArrow[3];\n const label = relArrow[4]?.trim();\n\n // Ensure both classes exist\n getOrCreateClass(sourceName, lineNumber);\n getOrCreateClass(targetName, lineNumber);\n\n result.relationships.push({\n source: classId(sourceName),\n target: classId(targetName),\n type: ARROW_TO_TYPE[arrow],\n ...(label && { label }),\n lineNumber,\n });\n continue;\n }\n\n // Try class declaration\n const classDecl = trimmed.match(CLASS_DECL_RE);\n if (classDecl) {\n const name = classDecl[1];\n const modifier = classDecl[2] as ClassModifier | undefined;\n const colorName = classDecl[3]?.trim();\n const color = colorName ? resolveColor(colorName, palette) : undefined;\n\n const node = getOrCreateClass(name, lineNumber);\n if (modifier) node.modifier = modifier;\n if (color) node.color = color;\n // Update line number to the declaration line (may have been created by relationship)\n node.lineNumber = lineNumber;\n\n currentClass = node;\n continue;\n }\n }\n\n // Validation\n if (result.classes.length === 0 && !result.error) {\n const diag = makeDgmoError(1, 'No classes found. Add class declarations like \"ClassName\" or \"ClassName [interface]\".');\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n }\n\n // Warn about isolated classes (not in any relationship)\n if (result.classes.length >= 2 && result.relationships.length >= 1 && !result.error) {\n const connectedIds = new Set<string>();\n for (const rel of result.relationships) {\n connectedIds.add(rel.source);\n connectedIds.add(rel.target);\n }\n for (const cls of result.classes) {\n if (!connectedIds.has(cls.id)) {\n result.diagnostics.push(makeDgmoError(cls.lineNumber, `Class \"${cls.name}\" is not connected to any other class`, 'warning'));\n }\n }\n }\n\n return result;\n}\n\n// ============================================================\n// Detection helper\n// ============================================================\n\n/**\n * Detect if content looks like a class diagram without explicit `chart: class`.\n * Requires class-like patterns (capitalized names with modifiers or UML relationships).\n * Must not false-positive on flowcharts.\n */\nexport function looksLikeClassDiagram(content: string): boolean {\n const lines = content.split('\\n');\n\n let hasModifier = false;\n let hasRelationship = false;\n let hasIndentedMember = false;\n let hasClassDecl = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('//')) continue;\n\n // Skip metadata\n if (/^(chart|title)\\s*:/i.test(trimmed)) continue;\n\n const indent = measureIndent(line);\n\n if (indent === 0) {\n // Check for modifier pattern: ClassName [abstract|interface|enum]\n if (/^[A-Z][A-Za-z0-9_]*\\s+\\[(abstract|interface|enum)\\]/i.test(trimmed)) {\n hasModifier = true;\n hasClassDecl = true;\n }\n // Check for relationship keywords\n if (REL_KEYWORD_RE.test(trimmed)) {\n hasRelationship = true;\n }\n // Check for relationship arrows\n if (REL_ARROW_RE.test(trimmed)) {\n hasRelationship = true;\n }\n // Check for plain class declaration (capitalized name only)\n if (CLASS_DECL_RE.test(trimmed)) {\n hasClassDecl = true;\n }\n } else {\n // Indented lines that look like members\n if (/^[+\\-#]?\\s*\\w+.*[:(]/.test(trimmed)) {\n hasIndentedMember = true;\n }\n }\n }\n\n // Require modifier OR (relationship + class-like declarations)\n // Modifier alone is strong enough signal\n if (hasModifier) return true;\n\n // Relationship keywords/arrows + at least one class declaration + member\n if (hasRelationship && hasClassDecl && hasIndentedMember) return true;\n\n return false;\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\nimport { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';\nimport type {\n ParsedERDiagram,\n ERTable,\n ERColumn,\n ERConstraint,\n ERCardinality,\n} from './types';\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nfunction tableId(name: string): string {\n return name.toLowerCase().trim();\n}\n\n// ============================================================\n// Regex patterns\n// ============================================================\n\n// Table declaration: table_name or table_name (color)\n// Allows lowercase, uppercase, underscores, digits — must start with letter or underscore\nconst TABLE_DECL_RE = /^([a-zA-Z_]\\w*)(?:\\s+\\(([^)]+)\\))?\\s*$/;\n\n// Column: name: type [constraints] or name [constraints] or name: type or name\nconst COLUMN_RE = /^(\\w+)(?:\\s*:\\s*(\\w[\\w()]*(?:\\s*\\[\\])?))?(?:\\s+\\[([^\\]]+)\\])?\\s*$/;\n\n// Constraint keywords\nconst CONSTRAINT_MAP: Record<string, ERConstraint> = {\n pk: 'pk',\n fk: 'fk',\n unique: 'unique',\n nullable: 'nullable',\n};\n\n// ============================================================\n// Cardinality parsing\n// ============================================================\n\n// Cardinality keyword map\nconst CARD_WORD: Record<string, ERCardinality> = {\n one: '1',\n many: '*',\n '1': '1',\n '*': '*',\n '?': '?',\n zero: '?',\n};\n\n/**\n * Parse a cardinality side token (e.g. \"1\", \"*\", \"?\", \"one\", \"many\", \"zero\").\n */\nfunction parseCardSide(token: string): ERCardinality | null {\n return CARD_WORD[token.toLowerCase()] ?? null;\n}\n\n/**\n * Try to parse a relationship line with cardinality.\n *\n * Supported forms:\n * tableName 1--* tableName : label\n * tableName 1-* tableName : label\n * tableName one-to-many tableName : label\n * tableName one to many tableName : label\n * tableName 1 to many tableName : label\n * tableName ?--1 tableName : label\n */\nconst REL_SYMBOLIC_RE =\n /^([a-zA-Z_]\\w*)\\s+([1*?])\\s*-{1,2}\\s*([1*?])\\s+([a-zA-Z_]\\w*)(?:\\s*:\\s*(.+))?$/;\n\nconst REL_KEYWORD_RE =\n /^([a-zA-Z_]\\w*)\\s+(one|many|zero|1|\\*|\\?)[- ]to[- ](one|many|zero|1|\\*|\\?)\\s+([a-zA-Z_]\\w*)(?:\\s*:\\s*(.+))?$/i;\n\nfunction parseRelationship(\n trimmed: string\n): {\n source: string;\n target: string;\n from: ERCardinality;\n to: ERCardinality;\n label?: string;\n} | null {\n // Symbolic: 1--*, 1-*, ?--1, etc.\n const sym = trimmed.match(REL_SYMBOLIC_RE);\n if (sym) {\n const fromCard = parseCardSide(sym[2]);\n const toCard = parseCardSide(sym[3]);\n if (fromCard && toCard) {\n return {\n source: sym[1],\n target: sym[4],\n from: fromCard,\n to: toCard,\n label: sym[5]?.trim(),\n };\n }\n }\n\n // Keyword / natural: one-to-many, one to many, 1 to many, etc.\n const kw = trimmed.match(REL_KEYWORD_RE);\n if (kw) {\n const fromCard = parseCardSide(kw[2]);\n const toCard = parseCardSide(kw[3]);\n if (fromCard && toCard) {\n return {\n source: kw[1],\n target: kw[4],\n from: fromCard,\n to: toCard,\n label: kw[5]?.trim(),\n };\n }\n }\n\n return null;\n}\n\n// ============================================================\n// Constraint parser\n// ============================================================\n\nfunction parseConstraints(raw: string): ERConstraint[] {\n const parts = raw.split(',').map((s) => s.trim().toLowerCase());\n const result: ERConstraint[] = [];\n for (const part of parts) {\n const c = CONSTRAINT_MAP[part];\n if (c) result.push(c);\n }\n return result;\n}\n\n// ============================================================\n// Main parser\n// ============================================================\n\nexport function parseERDiagram(\n content: string,\n palette?: PaletteColors\n): ParsedERDiagram {\n const lines = content.split('\\n');\n const result: ParsedERDiagram = {\n type: 'er',\n options: {},\n tables: [],\n relationships: [],\n diagnostics: [],\n };\n\n const fail = (line: number, message: string): ParsedERDiagram => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n };\n\n const tableMap = new Map<string, ERTable>();\n let currentTable: ERTable | null = null;\n let contentStarted = false;\n\n function getOrCreateTable(name: string, lineNumber: number): ERTable {\n const id = tableId(name);\n const existing = tableMap.get(id);\n if (existing) return existing;\n\n const table: ERTable = {\n id,\n name,\n columns: [],\n lineNumber,\n };\n tableMap.set(id, table);\n result.tables.push(table);\n return table;\n }\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n const trimmed = raw.trim();\n const lineNumber = i + 1;\n const indent = measureIndent(raw);\n\n // Skip empty lines\n if (!trimmed) {\n if (indent === 0) currentTable = null;\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // Metadata directives (before content)\n if (!contentStarted && indent === 0 && /^[a-z][a-z0-9-]*\\s*:/i.test(trimmed)) {\n const colonIdx = trimmed.indexOf(':');\n const key = trimmed.substring(0, colonIdx).trim().toLowerCase();\n const value = trimmed.substring(colonIdx + 1).trim();\n\n if (key === 'chart') {\n if (value.toLowerCase() !== 'er') {\n const allTypes = ['er', 'class', 'flowchart', 'sequence', 'org', 'bar', 'line', 'pie', 'scatter', 'sankey', 'venn', 'timeline', 'arc', 'slope'];\n let msg = `Expected chart type \"er\", got \"${value}\"`;\n const hint = suggest(value.toLowerCase(), allTypes);\n if (hint) msg += `. ${hint}`;\n return fail(lineNumber, msg);\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'notation') {\n result.options.notation = value.toLowerCase();\n continue;\n }\n\n // Unknown single-word keys are metadata — skip\n if (!/\\s/.test(key)) continue;\n }\n\n // Indented lines = columns of current table\n if (indent > 0 && currentTable) {\n const colMatch = trimmed.match(COLUMN_RE);\n if (colMatch) {\n const colName = colMatch[1];\n const colType = colMatch[2]?.trim();\n const constraintRaw = colMatch[3];\n const constraints = constraintRaw ? parseConstraints(constraintRaw) : [];\n\n currentTable.columns.push({\n name: colName,\n ...(colType && { type: colType }),\n constraints,\n lineNumber,\n });\n }\n continue;\n }\n\n // At indent 0 — this ends any previous table context\n currentTable = null;\n contentStarted = true;\n\n // Try relationship\n const rel = parseRelationship(trimmed);\n if (rel) {\n getOrCreateTable(rel.source, lineNumber);\n getOrCreateTable(rel.target, lineNumber);\n\n result.relationships.push({\n source: tableId(rel.source),\n target: tableId(rel.target),\n cardinality: { from: rel.from, to: rel.to },\n ...(rel.label && { label: rel.label }),\n lineNumber,\n });\n continue;\n }\n\n // Try table declaration\n const tableDecl = trimmed.match(TABLE_DECL_RE);\n if (tableDecl) {\n const name = tableDecl[1];\n const colorName = tableDecl[2]?.trim();\n const color = colorName ? resolveColor(colorName, palette) : undefined;\n\n const table = getOrCreateTable(name, lineNumber);\n if (color) table.color = color;\n table.lineNumber = lineNumber;\n\n currentTable = table;\n continue;\n }\n }\n\n // Validation\n if (result.tables.length === 0 && !result.error) {\n const diag = makeDgmoError(1, 'No tables found. Add table declarations like \"users\" or \"orders (blue)\".');\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n }\n\n // Warn about isolated tables (not in any relationship)\n if (result.tables.length >= 2 && result.relationships.length >= 1 && !result.error) {\n const connectedIds = new Set<string>();\n for (const rel of result.relationships) {\n connectedIds.add(rel.source);\n connectedIds.add(rel.target);\n }\n for (const table of result.tables) {\n if (!connectedIds.has(table.id)) {\n result.diagnostics.push(makeDgmoError(table.lineNumber, `Table \"${table.name}\" is not connected to any other table`, 'warning'));\n }\n }\n }\n\n return result;\n}\n\n// ============================================================\n// Detection helper\n// ============================================================\n\n/**\n * Detect if content looks like an ER diagram without explicit `chart: er`.\n * Looks for indented lines with [pk] or [fk] constraint patterns.\n */\nexport function looksLikeERDiagram(content: string): boolean {\n const lines = content.split('\\n');\n\n let hasConstraint = false;\n let hasTableDecl = false;\n let hasRelationship = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('//')) continue;\n\n // Skip metadata\n if (/^(chart|title|notation)\\s*:/i.test(trimmed)) continue;\n\n const indent = measureIndent(line);\n\n if (indent > 0) {\n // Indented line with [pk] or [fk] is strong ER signal\n if (/\\[(pk|fk)\\]/i.test(trimmed)) {\n hasConstraint = true;\n }\n } else {\n // Check for table-like declaration\n if (TABLE_DECL_RE.test(trimmed)) {\n hasTableDecl = true;\n }\n // Check for relationship patterns\n if (REL_SYMBOLIC_RE.test(trimmed) || REL_KEYWORD_RE.test(trimmed)) {\n hasRelationship = true;\n }\n }\n }\n\n // [pk]/[fk] constraint is a strong enough signal\n if (hasConstraint && hasTableDecl) return true;\n\n // Relationship with table declarations and constraints\n if (hasRelationship && hasTableDecl && hasConstraint) return true;\n\n return false;\n}\n","// ============================================================\n// Types\n// ============================================================\n\nexport type ChartType =\n | 'bar'\n | 'line'\n | 'pie'\n | 'doughnut'\n | 'area'\n | 'polar-area'\n | 'radar'\n | 'bar-stacked';\n\nexport interface ChartDataPoint {\n label: string;\n value: number;\n extraValues?: number[];\n color?: string;\n lineNumber: number;\n}\n\nimport type { DgmoError } from './diagnostics';\n\nexport interface ParsedChart {\n type: ChartType;\n title?: string;\n titleLineNumber?: number;\n series?: string;\n xlabel?: string;\n ylabel?: string;\n seriesNames?: string[];\n seriesNameColors?: (string | undefined)[];\n orientation?: 'horizontal' | 'vertical';\n color?: string;\n label?: string;\n labels?: 'name' | 'value' | 'percent' | 'full';\n data: ChartDataPoint[];\n diagnostics: DgmoError[];\n error?: string;\n}\n\n// ============================================================\n// Colors\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { PaletteColors } from './palettes';\nimport { makeDgmoError, formatDgmoError, suggest } from './diagnostics';\n\n// ============================================================\n// Parser\n// ============================================================\n\nconst VALID_TYPES = new Set<ChartType>([\n 'bar',\n 'line',\n 'pie',\n 'doughnut',\n 'area',\n 'polar-area',\n 'radar',\n 'bar-stacked',\n]);\n\nconst TYPE_ALIASES: Record<string, ChartType> = {\n 'multi-line': 'line',\n};\n\n/**\n * Parses the simple chart text format into a structured object.\n *\n * Format:\n * ```\n * chart: bar\n * title: My Chart\n * series: Revenue\n *\n * Jan: 120\n * Feb: 200\n * Mar: 150\n * ```\n */\nexport function parseChart(\n content: string,\n palette?: PaletteColors\n): ParsedChart {\n const lines = content.split('\\n');\n const result: ParsedChart = {\n type: 'bar',\n data: [],\n diagnostics: [],\n };\n\n const fail = (line: number, message: string): ParsedChart => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n };\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Recognize ## section headers (skip, but don't treat as comments)\n if (/^#{2,}\\s+/.test(trimmed)) continue;\n\n // Skip comments\n if (trimmed.startsWith('#') || trimmed.startsWith('//')) continue;\n\n // Parse key: value pairs\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = trimmed.substring(0, colonIndex).trim().toLowerCase();\n const value = trimmed.substring(colonIndex + 1).trim();\n\n // Handle metadata\n if (key === 'chart') {\n const raw = value.toLowerCase();\n const chartType = (TYPE_ALIASES[raw] ?? raw) as ChartType;\n if (VALID_TYPES.has(chartType)) {\n result.type = chartType;\n } else {\n let msg = `Unsupported chart type: ${value}. Supported types: ${[...VALID_TYPES].join(', ')}.`;\n const hint = suggest(raw, [...VALID_TYPES]);\n if (hint) msg += ` ${hint}`;\n return fail(lineNumber, msg);\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'xlabel') {\n result.xlabel = value;\n continue;\n }\n\n if (key === 'ylabel') {\n result.ylabel = value;\n continue;\n }\n\n if (key === 'label') {\n result.label = value;\n continue;\n }\n\n if (key === 'labels') {\n const v = value.toLowerCase();\n if (v === 'name' || v === 'value' || v === 'percent' || v === 'full') {\n result.labels = v;\n }\n continue;\n }\n\n if (key === 'orientation') {\n // Only bar and bar-stacked support orientation (axis swapping)\n if (result.type === 'bar' || result.type === 'bar-stacked') {\n const v = value.toLowerCase();\n if (v === 'horizontal' || v === 'vertical') {\n result.orientation = v;\n }\n }\n continue;\n }\n\n if (key === 'color') {\n result.color = resolveColor(value.trim(), palette);\n continue;\n }\n\n if (key === 'series') {\n result.series = value;\n // Parse comma-separated series names for multi-series chart types\n const rawNames = value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const names: string[] = [];\n const nameColors: (string | undefined)[] = [];\n for (const raw of rawNames) {\n const colorMatch = raw.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n const resolved = resolveColor(colorMatch[1].trim(), palette);\n nameColors.push(resolved);\n names.push(raw.substring(0, colorMatch.index!).trim());\n } else {\n nameColors.push(undefined);\n names.push(raw);\n }\n }\n if (names.length === 1) {\n result.series = names[0];\n }\n if (names.length > 1) {\n result.seriesNames = names;\n }\n if (nameColors.some(Boolean)) result.seriesNameColors = nameColors;\n continue;\n }\n\n // Data point: Label: value or Label: v1, v2, ...\n const parts = value.split(',').map((s) => s.trim());\n const numValue = parseFloat(parts[0]);\n if (!isNaN(numValue)) {\n let rawLabel = trimmed.substring(0, colonIndex).trim();\n let pointColor: string | undefined;\n const colorMatch = rawLabel.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n const resolved = resolveColor(colorMatch[1].trim(), palette);\n pointColor = resolved;\n rawLabel = rawLabel.substring(0, colorMatch.index!).trim();\n }\n const extra = parts\n .slice(1)\n .map((s) => parseFloat(s))\n .filter((n) => !isNaN(n));\n result.data.push({\n label: rawLabel,\n value: numValue,\n ...(extra.length > 0 && { extraValues: extra }),\n ...(pointColor && { color: pointColor }),\n lineNumber,\n });\n }\n }\n\n // Validation\n const setChartError = (line: number, message: string) => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n };\n\n const warn = (line: number, message: string): void => {\n result.diagnostics.push(makeDgmoError(line, message, 'warning'));\n };\n\n if (!result.error && result.data.length === 0) {\n warn(1, 'No data points found. Add data in format: Label: 123');\n }\n\n if (!result.error && result.type === 'bar-stacked' && !result.seriesNames) {\n setChartError(1, 'Chart type \"bar-stacked\" requires multiple series names. Use: series: Name1, Name2, Name3');\n }\n\n if (!result.error && result.seriesNames) {\n const expectedCount = result.seriesNames.length;\n for (const dp of result.data) {\n const actualCount = 1 + (dp.extraValues?.length ?? 0);\n if (actualCount !== expectedCount) {\n warn(dp.lineNumber, `Data point \"${dp.label}\" has ${actualCount} value(s), but ${expectedCount} series defined. Each row must have ${expectedCount} comma-separated values.`);\n }\n }\n // Filter out mismatched data points so renderers get clean data\n result.data = result.data.filter((dp) => {\n const actualCount = 1 + (dp.extraValues?.length ?? 0);\n return actualCount === expectedCount;\n });\n }\n\n return result;\n}\n","import * as echarts from 'echarts';\nimport type { EChartsOption } from 'echarts';\nimport { FONT_FAMILY } from './fonts';\nimport { injectBranding } from './branding';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport type EChartsChartType =\n | 'sankey'\n | 'chord'\n | 'function'\n | 'scatter'\n | 'heatmap'\n | 'funnel';\n\nexport interface EChartsDataPoint {\n label: string;\n value: number;\n color?: string;\n lineNumber: number;\n}\n\nexport interface ParsedSankeyLink {\n source: string;\n target: string;\n value: number;\n lineNumber: number;\n}\n\nexport interface ParsedFunction {\n name: string;\n expression: string;\n color?: string;\n lineNumber: number;\n}\n\nexport interface ParsedScatterPoint {\n name: string;\n x: number;\n y: number;\n size?: number;\n color?: string;\n category?: string;\n lineNumber: number;\n}\n\nexport interface ParsedHeatmapRow {\n label: string;\n values: number[];\n lineNumber: number;\n}\n\nimport type { DgmoError } from './diagnostics';\n\nexport interface ParsedEChart {\n type: EChartsChartType;\n title?: string;\n titleLineNumber?: number;\n series?: string;\n seriesNames?: string[];\n seriesNameColors?: (string | undefined)[];\n data: EChartsDataPoint[];\n links?: ParsedSankeyLink[];\n functions?: ParsedFunction[];\n scatterPoints?: ParsedScatterPoint[];\n heatmapRows?: ParsedHeatmapRow[];\n columns?: string[];\n rows?: string[];\n xRange?: { min: number; max: number };\n xlabel?: string;\n ylabel?: string;\n sizelabel?: string;\n showLabels?: boolean;\n categoryColors?: Record<string, string>;\n diagnostics: DgmoError[];\n error?: string;\n}\n\n// ============================================================\n// Nord Colors for Charts\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { PaletteColors } from './palettes';\nimport { getSeriesColors, getSegmentColors } from './palettes';\nimport { parseChart } from './chart';\nimport type { ParsedChart } from './chart';\nimport { makeDgmoError, formatDgmoError, suggest } from './diagnostics';\n\n// ============================================================\n// Parser\n// ============================================================\n\n/**\n * Parses the simple echart text format into a structured object.\n *\n * Format:\n * ```\n * chart: bar\n * title: My Chart\n * series: Revenue\n *\n * Jan: 120\n * Feb: 200\n * Mar: 150\n * ```\n */\nexport function parseEChart(\n content: string,\n palette?: PaletteColors\n): ParsedEChart {\n const lines = content.split('\\n');\n const result: ParsedEChart = {\n type: 'scatter',\n data: [],\n diagnostics: [],\n };\n\n // Track current category for grouped scatter charts\n let currentCategory = 'Default';\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Check for markdown-style category header: ## Category Name or ## Category Name(color)\n const mdCategoryMatch = trimmed.match(/^#{2,}\\s+(.+)$/);\n if (mdCategoryMatch) {\n let catName = mdCategoryMatch[1].trim();\n const catColorMatch = catName.match(/\\(([^)]+)\\)\\s*$/);\n if (catColorMatch) {\n const resolved = resolveColor(catColorMatch[1].trim(), palette);\n if (!result.categoryColors) result.categoryColors = {};\n catName = catName.substring(0, catColorMatch.index!).trim();\n result.categoryColors[catName] = resolved;\n }\n currentCategory = catName;\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('#') || trimmed.startsWith('//')) continue;\n\n // Check for category header: [Category Name]\n const categoryMatch = trimmed.match(/^\\[(.+)\\]$/);\n if (categoryMatch) {\n currentCategory = categoryMatch[1].trim();\n continue;\n }\n\n // Parse key: value pairs\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = trimmed.substring(0, colonIndex).trim().toLowerCase();\n const value = trimmed.substring(colonIndex + 1).trim();\n\n // Handle metadata\n if (key === 'chart') {\n const chartType = value.toLowerCase();\n if (\n chartType === 'sankey' ||\n chartType === 'chord' ||\n chartType === 'function' ||\n chartType === 'scatter' ||\n chartType === 'heatmap' ||\n chartType === 'funnel'\n ) {\n result.type = chartType;\n } else {\n const validTypes = ['scatter', 'sankey', 'chord', 'function', 'heatmap', 'funnel'];\n let msg = `Unsupported chart type: ${value}. Supported types: ${validTypes.join(', ')}.`;\n const hint = suggest(chartType, validTypes);\n if (hint) msg += ` ${hint}`;\n const diag = makeDgmoError(lineNumber, msg);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = value;\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n if (key === 'series') {\n result.series = value;\n const rawNames = value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const names: string[] = [];\n const nameColors: (string | undefined)[] = [];\n for (const raw of rawNames) {\n const colorMatch = raw.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n nameColors.push(resolveColor(colorMatch[1].trim(), palette));\n names.push(raw.substring(0, colorMatch.index!).trim());\n } else {\n nameColors.push(undefined);\n names.push(raw);\n }\n }\n if (names.length === 1) {\n result.series = names[0];\n }\n if (nameColors.some(Boolean)) result.seriesNameColors = nameColors;\n continue;\n }\n\n // Axis labels\n if (key === 'xlabel') {\n result.xlabel = value;\n continue;\n }\n\n if (key === 'ylabel') {\n result.ylabel = value;\n continue;\n }\n\n if (key === 'sizelabel') {\n result.sizelabel = value;\n continue;\n }\n\n if (key === 'labels') {\n result.showLabels =\n value.toLowerCase() === 'on' || value.toLowerCase() === 'true';\n continue;\n }\n\n // Heatmap columns and rows headers\n if (key === 'columns') {\n result.columns = value.split(',').map((s) => s.trim());\n continue;\n }\n\n if (key === 'rows') {\n result.rows = value.split(',').map((s) => s.trim());\n continue;\n }\n\n // Check for x range: \"x: min to max\"\n if (key === 'x') {\n const rangeMatch = value.match(/^(-?[\\d.]+)\\s+to\\s+(-?[\\d.]+)$/);\n if (rangeMatch) {\n result.xRange = {\n min: parseFloat(rangeMatch[1]),\n max: parseFloat(rangeMatch[2]),\n };\n }\n continue;\n }\n\n // Check for Sankey arrow syntax: Source -> Target: Value\n const arrowMatch = trimmed.match(/^(.+?)\\s*->\\s*(.+?):\\s*(\\d+(?:\\.\\d+)?)$/);\n if (arrowMatch) {\n const [, source, target, val] = arrowMatch;\n if (!result.links) result.links = [];\n result.links.push({\n source: source.trim(),\n target: target.trim(),\n value: parseFloat(val),\n lineNumber,\n });\n continue;\n }\n\n // For function charts, treat non-numeric values as function expressions\n if (result.type === 'function') {\n let fnName = trimmed.substring(0, colonIndex).trim();\n let fnColor: string | undefined;\n const colorMatch = fnName.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n fnColor = resolveColor(colorMatch[1].trim(), palette);\n fnName = fnName.substring(0, colorMatch.index!).trim();\n }\n if (!result.functions) result.functions = [];\n result.functions.push({\n name: fnName,\n expression: value,\n ...(fnColor && { color: fnColor }),\n lineNumber,\n });\n continue;\n }\n\n // For scatter charts, parse \"Name: x, y\" or \"Name: x, y, size\"\n if (result.type === 'scatter') {\n const scatterMatch = value.match(\n /^(-?[\\d.]+)\\s*,\\s*(-?[\\d.]+)(?:\\s*,\\s*(-?[\\d.]+))?$/\n );\n if (scatterMatch) {\n let scatterName = trimmed.substring(0, colonIndex).trim();\n let scatterColor: string | undefined;\n const colorMatch = scatterName.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n scatterColor = resolveColor(colorMatch[1].trim(), palette);\n scatterName = scatterName.substring(0, colorMatch.index!).trim();\n }\n if (!result.scatterPoints) result.scatterPoints = [];\n result.scatterPoints.push({\n name: scatterName,\n x: parseFloat(scatterMatch[1]),\n y: parseFloat(scatterMatch[2]),\n size: scatterMatch[3] ? parseFloat(scatterMatch[3]) : undefined,\n ...(scatterColor && { color: scatterColor }),\n ...(currentCategory !== 'Default' && { category: currentCategory }),\n lineNumber,\n });\n }\n continue;\n }\n\n // For heatmap, parse \"RowLabel: val1, val2, val3, ...\"\n if (result.type === 'heatmap') {\n const values = value.split(',').map((v) => parseFloat(v.trim()));\n if (values.length > 0 && values.every((v) => !isNaN(v))) {\n const originalKey = trimmed.substring(0, colonIndex).trim();\n if (!result.heatmapRows) result.heatmapRows = [];\n result.heatmapRows.push({ label: originalKey, values, lineNumber });\n }\n continue;\n }\n\n // Otherwise treat as data point (label: value)\n const numValue = parseFloat(value);\n if (!isNaN(numValue)) {\n // Use the original case for the label (before lowercasing)\n let rawLabel = trimmed.substring(0, colonIndex).trim();\n let pointColor: string | undefined;\n const colorMatch = rawLabel.match(/\\(([^)]+)\\)\\s*$/);\n if (colorMatch) {\n pointColor = resolveColor(colorMatch[1].trim(), palette);\n rawLabel = rawLabel.substring(0, colorMatch.index!).trim();\n }\n result.data.push({\n label: rawLabel,\n value: numValue,\n ...(pointColor && { color: pointColor }),\n lineNumber,\n });\n }\n }\n\n const warn = (line: number, message: string): void => {\n result.diagnostics.push(makeDgmoError(line, message, 'warning'));\n };\n\n if (!result.error) {\n if (result.type === 'sankey') {\n if (!result.links || result.links.length === 0) {\n warn(1, 'No links found. Add links in format: Source -> Target: 123');\n }\n } else if (result.type === 'chord') {\n if (!result.links || result.links.length === 0) {\n warn(1, 'No links found. Add links in format: Source -> Target: 123');\n }\n } else if (result.type === 'function') {\n if (!result.functions || result.functions.length === 0) {\n warn(1, 'No functions found. Add functions in format: Name: expression');\n }\n if (!result.xRange) {\n result.xRange = { min: -10, max: 10 }; // Default range\n }\n } else if (result.type === 'scatter') {\n if (!result.scatterPoints || result.scatterPoints.length === 0) {\n warn(1, 'No scatter points found. Add points in format: Name: x, y or Name: x, y, size');\n }\n } else if (result.type === 'heatmap') {\n if (!result.heatmapRows || result.heatmapRows.length === 0) {\n warn(1, 'No heatmap data found. Add data in format: RowLabel: val1, val2, val3');\n }\n if (!result.columns || result.columns.length === 0) {\n warn(1, 'No columns defined. Add columns in format: columns: Col1, Col2, Col3');\n }\n } else if (result.type === 'funnel') {\n if (result.data.length === 0) {\n warn(1, 'No data found. Add data in format: Label: value');\n }\n }\n }\n\n return result;\n}\n\n// ============================================================\n// ECharts Option Builder\n// ============================================================\n\n/**\n * Converts parsed echart data to ECharts option object.\n */\nexport function buildEChartsOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n isDark: boolean\n): EChartsOption {\n const textColor = palette.text;\n const axisLineColor = palette.border;\n const gridOpacity = isDark ? 0.7 : 0.55;\n const colors = getSeriesColors(palette);\n\n if (parsed.error) {\n // Return empty option, error will be shown separately\n return {};\n }\n\n // Common title configuration\n const titleConfig = parsed.title\n ? {\n text: parsed.title,\n left: 'center' as const,\n top: 8,\n textStyle: {\n color: textColor,\n fontSize: 20,\n fontWeight: 'bold' as const,\n fontFamily: FONT_FAMILY,\n },\n }\n : undefined;\n\n // Shared tooltip theme so tooltips match light/dark mode\n const tooltipTheme = {\n backgroundColor: palette.surface,\n borderColor: palette.border,\n textStyle: { color: palette.text },\n };\n\n // Sankey chart has different structure\n if (parsed.type === 'sankey') {\n return buildSankeyOption(\n parsed,\n textColor,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Chord diagram\n if (parsed.type === 'chord') {\n return buildChordOption(\n parsed,\n textColor,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Function plot\n if (parsed.type === 'function') {\n return buildFunctionOption(\n parsed,\n palette,\n textColor,\n axisLineColor,\n gridOpacity,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Scatter plot\n if (parsed.type === 'scatter') {\n return buildScatterOption(\n parsed,\n palette,\n textColor,\n axisLineColor,\n gridOpacity,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Funnel chart\n if (parsed.type === 'funnel') {\n return buildFunnelOption(\n parsed,\n textColor,\n colors,\n titleConfig,\n tooltipTheme\n );\n }\n\n // Heatmap\n return buildHeatmapOption(\n parsed,\n palette,\n textColor,\n axisLineColor,\n titleConfig,\n tooltipTheme\n );\n}\n\n/**\n * Builds ECharts option for sankey diagrams.\n */\nfunction buildSankeyOption(\n parsed: ParsedEChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n // Extract unique nodes from links\n const nodeSet = new Set<string>();\n if (parsed.links) {\n for (const link of parsed.links) {\n nodeSet.add(link.source);\n nodeSet.add(link.target);\n }\n }\n\n const nodes = Array.from(nodeSet).map((name, index) => ({\n name,\n itemStyle: {\n color: colors[index % colors.length],\n },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n show: false,\n ...tooltipTheme,\n },\n series: [\n {\n type: 'sankey',\n emphasis: {\n focus: 'adjacency',\n blurScope: 'global' as const,\n },\n nodeAlign: 'left',\n nodeGap: 12,\n nodeWidth: 20,\n data: nodes,\n links: parsed.links ?? [],\n lineStyle: {\n color: 'gradient',\n curveness: 0.5,\n },\n label: {\n color: textColor,\n fontSize: 12,\n },\n },\n ],\n };\n}\n\n/**\n * Builds ECharts option for chord diagrams.\n */\nfunction buildChordOption(\n parsed: ParsedEChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n // Extract unique nodes from links\n const nodeSet = new Set<string>();\n if (parsed.links) {\n for (const link of parsed.links) {\n nodeSet.add(link.source);\n nodeSet.add(link.target);\n }\n }\n\n const nodeNames = Array.from(nodeSet);\n const nodeCount = nodeNames.length;\n\n // Build adjacency matrix\n const matrix: number[][] = Array(nodeCount)\n .fill(null)\n .map(() => Array(nodeCount).fill(0));\n\n if (parsed.links) {\n for (const link of parsed.links) {\n const sourceIndex = nodeNames.indexOf(link.source);\n const targetIndex = nodeNames.indexOf(link.target);\n if (sourceIndex !== -1 && targetIndex !== -1) {\n matrix[sourceIndex][targetIndex] = link.value;\n }\n }\n }\n\n // Create category data for nodes with colors\n const categories = nodeNames.map((name, index) => ({\n name,\n itemStyle: {\n color: colors[index % colors.length],\n },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as {\n data?: { source: string; target: string; value: number };\n };\n if (p.data && p.data.source && p.data.target) {\n return `${p.data.source} → ${p.data.target}: ${p.data.value}`;\n }\n return '';\n },\n },\n legend: {\n data: nodeNames,\n bottom: 10,\n textStyle: {\n color: textColor,\n },\n },\n series: [\n {\n type: 'graph',\n layout: 'circular',\n circular: {\n rotateLabel: true,\n },\n center: ['50%', '55%'],\n width: '60%',\n height: '60%',\n data: categories.map((cat) => ({\n name: cat.name,\n symbolSize: 20,\n itemStyle: cat.itemStyle,\n label: {\n show: true,\n color: textColor,\n },\n })),\n links: (parsed.links ?? []).map((link) => ({\n source: link.source,\n target: link.target,\n value: link.value,\n lineStyle: {\n width: Math.max(1, Math.min(link.value / 20, 10)),\n color: colors[nodeNames.indexOf(link.source) % colors.length],\n curveness: 0.3,\n opacity: 0.6,\n },\n })),\n roam: true,\n label: {\n position: 'right',\n formatter: '{b}',\n },\n emphasis: {\n focus: 'adjacency',\n lineStyle: {\n width: 5,\n opacity: 1,\n },\n },\n },\n ],\n };\n}\n\n/**\n * Evaluates a mathematical expression for a given x value.\n * Supports: +, -, *, /, ^, sin, cos, tan, log, ln, exp, sqrt, abs, pi, e\n */\nfunction evaluateExpression(expr: string, x: number): number {\n try {\n // Replace mathematical constants and functions\n const processed = expr\n .replace(/\\bpi\\b/gi, String(Math.PI))\n .replace(/\\be\\b/g, String(Math.E))\n .replace(/\\bsin\\s*\\(/gi, 'Math.sin(')\n .replace(/\\bcos\\s*\\(/gi, 'Math.cos(')\n .replace(/\\btan\\s*\\(/gi, 'Math.tan(')\n .replace(/\\bln\\s*\\(/gi, 'Math.log(')\n .replace(/\\blog\\s*\\(/gi, 'Math.log10(')\n .replace(/\\bexp\\s*\\(/gi, 'Math.exp(')\n .replace(/\\bsqrt\\s*\\(/gi, 'Math.sqrt(')\n .replace(/\\babs\\s*\\(/gi, 'Math.abs(')\n .replace(/\\bx\\b/gi, `(${x})`)\n .replace(/\\^/g, '**');\n\n // Evaluate the expression\n const result = new Function(`return ${processed}`)() as unknown;\n return typeof result === 'number' && isFinite(result) ? result : NaN;\n } catch {\n return NaN;\n }\n}\n\n/**\n * Builds ECharts option for function plots.\n */\nfunction buildFunctionOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const xRange = parsed.xRange ?? { min: -10, max: 10 };\n const samples = 200;\n const step = (xRange.max - xRange.min) / samples;\n\n // Generate x values\n const xValues: number[] = [];\n for (let i = 0; i <= samples; i++) {\n xValues.push(xRange.min + i * step);\n }\n\n // Generate series for each function\n const series = (parsed.functions ?? []).map((fn, index) => {\n const data = xValues.map((x) => {\n const y = evaluateExpression(fn.expression, x);\n return [x, y];\n });\n\n const fnColor = fn.color ?? colors[index % colors.length];\n return {\n name: fn.name,\n type: 'line' as const,\n showSymbol: false,\n smooth: true,\n data,\n lineStyle: {\n width: 2,\n color: fnColor,\n },\n itemStyle: {\n color: fnColor,\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n };\n });\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: {\n type: 'cross',\n },\n },\n legend: {\n data: (parsed.functions ?? []).map((fn) => fn.name),\n bottom: 10,\n textStyle: {\n color: textColor,\n },\n },\n grid: {\n left: '4%',\n right: '4%',\n bottom: '15%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: {\n type: 'value',\n min: xRange.min,\n max: xRange.max,\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n yAxis: {\n type: 'value',\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n series,\n };\n}\n\n/**\n * Builds ECharts option for scatter plots.\n * Auto-detects categories and size from point data:\n * - hasCategories → multi-series with legend (one per category)\n * - hasSize → dynamic symbol sizing from 3rd value\n */\nfunction buildScatterOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const points = parsed.scatterPoints ?? [];\n const defaultSize = 15;\n\n const hasCategories = points.some((p) => p.category !== undefined);\n const hasSize = points.some((p) => p.size !== undefined);\n\n const labelConfig = {\n show: parsed.showLabels ?? false,\n formatter: '{b}',\n position: 'top' as const,\n color: textColor,\n fontSize: 11,\n };\n\n const emphasisConfig = {\n focus: 'self' as const,\n itemStyle: {\n shadowBlur: 10,\n shadowColor: 'rgba(0, 0, 0, 0.3)',\n },\n };\n\n // Build series based on whether categories are present\n let series;\n let legendData: string[] | undefined;\n\n if (hasCategories) {\n const categories = [\n ...new Set(points.map((p) => p.category).filter(Boolean)),\n ] as string[];\n legendData = categories;\n\n series = categories.map((category, catIndex) => {\n const categoryPoints = points.filter((p) => p.category === category);\n const catColor =\n parsed.categoryColors?.[category] ?? colors[catIndex % colors.length];\n\n const data = categoryPoints.map((p) => ({\n name: p.name,\n value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],\n ...(p.color && { itemStyle: { color: p.color } }),\n }));\n\n return {\n name: category,\n type: 'scatter' as const,\n data,\n ...(hasSize\n ? { symbolSize: (val: number[]) => val[2] }\n : { symbolSize: defaultSize }),\n itemStyle: { color: catColor },\n label: labelConfig,\n emphasis: emphasisConfig,\n };\n });\n } else {\n // Single series — per-point colors\n const data = points.map((p, index) => ({\n name: p.name,\n value: hasSize ? [p.x, p.y, p.size ?? 0] : [p.x, p.y],\n ...(hasSize\n ? { symbolSize: p.size ?? defaultSize }\n : { symbolSize: defaultSize }),\n itemStyle: {\n color: p.color ?? colors[index % colors.length],\n },\n }));\n\n series = [\n {\n type: 'scatter' as const,\n data,\n label: labelConfig,\n emphasis: emphasisConfig,\n },\n ];\n }\n\n // Tooltip adapts to available data\n const tooltip = {\n trigger: 'item' as const,\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as {\n seriesName: string;\n name: string;\n value: number[];\n };\n const xLabel = parsed.xlabel || 'x';\n const yLabel = parsed.ylabel || 'y';\n let html = `<strong>${p.name}</strong>`;\n if (hasCategories) html += `<br/>${p.seriesName}`;\n html += `<br/>${xLabel}: ${p.value[0]}<br/>${yLabel}: ${p.value[1]}`;\n if (hasSize) html += `<br/>${parsed.sizelabel || 'size'}: ${p.value[2]}`;\n return html;\n },\n };\n\n // Auto-fit axes to data range with ~10% padding\n const xValues = points.map((p) => p.x);\n const yValues = points.map((p) => p.y);\n const xMin = Math.min(...xValues);\n const xMax = Math.max(...xValues);\n const yMin = Math.min(...yValues);\n const yMax = Math.max(...yValues);\n const xPad = (xMax - xMin) * 0.1 || 1;\n const yPad = (yMax - yMin) * 0.1 || 1;\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip,\n ...(legendData && {\n legend: {\n data: legendData,\n bottom: 10,\n textStyle: { color: textColor },\n },\n }),\n grid: {\n left: parsed.ylabel ? '5%' : '3%',\n right: '4%',\n bottom: hasCategories ? '15%' : parsed.xlabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: {\n type: 'value',\n name: parsed.xlabel,\n nameLocation: 'middle',\n nameGap: 40,\n nameTextStyle: {\n color: textColor,\n fontSize: 18,\n },\n min: Math.floor(xMin - xPad),\n max: Math.ceil(xMax + xPad),\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n yAxis: {\n type: 'value',\n name: parsed.ylabel,\n nameLocation: 'middle',\n nameGap: 50,\n nameTextStyle: {\n color: textColor,\n fontSize: 18,\n },\n min: Math.floor(yMin - yPad),\n max: Math.ceil(yMax + yPad),\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: {\n color: palette.border,\n opacity: gridOpacity,\n },\n },\n },\n series,\n };\n}\n\n/**\n * Builds ECharts option for heatmap charts.\n */\nfunction buildHeatmapOption(\n parsed: ParsedEChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const heatmapRows = parsed.heatmapRows ?? [];\n const columns = parsed.columns ?? [];\n const rowLabels = heatmapRows.map((r) => r.label);\n\n // Convert row data to [colIndex, rowIndex, value] format\n const data: [number, number, number][] = [];\n let minValue = Infinity;\n let maxValue = -Infinity;\n\n heatmapRows.forEach((row, rowIndex) => {\n row.values.forEach((value, colIndex) => {\n data.push([colIndex, rowIndex, value]);\n minValue = Math.min(minValue, value);\n maxValue = Math.max(maxValue, value);\n });\n });\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as { data: [number, number, number] };\n const colName = columns[p.data[0]] ?? p.data[0];\n const rowName = rowLabels[p.data[1]] ?? p.data[1];\n return `${rowName} / ${colName}: <strong>${p.data[2]}</strong>`;\n },\n },\n grid: {\n left: '3%',\n right: '10%',\n bottom: '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: {\n type: 'category',\n data: columns,\n splitArea: {\n show: true,\n },\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n },\n yAxis: {\n type: 'category',\n data: rowLabels,\n splitArea: {\n show: true,\n },\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n fontSize: 16,\n },\n },\n visualMap: {\n min: minValue,\n max: maxValue,\n calculable: true,\n orient: 'vertical',\n right: '2%',\n top: 'center',\n inRange: {\n color: [\n palette.primary,\n palette.colors.cyan,\n palette.colors.yellow,\n palette.colors.orange,\n ],\n },\n textStyle: {\n color: textColor,\n },\n },\n series: [\n {\n type: 'heatmap',\n data,\n label: {\n show: true,\n color: '#ffffff',\n fontSize: 14,\n fontWeight: 'bold' as const,\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n itemStyle: {\n shadowBlur: 10,\n shadowColor: 'rgba(0, 0, 0, 0.5)',\n },\n },\n },\n ],\n };\n}\n\n/**\n * Builds ECharts option for funnel charts.\n */\nfunction buildFunnelOption(\n parsed: ParsedEChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n // Sort data descending by value for funnel ordering\n const sorted = [...parsed.data].sort((a, b) => b.value - a.value);\n const topValue = sorted.length > 0 ? sorted[0].value : 1;\n\n const data = sorted.map((d) => ({\n name: d.label,\n value: d.value,\n itemStyle: {\n color: d.color ?? colors[parsed.data.indexOf(d) % colors.length],\n borderWidth: 0,\n },\n }));\n\n // Build lookup for tooltip: previous step value (in sorted order)\n const prevValueMap = new Map<string, number>();\n for (let i = 0; i < sorted.length; i++) {\n prevValueMap.set(\n sorted[i].label,\n i > 0 ? sorted[i - 1].value : sorted[i].value\n );\n }\n\n const funnelTop = parsed.title ? 60 : 20;\n const funnelLayout = {\n left: '20%',\n top: funnelTop,\n bottom: 20,\n width: '60%',\n sort: 'descending' as const,\n gap: 2,\n minSize: '8%',\n };\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n formatter: (params: unknown) => {\n const p = params as { name: string; value: number; dataIndex: number };\n const val = p.value;\n const prev = prevValueMap.get(p.name) ?? val;\n const isFirst = p.dataIndex === 0;\n let html = `<strong>${p.name}</strong>: ${val}`;\n if (!isFirst) {\n const stepDrop = ((1 - val / prev) * 100).toFixed(1);\n html += `<br/>Step drop-off: ${stepDrop}%`;\n }\n if (!isFirst && topValue > 0) {\n const totalDrop = ((1 - val / topValue) * 100).toFixed(1);\n html += `<br/>Overall drop-off: ${totalDrop}%`;\n }\n return html;\n },\n },\n series: [\n {\n type: 'funnel',\n ...funnelLayout,\n label: {\n show: true,\n position: 'left',\n formatter: '{b}',\n color: textColor,\n fontSize: 13,\n },\n labelLine: {\n show: true,\n length: 10,\n lineStyle: { color: textColor, opacity: 0.3 },\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n label: {\n fontSize: 15,\n },\n },\n data,\n },\n {\n type: 'funnel',\n ...funnelLayout,\n silent: true,\n itemStyle: { color: 'transparent', borderWidth: 0 },\n label: {\n show: true,\n position: 'right',\n formatter: '{c}',\n color: textColor,\n fontSize: 13,\n },\n labelLine: {\n show: true,\n length: 10,\n lineStyle: { color: textColor, opacity: 0.3 },\n },\n emphasis: { disabled: true },\n data: data.map((d) => ({\n ...d,\n itemStyle: { color: 'transparent', borderWidth: 0 },\n })),\n },\n ],\n };\n}\n\n// ============================================================\n// Standard Chart → ECharts Option Builder\n// ============================================================\n\n/**\n * Resolves axis labels from parsed chart orientation/xlabel/ylabel/label.\n */\nfunction resolveAxisLabels(parsed: ParsedChart): {\n xLabel?: string;\n yLabel?: string;\n} {\n const isHorizontal = parsed.orientation === 'horizontal';\n return {\n xLabel: parsed.xlabel ?? (isHorizontal ? parsed.label : undefined),\n yLabel: parsed.ylabel ?? (isHorizontal ? undefined : parsed.label),\n };\n}\n\n/**\n * Produces a reusable axis config object for category or value axes.\n */\nfunction makeGridAxis(\n type: 'category' | 'value',\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n label?: string,\n data?: string[]\n): Record<string, unknown> {\n return {\n type,\n ...(data && { data }),\n axisLine: { lineStyle: { color: axisLineColor } },\n axisLabel: { color: textColor, fontSize: 16, fontFamily: FONT_FAMILY },\n splitLine: { lineStyle: { color: splitLineColor, opacity: gridOpacity } },\n ...(label && {\n name: label,\n nameLocation: 'middle',\n nameGap: 40,\n nameTextStyle: { color: textColor, fontSize: 18, fontFamily: FONT_FAMILY },\n }),\n };\n}\n\n/**\n * Converts a ParsedChart into an EChartsOption.\n * Renders standard chart types (bar, line, pie, etc.) with ECharts.\n */\nexport function buildEChartsOptionFromChart(\n parsed: ParsedChart,\n palette: PaletteColors,\n isDark: boolean\n): EChartsOption {\n if (parsed.error) return {};\n\n const textColor = palette.text;\n const axisLineColor = palette.border;\n const splitLineColor = palette.border;\n const gridOpacity = isDark ? 0.7 : 0.55;\n const colors = getSeriesColors(palette);\n\n const titleConfig = parsed.title\n ? {\n text: parsed.title,\n left: 'center' as const,\n top: 8,\n textStyle: {\n color: textColor,\n fontSize: 20,\n fontWeight: 'bold' as const,\n fontFamily: FONT_FAMILY,\n },\n }\n : undefined;\n\n const tooltipTheme = {\n backgroundColor: palette.surface,\n borderColor: palette.border,\n textStyle: { color: palette.text },\n };\n\n switch (parsed.type) {\n case 'bar':\n return buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);\n case 'bar-stacked':\n return buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme);\n case 'line':\n return parsed.seriesNames\n ? buildMultiLineOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, tooltipTheme)\n : buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);\n case 'area':\n return buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, tooltipTheme);\n case 'pie':\n return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, false);\n case 'doughnut':\n return buildPieOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme, true);\n case 'radar':\n return buildRadarOption(parsed, palette, textColor, gridOpacity, colors, titleConfig, tooltipTheme);\n case 'polar-area':\n return buildPolarAreaOption(parsed, textColor, getSegmentColors(palette, parsed.data.length), titleConfig, tooltipTheme);\n }\n}\n\n// ── Bar ──────────────────────────────────────────────────────\n\nfunction buildBarOption(\n parsed: ParsedChart,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const isHorizontal = parsed.orientation === 'horizontal';\n const labels = parsed.data.map((d) => d.label);\n const data = parsed.data.map((d, i) => ({\n value: d.value,\n itemStyle: { color: d.color ?? colors[i % colors.length] },\n }));\n\n const categoryAxis = makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);\n const valueAxis = makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);\n\n // xAxis is always the bottom axis, yAxis is always the left axis in ECharts\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'shadow' },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: xLabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: isHorizontal ? valueAxis : categoryAxis,\n yAxis: isHorizontal ? categoryAxis : valueAxis,\n series: [\n {\n type: 'bar',\n data,\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Line ─────────────────────────────────────────────────────\n\nfunction buildLineOption(\n parsed: ParsedChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n const labels = parsed.data.map((d) => d.label);\n const values = parsed.data.map((d) => d.value);\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'line' },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: xLabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),\n yAxis: makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),\n series: [\n {\n type: 'line',\n data: values,\n smooth: false,\n symbolSize: 8,\n lineStyle: { color: lineColor, width: 3 },\n itemStyle: { color: lineColor },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Multi-line ───────────────────────────────────────────────\n\nfunction buildMultiLineOption(\n parsed: ParsedChart,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const seriesNames = parsed.seriesNames ?? [];\n const labels = parsed.data.map((d) => d.label);\n\n const series = seriesNames.map((name, idx) => {\n const color = parsed.seriesNameColors?.[idx] ?? colors[idx % colors.length];\n const data = parsed.data.map((dp) =>\n idx === 0 ? dp.value : (dp.extraValues?.[idx - 1] ?? 0)\n );\n return {\n name,\n type: 'line' as const,\n data,\n smooth: false,\n symbolSize: 8,\n lineStyle: { color, width: 3 },\n itemStyle: { color },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n };\n });\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'line' },\n },\n legend: {\n data: seriesNames,\n bottom: 10,\n textStyle: { color: textColor },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: '15%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),\n yAxis: makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),\n series,\n };\n}\n\n// ── Area ─────────────────────────────────────────────────────\n\nfunction buildAreaOption(\n parsed: ParsedChart,\n palette: PaletteColors,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n const labels = parsed.data.map((d) => d.label);\n const values = parsed.data.map((d) => d.value);\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'line' },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: xLabel ? '10%' : '3%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, xLabel, labels),\n yAxis: makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, yLabel),\n series: [\n {\n type: 'line',\n data: values,\n smooth: false,\n symbolSize: 8,\n lineStyle: { color: lineColor, width: 3 },\n itemStyle: { color: lineColor },\n areaStyle: { opacity: 0.25 },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Segment label formatter ──────────────────────────────────\n\nfunction segmentLabelFormatter(mode: ParsedChart['labels']): string {\n switch (mode) {\n case 'name': return '{b}';\n case 'value': return '{b} — {c}';\n case 'percent': return '{b} — {d}%';\n default: return '{b} — {c} ({d}%)';\n }\n}\n\n// ── Pie / Doughnut ───────────────────────────────────────────\n\nfunction buildPieOption(\n parsed: ParsedChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>,\n isDoughnut: boolean\n): EChartsOption {\n const data = parsed.data.map((d, i) => ({\n name: d.label,\n value: d.value,\n itemStyle: { color: d.color ?? colors[i % colors.length] },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n },\n series: [\n {\n type: 'pie',\n radius: isDoughnut ? ['40%', '70%'] : ['0%', '70%'],\n data,\n label: {\n position: 'outside',\n formatter: segmentLabelFormatter(parsed.labels),\n color: textColor,\n fontFamily: FONT_FAMILY,\n },\n labelLine: { show: true },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Radar ────────────────────────────────────────────────────\n\nfunction buildRadarOption(\n parsed: ParsedChart,\n palette: PaletteColors,\n textColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const radarColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n const values = parsed.data.map((d) => d.value);\n const maxValue = Math.max(...values) * 1.15;\n\n const indicator = parsed.data.map((d) => ({\n name: d.label,\n max: maxValue,\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n },\n radar: {\n indicator,\n axisName: {\n color: textColor,\n fontFamily: FONT_FAMILY,\n fontSize: 16,\n },\n splitLine: {\n lineStyle: { color: palette.border, opacity: gridOpacity },\n },\n axisLine: {\n lineStyle: { color: palette.border, opacity: gridOpacity },\n },\n splitArea: { show: false },\n },\n series: [\n {\n type: 'radar',\n data: [\n {\n value: values,\n name: parsed.series ?? 'Value',\n areaStyle: { color: radarColor, opacity: 0.25 },\n lineStyle: { color: radarColor },\n itemStyle: { color: radarColor },\n symbol: 'circle',\n symbolSize: 8,\n label: {\n show: true,\n formatter: '{c}',\n color: textColor,\n fontSize: 11,\n fontFamily: FONT_FAMILY,\n },\n },\n ],\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Polar Area ───────────────────────────────────────────────\n\nfunction buildPolarAreaOption(\n parsed: ParsedChart,\n textColor: string,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const data = parsed.data.map((d, i) => ({\n name: d.label,\n value: d.value,\n itemStyle: { color: d.color ?? colors[i % colors.length] },\n }));\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'item',\n ...tooltipTheme,\n },\n series: [\n {\n type: 'pie',\n roseType: 'radius',\n radius: ['10%', '70%'],\n data,\n label: {\n position: 'outside',\n formatter: segmentLabelFormatter(parsed.labels),\n color: textColor,\n fontFamily: FONT_FAMILY,\n },\n labelLine: { show: true },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n },\n ],\n };\n}\n\n// ── Bar Stacked ──────────────────────────────────────────────\n\nfunction buildBarStackedOption(\n parsed: ParsedChart,\n textColor: string,\n axisLineColor: string,\n splitLineColor: string,\n gridOpacity: number,\n colors: string[],\n titleConfig: EChartsOption['title'],\n tooltipTheme: Record<string, unknown>\n): EChartsOption {\n const { xLabel, yLabel } = resolveAxisLabels(parsed);\n const isHorizontal = parsed.orientation === 'horizontal';\n const seriesNames = parsed.seriesNames ?? [];\n const labels = parsed.data.map((d) => d.label);\n\n const series = seriesNames.map((name, idx) => {\n const color = parsed.seriesNameColors?.[idx] ?? colors[idx % colors.length];\n const data = parsed.data.map((dp) =>\n idx === 0 ? dp.value : (dp.extraValues?.[idx - 1] ?? 0)\n );\n return {\n name,\n type: 'bar' as const,\n stack: 'total',\n data,\n itemStyle: { color },\n label: {\n show: true,\n position: 'inside' as const,\n formatter: '{c}',\n color: '#ffffff',\n fontSize: 14,\n fontWeight: 'bold' as const,\n fontFamily: FONT_FAMILY,\n },\n emphasis: {\n focus: 'self' as const,\n blurScope: 'global' as const,\n },\n };\n });\n\n const categoryAxis = makeGridAxis('category', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? yLabel : xLabel, labels);\n const valueAxis = makeGridAxis('value', textColor, axisLineColor, splitLineColor, gridOpacity, isHorizontal ? xLabel : yLabel);\n\n return {\n backgroundColor: 'transparent',\n animation: false,\n title: titleConfig,\n tooltip: {\n trigger: 'axis',\n ...tooltipTheme,\n axisPointer: { type: 'shadow' },\n },\n legend: {\n data: seriesNames,\n bottom: 10,\n textStyle: { color: textColor },\n },\n grid: {\n left: yLabel ? '5%' : '3%',\n right: '4%',\n bottom: '15%',\n top: parsed.title ? '15%' : '5%',\n containLabel: true,\n },\n xAxis: isHorizontal ? valueAxis : categoryAxis,\n yAxis: isHorizontal ? categoryAxis : valueAxis,\n series,\n };\n}\n\n// ============================================================\n// ECharts SSR Export\n// ============================================================\n\nconst ECHART_EXPORT_WIDTH = 1200;\nconst ECHART_EXPORT_HEIGHT = 800;\n\nconst STANDARD_CHART_TYPES = new Set([\n 'bar',\n 'line',\n 'multi-line',\n 'area',\n 'pie',\n 'doughnut',\n 'radar',\n 'polar-area',\n 'bar-stacked',\n]);\n\n/**\n * Renders an ECharts diagram to SVG using server-side rendering.\n * Mirrors the `renderD3ForExport` API — returns an SVG string or empty string on failure.\n */\nexport async function renderEChartsForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette?: PaletteColors,\n options?: { branding?: boolean }\n): Promise<string> {\n const isDark = theme === 'dark';\n\n // Fall back to Nord palette if none provided\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n // Detect chart type to dispatch to the right parser/builder\n const chartLine = content.match(/^chart\\s*:\\s*(.+)/im);\n const chartType = chartLine?.[1]?.trim().toLowerCase();\n\n let option: EChartsOption;\n if (chartType && STANDARD_CHART_TYPES.has(chartType)) {\n const parsed = parseChart(content, effectivePalette);\n if (parsed.error) return '';\n option = buildEChartsOptionFromChart(parsed, effectivePalette, isDark);\n } else {\n const parsed = parseEChart(content, effectivePalette);\n if (parsed.error) return '';\n option = buildEChartsOption(parsed, effectivePalette, isDark);\n }\n if (!option || Object.keys(option).length === 0) return '';\n\n const chart = echarts.init(null, null, {\n renderer: 'svg',\n ssr: true,\n width: ECHART_EXPORT_WIDTH,\n height: ECHART_EXPORT_HEIGHT,\n });\n\n try {\n chart.setOption(option);\n const svgString = chart.renderToSVGString();\n if (!svgString) return '';\n\n // The SSR output already includes xmlns, width, height, and viewBox.\n // Inject font-family and background on the root <svg> element.\n const bgStyle = theme !== 'transparent' ? `background: ${effectivePalette.bg}; ` : '';\n let result = svgString.replace(\n /^<svg /,\n `<svg style=\"${bgStyle}font-family: ${FONT_FAMILY}\" `\n );\n\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n result = injectBranding(result, brandColor);\n }\n\n return result;\n } finally {\n chart.dispose();\n }\n}\n","import { resolveColor } from '../colors';\nimport type { PaletteColors } from '../palettes';\nimport type { DgmoError } from '../diagnostics';\nimport { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface OrgTagEntry {\n value: string;\n color: string;\n lineNumber: number;\n}\n\nexport interface OrgTagGroup {\n name: string;\n alias?: string;\n entries: OrgTagEntry[];\n /** Value of the entry marked `default` (nodes without metadata get this) */\n defaultValue?: string;\n lineNumber: number;\n}\n\nexport interface OrgNode {\n id: string;\n label: string;\n metadata: Record<string, string>;\n children: OrgNode[];\n parentId: string | null;\n isContainer: boolean;\n lineNumber: number;\n color?: string;\n}\n\nexport interface ParsedOrg {\n title: string | null;\n titleLineNumber: number | null;\n roots: OrgNode[];\n tagGroups: OrgTagGroup[];\n options: Record<string, string>;\n diagnostics: DgmoError[];\n error: string | null;\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction measureIndent(line: string): number {\n let indent = 0;\n for (const ch of line) {\n if (ch === ' ') indent++;\n else if (ch === '\\t') indent += 4;\n else break;\n }\n return indent;\n}\n\nconst COLOR_SUFFIX_RE = /\\(([^)]+)\\)\\s*$/;\n\nfunction extractColor(\n label: string,\n palette?: PaletteColors\n): { label: string; color?: string } {\n const m = label.match(COLOR_SUFFIX_RE);\n if (!m) return { label };\n const colorName = m[1].trim();\n return {\n label: label.substring(0, m.index!).trim(),\n color: resolveColor(colorName, palette),\n };\n}\n\nconst GROUP_HEADING_RE = /^##\\s+(.+?)(?:\\s+alias\\s+(\\w+))?(?:\\s*\\(([^)]+)\\))?\\s*$/;\nconst CONTAINER_RE = /^\\[([^\\]]+)\\]$/;\nconst METADATA_RE = /^([^:]+):\\s*(.+)$/;\nconst CHART_TYPE_RE = /^chart\\s*:\\s*(.+)/i;\nconst TITLE_RE = /^title\\s*:\\s*(.+)/i;\nconst OPTION_RE = /^([a-z][a-z0-9-]*)\\s*:\\s*(.+)$/i;\n\n// ============================================================\n// Parser\n// ============================================================\n\nexport function parseOrg(\n content: string,\n palette?: PaletteColors\n): ParsedOrg {\n const result: ParsedOrg = {\n title: null,\n titleLineNumber: null,\n roots: [],\n tagGroups: [],\n options: {},\n diagnostics: [],\n error: null,\n };\n\n const fail = (line: number, message: string): ParsedOrg => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n };\n\n /** Push a recoverable error and continue parsing. */\n const pushError = (line: number, message: string): void => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n if (!result.error) result.error = formatDgmoError(diag);\n };\n\n if (!content || !content.trim()) {\n return fail(0, 'No content provided');\n }\n\n const lines = content.split('\\n');\n let contentStarted = false;\n let nodeCounter = 0;\n let containerCounter = 0;\n\n // Tag group parsing state\n let currentTagGroup: OrgTagGroup | null = null;\n\n // Alias map: alias (lowercased) → group name (lowercased)\n const aliasMap = new Map<string, string>();\n\n // Indent stack for hierarchy tracking\n // Each entry: { node, indent }\n const indentStack: { node: OrgNode; indent: number }[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNumber = i + 1;\n const trimmed = line.trim();\n\n // Skip empty lines\n if (!trimmed) {\n // Empty line ends a tag group\n if (currentTagGroup) {\n currentTagGroup = null;\n }\n continue;\n }\n\n // Skip comments\n if (trimmed.startsWith('//')) continue;\n\n // --- Header phase ---\n\n // chart: type\n if (!contentStarted) {\n const chartMatch = trimmed.match(CHART_TYPE_RE);\n if (chartMatch) {\n const chartType = chartMatch[1].trim().toLowerCase();\n if (chartType !== 'org') {\n const allTypes = ['org', 'class', 'flowchart', 'sequence', 'er', 'bar', 'line', 'pie', 'scatter', 'sankey', 'venn', 'timeline', 'arc', 'slope'];\n let msg = `Expected chart type \"org\", got \"${chartType}\"`;\n const hint = suggest(chartType, allTypes);\n if (hint) msg += `. ${hint}`;\n return fail(lineNumber, msg);\n }\n continue;\n }\n }\n\n // title: value\n if (!contentStarted) {\n const titleMatch = trimmed.match(TITLE_RE);\n if (titleMatch) {\n result.title = titleMatch[1].trim();\n result.titleLineNumber = lineNumber;\n continue;\n }\n }\n\n // Generic header options (key: value lines before content/tag groups)\n // Only match non-indented lines with simple hyphenated keys\n if (!contentStarted && !currentTagGroup && measureIndent(line) === 0) {\n const optMatch = trimmed.match(OPTION_RE);\n if (optMatch && !trimmed.startsWith('##')) {\n const key = optMatch[1].trim().toLowerCase();\n if (key !== 'chart' && key !== 'title') {\n result.options[key] = optMatch[2].trim();\n continue;\n }\n }\n }\n\n // ## Tag group heading\n const groupMatch = trimmed.match(GROUP_HEADING_RE);\n if (groupMatch) {\n if (contentStarted) {\n pushError(lineNumber, 'Tag groups (##) must appear before org content');\n continue;\n }\n const groupName = groupMatch[1].trim();\n const alias = groupMatch[2] || undefined;\n currentTagGroup = {\n name: groupName,\n alias,\n entries: [],\n lineNumber,\n };\n if (alias) {\n aliasMap.set(alias.toLowerCase(), groupName.toLowerCase());\n }\n result.tagGroups.push(currentTagGroup);\n continue;\n }\n\n // Tag group entries (indented Value(color) [default] under ## heading)\n if (currentTagGroup && !contentStarted) {\n const indent = measureIndent(line);\n if (indent > 0) {\n // Strip trailing `default` keyword before extracting color\n const isDefault = /\\bdefault\\s*$/.test(trimmed);\n const entryText = isDefault\n ? trimmed.replace(/\\s+default\\s*$/, '').trim()\n : trimmed;\n const { label, color } = extractColor(entryText, palette);\n if (!color) {\n pushError(lineNumber, `Expected 'Value(color)' in tag group '${currentTagGroup.name}'`);\n continue;\n }\n if (isDefault) {\n currentTagGroup.defaultValue = label;\n }\n currentTagGroup.entries.push({\n value: label,\n color,\n lineNumber,\n });\n continue;\n }\n // Non-indented line after tag group — fall through to content parsing\n currentTagGroup = null;\n }\n\n // --- Org content phase ---\n contentStarted = true;\n currentTagGroup = null;\n\n const indent = measureIndent(line);\n\n // Check for container syntax: [Team Name]\n const containerMatch = trimmed.match(CONTAINER_RE);\n\n // Check for metadata syntax: key: value\n // Lines containing '|' are pipe-delimited nodes (e.g. \"Alice | role: Engineer\"),\n // not metadata — skip the metadata regex for them.\n const metadataMatch = trimmed.includes('|') ? null : trimmed.match(METADATA_RE);\n\n if (containerMatch) {\n // It's a container node\n const rawLabel = containerMatch[1].trim();\n const { label, color } = extractColor(rawLabel, palette);\n\n containerCounter++;\n const node: OrgNode = {\n id: `container-${containerCounter}`,\n label,\n metadata: {},\n children: [],\n parentId: null,\n isContainer: true,\n lineNumber,\n color,\n };\n\n attachNode(node, indent, indentStack, result);\n } else if (metadataMatch && indentStack.length > 0) {\n // It's a metadata line — attach to most recent node on stack at shallower indent\n const rawKey = metadataMatch[1].trim().toLowerCase();\n const key = aliasMap.get(rawKey) ?? rawKey;\n const value = metadataMatch[2].trim();\n\n // Find the parent node: top of stack (the most recent node)\n const parent = findMetadataParent(indent, indentStack);\n if (!parent) {\n pushError(lineNumber, 'Metadata has no parent node');\n } else {\n parent.metadata[key] = value;\n }\n } else if (metadataMatch && indentStack.length === 0) {\n // Metadata with no parent — could be a node label that happens to contain ':'\n // Treat it as a node if it's at indent 0 and no nodes exist yet\n // Otherwise it's an orphan metadata error\n if (indent === 0) {\n // Treat as a node label (e.g., \"Dr. Smith: Surgeon\" is a valid name)\n const node = parseNodeLabel(trimmed, indent, lineNumber, palette, ++nodeCounter, aliasMap);\n attachNode(node, indent, indentStack, result);\n } else {\n pushError(lineNumber, 'Metadata has no parent node');\n }\n } else {\n // It's a node label — possibly with single-line pipe-delimited metadata\n const node = parseNodeLabel(trimmed, indent, lineNumber, palette, ++nodeCounter, aliasMap);\n attachNode(node, indent, indentStack, result);\n }\n }\n\n if (result.roots.length === 0 && !result.error) {\n const diag = makeDgmoError(1, 'No nodes found in org chart');\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n }\n\n return result;\n}\n\n// ============================================================\n// Internal helpers\n// ============================================================\n\nfunction parseNodeLabel(\n trimmed: string,\n _indent: number,\n lineNumber: number,\n palette: PaletteColors | undefined,\n counter: number,\n aliasMap: Map<string, string> = new Map()\n): OrgNode {\n // Check for single-line compact metadata: \"Alice Park | role: Senior | location: NY\"\n const segments = trimmed.split('|').map((s) => s.trim());\n\n let rawLabel = segments[0];\n const { label, color } = extractColor(rawLabel, palette);\n\n const metadata: Record<string, string> = {};\n // Collect all metadata parts: split pipe segments further on commas\n const metaParts: string[] = [];\n for (let j = 1; j < segments.length; j++) {\n for (const part of segments[j].split(',')) {\n const trimmedPart = part.trim();\n if (trimmedPart) metaParts.push(trimmedPart);\n }\n }\n for (const part of metaParts) {\n const colonIdx = part.indexOf(':');\n if (colonIdx > 0) {\n const rawKey = part.substring(0, colonIdx).trim().toLowerCase();\n const key = aliasMap.get(rawKey) ?? rawKey;\n const value = part.substring(colonIdx + 1).trim();\n metadata[key] = value;\n }\n }\n\n return {\n id: `node-${counter}`,\n label,\n metadata,\n children: [],\n parentId: null,\n isContainer: false,\n lineNumber,\n color,\n };\n}\n\nfunction attachNode(\n node: OrgNode,\n indent: number,\n indentStack: { node: OrgNode; indent: number }[],\n result: ParsedOrg\n): void {\n // Pop stack entries with indent >= current indent\n while (indentStack.length > 0) {\n const top = indentStack[indentStack.length - 1];\n if (top.indent < indent) break;\n indentStack.pop();\n }\n\n if (indentStack.length > 0) {\n // Stack top becomes parent\n const parent = indentStack[indentStack.length - 1].node;\n node.parentId = parent.id;\n parent.children.push(node);\n } else {\n // Top-level root\n result.roots.push(node);\n }\n\n // Push new node onto stack\n indentStack.push({ node, indent });\n}\n\nfunction findMetadataParent(\n indent: number,\n indentStack: { node: OrgNode; indent: number }[]\n): OrgNode | null {\n // Walk backward from the top of the stack to find the most recent node\n // at a shallower indent than the metadata line\n for (let i = indentStack.length - 1; i >= 0; i--) {\n if (indentStack[i].indent < indent) {\n return indentStack[i].node;\n }\n }\n // If metadata is at same indent as top node, attach to top node\n if (indentStack.length > 0) {\n return indentStack[indentStack.length - 1].node;\n }\n return null;\n}\n","// ============================================================\n// .dgmo Unified Format — Chart Type Router\n// ============================================================\n\nimport { looksLikeSequence, parseSequenceDgmo } from './sequence/parser';\nimport { looksLikeFlowchart, parseFlowchart } from './graph/flowchart-parser';\nimport { looksLikeClassDiagram, parseClassDiagram } from './class/parser';\nimport { looksLikeERDiagram, parseERDiagram } from './er/parser';\nimport { parseChart } from './chart';\nimport { parseEChart } from './echarts';\nimport { parseD3 } from './d3';\nimport { parseOrg } from './org/parser';\nimport type { DgmoError } from './diagnostics';\n\n/**\n * Framework identifiers used by the .dgmo router.\n * Maps to the existing preview components and export paths.\n */\nexport type DgmoFramework = 'echart' | 'd3' | 'mermaid';\n\n/**\n * Maps every supported chart type string to its backing framework.\n *\n * ECharts: standard chart types (bar, line, pie, etc.), scatter, flow/relationship diagrams, math, heatmap\n * D3: slope, wordcloud, arc diagram, timeline\n */\nexport const DGMO_CHART_TYPE_MAP: Record<string, DgmoFramework> = {\n // Standard charts (via ECharts)\n bar: 'echart',\n line: 'echart',\n 'multi-line': 'echart',\n area: 'echart',\n pie: 'echart',\n doughnut: 'echart',\n radar: 'echart',\n 'polar-area': 'echart',\n 'bar-stacked': 'echart',\n\n // ECharts\n scatter: 'echart',\n sankey: 'echart',\n chord: 'echart',\n function: 'echart',\n heatmap: 'echart',\n funnel: 'echart',\n\n // D3\n slope: 'd3',\n wordcloud: 'd3',\n arc: 'd3',\n timeline: 'd3',\n venn: 'd3',\n quadrant: 'd3',\n sequence: 'd3',\n flowchart: 'd3',\n class: 'd3',\n er: 'd3',\n org: 'd3',\n};\n\n/**\n * Returns the framework for a given chart type, or `null` if unknown.\n */\nexport function getDgmoFramework(chartType: string): DgmoFramework | null {\n return DGMO_CHART_TYPE_MAP[chartType.toLowerCase()] ?? null;\n}\n\n/**\n * Extracts the `chart:` type value from raw file content.\n * Falls back to inference when no explicit `chart:` line is found\n * (e.g. content containing `->` is inferred as `sequence`).\n */\nexport function parseDgmoChartType(content: string): string | null {\n const lines = content.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n // Skip empty lines and comments\n if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('//'))\n continue;\n const match = trimmed.match(/^chart\\s*:\\s*(.+)/i);\n if (match) return match[1].trim().toLowerCase();\n }\n\n // Infer chart type from content patterns (sequence before flowchart —\n // both use `->` but sequence uses bare names while flowchart uses shape delimiters)\n if (looksLikeSequence(content)) return 'sequence';\n if (looksLikeFlowchart(content)) return 'flowchart';\n if (looksLikeClassDiagram(content)) return 'class';\n if (looksLikeERDiagram(content)) return 'er';\n\n return null;\n}\n\n// Standard chart types parsed by parseChart (then rendered via ECharts)\nconst STANDARD_CHART_TYPES = new Set([\n 'bar', 'line', 'multi-line', 'area', 'pie', 'doughnut',\n 'radar', 'polar-area', 'bar-stacked',\n]);\n\n// ECharts-native types parsed by parseEChart\nconst ECHART_TYPES = new Set([\n 'scatter', 'sankey', 'chord', 'function', 'heatmap', 'funnel',\n]);\n\n/**\n * Parse DGMO content and return diagnostics without rendering.\n * Useful for the CLI and editor to surface all errors before attempting render.\n */\nexport function parseDgmo(content: string): { diagnostics: DgmoError[] } {\n const chartType = parseDgmoChartType(content);\n\n if (!chartType) {\n // No chart type detected — try D3 parser as fallback (it handles missing chart: line)\n const parsed = parseD3(content);\n return { diagnostics: parsed.diagnostics };\n }\n\n if (chartType === 'sequence') {\n const parsed = parseSequenceDgmo(content);\n return { diagnostics: parsed.diagnostics };\n }\n if (chartType === 'flowchart') {\n const parsed = parseFlowchart(content);\n return { diagnostics: parsed.diagnostics };\n }\n if (chartType === 'class') {\n const parsed = parseClassDiagram(content);\n return { diagnostics: parsed.diagnostics };\n }\n if (chartType === 'er') {\n const parsed = parseERDiagram(content);\n return { diagnostics: parsed.diagnostics };\n }\n if (chartType === 'org') {\n const parsed = parseOrg(content);\n return { diagnostics: parsed.diagnostics };\n }\n if (STANDARD_CHART_TYPES.has(chartType)) {\n const parsed = parseChart(content);\n return { diagnostics: parsed.diagnostics };\n }\n if (ECHART_TYPES.has(chartType)) {\n const parsed = parseEChart(content);\n return { diagnostics: parsed.diagnostics };\n }\n\n // D3 types (slope, wordcloud, arc, timeline, venn, quadrant)\n const parsed = parseD3(content);\n return { diagnostics: parsed.diagnostics };\n}\n","// ============================================================\n// Org Chart Tree Layout Engine (d3-hierarchy)\n// ============================================================\n\nimport { hierarchy, tree } from 'd3-hierarchy';\nimport type { ParsedOrg, OrgNode, OrgTagGroup } from './parser';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface OrgLayoutNode {\n id: string;\n label: string;\n metadata: Record<string, string>;\n isContainer: boolean;\n lineNumber: number;\n color?: string;\n x: number;\n y: number;\n width: number;\n height: number;\n /** Count of hidden descendants when this node is collapsed */\n hiddenCount?: number;\n /** True if node has children (expanded or collapsed) — drives toggle UI */\n hasChildren?: boolean;\n}\n\nexport interface OrgLayoutEdge {\n sourceId: string;\n targetId: string;\n points: { x: number; y: number }[];\n}\n\nexport interface OrgContainerBounds {\n nodeId: string;\n label: string;\n lineNumber: number;\n color?: string;\n metadata: Record<string, string>;\n x: number;\n y: number;\n width: number;\n height: number;\n labelHeight: number;\n /** Count of hidden descendants when this container is collapsed */\n hiddenCount?: number;\n /** True if container has children (expanded or collapsed) — drives toggle UI */\n hasChildren?: boolean;\n}\n\nexport interface OrgLegendEntry {\n value: string;\n color: string;\n}\n\nexport interface OrgLegendGroup {\n name: string;\n entries: OrgLegendEntry[];\n x: number;\n y: number;\n width: number;\n height: number;\n minifiedWidth: number;\n minifiedHeight: number;\n}\n\nexport interface OrgLayoutResult {\n nodes: OrgLayoutNode[];\n edges: OrgLayoutEdge[];\n containers: OrgContainerBounds[];\n legend: OrgLegendGroup[];\n width: number;\n height: number;\n}\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst CHAR_WIDTH = 7.5;\nconst LABEL_FONT_SIZE = 13;\nconst META_FONT_SIZE = 11;\nconst META_LINE_HEIGHT = 16;\nconst HEADER_HEIGHT = 28;\nconst SEPARATOR_GAP = 6;\nconst CARD_H_PAD = 20;\nconst CARD_V_PAD = 10;\nconst MIN_CARD_WIDTH = 140;\nconst H_GAP = 30;\nconst V_GAP = 50;\nconst MARGIN = 40;\nconst CONTAINER_PAD_X = 24;\nconst CONTAINER_PAD_BOTTOM = 24;\nconst CONTAINER_LABEL_HEIGHT = 28;\nconst CONTAINER_META_LINE_HEIGHT = 16;\nconst STACK_V_GAP = 20;\n\n\n// Legend\nconst LEGEND_GAP = 30;\nconst LEGEND_DOT_R = 5;\nconst LEGEND_DOT_TEXT_GAP = 6;\nconst LEGEND_ENTRY_GAP = 12;\nconst LEGEND_PAD = 10;\nconst LEGEND_HEADER_H = 20;\nconst LEGEND_ENTRY_H = 18;\nconst LEGEND_MAX_PER_ROW = 3;\nconst LEGEND_V_GAP = 12;\nconst EYE_ICON_WIDTH = 16;\nconst EYE_ICON_GAP = 6;\n\n// ============================================================\n// Helpers\n// ============================================================\n\n/** Count all non-container descendants recursively, including hidden (collapsed) ones. */\nfunction countDescendantNodes(node: OrgNode, hiddenCounts?: Map<string, number>): number {\n let count = 0;\n for (const child of node.children) {\n count += (child.isContainer ? 0 : 1) + countDescendantNodes(child, hiddenCounts);\n const hc = hiddenCounts?.get(child.id);\n if (hc) count += hc;\n }\n return count;\n}\n\n// ============================================================\n// Card Sizing\n// ============================================================\n\nfunction filterMetadata(\n metadata: Record<string, string>,\n hiddenAttributes?: Set<string>\n): Record<string, string> {\n if (!hiddenAttributes || hiddenAttributes.size === 0) return metadata;\n const filtered: Record<string, string> = {};\n for (const [key, value] of Object.entries(metadata)) {\n if (!hiddenAttributes.has(key)) {\n filtered[key] = value;\n }\n }\n return filtered;\n}\n\nfunction computeCardWidth(label: string, meta: Record<string, string>): number {\n let maxChars = label.length;\n\n for (const [key, value] of Object.entries(meta)) {\n const lineChars = key.length + 2 + value.length; // \"key: value\"\n if (lineChars > maxChars) maxChars = lineChars;\n }\n\n return Math.max(MIN_CARD_WIDTH, Math.ceil(maxChars * CHAR_WIDTH) + CARD_H_PAD * 2);\n}\n\nfunction computeCardHeight(meta: Record<string, string>): number {\n const metaCount = Object.keys(meta).length;\n if (metaCount === 0) return HEADER_HEIGHT + CARD_V_PAD;\n return HEADER_HEIGHT + SEPARATOR_GAP + metaCount * META_LINE_HEIGHT + CARD_V_PAD;\n}\n\n// ============================================================\n// Tag Group Color Resolution\n// ============================================================\n\nfunction resolveNodeColor(\n node: OrgNode,\n tagGroups: OrgTagGroup[],\n activeGroupName: string | null\n): string | undefined {\n if (node.color) return node.color;\n if (!activeGroupName) return undefined;\n\n const group = tagGroups.find(\n (g) => g.name.toLowerCase() === activeGroupName.toLowerCase()\n );\n if (!group) return undefined;\n const metaValue =\n node.metadata[group.name.toLowerCase()] ??\n (node.isContainer ? undefined : group.defaultValue);\n if (!metaValue) return '#999999';\n return group.entries.find(\n (e) => e.value.toLowerCase() === metaValue.toLowerCase()\n )?.color ?? '#999999';\n}\n\n// ============================================================\n// Hierarchy Helpers\n// ============================================================\n\ninterface TreeNode {\n orgNode: OrgNode;\n children: TreeNode[];\n width: number;\n height: number;\n}\n\nfunction buildTreeNodes(\n nodes: OrgNode[],\n hiddenCounts?: Map<string, number>,\n hiddenAttributes?: Set<string>,\n subNodeLabel?: string,\n showSubNodeCount?: boolean\n): TreeNode[] {\n return nodes.map((orgNode) => {\n const meta = filterMetadata(orgNode.metadata, hiddenAttributes);\n const hc = hiddenCounts?.get(orgNode.id);\n if (!orgNode.isContainer && showSubNodeCount && !(hc != null && hc > 0)) {\n const count = countDescendantNodes(orgNode, hiddenCounts);\n if (count > 0) {\n meta[subNodeLabel ?? 'Sub-node Count'] = String(count);\n }\n }\n return {\n orgNode,\n children: buildTreeNodes(orgNode.children, hiddenCounts, hiddenAttributes, subNodeLabel, showSubNodeCount),\n width: computeCardWidth(orgNode.label, meta),\n height: computeCardHeight(meta),\n };\n });\n}\n\n/**\n * Count total descendants (children + grandchildren + ...) of a TreeNode.\n */\nfunction countDescendants(node: TreeNode): number {\n let count = 0;\n for (const child of node.children) {\n count += 1 + countDescendants(child);\n }\n return count;\n}\n\n/**\n * Recursively reorder children so subtrees with the most descendants\n * occupy center positions. Produces a balanced, symmetrical layout.\n * Skips nodes with ≤2 children (no meaningful center to target).\n */\nfunction centerHeavyChildren(node: TreeNode): void {\n for (const child of node.children) {\n centerHeavyChildren(child);\n }\n if (node.children.length <= 2) return;\n\n const weighted = node.children\n .map((child) => ({ child, weight: countDescendants(child) }))\n .sort((a, b) => b.weight - a.weight);\n\n const result: TreeNode[] = new Array(weighted.length);\n const mid = Math.floor((weighted.length - 1) / 2);\n let left = mid;\n let right = mid;\n\n for (let i = 0; i < weighted.length; i++) {\n if (i === 0) {\n result[mid] = weighted[i].child;\n } else if (i % 2 === 1) {\n right++;\n result[right] = weighted[i].child;\n } else {\n left--;\n result[left] = weighted[i].child;\n }\n }\n\n node.children = result;\n}\n\n// ============================================================\n// Layout\n// ============================================================\n\nfunction computeLegendGroups(tagGroups: OrgTagGroup[], showEyeIcons: boolean): OrgLegendGroup[] {\n const groups: OrgLegendGroup[] = [];\n\n for (const group of tagGroups) {\n if (group.entries.length === 0) continue;\n\n const entryWidths = group.entries.map(\n (e) =>\n LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP + e.value.length * CHAR_WIDTH\n );\n\n // Compute max width per column so columns align across rows\n const numRows = Math.ceil(entryWidths.length / LEGEND_MAX_PER_ROW);\n const colWidths: number[] = [];\n for (let col = 0; col < LEGEND_MAX_PER_ROW; col++) {\n let maxW = 0;\n for (let row = 0; row < numRows; row++) {\n const idx = row * LEGEND_MAX_PER_ROW + col;\n if (idx < entryWidths.length && entryWidths[idx] > maxW) {\n maxW = entryWidths[idx];\n }\n }\n if (maxW > 0) colWidths.push(maxW);\n }\n\n const eyeExtra = showEyeIcons ? EYE_ICON_GAP + EYE_ICON_WIDTH : 0;\n const headerWidth = group.name.length * CHAR_WIDTH + eyeExtra;\n const totalColumnsWidth =\n colWidths.reduce((s, w) => s + w, 0) +\n (colWidths.length - 1) * LEGEND_ENTRY_GAP;\n const maxRowWidth = Math.max(headerWidth, totalColumnsWidth);\n\n const minifiedWidth = group.name.length * CHAR_WIDTH + LEGEND_PAD * 2;\n\n groups.push({\n name: group.name,\n entries: group.entries.map((e) => ({ value: e.value, color: e.color })),\n x: 0,\n y: 0,\n width: maxRowWidth + LEGEND_PAD * 2,\n height: LEGEND_HEADER_H + numRows * LEGEND_ENTRY_H + LEGEND_PAD,\n minifiedWidth,\n minifiedHeight: LEGEND_HEADER_H + LEGEND_PAD,\n });\n }\n\n return groups;\n}\n\n/**\n * Inject default tag group values into non-container node metadata.\n * Idempotent — only sets keys not already present.\n */\nfunction injectDefaultMetadata(\n roots: OrgNode[],\n tagGroups: OrgTagGroup[]\n): void {\n const defaults: { key: string; value: string }[] = [];\n for (const group of tagGroups) {\n if (group.defaultValue) {\n defaults.push({ key: group.name.toLowerCase(), value: group.defaultValue });\n }\n }\n if (defaults.length === 0) return;\n\n const walk = (node: OrgNode) => {\n if (!node.isContainer) {\n for (const { key, value } of defaults) {\n if (!(key in node.metadata)) {\n node.metadata[key] = value;\n }\n }\n }\n for (const child of node.children) walk(child);\n };\n for (const root of roots) walk(root);\n}\n\nexport function layoutOrg(\n parsed: ParsedOrg,\n hiddenCounts?: Map<string, number>,\n activeTagGroup?: string | null,\n hiddenAttributes?: Set<string>\n): OrgLayoutResult {\n if (parsed.roots.length === 0) {\n return { nodes: [], edges: [], containers: [], legend: [], width: 0, height: 0 };\n }\n\n // Inject default tag group values into node metadata for display.\n // Must happen before buildTreeNodes so card sizing accounts for extra rows.\n injectDefaultMetadata(parsed.roots, parsed.tagGroups);\n\n // Build tree structure\n const subNodeLabel = parsed.options['sub-node-label'] ?? undefined;\n const showSubNodeCount = parsed.options['show-sub-node-count']?.toLowerCase() === 'yes';\n const treeNodes = buildTreeNodes(parsed.roots, hiddenCounts, hiddenAttributes, subNodeLabel, showSubNodeCount);\n\n // Single root or virtual root for multiple roots\n let root: TreeNode;\n if (treeNodes.length === 1) {\n root = treeNodes[0];\n } else {\n root = {\n orgNode: {\n id: '__virtual_root__',\n label: '',\n metadata: {},\n children: parsed.roots,\n parentId: null,\n isContainer: false,\n lineNumber: 0,\n },\n children: treeNodes,\n width: 0,\n height: 0,\n };\n }\n\n // Pre-compute max card dimensions for node separation\n let maxWidth = 0;\n let maxHeight = 0;\n const allTreeNodes: TreeNode[] = [];\n const collectNodes = (tn: TreeNode) => {\n if (tn.orgNode.id !== '__virtual_root__') {\n allTreeNodes.push(tn);\n if (tn.width > maxWidth) maxWidth = tn.width;\n if (tn.height > maxHeight) maxHeight = tn.height;\n }\n for (const child of tn.children) collectNodes(child);\n };\n collectNodes(root);\n\n // Standardize all cards to the widest width for uniform appearance\n for (const tn of allTreeNodes) {\n tn.width = maxWidth;\n }\n\n // Collapse leaf containers: when a container's children are ALL leaves\n // (no grandchildren), replace them with a single virtual stack node so\n // the d3 tree allocates a narrow column instead of a wide row.\n const leafStacks = new Map<\n string,\n { children: TreeNode[]; placeholderId: string }\n >();\n\n const collapseLeafContainers = (tn: TreeNode): void => {\n for (const child of tn.children) collapseLeafContainers(child);\n\n if (\n tn.orgNode.isContainer &&\n tn.children.length > 0 &&\n tn.children.every((c) => c.children.length === 0)\n ) {\n const placeholderId = `__stack_${tn.orgNode.id}`;\n leafStacks.set(tn.orgNode.id, {\n children: [...tn.children],\n placeholderId,\n });\n\n const maxW = Math.max(...tn.children.map((c) => c.width));\n // Standardize all children to the widest card width\n for (const child of tn.children) {\n child.width = maxW;\n }\n const totalH =\n tn.children.reduce((s, c) => s + c.height, 0) +\n (tn.children.length - 1) * STACK_V_GAP;\n\n tn.children = [\n {\n orgNode: {\n id: placeholderId,\n label: '',\n metadata: {},\n children: [],\n parentId: tn.orgNode.id,\n isContainer: false,\n lineNumber: 0,\n },\n children: [],\n width: maxW,\n height: totalH,\n },\n ];\n }\n };\n collapseLeafContainers(root);\n\n // Reorder children: heaviest subtrees in center positions\n centerHeavyChildren(root);\n\n // Build d3 hierarchy\n const h = hierarchy<TreeNode>(root, (d) => d.children);\n\n // Run Reingold-Tilford tree layout with nodeSize\n // x = horizontal spread, y = vertical (depth)\n const treeLayout = tree<TreeNode>().nodeSize([\n maxWidth + H_GAP,\n maxHeight + V_GAP,\n ]);\n treeLayout(h);\n\n // Post-layout: compact vertical spacing per depth level.\n // D3 tree uses uniform nodeSize (maxHeight + V_GAP) for every level, which\n // creates disproportionate gaps when short nodes (no metadata) are placed at\n // the same level-spacing as tall nodes (multiple metadata rows). Recompute\n // Y positions so each level's gap is based on the actual max height at that\n // level rather than the global max.\n {\n const descendants = h.descendants().filter(\n (d) => d.data.orgNode.id !== '__virtual_root__'\n );\n\n // Collect max actual card height per depth level\n const levelMaxHeight = new Map<number, number>();\n for (const d of descendants) {\n const cur = levelMaxHeight.get(d.depth) ?? 0;\n if (d.data.height > cur) levelMaxHeight.set(d.depth, d.data.height);\n }\n\n // Compute compacted Y position for each depth level\n const maxDepth = Math.max(...levelMaxHeight.keys(), 0);\n const compactedY = new Map<number, number>();\n // Virtual root (depth 0 in hierarchy) stays at y=0\n // First real level starts at depth 1 for multi-root or depth 0 for single root.\n // We compute based on the d3 hierarchy's depth numbering.\n const rootDepth = treeNodes.length === 1 ? 0 : 1;\n compactedY.set(rootDepth, 0);\n for (let d = rootDepth + 1; d <= maxDepth; d++) {\n const parentH = levelMaxHeight.get(d - 1) ?? maxHeight;\n const prevY = compactedY.get(d - 1) ?? 0;\n compactedY.set(d, prevY + parentH + V_GAP);\n }\n\n // Shift each node from uniform Y to compacted Y (top-aligned).\n // Siblings share the same Y so connecting edges align cleanly.\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n d.y = compactedY.get(d.depth) ?? d.y!;\n }\n }\n\n // Post-layout: tighten vertical spacing inside containers.\n // Container-with-children nodes render as background boxes (not cards),\n // so their children can sit closer to the container header.\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (!d.data.orgNode.isContainer) continue;\n if (!d.children || d.children.length === 0) continue;\n\n // Actual gap between this container and its direct children\n const childY = d.children[0].y!;\n const actualLevelGap = childY - d.y!;\n\n const metaCount = Object.keys(d.data.orgNode.metadata).length;\n const headerHeight =\n CONTAINER_LABEL_HEIGHT + metaCount * CONTAINER_META_LINE_HEIGHT;\n const desiredGap = headerHeight + 15;\n const shiftUp = actualLevelGap - desiredGap;\n if (shiftUp <= 0) continue;\n\n // Shift all descendants upward\n const shift = (node: typeof d) => {\n if (node.children) {\n for (const child of node.children) {\n child.y! -= shiftUp;\n shift(child);\n }\n }\n };\n shift(d);\n }\n\n // Post-layout: tighten gap between non-container parents and their\n // container children. Containers render as header boxes (not full cards),\n // so the standard inter-level gap is visually excessive.\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (d.data.orgNode.isContainer) continue; // only non-container parents\n if (!d.children || d.children.length === 0) continue;\n\n // Only apply when ALL direct children are containers — mixed children\n // need standard spacing so siblings stay aligned.\n if (!d.children.every((c) => c.data.orgNode.isContainer)) continue;\n\n const parentBottomY = d.y! + d.data.height;\n const firstChildY = Math.min(...d.children.map((c) => c.y!));\n const currentGap = firstChildY - parentBottomY;\n const desiredGap = V_GAP * 0.6;\n const shiftUp = currentGap - desiredGap;\n if (shiftUp <= 0) continue;\n\n // Shift all container children and their descendants up\n const shiftDown = (node: typeof d) => {\n node.y! -= shiftUp;\n if (node.children) {\n for (const child of node.children) {\n shiftDown(child);\n }\n }\n };\n for (const child of d.children) {\n shiftDown(child);\n }\n }\n\n // Post-layout: compact sibling spacing based on actual subtree widths.\n // D3 uses uniform nodeSize so narrow stacks get the same gap as wide\n // subtrees. Process bottom-up so inner subtrees are compact first.\n {\n type HNode = (typeof h);\n const subtreeExtent = (node: HNode): { minX: number; maxX: number } => {\n // Start with this node's own card/header bounds\n let min = node.x! - node.data.width / 2;\n let max = node.x! + node.data.width / 2;\n\n // Include children's subtree extents\n if (node.children) {\n for (const child of node.children) {\n const childExt = subtreeExtent(child);\n if (childExt.minX < min) min = childExt.minX;\n if (childExt.maxX > max) max = childExt.maxX;\n }\n }\n\n // Container boxes wrap their content with padding — mirror the\n // actual bounding-box computation so compaction sees the true width.\n if (node.data.orgNode.isContainer) {\n min -= CONTAINER_PAD_X;\n max += CONTAINER_PAD_X;\n }\n\n return { minX: min, maxX: max };\n };\n\n const shiftX = (node: HNode, dx: number) => {\n node.x! += dx;\n if (node.children) node.children.forEach((c) => shiftX(c, dx));\n };\n\n const internalNodes = h\n .descendants()\n .filter((d) => d.children && d.children.length >= 2)\n .sort((a, b) => b.depth - a.depth);\n\n for (const parent of internalNodes) {\n const children = parent.children!;\n\n const extents = children.map((child) => {\n const ext = subtreeExtent(child);\n return {\n relLeft: ext.minX - child.x!,\n relRight: ext.maxX - child.x!,\n };\n });\n\n const currentCenter =\n (children[0].x! + children[children.length - 1].x!) / 2;\n\n const positions: number[] = [0];\n for (let i = 1; i < children.length; i++) {\n const prevRight = positions[i - 1] + extents[i - 1].relRight;\n positions[i] = prevRight + H_GAP - extents[i].relLeft;\n }\n\n const newCenter =\n (positions[0] + positions[positions.length - 1]) / 2;\n const centerShift = currentCenter - newCenter;\n\n for (let i = 0; i < children.length; i++) {\n const newX = positions[i] + centerShift;\n const dx = newX - children[i].x!;\n if (Math.abs(dx) > 0.001) {\n shiftX(children[i], dx);\n }\n }\n }\n }\n\n // Post-layout: center each parent exactly over its direct children.\n // d3-hierarchy centers over the subtree centroid, which drifts when\n // grandchildren have asymmetric widths. Process bottom-up so parents\n // see already-adjusted child positions.\n {\n const parentNodes = h\n .descendants()\n .filter(\n (d) =>\n d.children &&\n d.children.length >= 1 &&\n d.data.orgNode.id !== '__virtual_root__'\n )\n .sort((a, b) => b.depth - a.depth);\n\n for (const parent of parentNodes) {\n const childXs = parent.children!.map((c) => c.x!);\n const desiredX = (Math.min(...childXs) + Math.max(...childXs)) / 2;\n parent.x = desiredX;\n }\n }\n\n // Collect positioned nodes and edges\n const layoutNodes: OrgLayoutNode[] = [];\n const layoutEdges: OrgLayoutEdge[] = [];\n\n // Find bounding box and build outputs\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n\n // Expand leaf container stacks: compute individual child positions\n // in d3 coordinate space (before offset) so bounding box is correct\n interface ExpandedChild {\n orgNode: OrgNode;\n width: number;\n height: number;\n cx: number;\n cy: number;\n }\n const expandedChildren: ExpandedChild[] = [];\n\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (!d.data.orgNode.id.startsWith('__stack_')) continue;\n\n const containerId = d.data.orgNode.id.replace('__stack_', '');\n const stack = leafStacks.get(containerId);\n if (!stack) continue;\n\n let currentY = d.y!;\n for (const child of stack.children) {\n expandedChildren.push({\n orgNode: child.orgNode,\n width: child.width,\n height: child.height,\n cx: d.x!,\n cy: currentY,\n });\n currentY += child.height + STACK_V_GAP;\n }\n }\n\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (d.data.orgNode.id.startsWith('__stack_')) continue;\n\n const w = d.data.width;\n const ht = d.data.height;\n const cx = d.x!;\n const cy = d.y!;\n\n if (cx - w / 2 < minX) minX = cx - w / 2;\n if (cx + w / 2 > maxX) maxX = cx + w / 2;\n if (cy < minY) minY = cy;\n if (cy + ht > maxY) maxY = cy + ht;\n }\n\n for (const ec of expandedChildren) {\n if (ec.cx - ec.width / 2 < minX) minX = ec.cx - ec.width / 2;\n if (ec.cx + ec.width / 2 > maxX) maxX = ec.cx + ec.width / 2;\n if (ec.cy < minY) minY = ec.cy;\n if (ec.cy + ec.height > maxY) maxY = ec.cy + ec.height;\n }\n\n // Translate so all coordinates are positive, starting at MARGIN\n const offsetX = -minX + MARGIN;\n const offsetY = -minY + MARGIN;\n\n // Add expanded stack children as layout nodes\n const subNodeKey = subNodeLabel ?? 'Sub-node Count';\n for (const ec of expandedChildren) {\n const hc = hiddenCounts?.get(ec.orgNode.id);\n const meta = filterMetadata(ec.orgNode.metadata, hiddenAttributes);\n if (!ec.orgNode.isContainer && showSubNodeCount && !(hc != null && hc > 0)) {\n const count = countDescendantNodes(ec.orgNode, hiddenCounts);\n if (count > 0) meta[subNodeKey] = String(count);\n }\n layoutNodes.push({\n id: ec.orgNode.id,\n label: ec.orgNode.label,\n metadata: meta,\n isContainer: ec.orgNode.isContainer,\n lineNumber: ec.orgNode.lineNumber,\n color: resolveNodeColor(ec.orgNode, parsed.tagGroups, activeTagGroup ?? null),\n x: ec.cx + offsetX,\n y: ec.cy + offsetY,\n width: ec.width,\n height: ec.height,\n hiddenCount: hc,\n hasChildren: (ec.orgNode.children.length > 0 || (hc != null && hc > 0)) || undefined,\n });\n }\n\n // Map parent ID → { parentX, parentBottomY, children[] } for bus-style edges\n const busGroups = new Map<\n string,\n {\n parentX: number;\n parentBottomY: number;\n children: { id: string; x: number; topY: number }[];\n }\n >();\n\n for (const d of h.descendants()) {\n if (d.data.orgNode.id === '__virtual_root__') continue;\n if (d.data.orgNode.id.startsWith('__stack_')) continue;\n\n const orgNode = d.data.orgNode;\n const w = d.data.width;\n const ht = d.data.height;\n const x = d.x! + offsetX;\n const y = d.y! + offsetY;\n\n const hc = hiddenCounts?.get(orgNode.id);\n const nodeMeta = filterMetadata(orgNode.metadata, hiddenAttributes);\n if (!orgNode.isContainer && showSubNodeCount && !(hc != null && hc > 0)) {\n const count = countDescendantNodes(orgNode, hiddenCounts);\n if (count > 0) nodeMeta[subNodeKey] = String(count);\n }\n layoutNodes.push({\n id: orgNode.id,\n label: orgNode.label,\n metadata: nodeMeta,\n isContainer: orgNode.isContainer,\n lineNumber: orgNode.lineNumber,\n color: resolveNodeColor(orgNode, parsed.tagGroups, activeTagGroup ?? null),\n x,\n y,\n width: w,\n height: ht,\n hiddenCount: hc,\n hasChildren: (d.children != null && d.children.length > 0) || (hc != null && hc > 0) || undefined,\n });\n\n // Collect children per parent for bus-style edge generation\n const parentIsContainerBox =\n d.parent?.data.orgNode.isContainer &&\n d.parent.children &&\n d.parent.children.length > 0;\n if (\n d.parent &&\n d.parent.data.orgNode.id !== '__virtual_root__' &&\n !parentIsContainerBox\n ) {\n const parentId = d.parent.data.orgNode.id;\n if (!busGroups.has(parentId)) {\n const px = d.parent.x! + offsetX;\n const py = d.parent.y! + offsetY;\n const parentH = d.parent.data.height;\n busGroups.set(parentId, {\n parentX: px,\n parentBottomY: py + parentH,\n children: [],\n });\n }\n busGroups.get(parentId)!.children.push({\n id: orgNode.id,\n x,\n topY: y,\n });\n }\n }\n\n // Generate non-overlapping edges using bus pattern\n for (const [parentId, group] of busGroups) {\n const { parentX, parentBottomY, children } = group;\n\n if (children.length === 1) {\n // Single child: simple elbow (no overlap possible)\n const child = children[0];\n const midY = (parentBottomY + child.topY) / 2;\n layoutEdges.push({\n sourceId: parentId,\n targetId: child.id,\n points: [\n { x: parentX, y: parentBottomY },\n { x: parentX, y: midY },\n { x: child.x, y: midY },\n { x: child.x, y: child.topY },\n ],\n });\n } else {\n // Bus pattern: trunk + horizontal bar + per-child drops\n const midY = (parentBottomY + children[0].topY) / 2;\n const childXs = children.map((c) => c.x);\n const leftX = Math.min(...childXs);\n const rightX = Math.max(...childXs);\n\n // Trunk: parent bottom → midY\n layoutEdges.push({\n sourceId: parentId,\n targetId: parentId,\n points: [\n { x: parentX, y: parentBottomY },\n { x: parentX, y: midY },\n ],\n });\n\n // Horizontal bus: leftmost child → rightmost child at midY\n layoutEdges.push({\n sourceId: parentId,\n targetId: parentId,\n points: [\n { x: leftX, y: midY },\n { x: rightX, y: midY },\n ],\n });\n\n // Drops: midY → child top for each child\n for (const child of children) {\n layoutEdges.push({\n sourceId: parentId,\n targetId: child.id,\n points: [\n { x: child.x, y: midY },\n { x: child.x, y: child.topY },\n ],\n });\n }\n }\n }\n\n // Compute container bounds from d3 hierarchy (bottom-up so inner\n // container boxes are available when computing outer containers)\n const allContainerNodes = h.descendants().filter(\n (d) =>\n d.data.orgNode.id !== '__virtual_root__' &&\n d.data.orgNode.isContainer\n );\n\n // Map from node ID to computed visual bounds (offset-space)\n const containerBoundsMap = new Map<\n string,\n { minX: number; maxX: number; minY: number; maxY: number }\n >();\n\n const containers: OrgContainerBounds[] = [];\n\n // First pass: childless containers — simple boxes at their own position.\n // Must be computed before parent containers so their bounds are available.\n const EMPTY_CONTAINER_MIN_HEIGHT = 60;\n for (const d of allContainerNodes) {\n if (d.children && d.children.length > 0) continue;\n\n const cx = d.x! + offsetX;\n const cy = d.y! + offsetY;\n const metaCount = Object.keys(d.data.orgNode.metadata).length;\n const labelHeight =\n CONTAINER_LABEL_HEIGHT + metaCount * CONTAINER_META_LINE_HEIGHT;\n const boxWidth = d.data.width;\n const boxHeight = Math.max(labelHeight + CONTAINER_PAD_BOTTOM, EMPTY_CONTAINER_MIN_HEIGHT);\n const boxX = cx - boxWidth / 2;\n const boxY = cy;\n\n containerBoundsMap.set(d.data.orgNode.id, {\n minX: boxX,\n maxX: boxX + boxWidth,\n minY: boxY,\n maxY: boxY + boxHeight,\n });\n\n const chc = hiddenCounts?.get(d.data.orgNode.id);\n const cMeta = filterMetadata(d.data.orgNode.metadata, hiddenAttributes);\n containers.push({\n nodeId: d.data.orgNode.id,\n label: d.data.orgNode.label,\n lineNumber: d.data.orgNode.lineNumber,\n color: resolveNodeColor(d.data.orgNode, parsed.tagGroups, activeTagGroup ?? null),\n metadata: cMeta,\n x: boxX,\n y: boxY,\n width: boxWidth,\n height: boxHeight,\n labelHeight,\n hiddenCount: chc,\n hasChildren: (chc != null && chc > 0) || undefined,\n });\n }\n\n // Second pass: containers with children, deepest first\n const containerCandidates = allContainerNodes.filter(\n (d) => d.children && d.children.length > 0\n );\n containerCandidates.sort((a, b) => b.depth - a.depth);\n\n for (const d of containerCandidates) {\n // Collect all descendants (not just direct children)\n const allDesc: typeof d[] = [];\n const collectDesc = (node: typeof d) => {\n if (node.children) {\n for (const child of node.children) {\n allDesc.push(child);\n collectDesc(child);\n }\n }\n };\n collectDesc(d);\n\n if (allDesc.length === 0) continue;\n\n // Compute bounding box from all descendants, using inner container\n // bounds when available (so nested boxes don't overlap)\n let descMinX = Infinity;\n let descMaxX = -Infinity;\n let descMaxY = -Infinity;\n\n for (const desc of allDesc) {\n const innerBounds = containerBoundsMap.get(desc.data.orgNode.id);\n if (innerBounds) {\n // Use the inner container's expanded box\n if (innerBounds.minX < descMinX) descMinX = innerBounds.minX;\n if (innerBounds.maxX > descMaxX) descMaxX = innerBounds.maxX;\n if (innerBounds.maxY > descMaxY) descMaxY = innerBounds.maxY;\n } else if (desc.data.orgNode.id.startsWith('__stack_')) {\n // Use expanded children positions for stack placeholders\n const cid = desc.data.orgNode.id.replace('__stack_', '');\n const stack = leafStacks.get(cid);\n if (stack) {\n for (const ec of expandedChildren) {\n if (ec.orgNode.parentId !== cid) continue;\n const ex = ec.cx + offsetX;\n const ey = ec.cy + offsetY;\n if (ex - ec.width / 2 < descMinX) descMinX = ex - ec.width / 2;\n if (ex + ec.width / 2 > descMaxX) descMaxX = ex + ec.width / 2;\n if (ey + ec.height > descMaxY) descMaxY = ey + ec.height;\n }\n }\n } else {\n // Use card dimensions\n const dw = desc.data.width;\n const dh = desc.data.height;\n const dx = desc.x! + offsetX;\n const dy = desc.y! + offsetY;\n\n if (dx - dw / 2 < descMinX) descMinX = dx - dw / 2;\n if (dx + dw / 2 > descMaxX) descMaxX = dx + dw / 2;\n if (dy + dh > descMaxY) descMaxY = dy + dh;\n }\n }\n\n const containerX = d.x! + offsetX;\n const containerY = d.y! + offsetY;\n const metaCount = Object.keys(d.data.orgNode.metadata).length;\n const labelHeight =\n CONTAINER_LABEL_HEIGHT + metaCount * CONTAINER_META_LINE_HEIGHT;\n\n // Box top = container's own y, extends to cover all children\n const boxY = containerY;\n const boxHeight = descMaxY - containerY + CONTAINER_PAD_BOTTOM;\n\n // Tight-fit box around content with padding\n const boxX = descMinX - CONTAINER_PAD_X;\n const contentWidth = descMaxX - descMinX + CONTAINER_PAD_X * 2;\n const finalBoxWidth = Math.max(contentWidth, d.data.width);\n // Center the box if the label is wider than the content\n const centeredBoxX =\n finalBoxWidth > contentWidth\n ? containerX - finalBoxWidth / 2\n : boxX;\n\n // Store bounds for parent containers to reference\n containerBoundsMap.set(d.data.orgNode.id, {\n minX: centeredBoxX,\n maxX: centeredBoxX + finalBoxWidth,\n minY: boxY,\n maxY: boxY + boxHeight,\n });\n\n const chc2 = hiddenCounts?.get(d.data.orgNode.id);\n const cMeta2 = filterMetadata(d.data.orgNode.metadata, hiddenAttributes);\n containers.push({\n nodeId: d.data.orgNode.id,\n label: d.data.orgNode.label,\n lineNumber: d.data.orgNode.lineNumber,\n color: resolveNodeColor(d.data.orgNode, parsed.tagGroups, activeTagGroup ?? null),\n metadata: cMeta2,\n x: centeredBoxX,\n y: boxY,\n width: finalBoxWidth,\n height: boxHeight,\n labelHeight,\n hiddenCount: chc2,\n hasChildren: true,\n });\n }\n\n // Reverse so outer containers render first (behind inner containers)\n containers.reverse();\n\n // Bounding box — expand for container backgrounds that may extend beyond nodes\n // Convert container coords (offset space) back to pre-offset space for comparison\n let finalMinX = minX;\n let finalMaxX = maxX;\n let finalMaxY = maxY;\n for (const c of containers) {\n const cLeft = c.x - offsetX;\n const cRight = cLeft + c.width;\n const cBottom = c.y - offsetY + c.height;\n if (cLeft < finalMinX) finalMinX = cLeft;\n if (cRight > finalMaxX) finalMaxX = cRight;\n if (cBottom > finalMaxY) finalMaxY = cBottom;\n }\n\n const totalWidth = finalMaxX - finalMinX + MARGIN * 2;\n const totalHeight = finalMaxY - minY + MARGIN * 2;\n\n // Compute legend for tag groups\n const showEyeIcons = hiddenAttributes !== undefined;\n const legendGroups = computeLegendGroups(parsed.tagGroups, showEyeIcons);\n let finalWidth = totalWidth;\n let finalHeight = totalHeight;\n\n const legendPosition = parsed.options?.['legend-position'] ?? 'bottom';\n\n // When a tag group is active, only that group is laid out (full size).\n // When none is active, all groups are laid out minified.\n const visibleGroups = activeTagGroup != null\n ? legendGroups.filter((g) => g.name.toLowerCase() === activeTagGroup.toLowerCase())\n : legendGroups;\n const effectiveW = (g: OrgLegendGroup) =>\n activeTagGroup != null ? g.width : g.minifiedWidth;\n const effectiveH = (g: OrgLegendGroup) =>\n activeTagGroup != null ? g.height : g.minifiedHeight;\n\n if (visibleGroups.length > 0) {\n if (legendPosition === 'bottom') {\n // Bottom: center legend groups horizontally below diagram content\n const totalGroupsWidth =\n visibleGroups.reduce((s, g) => s + effectiveW(g), 0) +\n (visibleGroups.length - 1) * H_GAP;\n const neededWidth = totalGroupsWidth + MARGIN * 2;\n\n if (neededWidth > totalWidth) {\n finalWidth = neededWidth;\n const shift = (finalWidth - totalWidth) / 2;\n for (const n of layoutNodes) n.x += shift;\n for (const c of containers) c.x += shift;\n for (const e of layoutEdges) {\n for (const p of e.points) p.x += shift;\n }\n }\n\n const contentBottom = totalHeight - MARGIN;\n const legendY = contentBottom + LEGEND_GAP;\n const startX = (finalWidth - totalGroupsWidth) / 2;\n\n let cx = startX;\n let maxH = 0;\n for (const g of visibleGroups) {\n g.x = cx;\n g.y = legendY;\n cx += effectiveW(g) + H_GAP;\n const h = effectiveH(g);\n if (h > maxH) maxH = h;\n }\n\n finalHeight = totalHeight + LEGEND_GAP + maxH;\n } else {\n // Top (default): stack legend groups vertically at top-right\n const maxLegendWidth = Math.max(...visibleGroups.map((g) => effectiveW(g)));\n const legendStartX = totalWidth - MARGIN + LEGEND_GAP;\n let legendY = MARGIN;\n\n for (const g of visibleGroups) {\n g.x = legendStartX;\n g.y = legendY;\n legendY += effectiveH(g) + LEGEND_V_GAP;\n }\n\n const legendRight = legendStartX + maxLegendWidth + MARGIN;\n if (legendRight > finalWidth) {\n finalWidth = legendRight;\n }\n\n const legendBottom = legendY - LEGEND_V_GAP + MARGIN;\n if (legendBottom > finalHeight) {\n finalHeight = legendBottom;\n }\n }\n }\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n containers,\n legend: legendGroups,\n width: finalWidth,\n height: finalHeight,\n };\n}\n","// ============================================================\n// Org Chart Collapse/Expand — prune subtrees of collapsed nodes\n// ============================================================\n\nimport type { OrgNode, ParsedOrg } from './parser';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface CollapsedOrgResult {\n /** ParsedOrg with collapsed subtrees pruned (deep-cloned, never mutates original) */\n parsed: ParsedOrg;\n /** nodeId → count of hidden descendants */\n hiddenCounts: Map<string, number>;\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction cloneNode(node: OrgNode): OrgNode {\n return {\n id: node.id,\n label: node.label,\n metadata: { ...node.metadata },\n children: node.children.map(cloneNode),\n parentId: node.parentId,\n isContainer: node.isContainer,\n lineNumber: node.lineNumber,\n color: node.color,\n };\n}\n\nfunction countDescendants(node: OrgNode): number {\n let count = 0;\n for (const child of node.children) {\n count += (child.isContainer ? 0 : 1) + countDescendants(child);\n }\n return count;\n}\n\n/** Compute hidden counts from the ORIGINAL (unpruned) tree so nested\n * collapses don't lose ancestor descendant totals. */\nfunction computeHiddenCounts(\n nodes: OrgNode[],\n collapsedIds: Set<string>,\n hiddenCounts: Map<string, number>\n): void {\n for (const node of nodes) {\n if (collapsedIds.has(node.id) && node.children.length > 0) {\n hiddenCounts.set(node.id, countDescendants(node));\n }\n computeHiddenCounts(node.children, collapsedIds, hiddenCounts);\n }\n}\n\n/** Remove children of collapsed nodes on the cloned tree. */\nfunction pruneCollapsed(\n node: OrgNode,\n collapsedIds: Set<string>\n): void {\n for (const child of node.children) {\n pruneCollapsed(child, collapsedIds);\n }\n if (collapsedIds.has(node.id) && node.children.length > 0) {\n node.children = [];\n }\n}\n\n// ============================================================\n// Main\n// ============================================================\n\nexport function collapseOrgTree(\n original: ParsedOrg,\n collapsedIds: Set<string>\n): CollapsedOrgResult {\n const hiddenCounts = new Map<string, number>();\n\n if (collapsedIds.size === 0) {\n return { parsed: original, hiddenCounts };\n }\n\n // Compute counts from the ORIGINAL tree before any pruning\n computeHiddenCounts(original.roots, collapsedIds, hiddenCounts);\n\n // Deep-clone roots and prune collapsed subtrees\n const clonedRoots = original.roots.map(cloneNode);\n for (const root of clonedRoots) {\n pruneCollapsed(root, collapsedIds);\n }\n\n return {\n parsed: {\n ...original,\n roots: clonedRoots,\n },\n hiddenCounts,\n };\n}\n","// ============================================================\n// Org Chart SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport type { ParsedOrg } from './parser';\nimport type { OrgLayoutResult, OrgLayoutNode } from './layout';\nimport { parseOrg } from './parser';\nimport { layoutOrg } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst MAX_SCALE = 3;\nconst TITLE_HEIGHT = 30;\nconst TITLE_FONT_SIZE = 18;\nconst LABEL_FONT_SIZE = 13;\nconst META_FONT_SIZE = 11;\nconst META_LINE_HEIGHT = 16;\nconst HEADER_HEIGHT = 28;\nconst SEPARATOR_GAP = 6;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst CARD_RADIUS = 6;\nconst CONTAINER_RADIUS = 8;\nconst CONTAINER_LABEL_FONT_SIZE = 13;\nconst CONTAINER_META_FONT_SIZE = 11;\nconst CONTAINER_META_LINE_HEIGHT = 16;\nconst CONTAINER_HEADER_HEIGHT = 28;\n\n// Collapsed-node accent bar\nconst COLLAPSE_BAR_HEIGHT = 6;\nconst COLLAPSE_BAR_INSET = 0;\n\n// Legend\nconst LEGEND_RADIUS = 6;\nconst LEGEND_DOT_R = 5;\nconst LEGEND_DOT_TEXT_GAP = 6;\nconst LEGEND_ENTRY_GAP = 12;\nconst LEGEND_PAD = 10;\nconst LEGEND_HEADER_H = 20;\nconst LEGEND_ENTRY_H = 18;\nconst LEGEND_FONT_SIZE = 11;\nconst LEGEND_MAX_PER_ROW = 3;\nconst LEGEND_CHAR_WIDTH = 7.5;\n\n// Eye icon (12×12 viewBox, scaled from 0,0 to 12,12)\nconst EYE_ICON_SIZE = 12;\nconst EYE_ICON_GAP = 6;\n// Open eye: elliptical outline + circle pupil\nconst EYE_OPEN_PATH =\n 'M1 6C1 6 3 2 6 2C9 2 11 6 11 6C11 6 9 10 6 10C3 10 1 6 1 6Z';\nconst EYE_PUPIL_CX = 6;\nconst EYE_PUPIL_CY = 6;\nconst EYE_PUPIL_R = 1.8;\n// Closed eye: same outline + diagonal slash\nconst EYE_SLASH_PATH = 'M2 2L10 10';\n\n// ============================================================\n// Color helpers (inline to avoid cross-module import issues)\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0] + r[0] + r[1] + r[1] + r[2] + r[2] : r;\n return [\n parseInt(f.substring(0, 2), 16),\n parseInt(f.substring(2, 4), 16),\n parseInt(f.substring(4, 6), 16),\n ];\n };\n const [ar, ag, ab] = parse(a),\n [br, bg, bb] = parse(b),\n t = pct / 100;\n const c = (x: number, y: number) =>\n Math.round(x * t + y * (1 - t))\n .toString(16)\n .padStart(2, '0');\n return `#${c(ar, br)}${c(ag, bg)}${c(ab, bb)}`;\n}\n\nfunction nodeFill(\n palette: PaletteColors,\n isDark: boolean,\n nodeColor?: string\n): string {\n if (nodeColor) {\n return mix(nodeColor, isDark ? palette.surface : palette.bg, 25);\n }\n return mix(palette.primary, isDark ? palette.surface : palette.bg, 15);\n}\n\nfunction nodeStroke(palette: PaletteColors, nodeColor?: string): string {\n return nodeColor ?? palette.textMuted;\n}\n\nfunction containerFill(\n palette: PaletteColors,\n isDark: boolean,\n nodeColor?: string\n): string {\n if (nodeColor) {\n return mix(nodeColor, isDark ? palette.surface : palette.bg, 10);\n }\n return mix(palette.surface, palette.bg, 40);\n}\n\nfunction containerStroke(palette: PaletteColors, nodeColor?: string): string {\n return nodeColor ?? palette.textMuted;\n}\n\n// ============================================================\n// Main Renderer\n// ============================================================\n\ntype GSelection = d3Selection.Selection<SVGGElement, unknown, null, undefined>;\n\nexport function renderOrg(\n container: HTMLDivElement,\n parsed: ParsedOrg,\n layout: OrgLayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number },\n activeTagGroup?: string | null,\n hiddenAttributes?: Set<string>\n): void {\n // Clear existing content\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleOffset = parsed.title ? TITLE_HEIGHT : 0;\n\n // Compute scale to fit diagram in viewport\n const diagramW = layout.width;\n const diagramH = layout.height + titleOffset;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (height - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(MAX_SCALE, scaleX, scaleY);\n\n // Center the diagram\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = DIAGRAM_PADDING;\n\n // Create SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // Main content group with scale/translate\n const mainG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // Title\n if (parsed.title) {\n const titleEl = mainG\n .append('text')\n .attr('x', diagramW / 2)\n .attr('y', TITLE_FONT_SIZE)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', TITLE_FONT_SIZE)\n .attr('font-weight', 'bold')\n .attr('class', 'org-title chart-title')\n .style(\n 'cursor',\n onClickItem && parsed.titleLineNumber ? 'pointer' : 'default'\n )\n .text(parsed.title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n }\n }\n }\n\n // Content group (offset by title)\n const contentG = mainG\n .append('g')\n .attr('transform', `translate(0, ${titleOffset})`);\n\n // Build display name map from tag groups (lowercase key → original casing)\n const displayNames = new Map<string, string>();\n for (const group of parsed.tagGroups) {\n displayNames.set(group.name.toLowerCase(), group.name);\n }\n\n // Render container backgrounds (bottom layer)\n const colorOff = parsed.options?.color === 'off';\n for (const c of layout.containers) {\n const cG = contentG\n .append('g')\n .attr('transform', `translate(${c.x}, ${c.y})`)\n .attr('class', 'org-container')\n .attr('data-line-number', String(c.lineNumber)) as GSelection;\n\n // Toggle attribute for containers that have (or had) children\n if (c.hasChildren) {\n cG.attr('data-node-toggle', c.nodeId)\n .attr('tabindex', '0')\n .attr('role', 'button')\n .attr(\n 'aria-expanded',\n String(!c.hiddenCount)\n )\n .attr('aria-label', c.label);\n }\n\n if (onClickItem) {\n cG.style('cursor', 'pointer').on('click', () => {\n onClickItem(c.lineNumber);\n });\n }\n\n const fill = containerFill(palette, isDark, colorOff ? undefined : c.color);\n const stroke = containerStroke(palette, colorOff ? undefined : c.color);\n\n // Background rect\n cG.append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', c.width)\n .attr('height', c.height)\n .attr('rx', CONTAINER_RADIUS)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-opacity', 0.35)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Container label (bold, at top)\n cG.append('text')\n .attr('x', c.width / 2)\n .attr('y', CONTAINER_HEADER_HEIGHT / 2 + CONTAINER_LABEL_FONT_SIZE / 2 - 2)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', CONTAINER_LABEL_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(c.label);\n\n // Container metadata (below label)\n const metaEntries = Object.entries(c.metadata);\n if (metaEntries.length > 0) {\n // Compute max key width so values align vertically\n const metaDisplayKeys = metaEntries.map(([k]) => displayNames.get(k) ?? k);\n const maxKeyLen = Math.max(...metaDisplayKeys.map((k) => k.length));\n const valueX = 10 + (maxKeyLen + 2) * (CONTAINER_META_FONT_SIZE * 0.6);\n\n const metaStartY = CONTAINER_HEADER_HEIGHT + CONTAINER_META_FONT_SIZE - 2;\n for (let i = 0; i < metaEntries.length; i++) {\n const [, value] = metaEntries[i];\n const displayKey = metaDisplayKeys[i];\n const rowY = metaStartY + i * CONTAINER_META_LINE_HEIGHT;\n\n cG.append('text')\n .attr('x', 10)\n .attr('y', rowY)\n .attr('fill', palette.textMuted)\n .attr('font-size', CONTAINER_META_FONT_SIZE)\n .text(`${displayKey}: `);\n\n cG.append('text')\n .attr('x', valueX)\n .attr('y', rowY)\n .attr('fill', palette.text)\n .attr('font-size', CONTAINER_META_FONT_SIZE)\n .text(value);\n }\n }\n\n // Collapsed accent bar (interactive only), clipped to card shape\n if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {\n const clipId = `clip-${c.nodeId}`;\n cG.append('clipPath').attr('id', clipId)\n .append('rect')\n .attr('width', c.width).attr('height', c.height)\n .attr('rx', CONTAINER_RADIUS);\n cG.append('rect')\n .attr('x', COLLAPSE_BAR_INSET)\n .attr('y', c.height - COLLAPSE_BAR_HEIGHT)\n .attr('width', c.width - COLLAPSE_BAR_INSET * 2)\n .attr('height', COLLAPSE_BAR_HEIGHT)\n .attr('fill', containerStroke(palette, colorOff ? undefined : c.color))\n .attr('clip-path', `url(#${clipId})`)\n .attr('class', 'org-collapse-bar');\n }\n\n }\n\n // Render edges\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n\n const pathParts: string[] = [];\n pathParts.push(`M ${edge.points[0].x} ${edge.points[0].y}`);\n for (let i = 1; i < edge.points.length; i++) {\n pathParts.push(`L ${edge.points[i].x} ${edge.points[i].y}`);\n }\n\n contentG\n .append('path')\n .attr('d', pathParts.join(' '))\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('class', 'org-edge');\n }\n\n // Collect container node IDs so we can skip them in card rendering\n const containerNodeIds = new Set(layout.containers.map((c) => c.nodeId));\n\n // Render node cards (top layer) — skip containers (already drawn as background boxes)\n for (const node of layout.nodes) {\n if (containerNodeIds.has(node.id)) continue;\n\n const nodeG = contentG\n .append('g')\n .attr(\n 'transform',\n `translate(${node.x - node.width / 2}, ${node.y})`\n )\n .attr('class', 'org-node')\n .attr('data-line-number', String(node.lineNumber)) as GSelection;\n\n // Toggle attribute for nodes that have (or had) children\n if (node.hasChildren) {\n nodeG\n .attr('data-node-toggle', node.id)\n .attr('tabindex', '0')\n .attr('role', 'button')\n .attr('aria-expanded', String(!node.hiddenCount))\n .attr('aria-label', node.label);\n }\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n // Card background\n const fill = nodeFill(palette, isDark, colorOff ? undefined : node.color);\n const stroke = nodeStroke(palette, colorOff ? undefined : node.color);\n\n const rect = nodeG\n .append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', node.width)\n .attr('height', node.height)\n .attr('rx', CARD_RADIUS)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Container nodes: dashed border\n if (node.isContainer) {\n rect.attr('stroke-dasharray', '6 3');\n }\n\n // Label\n nodeG\n .append('text')\n .attr('x', node.width / 2)\n .attr('y', HEADER_HEIGHT / 2 + LABEL_FONT_SIZE / 2 - 2)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', LABEL_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(node.label);\n\n // Metadata\n const metaEntries = Object.entries(node.metadata);\n if (metaEntries.length > 0) {\n // Header separator line\n nodeG\n .append('line')\n .attr('x1', 0)\n .attr('y1', HEADER_HEIGHT)\n .attr('x2', node.width)\n .attr('y2', HEADER_HEIGHT)\n .attr('stroke', stroke)\n .attr('stroke-opacity', 0.3)\n .attr('stroke-width', 1);\n\n // Metadata rows — compute max key width so values align vertically\n const metaDisplayKeys = metaEntries.map(([k]) => displayNames.get(k) ?? k);\n const maxKeyLen = Math.max(...metaDisplayKeys.map((k) => k.length));\n const valueX = 10 + (maxKeyLen + 2) * (META_FONT_SIZE * 0.6);\n\n const metaStartY = HEADER_HEIGHT + SEPARATOR_GAP + META_FONT_SIZE;\n for (let i = 0; i < metaEntries.length; i++) {\n const [, value] = metaEntries[i];\n const displayKey = metaDisplayKeys[i];\n const rowY = metaStartY + i * META_LINE_HEIGHT;\n\n // Key (muted)\n nodeG\n .append('text')\n .attr('x', 10)\n .attr('y', rowY)\n .attr('fill', palette.textMuted)\n .attr('font-size', META_FONT_SIZE)\n .text(`${displayKey}: `);\n\n // Value (normal)\n nodeG\n .append('text')\n .attr('x', valueX)\n .attr('y', rowY)\n .attr('fill', palette.text)\n .attr('font-size', META_FONT_SIZE)\n .text(value);\n }\n }\n\n // Collapsed accent bar (interactive only), clipped to card shape\n if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {\n const clipId = `clip-${node.id}`;\n nodeG.append('clipPath').attr('id', clipId)\n .append('rect')\n .attr('width', node.width).attr('height', node.height)\n .attr('rx', CARD_RADIUS);\n nodeG\n .append('rect')\n .attr('x', COLLAPSE_BAR_INSET)\n .attr('y', node.height - COLLAPSE_BAR_HEIGHT)\n .attr('width', node.width - COLLAPSE_BAR_INSET * 2)\n .attr('height', COLLAPSE_BAR_HEIGHT)\n .attr('fill', nodeStroke(palette, colorOff ? undefined : node.color))\n .attr('clip-path', `url(#${clipId})`)\n .attr('class', 'org-collapse-bar');\n }\n\n }\n\n // Render legend — skip entirely in export mode.\n // No active group: all groups rendered minified (compact chips).\n // Active group selected: only that group rendered (full size), others hidden.\n if (!exportDims) for (const group of layout.legend) {\n const isActive =\n activeTagGroup != null &&\n group.name.toLowerCase() === activeTagGroup.toLowerCase();\n\n // When a group is active, skip all other groups entirely\n if (activeTagGroup != null && !isActive) continue;\n\n // No active group → minified; active group → full\n const isMinified = activeTagGroup == null;\n\n const renderW = isMinified ? group.minifiedWidth : group.width;\n const renderH = isMinified ? group.minifiedHeight : group.height;\n\n const gEl = contentG\n .append('g')\n .attr('transform', `translate(${group.x}, ${group.y})`)\n .attr('class', 'org-legend-group')\n .attr('data-legend-group', group.name.toLowerCase())\n .style('cursor', 'pointer');\n\n // Background rect\n const legendFill = mix(palette.surface, palette.bg, 40);\n const bgRect = gEl\n .append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', renderW)\n .attr('height', renderH)\n .attr('rx', LEGEND_RADIUS)\n .attr('fill', legendFill);\n\n if (isActive) {\n bgRect\n .attr('stroke', palette.primary)\n .attr('stroke-opacity', 0.8)\n .attr('stroke-width', 2);\n } else {\n bgRect\n .attr('stroke', palette.textMuted)\n .attr('stroke-opacity', 0.35)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n }\n\n // Group name header\n gEl\n .append('text')\n .attr('x', LEGEND_PAD)\n .attr('y', LEGEND_HEADER_H / 2 + LEGEND_FONT_SIZE / 2 - 2)\n .attr('fill', isMinified ? palette.textMuted : palette.text)\n .attr('font-size', LEGEND_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(group.name);\n\n // Minified groups only show the header — skip entries and eye icon\n if (isMinified) continue;\n\n // Eye icon for visibility toggle (interactive only, not export)\n if (hiddenAttributes !== undefined && !exportDims) {\n const groupKey = group.name.toLowerCase();\n const isHidden = hiddenAttributes.has(groupKey);\n const eyeX =\n LEGEND_PAD + group.name.length * LEGEND_CHAR_WIDTH + EYE_ICON_GAP;\n const eyeY = (LEGEND_HEADER_H - EYE_ICON_SIZE) / 2;\n\n const eyeG = gEl\n .append('g')\n .attr('class', 'org-legend-eye')\n .attr('data-legend-visibility', groupKey)\n .attr('transform', `translate(${eyeX}, ${eyeY})`);\n\n // Transparent hit area\n eyeG\n .append('rect')\n .attr('x', -4)\n .attr('y', -4)\n .attr('width', EYE_ICON_SIZE + 8)\n .attr('height', EYE_ICON_SIZE + 8)\n .attr('fill', 'transparent');\n\n // Eye outline\n eyeG\n .append('path')\n .attr('d', EYE_OPEN_PATH)\n .attr('fill', isHidden ? 'none' : palette.textMuted)\n .attr('fill-opacity', isHidden ? 0 : 0.15)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.2)\n .attr('opacity', isHidden ? 0.5 : 0.7);\n\n if (!isHidden) {\n // Pupil (only when visible)\n eyeG\n .append('circle')\n .attr('cx', EYE_PUPIL_CX)\n .attr('cy', EYE_PUPIL_CY)\n .attr('r', EYE_PUPIL_R)\n .attr('fill', palette.textMuted)\n .attr('opacity', 0.7);\n } else {\n // Slash through the eye (hidden state)\n eyeG\n .append('line')\n .attr('x1', 2)\n .attr('y1', 2)\n .attr('x2', 10)\n .attr('y2', 10)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.5)\n .attr('opacity', 0.5);\n }\n }\n\n // Pre-compute column widths so dots align across rows\n const entryWidths = group.entries.map(\n (e) =>\n LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP + e.value.length * LEGEND_CHAR_WIDTH\n );\n const numRows = Math.ceil(group.entries.length / LEGEND_MAX_PER_ROW);\n const colWidths: number[] = [];\n for (let col = 0; col < LEGEND_MAX_PER_ROW; col++) {\n let maxW = 0;\n for (let r = 0; r < numRows; r++) {\n const idx = r * LEGEND_MAX_PER_ROW + col;\n if (idx < entryWidths.length && entryWidths[idx] > maxW) {\n maxW = entryWidths[idx];\n }\n }\n if (maxW > 0) colWidths.push(maxW);\n }\n const colX: number[] = [LEGEND_PAD];\n for (let c = 1; c < colWidths.length; c++) {\n colX.push(colX[c - 1] + colWidths[c - 1] + LEGEND_ENTRY_GAP);\n }\n\n // Entries: colored dot + value label\n for (let i = 0; i < group.entries.length; i++) {\n const entry = group.entries[i];\n const row = Math.floor(i / LEGEND_MAX_PER_ROW);\n const col = i % LEGEND_MAX_PER_ROW;\n const entryX = colX[col];\n\n const entryY =\n LEGEND_HEADER_H + row * LEGEND_ENTRY_H + LEGEND_ENTRY_H / 2;\n\n // Colored dot\n gEl\n .append('circle')\n .attr('cx', entryX + LEGEND_DOT_R)\n .attr('cy', entryY)\n .attr('r', LEGEND_DOT_R)\n .attr('fill', entry.color);\n\n // Value label\n gEl\n .append('text')\n .attr('x', entryX + LEGEND_DOT_R * 2 + LEGEND_DOT_TEXT_GAP)\n .attr('y', entryY + LEGEND_FONT_SIZE / 2 - 2)\n .attr('fill', palette.text)\n .attr('font-size', LEGEND_FONT_SIZE)\n .text(entry.value);\n }\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderOrgForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseOrg(content, palette);\n if (parsed.error || parsed.roots.length === 0) return '';\n\n // Extract hide option for export: cards sized without hidden attributes\n const hideOption = parsed.options?.['hide'];\n const exportHidden = hideOption\n ? new Set(hideOption.split(',').map((s) => s.trim().toLowerCase()))\n : undefined;\n\n const layout = layoutOrg(parsed, undefined, undefined, exportHidden);\n const isDark = theme === 'dark';\n\n // Create offscreen container\n const container = document.createElement('div');\n const titleOffset = parsed.title ? TITLE_HEIGHT : 0;\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight =\n layout.height + DIAGRAM_PADDING * 2 + titleOffset;\n\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n // No hiddenAttributes passed to renderOrg — export never shows eye icons\n renderOrg(container, parsed, layout, palette, isDark, undefined, {\n width: exportWidth,\n height: exportHeight,\n });\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n ParsedClassDiagram,\n ClassNode,\n ClassRelationship,\n RelationshipType,\n} from './types';\n\n// ============================================================\n// Layout types\n// ============================================================\n\nexport interface ClassLayoutNode extends ClassNode {\n x: number;\n y: number;\n width: number;\n height: number;\n headerHeight: number;\n fieldsHeight: number;\n methodsHeight: number;\n}\n\nexport interface ClassLayoutEdge {\n source: string;\n target: string;\n type: RelationshipType;\n points: { x: number; y: number }[];\n label?: string;\n lineNumber: number;\n}\n\nexport interface ClassLayoutResult {\n nodes: ClassLayoutNode[];\n edges: ClassLayoutEdge[];\n width: number;\n height: number;\n}\n\n// ============================================================\n// Sizing constants\n// ============================================================\n\nconst MIN_WIDTH = 140;\nconst CHAR_WIDTH = 7.5;\nconst PADDING_X = 24;\nconst HEADER_BASE = 36;\nconst MODIFIER_BADGE = 16; // extra height for <<interface>> etc.\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst SEPARATOR_HEIGHT = 1;\n\n// ============================================================\n// Node sizing\n// ============================================================\n\nfunction computeNodeDimensions(node: ClassNode): {\n width: number;\n height: number;\n headerHeight: number;\n fieldsHeight: number;\n methodsHeight: number;\n} {\n const fields = node.members.filter((m) => !m.isMethod);\n const methods = node.members.filter((m) => m.isMethod);\n const isEnum = node.modifier === 'enum';\n\n // Width: max of class name, member text lengths\n let maxTextLen = node.name.length;\n if (node.modifier) {\n maxTextLen = Math.max(maxTextLen, `<<${node.modifier}>>`.length);\n }\n for (const m of node.members) {\n let memberText = m.name;\n if (m.isMethod) {\n memberText += `(${m.params ?? ''})`;\n if (m.type) memberText += `: ${m.type}`;\n } else if (m.type) {\n memberText += `: ${m.type}`;\n }\n // Add visibility prefix width\n memberText = `+ ${memberText}`;\n maxTextLen = Math.max(maxTextLen, memberText.length);\n }\n const width = Math.max(MIN_WIDTH, maxTextLen * CHAR_WIDTH + PADDING_X);\n\n // Header height\n const headerHeight = HEADER_BASE + (node.modifier ? MODIFIER_BADGE : 0);\n\n // Fields compartment\n let fieldsHeight = 0;\n if (isEnum) {\n // Enum values go in fields compartment\n const enumValues = node.members; // all members are enum values\n if (enumValues.length > 0) {\n fieldsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n enumValues.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n } else {\n if (fields.length > 0) {\n fieldsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n fields.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n }\n\n // Methods compartment (not for enums)\n let methodsHeight = 0;\n if (!isEnum && methods.length > 0) {\n methodsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n methods.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n\n // If no members at all, add minimal padding\n const height =\n headerHeight +\n fieldsHeight +\n methodsHeight +\n (fieldsHeight === 0 && methodsHeight === 0 ? 4 : 0);\n\n return { width, height, headerHeight, fieldsHeight, methodsHeight };\n}\n\n// ============================================================\n// Layout engine\n// ============================================================\n\nexport function layoutClassDiagram(\n parsed: ParsedClassDiagram\n): ClassLayoutResult {\n if (parsed.classes.length === 0) {\n return { nodes: [], edges: [], width: 0, height: 0 };\n }\n\n const g = new dagre.graphlib.Graph();\n g.setGraph({\n rankdir: 'TB',\n nodesep: 60,\n ranksep: 80,\n edgesep: 20,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n // Compute dimensions and add nodes\n const dimMap = new Map<\n string,\n {\n width: number;\n height: number;\n headerHeight: number;\n fieldsHeight: number;\n methodsHeight: number;\n }\n >();\n\n for (const node of parsed.classes) {\n const dims = computeNodeDimensions(node);\n dimMap.set(node.id, dims);\n g.setNode(node.id, {\n label: node.name,\n width: dims.width,\n height: dims.height,\n });\n }\n\n // Add edges\n for (const rel of parsed.relationships) {\n g.setEdge(rel.source, rel.target, { label: rel.label ?? '' });\n }\n\n // Run layout\n dagre.layout(g);\n\n // Extract positioned nodes\n const layoutNodes: ClassLayoutNode[] = parsed.classes.map((node) => {\n const pos = g.node(node.id);\n const dims = dimMap.get(node.id)!;\n return {\n ...node,\n x: pos.x,\n y: pos.y,\n width: dims.width,\n height: dims.height,\n headerHeight: dims.headerHeight,\n fieldsHeight: dims.fieldsHeight,\n methodsHeight: dims.methodsHeight,\n };\n });\n\n // Extract edge waypoints\n const layoutEdges: ClassLayoutEdge[] = parsed.relationships.map((rel) => {\n const edgeData = g.edge(rel.source, rel.target);\n return {\n source: rel.source,\n target: rel.target,\n type: rel.type,\n points: edgeData?.points ?? [],\n label: rel.label,\n lineNumber: rel.lineNumber,\n };\n });\n\n // Compute total dimensions\n let totalWidth = 0;\n let totalHeight = 0;\n for (const node of layoutNodes) {\n const right = node.x + node.width / 2;\n const bottom = node.y + node.height / 2;\n if (right > totalWidth) totalWidth = right;\n if (bottom > totalHeight) totalHeight = bottom;\n }\n totalWidth += 40;\n totalHeight += 40;\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n width: totalWidth,\n height: totalHeight,\n };\n}\n","// ============================================================\n// Class Diagram SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport type { ParsedClassDiagram, ClassModifier, RelationshipType } from './types';\nimport type { ClassLayoutResult, ClassLayoutNode, ClassLayoutEdge } from './layout';\nimport { parseClassDiagram } from './parser';\nimport { layoutClassDiagram } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst MAX_SCALE = 3;\nconst CLASS_FONT_SIZE = 13;\nconst MEMBER_FONT_SIZE = 11;\nconst EDGE_LABEL_FONT_SIZE = 11;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst MEMBER_PADDING_X = 10;\n\n// ============================================================\n// Color helpers\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\nfunction modifierColor(modifier: ClassModifier | undefined, palette: PaletteColors, colorOff?: boolean): string {\n if (colorOff) return palette.textMuted;\n switch (modifier) {\n case 'interface': return palette.colors.blue;\n case 'abstract': return palette.colors.purple;\n case 'enum': return palette.colors.yellow;\n default: return palette.colors.teal;\n }\n}\n\nfunction nodeFill(palette: PaletteColors, isDark: boolean, modifier: ClassModifier | undefined, nodeColor?: string, colorOff?: boolean): string {\n const color = nodeColor ?? modifierColor(modifier, palette, colorOff);\n return mix(color, isDark ? palette.surface : palette.bg, 20);\n}\n\nfunction nodeStroke(palette: PaletteColors, modifier: ClassModifier | undefined, nodeColor?: string, colorOff?: boolean): string {\n return nodeColor ?? modifierColor(modifier, palette, colorOff);\n}\n\n// ============================================================\n// Visibility symbols\n// ============================================================\n\nfunction visibilitySymbol(vis: 'public' | 'private' | 'protected'): string {\n switch (vis) {\n case 'public': return '+';\n case 'private': return '-';\n case 'protected': return '#';\n }\n}\n\n// ============================================================\n// Edge path generator\n// ============================================================\n\nconst lineGenerator = d3Shape.line<{ x: number; y: number }>()\n .x((d) => d.x)\n .y((d) => d.y)\n .curve(d3Shape.curveBasis);\n\n// ============================================================\n// Edge line style\n// ============================================================\n\nfunction isDashedEdge(type: RelationshipType): boolean {\n return type === 'implements' || type === 'depends';\n}\n\nfunction markerIdForType(type: RelationshipType): string {\n switch (type) {\n case 'extends': return 'cd-arrow-inherit';\n case 'implements': return 'cd-arrow-implement';\n case 'composes': return 'cd-arrow-compose';\n case 'aggregates': return 'cd-arrow-aggregate';\n case 'depends': return 'cd-arrow-depend';\n case 'associates': return 'cd-arrow-assoc';\n }\n}\n\n// Where to place marker — source-end for compose/aggregate, target-end for others\nfunction isSourceMarker(type: RelationshipType): boolean {\n return type === 'composes' || type === 'aggregates';\n}\n\n// ============================================================\n// Main renderer\n// ============================================================\n\ntype GSelection = d3Selection.Selection<SVGGElement, unknown, null, undefined>;\n\nexport function renderClassDiagram(\n container: HTMLDivElement,\n parsed: ParsedClassDiagram,\n layout: ClassLayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number }\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = parsed.title ? 40 : 0;\n const diagramW = layout.width;\n const diagramH = layout.height;\n const availH = height - titleHeight;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (availH - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(MAX_SCALE, scaleX, scaleY);\n\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = titleHeight + (availH - scaledH) / 2;\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // ── Marker defs ──\n const defs = svg.append('defs');\n const AW = 12; // arrowhead width\n const AH = 8; // arrowhead height\n\n // Filled triangle (inheritance) — filled with stroke color\n defs.append('marker')\n .attr('id', 'cd-arrow-inherit')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', palette.textMuted)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Hollow triangle (implementation) — white/bg fill\n defs.append('marker')\n .attr('id', 'cd-arrow-implement')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', palette.bg)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Filled diamond (composition) — at source end\n const DW = 12;\n const DH = 8;\n defs.append('marker')\n .attr('id', 'cd-arrow-compose')\n .attr('viewBox', `0 0 ${DW} ${DH}`)\n .attr('refX', 0).attr('refY', DH / 2)\n .attr('markerWidth', DW).attr('markerHeight', DH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `${DW / 2},0 ${DW},${DH / 2} ${DW / 2},${DH} 0,${DH / 2}`)\n .attr('fill', palette.textMuted)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Hollow diamond (aggregation) — at source end\n defs.append('marker')\n .attr('id', 'cd-arrow-aggregate')\n .attr('viewBox', `0 0 ${DW} ${DH}`)\n .attr('refX', 0).attr('refY', DH / 2)\n .attr('markerWidth', DW).attr('markerHeight', DH)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `${DW / 2},0 ${DW},${DH / 2} ${DW / 2},${DH} 0,${DH / 2}`)\n .attr('fill', palette.bg)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1);\n\n // Open arrowhead (dependency)\n defs.append('marker')\n .attr('id', 'cd-arrow-depend')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polyline')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.5);\n\n // Open arrowhead (association)\n defs.append('marker')\n .attr('id', 'cd-arrow-assoc')\n .attr('viewBox', `0 0 ${AW} ${AH}`)\n .attr('refX', AW).attr('refY', AH / 2)\n .attr('markerWidth', AW).attr('markerHeight', AH)\n .attr('orient', 'auto')\n .append('polyline')\n .attr('points', `0,0 ${AW},${AH / 2} 0,${AH}`)\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.5);\n\n // ── Title ──\n if (parsed.title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(parsed.title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // ── Content group ──\n const contentG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // ── Edges (behind nodes) ──\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n\n const edgeG = contentG\n .append('g')\n .attr('class', 'cd-edge-group')\n .attr('data-line-number', String(edge.lineNumber));\n\n const edgeColor = palette.textMuted;\n const markerId = markerIdForType(edge.type);\n const dashed = isDashedEdge(edge.type);\n const sourceMarker = isSourceMarker(edge.type);\n\n const pathD = lineGenerator(edge.points);\n if (pathD) {\n const pathEl = edgeG\n .append('path')\n .attr('d', pathD)\n .attr('fill', 'none')\n .attr('stroke', edgeColor)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('class', 'cd-edge');\n\n if (dashed) {\n pathEl.attr('stroke-dasharray', '6 3');\n }\n\n if (sourceMarker) {\n pathEl.attr('marker-start', `url(#${markerId})`);\n } else {\n pathEl.attr('marker-end', `url(#${markerId})`);\n }\n }\n\n // Edge label at midpoint\n if (edge.label) {\n const midIdx = Math.floor(edge.points.length / 2);\n const midPt = edge.points[midIdx];\n const labelLen = edge.label.length;\n const bgW = labelLen * 7 + 8;\n const bgH = 16;\n\n edgeG.append('rect')\n .attr('x', midPt.x - bgW / 2)\n .attr('y', midPt.y - bgH / 2 - 1)\n .attr('width', bgW)\n .attr('height', bgH)\n .attr('rx', 3)\n .attr('fill', palette.bg)\n .attr('opacity', 0.85)\n .attr('class', 'cd-edge-label-bg');\n\n edgeG.append('text')\n .attr('x', midPt.x)\n .attr('y', midPt.y + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', edgeColor)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .attr('class', 'cd-edge-label')\n .text(edge.label);\n }\n }\n\n // ── Nodes (top layer) ──\n for (const node of layout.nodes) {\n const nodeG = contentG\n .append('g')\n .attr('transform', `translate(${node.x}, ${node.y})`)\n .attr('class', 'cd-class')\n .attr('data-line-number', String(node.lineNumber))\n .attr('data-node-id', node.id);\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n const w = node.width;\n const h = node.height;\n const colorOff = parsed.options?.color === 'off';\n const fill = nodeFill(palette, isDark, node.modifier, node.color, colorOff);\n const stroke = nodeStroke(palette, node.modifier, node.color, colorOff);\n\n // Outer rectangle\n nodeG.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Header section\n let yPos = -h / 2;\n const headerCenterY = yPos + node.headerHeight / 2;\n\n // Modifier badge <<interface>> etc.\n if (node.modifier) {\n const badgeText = `\\u00AB${node.modifier}\\u00BB`; // « »\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY - 6)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.textMuted)\n .attr('font-size', MEMBER_FONT_SIZE)\n .attr('font-style', 'italic')\n .text(badgeText);\n\n // Class name below badge\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY + 10)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', CLASS_FONT_SIZE)\n .attr('font-weight', 'bold')\n .attr('font-style', node.modifier === 'abstract' ? 'italic' : 'normal')\n .text(node.name);\n } else {\n // Just class name centered\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', CLASS_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(node.name);\n }\n\n yPos += node.headerHeight;\n\n const isEnum = node.modifier === 'enum';\n const fields = node.members.filter((m) => !m.isMethod);\n const methods = node.members.filter((m) => m.isMethod);\n\n if (isEnum) {\n // Enum: all members as values\n if (node.members.length > 0) {\n // Separator\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const member of node.members) {\n nodeG.append('text')\n .attr('x', -w / 2 + MEMBER_PADDING_X)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', MEMBER_FONT_SIZE)\n .text(member.name);\n memberY += MEMBER_LINE_HEIGHT;\n }\n }\n } else {\n // Fields compartment\n if (fields.length > 0) {\n // Separator\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const field of fields) {\n const vis = visibilitySymbol(field.visibility);\n let text = `${vis} ${field.name}`;\n if (field.type) text += `: ${field.type}`;\n\n const textEl = nodeG.append('text')\n .attr('x', -w / 2 + MEMBER_PADDING_X)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', MEMBER_FONT_SIZE);\n\n if (field.isStatic) {\n textEl.attr('text-decoration', 'underline');\n }\n textEl.text(text);\n\n memberY += MEMBER_LINE_HEIGHT;\n }\n yPos += node.fieldsHeight;\n }\n\n // Methods compartment\n if (methods.length > 0) {\n // Separator\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const method of methods) {\n const vis = visibilitySymbol(method.visibility);\n let text = `${vis} ${method.name}(${method.params ?? ''})`;\n if (method.type) text += `: ${method.type}`;\n\n const textEl = nodeG.append('text')\n .attr('x', -w / 2 + MEMBER_PADDING_X)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', MEMBER_FONT_SIZE);\n\n if (method.isStatic) {\n textEl.attr('text-decoration', 'underline');\n }\n textEl.text(text);\n\n memberY += MEMBER_LINE_HEIGHT;\n }\n }\n }\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderClassDiagramForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseClassDiagram(content, palette);\n if (parsed.error || parsed.classes.length === 0) return '';\n\n const layout = layoutClassDiagram(parsed);\n const isDark = theme === 'dark';\n\n const container = document.createElement('div');\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0);\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderClassDiagram(\n container,\n parsed,\n layout,\n palette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","import dagre from '@dagrejs/dagre';\nimport type { ParsedERDiagram, ERTable } from './types';\n\n// ============================================================\n// Layout types\n// ============================================================\n\nexport interface ERLayoutNode extends ERTable {\n x: number;\n y: number;\n width: number;\n height: number;\n headerHeight: number;\n columnsHeight: number;\n}\n\nexport interface ERLayoutEdge {\n source: string;\n target: string;\n cardinality: { from: string; to: string };\n points: { x: number; y: number }[];\n label?: string;\n lineNumber: number;\n}\n\nexport interface ERLayoutResult {\n nodes: ERLayoutNode[];\n edges: ERLayoutEdge[];\n width: number;\n height: number;\n}\n\n// ============================================================\n// Sizing constants\n// ============================================================\n\nconst MIN_WIDTH = 140;\nconst CHAR_WIDTH = 7.5;\nconst PADDING_X = 24;\nconst HEADER_BASE = 36;\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst SEPARATOR_HEIGHT = 1;\n\n// ============================================================\n// Node sizing\n// ============================================================\n\nfunction computeNodeDimensions(table: ERTable): {\n width: number;\n height: number;\n headerHeight: number;\n columnsHeight: number;\n} {\n // Width: max of table name, column text lengths\n let maxTextLen = table.name.length;\n for (const col of table.columns) {\n let colText = col.name;\n if (col.type) colText += ` ${col.type}`;\n if (col.constraints.length > 0) colText += ` XX`; // icon space\n maxTextLen = Math.max(maxTextLen, colText.length);\n }\n const width = Math.max(MIN_WIDTH, maxTextLen * CHAR_WIDTH + PADDING_X);\n\n const headerHeight = HEADER_BASE;\n\n let columnsHeight = 0;\n if (table.columns.length > 0) {\n columnsHeight =\n COMPARTMENT_PADDING_Y * 2 +\n table.columns.length * MEMBER_LINE_HEIGHT +\n SEPARATOR_HEIGHT;\n }\n\n const height =\n headerHeight + columnsHeight + (columnsHeight === 0 ? 4 : 0);\n\n return { width, height, headerHeight, columnsHeight };\n}\n\n// ============================================================\n// Layout engine\n// ============================================================\n\nexport function layoutERDiagram(parsed: ParsedERDiagram): ERLayoutResult {\n if (parsed.tables.length === 0) {\n return { nodes: [], edges: [], width: 0, height: 0 };\n }\n\n const g = new dagre.graphlib.Graph();\n g.setGraph({\n rankdir: 'TB',\n nodesep: 60,\n ranksep: 80,\n edgesep: 20,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n // Compute dimensions and add nodes\n const dimMap = new Map<\n string,\n {\n width: number;\n height: number;\n headerHeight: number;\n columnsHeight: number;\n }\n >();\n\n for (const table of parsed.tables) {\n const dims = computeNodeDimensions(table);\n dimMap.set(table.id, dims);\n g.setNode(table.id, {\n label: table.name,\n width: dims.width,\n height: dims.height,\n });\n }\n\n // Add edges\n for (const rel of parsed.relationships) {\n g.setEdge(rel.source, rel.target, { label: rel.label ?? '' });\n }\n\n // Run layout\n dagre.layout(g);\n\n // Extract positioned nodes\n const layoutNodes: ERLayoutNode[] = parsed.tables.map((table) => {\n const pos = g.node(table.id);\n const dims = dimMap.get(table.id)!;\n return {\n ...table,\n x: pos.x,\n y: pos.y,\n width: dims.width,\n height: dims.height,\n headerHeight: dims.headerHeight,\n columnsHeight: dims.columnsHeight,\n };\n });\n\n // Extract edge waypoints\n const layoutEdges: ERLayoutEdge[] = parsed.relationships.map((rel) => {\n const edgeData = g.edge(rel.source, rel.target);\n return {\n source: rel.source,\n target: rel.target,\n cardinality: rel.cardinality,\n points: edgeData?.points ?? [],\n label: rel.label,\n lineNumber: rel.lineNumber,\n };\n });\n\n // Compute total dimensions from nodes, edge points, and labels\n let minX = Infinity;\n let minY = Infinity;\n let maxX = 0;\n let maxY = 0;\n for (const node of layoutNodes) {\n const left = node.x - node.width / 2;\n const right = node.x + node.width / 2;\n const top = node.y - node.height / 2;\n const bottom = node.y + node.height / 2;\n if (left < minX) minX = left;\n if (right > maxX) maxX = right;\n if (top < minY) minY = top;\n if (bottom > maxY) maxY = bottom;\n }\n for (const edge of layoutEdges) {\n for (const pt of edge.points) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n // Edge labels extend ~50px from midpoint\n if (edge.label && edge.points.length > 0) {\n const midPt = edge.points[Math.floor(edge.points.length / 2)];\n const labelHalfW = (edge.label.length * 7 + 8) / 2;\n if (midPt.x + labelHalfW > maxX) maxX = midPt.x + labelHalfW;\n if (midPt.x - labelHalfW < minX) minX = midPt.x - labelHalfW;\n }\n }\n\n // Padding for cardinality markers (~25px) + edge labels\n const EDGE_MARGIN = 60;\n const HALF_MARGIN = EDGE_MARGIN / 2;\n\n // Shift all nodes and edges so content starts at HALF_MARGIN (breathing room on all sides)\n const shiftX = -minX + HALF_MARGIN;\n const shiftY = -minY + HALF_MARGIN;\n for (const node of layoutNodes) {\n node.x += shiftX;\n node.y += shiftY;\n }\n for (const edge of layoutEdges) {\n for (const pt of edge.points) {\n pt.x += shiftX;\n pt.y += shiftY;\n }\n }\n maxX += shiftX;\n maxY += shiftY;\n\n const totalWidth = maxX + HALF_MARGIN;\n const totalHeight = maxY + HALF_MARGIN;\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n width: totalWidth,\n height: totalHeight,\n };\n}\n","// ============================================================\n// ER Diagram SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport { getSeriesColors } from '../palettes';\nimport type { ParsedERDiagram, ERConstraint } from './types';\nimport type { ERLayoutResult, ERLayoutNode, ERLayoutEdge } from './layout';\nimport { parseERDiagram } from './parser';\nimport { layoutERDiagram } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst MAX_SCALE = 3;\nconst TABLE_FONT_SIZE = 13;\nconst COLUMN_FONT_SIZE = 11;\nconst EDGE_LABEL_FONT_SIZE = 11;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst MEMBER_LINE_HEIGHT = 18;\nconst COMPARTMENT_PADDING_Y = 8;\nconst MEMBER_PADDING_X = 10;\n\n// ============================================================\n// Color helpers\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\n// ============================================================\n// Constraint icons (text glyphs for resvg compat)\n// ============================================================\n\nfunction constraintIcon(constraint: ERConstraint): string {\n switch (constraint) {\n case 'pk': return '\\u2666'; // ♦\n case 'fk': return '\\u2192'; // →\n case 'unique': return '\\u25C6'; // ◆\n case 'nullable': return '\\u25CB'; // ○\n }\n}\n\n// ============================================================\n// Edge path generator\n// ============================================================\n\nconst lineGenerator = d3Shape.line<{ x: number; y: number }>()\n .x((d) => d.x)\n .y((d) => d.y)\n .curve(d3Shape.curveBasis);\n\n// ============================================================\n// Crow's foot marker drawing\n// ============================================================\n\n/**\n * Draw a crow's foot cardinality indicator at the given endpoint.\n *\n * Crow's foot notation:\n * 1 = perpendicular bar across the line\n * * = three prongs splaying outward from the line toward the entity\n * ? = open circle on the line + perpendicular bar\n *\n * The prongs fan out from a point on the line toward the entity edge,\n * like a bird's foot — NOT converging inward like an arrowhead.\n *\n * @param g - parent SVG group\n * @param point - endpoint position (where edge meets the entity)\n * @param prevPoint - previous point to determine angle\n * @param cardinality - '1', '*', or '?'\n * @param color - stroke color\n * @param useLabels - if true, render text labels instead of crow's foot\n */\nfunction drawCardinality(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n point: { x: number; y: number },\n prevPoint: { x: number; y: number },\n cardinality: string,\n color: string,\n useLabels: boolean\n): void {\n const dx = point.x - prevPoint.x;\n const dy = point.y - prevPoint.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n if (len === 0) return;\n\n // Unit vector from prev toward endpoint (direction of edge arriving at entity)\n const ux = dx / len;\n const uy = dy / len;\n // Perpendicular\n const px = -uy;\n const py = ux;\n\n const sw = EDGE_STROKE_WIDTH + 0.5; // slightly heavier for visibility\n\n if (useLabels) {\n const offset = 15;\n const bx = point.x - ux * offset;\n const by = point.y - uy * offset;\n const labelText = cardinality === '1' ? '1' : cardinality === '*' ? '*' : '0..1';\n g.append('text')\n .attr('x', bx + px * 12)\n .attr('y', by + py * 12)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', color)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .text(labelText);\n return;\n }\n\n // Crow's foot notation\n const barOffset = 14; // how far back from the entity the bar sits\n const spread = 9; // half-width of the perpendicular bar / prong span\n\n if (cardinality === '1') {\n // Single perpendicular bar\n const bx = point.x - ux * barOffset;\n const by = point.y - uy * barOffset;\n g.append('line')\n .attr('x1', bx + px * spread)\n .attr('y1', by + py * spread)\n .attr('x2', bx - px * spread)\n .attr('y2', by - py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n } else if (cardinality === '*') {\n // Crow's foot: three prongs fan out FROM a point on the line\n // TOWARD the entity — the fork opens at the entity side.\n const forkOrigin = 18; // distance back from entity where prongs originate\n const forkEnd = 5; // distance from entity where prongs terminate\n\n // Origin point (on the line, away from entity)\n const ox = point.x - ux * forkOrigin;\n const oy = point.y - uy * forkOrigin;\n\n // End points (near entity, splayed outward)\n const ex = point.x - ux * forkEnd;\n const ey = point.y - uy * forkEnd;\n\n // Top prong\n g.append('line')\n .attr('x1', ox)\n .attr('y1', oy)\n .attr('x2', ex + px * spread)\n .attr('y2', ey + py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n // Bottom prong\n g.append('line')\n .attr('x1', ox)\n .attr('y1', oy)\n .attr('x2', ex - px * spread)\n .attr('y2', ey - py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n // Middle prong (straight to entity)\n g.append('line')\n .attr('x1', ox)\n .attr('y1', oy)\n .attr('x2', ex)\n .attr('y2', ey)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n } else if (cardinality === '?') {\n // Circle (zero) + perpendicular bar (one)\n const circleR = 5;\n const circleCenter = barOffset + circleR * 2 + 2; // circle sits behind the bar\n const cx = point.x - ux * circleCenter;\n const cy = point.y - uy * circleCenter;\n g.append('circle')\n .attr('cx', cx)\n .attr('cy', cy)\n .attr('r', circleR)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', sw);\n // Perpendicular bar\n const bx = point.x - ux * barOffset;\n const by = point.y - uy * barOffset;\n g.append('line')\n .attr('x1', bx + px * spread)\n .attr('y1', by + py * spread)\n .attr('x2', bx - px * spread)\n .attr('y2', by - py * spread)\n .attr('stroke', color)\n .attr('stroke-width', sw);\n }\n}\n\n// ============================================================\n// Main renderer\n// ============================================================\n\nexport function renderERDiagram(\n container: HTMLDivElement,\n parsed: ParsedERDiagram,\n layout: ERLayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number }\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = parsed.title ? 40 : 0;\n const diagramW = layout.width;\n const diagramH = layout.height;\n const availH = height - titleHeight;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (availH - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(MAX_SCALE, scaleX, scaleY);\n\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = titleHeight + (availH - scaledH) / 2;\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // ── Title ──\n if (parsed.title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(parsed.title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // ── Content group ──\n const contentG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // ── Auto-assign colors ──\n const seriesColors = getSeriesColors(palette);\n\n // ── Edges (behind nodes) ──\n const useLabels = parsed.options.notation === 'labels';\n\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n\n const edgeG = contentG\n .append('g')\n .attr('class', 'er-edge-group')\n .attr('data-line-number', String(edge.lineNumber));\n\n const edgeColor = palette.textMuted;\n\n const pathD = lineGenerator(edge.points);\n if (pathD) {\n edgeG\n .append('path')\n .attr('d', pathD)\n .attr('fill', 'none')\n .attr('stroke', edgeColor)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('class', 'er-edge');\n }\n\n // Cardinality markers at endpoints\n const pts = edge.points;\n // Source side (from cardinality)\n drawCardinality(\n edgeG,\n pts[0],\n pts[1],\n edge.cardinality.from,\n edgeColor,\n useLabels\n );\n // Target side (to cardinality)\n drawCardinality(\n edgeG,\n pts[pts.length - 1],\n pts[pts.length - 2],\n edge.cardinality.to,\n edgeColor,\n useLabels\n );\n\n // Edge label at midpoint\n if (edge.label) {\n const midIdx = Math.floor(pts.length / 2);\n const midPt = pts[midIdx];\n const labelLen = edge.label.length;\n const bgW = labelLen * 7 + 8;\n const bgH = 16;\n\n edgeG.append('rect')\n .attr('x', midPt.x - bgW / 2)\n .attr('y', midPt.y - bgH / 2 - 1)\n .attr('width', bgW)\n .attr('height', bgH)\n .attr('rx', 3)\n .attr('fill', palette.bg)\n .attr('opacity', 0.85)\n .attr('class', 'er-edge-label-bg');\n\n edgeG.append('text')\n .attr('x', midPt.x)\n .attr('y', midPt.y + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', edgeColor)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .attr('class', 'er-edge-label')\n .text(edge.label);\n }\n }\n\n // ── Nodes (top layer) ──\n for (let ni = 0; ni < layout.nodes.length; ni++) {\n const node = layout.nodes[ni];\n const nodeColor = node.color ?? seriesColors[ni % seriesColors.length];\n\n const nodeG = contentG\n .append('g')\n .attr('transform', `translate(${node.x}, ${node.y})`)\n .attr('class', 'er-table')\n .attr('data-line-number', String(node.lineNumber))\n .attr('data-node-id', node.id);\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n const w = node.width;\n const h = node.height;\n const fill = mix(nodeColor, isDark ? palette.surface : palette.bg, 20);\n const stroke = nodeColor;\n\n // Outer rectangle\n nodeG.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', fill)\n .attr('stroke', stroke)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n\n // Header section — table name\n let yPos = -h / 2;\n const headerCenterY = yPos + node.headerHeight / 2;\n\n nodeG.append('text')\n .attr('x', 0)\n .attr('y', headerCenterY)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', TABLE_FONT_SIZE)\n .attr('font-weight', 'bold')\n .text(node.name);\n\n yPos += node.headerHeight;\n\n // Columns compartment\n if (node.columns.length > 0) {\n // Separator line\n nodeG.append('line')\n .attr('x1', -w / 2)\n .attr('y1', yPos)\n .attr('x2', w / 2)\n .attr('y2', yPos)\n .attr('stroke', stroke)\n .attr('stroke-width', 0.5)\n .attr('stroke-opacity', 0.5);\n\n let memberY = yPos + COMPARTMENT_PADDING_Y;\n for (const col of node.columns) {\n // Constraint icon (leftmost)\n const iconX = -w / 2 + MEMBER_PADDING_X;\n const primaryConstraint = col.constraints[0];\n if (primaryConstraint) {\n nodeG.append('text')\n .attr('x', iconX)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.textMuted)\n .attr('font-size', COLUMN_FONT_SIZE)\n .text(constraintIcon(primaryConstraint));\n }\n\n // Column name + type\n const textX = -w / 2 + MEMBER_PADDING_X + (primaryConstraint ? 16 : 0);\n let colText = col.name;\n if (col.type) colText += `: ${col.type}`;\n\n nodeG.append('text')\n .attr('x', textX)\n .attr('y', memberY + MEMBER_LINE_HEIGHT / 2)\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', COLUMN_FONT_SIZE)\n .text(colText);\n\n memberY += MEMBER_LINE_HEIGHT;\n }\n }\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderERDiagramForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseERDiagram(content, palette);\n if (parsed.error || parsed.tables.length === 0) return '';\n\n const layout = layoutERDiagram(parsed);\n const isDark = theme === 'dark';\n\n const container = document.createElement('div');\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0);\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderERDiagram(\n container,\n parsed,\n layout,\n palette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n ParsedGraph,\n GraphNode,\n GraphEdge,\n GraphShape,\n} from './types';\n\nexport interface LayoutNode {\n id: string;\n label: string;\n shape: GraphShape;\n color?: string;\n group?: string;\n lineNumber: number;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface LayoutEdge {\n source: string;\n target: string;\n points: { x: number; y: number }[];\n label?: string;\n color?: string;\n lineNumber: number;\n}\n\nexport interface LayoutGroup {\n id: string;\n label: string;\n color?: string;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface LayoutResult {\n nodes: LayoutNode[];\n edges: LayoutEdge[];\n groups: LayoutGroup[];\n width: number;\n height: number;\n}\n\nconst GROUP_PADDING = 20;\n\nfunction computeNodeWidth(label: string, shape: GraphShape): number {\n const base = Math.max(120, label.length * 9 + 40);\n if (shape === 'subroutine') return base + 10;\n return base;\n}\n\nfunction computeNodeHeight(shape: GraphShape): number {\n return shape === 'decision' ? 60 : 50;\n}\n\nexport function layoutGraph(graph: ParsedGraph): LayoutResult {\n if (graph.nodes.length === 0) {\n return { nodes: [], edges: [], groups: [], width: 0, height: 0 };\n }\n\n const g = new dagre.graphlib.Graph({ compound: true });\n g.setGraph({\n rankdir: graph.direction,\n nodesep: 50,\n ranksep: 60,\n edgesep: 20,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n // Build a lookup for original node data\n const nodeDataMap = new Map<string, GraphNode>();\n for (const node of graph.nodes) {\n nodeDataMap.set(node.id, node);\n }\n\n // Add group parent nodes\n if (graph.groups) {\n for (const group of graph.groups) {\n g.setNode(group.id, {\n label: group.label,\n clusterLabelPos: 'top',\n });\n }\n }\n\n // Add nodes with computed dimensions\n for (const node of graph.nodes) {\n const width = computeNodeWidth(node.label, node.shape);\n const height = computeNodeHeight(node.shape);\n g.setNode(node.id, { label: node.label, width, height });\n\n // Set parent for grouped nodes\n if (node.group && graph.groups?.some((gr) => gr.id === node.group)) {\n g.setParent(node.id, node.group);\n }\n }\n\n // Build edge lookup for original data\n const edgeDataMap = new Map<string, GraphEdge>();\n for (const edge of graph.edges) {\n const key = `${edge.source}->${edge.target}`;\n edgeDataMap.set(key, edge);\n g.setEdge(edge.source, edge.target, {\n label: edge.label ?? '',\n });\n }\n\n // Run layout\n dagre.layout(g);\n\n // Extract positioned nodes\n const layoutNodes: LayoutNode[] = graph.nodes.map((node) => {\n const pos = g.node(node.id);\n return {\n id: node.id,\n label: node.label,\n shape: node.shape,\n color: node.color,\n group: node.group,\n lineNumber: node.lineNumber,\n x: pos.x,\n y: pos.y,\n width: pos.width,\n height: pos.height,\n };\n });\n\n // Extract edge waypoints\n const layoutEdges: LayoutEdge[] = graph.edges.map((edge) => {\n const edgeData = g.edge(edge.source, edge.target);\n return {\n source: edge.source,\n target: edge.target,\n points: edgeData?.points ?? [],\n label: edge.label,\n color: edge.color,\n lineNumber: edge.lineNumber,\n };\n });\n\n // Compute group bounding boxes from member node positions\n const layoutGroups: LayoutGroup[] = [];\n if (graph.groups) {\n const nodeMap = new Map(layoutNodes.map((n) => [n.id, n]));\n for (const group of graph.groups) {\n const members = group.nodeIds\n .map((id) => nodeMap.get(id))\n .filter((n): n is LayoutNode => n !== undefined);\n\n if (members.length === 0) {\n layoutGroups.push({\n id: group.id,\n label: group.label,\n color: group.color,\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n });\n continue;\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const member of members) {\n const left = member.x - member.width / 2;\n const right = member.x + member.width / 2;\n const top = member.y - member.height / 2;\n const bottom = member.y + member.height / 2;\n if (left < minX) minX = left;\n if (right > maxX) maxX = right;\n if (top < minY) minY = top;\n if (bottom > maxY) maxY = bottom;\n }\n\n layoutGroups.push({\n id: group.id,\n label: group.label,\n color: group.color,\n x: minX - GROUP_PADDING,\n y: minY - GROUP_PADDING,\n width: maxX - minX + GROUP_PADDING * 2,\n height: maxY - minY + GROUP_PADDING * 2,\n });\n }\n }\n\n // Compute total diagram dimensions\n let totalWidth = 0;\n let totalHeight = 0;\n for (const node of layoutNodes) {\n const right = node.x + node.width / 2;\n const bottom = node.y + node.height / 2;\n if (right > totalWidth) totalWidth = right;\n if (bottom > totalHeight) totalHeight = bottom;\n }\n for (const group of layoutGroups) {\n const right = group.x + group.width;\n const bottom = group.y + group.height;\n if (right > totalWidth) totalWidth = right;\n if (bottom > totalHeight) totalHeight = bottom;\n }\n // Add margin\n totalWidth += 40;\n totalHeight += 40;\n\n return {\n nodes: layoutNodes,\n edges: layoutEdges,\n groups: layoutGroups,\n width: totalWidth,\n height: totalHeight,\n };\n}\n","// ============================================================\n// Flowchart SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport { FONT_FAMILY } from '../fonts';\nimport type { PaletteColors } from '../palettes';\nimport type { ParsedGraph, GraphShape } from './types';\nimport type { LayoutResult, LayoutNode, LayoutEdge, LayoutGroup } from './layout';\nimport { parseFlowchart } from './flowchart-parser';\nimport { layoutGraph } from './layout';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst DIAGRAM_PADDING = 20;\nconst MAX_SCALE = 3;\nconst NODE_FONT_SIZE = 13;\nconst EDGE_LABEL_FONT_SIZE = 11;\nconst GROUP_LABEL_FONT_SIZE = 11;\nconst EDGE_STROKE_WIDTH = 1.5;\nconst NODE_STROKE_WIDTH = 1.5;\nconst ARROWHEAD_W = 10;\nconst ARROWHEAD_H = 7;\nconst IO_SKEW = 15;\nconst SUBROUTINE_INSET = 8;\nconst DOC_WAVE_HEIGHT = 10;\nconst GROUP_EXTRA_PADDING = 12;\n\n// ============================================================\n// Color helpers (inline mix to avoid cross-module import issues)\n// ============================================================\n\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\nfunction shapeDefaultColor(shape: GraphShape, palette: PaletteColors, isEndTerminal?: boolean, colorOff?: boolean): string {\n if (colorOff) return palette.textMuted;\n switch (shape) {\n case 'terminal': return isEndTerminal ? palette.colors.red : palette.colors.green;\n case 'process': return palette.colors.blue;\n case 'decision': return palette.colors.yellow;\n case 'io': return palette.colors.purple;\n case 'subroutine': return palette.colors.teal;\n case 'document': return palette.colors.orange;\n }\n}\n\nfunction nodeFill(palette: PaletteColors, isDark: boolean, shape: GraphShape, nodeColor?: string, isEndTerminal?: boolean, colorOff?: boolean): string {\n const color = nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);\n return mix(color, isDark ? palette.surface : palette.bg, 25);\n}\n\nfunction nodeStroke(palette: PaletteColors, shape: GraphShape, nodeColor?: string, isEndTerminal?: boolean, colorOff?: boolean): string {\n return nodeColor ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);\n}\n\n// ============================================================\n// Shape renderers\n// ============================================================\n\ntype GSelection = d3Selection.Selection<SVGGElement, unknown, null, undefined>;\n\nfunction renderTerminal(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, isEnd: boolean, colorOff?: boolean): void {\n const w = node.width;\n const h = node.height;\n const rx = h / 2;\n g.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', rx)\n .attr('ry', rx)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color, isEnd, colorOff))\n .attr('stroke', nodeStroke(palette, node.shape, node.color, isEnd, colorOff))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderProcess(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, colorOff?: boolean): void {\n const w = node.width;\n const h = node.height;\n g.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color, undefined, colorOff))\n .attr('stroke', nodeStroke(palette, node.shape, node.color, undefined, colorOff))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderDecision(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, colorOff?: boolean): void {\n const w = node.width / 2;\n const h = node.height / 2;\n const points = [\n `${0},${-h}`, // top\n `${w},${0}`, // right\n `${0},${h}`, // bottom\n `${-w},${0}`, // left\n ].join(' ');\n g.append('polygon')\n .attr('points', points)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color, undefined, colorOff))\n .attr('stroke', nodeStroke(palette, node.shape, node.color, undefined, colorOff))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderIO(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, colorOff?: boolean): void {\n const w = node.width / 2;\n const h = node.height / 2;\n const sk = IO_SKEW;\n const points = [\n `${-w + sk},${-h}`, // top-left (shifted right)\n `${w + sk},${-h}`, // top-right (shifted right)\n `${w - sk},${h}`, // bottom-right (shifted left)\n `${-w - sk},${h}`, // bottom-left (shifted left)\n ].join(' ');\n g.append('polygon')\n .attr('points', points)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color, undefined, colorOff))\n .attr('stroke', nodeStroke(palette, node.shape, node.color, undefined, colorOff))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderSubroutine(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, colorOff?: boolean): void {\n const w = node.width;\n const h = node.height;\n const s = nodeStroke(palette, node.shape, node.color, undefined, colorOff);\n // Outer rectangle\n g.append('rect')\n .attr('x', -w / 2)\n .attr('y', -h / 2)\n .attr('width', w)\n .attr('height', h)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color, undefined, colorOff))\n .attr('stroke', s)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n // Left inner border\n g.append('line')\n .attr('x1', -w / 2 + SUBROUTINE_INSET)\n .attr('y1', -h / 2)\n .attr('x2', -w / 2 + SUBROUTINE_INSET)\n .attr('y2', h / 2)\n .attr('stroke', s)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n // Right inner border\n g.append('line')\n .attr('x1', w / 2 - SUBROUTINE_INSET)\n .attr('y1', -h / 2)\n .attr('x2', w / 2 - SUBROUTINE_INSET)\n .attr('y2', h / 2)\n .attr('stroke', s)\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderDocument(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, colorOff?: boolean): void {\n const w = node.width;\n const h = node.height;\n const waveH = DOC_WAVE_HEIGHT;\n const left = -w / 2;\n const right = w / 2;\n const top = -h / 2;\n const bottom = h / 2 - waveH;\n\n // Path: straight top, straight right side, wavy bottom, straight left side\n const d = [\n `M ${left} ${top}`,\n `L ${right} ${top}`,\n `L ${right} ${bottom}`,\n `C ${right - w * 0.25} ${bottom + waveH * 2}, ${left + w * 0.25} ${bottom - waveH}, ${left} ${bottom}`,\n 'Z',\n ].join(' ');\n\n g.append('path')\n .attr('d', d)\n .attr('fill', nodeFill(palette, isDark, node.shape, node.color, undefined, colorOff))\n .attr('stroke', nodeStroke(palette, node.shape, node.color, undefined, colorOff))\n .attr('stroke-width', NODE_STROKE_WIDTH);\n}\n\nfunction renderNodeShape(g: GSelection, node: LayoutNode, palette: PaletteColors, isDark: boolean, endTerminalIds: Set<string>, colorOff?: boolean): void {\n switch (node.shape) {\n case 'terminal':\n renderTerminal(g, node, palette, isDark, endTerminalIds.has(node.id), colorOff);\n break;\n case 'process':\n renderProcess(g, node, palette, isDark, colorOff);\n break;\n case 'decision':\n renderDecision(g, node, palette, isDark, colorOff);\n break;\n case 'io':\n renderIO(g, node, palette, isDark, colorOff);\n break;\n case 'subroutine':\n renderSubroutine(g, node, palette, isDark, colorOff);\n break;\n case 'document':\n renderDocument(g, node, palette, isDark, colorOff);\n break;\n }\n}\n\n// ============================================================\n// Edge path generator\n// ============================================================\n\nconst lineGenerator = d3Shape.line<{ x: number; y: number }>()\n .x((d) => d.x)\n .y((d) => d.y)\n .curve(d3Shape.curveBasis);\n\n// ============================================================\n// Main renderer\n// ============================================================\n\nexport function renderFlowchart(\n container: HTMLDivElement,\n graph: ParsedGraph,\n layout: LayoutResult,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: { width?: number; height?: number }\n): void {\n // Clear existing content (preserve tooltips)\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = graph.title ? 40 : 0;\n\n // Compute scale to fit diagram in available space below title\n const diagramW = layout.width;\n const diagramH = layout.height;\n const availH = height - titleHeight;\n const scaleX = (width - DIAGRAM_PADDING * 2) / diagramW;\n const scaleY = (availH - DIAGRAM_PADDING * 2) / diagramH;\n const scale = Math.min(MAX_SCALE, scaleX, scaleY);\n\n // Center the diagram in the area below the title\n const scaledW = diagramW * scale;\n const scaledH = diagramH * scale;\n const offsetX = (width - scaledW) / 2;\n const offsetY = titleHeight + (availH - scaledH) / 2;\n\n // Create SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('font-family', FONT_FAMILY);\n\n // Defs: arrowhead markers\n const defs = svg.append('defs');\n\n // Default arrowhead\n defs\n .append('marker')\n .attr('id', 'fc-arrow')\n .attr('viewBox', `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`)\n .attr('refX', ARROWHEAD_W)\n .attr('refY', ARROWHEAD_H / 2)\n .attr('markerWidth', ARROWHEAD_W)\n .attr('markerHeight', ARROWHEAD_H)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`)\n .attr('fill', palette.textMuted);\n\n // Collect unique edge colors for custom markers\n const edgeColors = new Set<string>();\n for (const edge of layout.edges) {\n if (edge.color) edgeColors.add(edge.color);\n }\n for (const color of edgeColors) {\n const id = `fc-arrow-${color.replace('#', '')}`;\n defs\n .append('marker')\n .attr('id', id)\n .attr('viewBox', `0 0 ${ARROWHEAD_W} ${ARROWHEAD_H}`)\n .attr('refX', ARROWHEAD_W)\n .attr('refY', ARROWHEAD_H / 2)\n .attr('markerWidth', ARROWHEAD_W)\n .attr('markerHeight', ARROWHEAD_H)\n .attr('orient', 'auto')\n .append('polygon')\n .attr('points', `0,0 ${ARROWHEAD_W},${ARROWHEAD_H / 2} 0,${ARROWHEAD_H}`)\n .attr('fill', color);\n }\n\n // Title (rendered directly on SVG, not inside scaled group)\n if (graph.title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && graph.titleLineNumber ? 'pointer' : 'default')\n .text(graph.title);\n\n if (graph.titleLineNumber) {\n titleEl.attr('data-line-number', graph.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(graph.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // Main content group with scale/translate\n const contentG = svg\n .append('g')\n .attr('transform', `translate(${offsetX}, ${offsetY}) scale(${scale})`);\n\n // Render groups (background layer)\n for (const group of layout.groups) {\n if (group.width === 0 && group.height === 0) continue;\n const gx = group.x - GROUP_EXTRA_PADDING;\n const gy = group.y - GROUP_EXTRA_PADDING - GROUP_LABEL_FONT_SIZE - 4;\n const gw = group.width + GROUP_EXTRA_PADDING * 2;\n const gh = group.height + GROUP_EXTRA_PADDING * 2 + GROUP_LABEL_FONT_SIZE + 4;\n\n const fillColor = group.color\n ? mix(group.color, isDark ? palette.surface : palette.bg, 10)\n : isDark\n ? palette.surface\n : mix(palette.border, palette.bg, 30);\n const strokeColor = group.color ?? palette.textMuted;\n\n contentG\n .append('rect')\n .attr('x', gx)\n .attr('y', gy)\n .attr('width', gw)\n .attr('height', gh)\n .attr('rx', 6)\n .attr('fill', fillColor)\n .attr('stroke', strokeColor)\n .attr('stroke-width', 1)\n .attr('stroke-opacity', 0.5)\n .attr('class', 'fc-group');\n\n contentG\n .append('text')\n .attr('x', gx + 8)\n .attr('y', gy + GROUP_LABEL_FONT_SIZE + 4)\n .attr('fill', strokeColor)\n .attr('font-size', GROUP_LABEL_FONT_SIZE)\n .attr('font-weight', 'bold')\n .attr('opacity', 0.7)\n .attr('class', 'fc-group-label')\n .text(group.label);\n }\n\n // Render edges (middle layer)\n for (const edge of layout.edges) {\n if (edge.points.length < 2) continue;\n const edgeG = contentG\n .append('g')\n .attr('class', 'fc-edge-group')\n .attr('data-line-number', String(edge.lineNumber));\n\n const edgeColor = edge.color ?? palette.textMuted;\n const markerId = edge.color\n ? `fc-arrow-${edge.color.replace('#', '')}`\n : 'fc-arrow';\n\n const pathD = lineGenerator(edge.points);\n if (pathD) {\n edgeG\n .append('path')\n .attr('d', pathD)\n .attr('fill', 'none')\n .attr('stroke', edgeColor)\n .attr('stroke-width', EDGE_STROKE_WIDTH)\n .attr('marker-end', `url(#${markerId})`)\n .attr('class', 'fc-edge');\n }\n\n // Edge label at midpoint\n if (edge.label) {\n const midIdx = Math.floor(edge.points.length / 2);\n const midPt = edge.points[midIdx];\n\n // Background rect for legibility\n const labelLen = edge.label.length;\n const bgW = labelLen * 7 + 8;\n const bgH = 16;\n edgeG\n .append('rect')\n .attr('x', midPt.x - bgW / 2)\n .attr('y', midPt.y - bgH / 2 - 1)\n .attr('width', bgW)\n .attr('height', bgH)\n .attr('rx', 3)\n .attr('fill', palette.bg)\n .attr('opacity', 0.85)\n .attr('class', 'fc-edge-label-bg');\n\n edgeG\n .append('text')\n .attr('x', midPt.x)\n .attr('y', midPt.y + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', edgeColor)\n .attr('font-size', EDGE_LABEL_FONT_SIZE)\n .attr('class', 'fc-edge-label')\n .text(edge.label);\n }\n }\n\n // Identify end terminals (terminal nodes with no outgoing edges)\n const nodesWithOutgoing = new Set<string>();\n for (const edge of layout.edges) nodesWithOutgoing.add(edge.source);\n const endTerminalIds = new Set<string>();\n for (const node of layout.nodes) {\n if (node.shape === 'terminal' && !nodesWithOutgoing.has(node.id)) {\n endTerminalIds.add(node.id);\n }\n }\n\n // Render nodes (top layer)\n const colorOff = graph.options?.color === 'off';\n for (const node of layout.nodes) {\n const nodeG = contentG\n .append('g')\n .attr('transform', `translate(${node.x}, ${node.y})`)\n .attr('class', 'fc-node')\n .attr('data-line-number', String(node.lineNumber))\n .attr('data-node-id', node.id);\n\n if (onClickItem) {\n nodeG.style('cursor', 'pointer').on('click', () => {\n onClickItem(node.lineNumber);\n });\n }\n\n // Shape\n renderNodeShape(nodeG as GSelection, node, palette, isDark, endTerminalIds, colorOff);\n\n // Label\n nodeG\n .append('text')\n .attr('x', 0)\n .attr('y', 0)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', palette.text)\n .attr('font-size', NODE_FONT_SIZE)\n .text(node.label);\n }\n}\n\n// ============================================================\n// Export convenience function\n// ============================================================\n\nexport function renderFlowchartForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette: PaletteColors\n): string {\n const parsed = parseFlowchart(content, palette);\n if (parsed.error || parsed.nodes.length === 0) return '';\n\n const layout = layoutGraph(parsed);\n const isDark = theme === 'dark';\n\n // Create offscreen container\n const container = document.createElement('div');\n container.style.width = `${layout.width + DIAGRAM_PADDING * 2}px`;\n container.style.height = `${layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0)}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n const exportWidth = layout.width + DIAGRAM_PADDING * 2;\n const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0);\n\n try {\n renderFlowchart(\n container,\n parsed,\n layout,\n palette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\n}\n","// ============================================================\n// Sequence Diagram SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport type { PaletteColors } from '../palettes';\nimport { resolveColor } from '../colors';\nimport { FONT_FAMILY } from '../fonts';\nimport type {\n ParsedSequenceDgmo,\n SequenceElement,\n SequenceGroup,\n SequenceMessage,\n SequenceNote,\n SequenceParticipant,\n} from './parser';\nimport { isSequenceBlock, isSequenceSection, isSequenceNote } from './parser';\n\n// ============================================================\n// Layout Constants\n// ============================================================\n\nconst PARTICIPANT_GAP = 160;\nconst PARTICIPANT_BOX_WIDTH = 120;\nconst PARTICIPANT_BOX_HEIGHT = 50;\nconst TOP_MARGIN = 20;\nconst TITLE_HEIGHT = 30;\nconst PARTICIPANT_Y_OFFSET = 10;\nconst SERVICE_BORDER_RADIUS = 10;\nconst MESSAGE_START_OFFSET = 30;\nconst LIFELINE_TAIL = 30;\nconst ARROWHEAD_SIZE = 8;\n\n// Note rendering constants\nconst NOTE_MAX_W = 200;\nconst NOTE_FOLD = 10;\nconst NOTE_PAD_H = 8;\nconst NOTE_PAD_V = 6;\nconst NOTE_FONT_SIZE = 10;\nconst NOTE_LINE_H = 14;\nconst NOTE_GAP = 15;\nconst NOTE_CHAR_W = 6;\nconst NOTE_CHARS_PER_LINE = Math.floor((NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W);\nconst COLLAPSED_NOTE_H = 20;\nconst COLLAPSED_NOTE_W = 40;\n\ninterface InlineSpan {\n text: string;\n bold?: boolean;\n italic?: boolean;\n code?: boolean;\n href?: string;\n}\n\nexport function parseInlineMarkdown(text: string): InlineSpan[] {\n const spans: InlineSpan[] = [];\n const regex =\n /\\*\\*(.+?)\\*\\*|__(.+?)__|\\*(.+?)\\*|_(.+?)_|`(.+?)`|\\[(.+?)\\]\\((.+?)\\)|(https?:\\/\\/[^\\s)>\\]]+|www\\.[^\\s)>\\]]+)|([^*_`[]+?(?=https?:\\/\\/|www\\.|$)|[^*_`[]+)/g;\n let match;\n while ((match = regex.exec(text)) !== null) {\n if (match[1]) spans.push({ text: match[1], bold: true }); // **bold**\n else if (match[2]) spans.push({ text: match[2], bold: true }); // __bold__\n else if (match[3]) spans.push({ text: match[3], italic: true }); // *italic*\n else if (match[4]) spans.push({ text: match[4], italic: true }); // _italic_\n else if (match[5]) spans.push({ text: match[5], code: true }); // `code`\n else if (match[6]) spans.push({ text: match[6], href: match[7] }); // [text](url)\n else if (match[8]) { // bare URL\n const url = match[8];\n const href = url.startsWith('www.') ? `https://${url}` : url;\n spans.push({ text: url, href });\n } else if (match[9]) spans.push({ text: match[9] }); // plain text\n }\n return spans;\n}\n\nconst BARE_URL_MAX_DISPLAY = 35;\n\nexport function truncateBareUrl(url: string): string {\n const stripped = url.replace(/^https?:\\/\\//, '').replace(/^www\\./, '');\n if (stripped.length <= BARE_URL_MAX_DISPLAY) return stripped;\n return stripped.slice(0, BARE_URL_MAX_DISPLAY - 1) + '\\u2026';\n}\n\nfunction renderInlineText(\n textEl: d3Selection.Selection<SVGTextElement, unknown, null, undefined>,\n text: string,\n palette: PaletteColors,\n fontSize?: number\n): void {\n const spans = parseInlineMarkdown(text);\n for (const span of spans) {\n if (span.href) {\n // Bare URLs (text === href or href with https:// prepended) get truncated display;\n // markdown links [text](url) keep their user-chosen text as-is.\n const isBareUrl =\n span.text === span.href ||\n `https://${span.text}` === span.href;\n const display = isBareUrl ? truncateBareUrl(span.text) : span.text;\n const a = textEl.append('a').attr('href', span.href);\n a.append('tspan')\n .text(display)\n .attr('fill', palette.primary)\n .style('text-decoration', 'underline');\n } else {\n const tspan = textEl.append('tspan').text(span.text);\n if (span.bold) tspan.attr('font-weight', 'bold');\n if (span.italic) tspan.attr('font-style', 'italic');\n if (span.code) {\n tspan.attr('font-family', 'monospace');\n if (fontSize) tspan.attr('font-size', fontSize - 1);\n }\n }\n }\n}\n\nfunction wrapTextLines(text: string, maxChars: number): string[] {\n const rawLines = text.split('\\n');\n const wrapped: string[] = [];\n for (const line of rawLines) {\n if (line.length <= maxChars) {\n wrapped.push(line);\n } else {\n const words = line.split(' ');\n let current = '';\n for (const word of words) {\n if (current && (current + ' ' + word).length > maxChars) {\n wrapped.push(current);\n current = word;\n } else {\n current = current ? current + ' ' + word : word;\n }\n }\n if (current) wrapped.push(current);\n }\n }\n return wrapped;\n}\n\n// Mix two hex colors in sRGB: pct% of a, rest of b\nfunction mix(a: string, b: string, pct: number): string {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n}\n\n// Shared fill/stroke helpers\nconst fill = (palette: PaletteColors, isDark: boolean): string =>\n mix(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);\nconst stroke = (palette: PaletteColors): string => palette.textMuted;\nconst SW = 1.5;\nconst W = PARTICIPANT_BOX_WIDTH;\nconst H = PARTICIPANT_BOX_HEIGHT;\n\n// ============================================================\n// Participant Shape Renderers\n// ============================================================\n\nfunction renderRectParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', H)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW);\n}\n\nfunction renderServiceParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', H)\n .attr('rx', SERVICE_BORDER_RADIUS)\n .attr('ry', SERVICE_BORDER_RADIUS)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW);\n}\n\nfunction renderActorParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors\n): void {\n // Stick figure — no background, natural proportions\n const headR = 8;\n const cx = 0;\n const headY = headR + 2;\n const bodyTopY = headY + headR + 1;\n const bodyBottomY = H * 0.65;\n const legY = H - 2;\n const armSpan = 16;\n const legSpan = 12;\n const s = stroke(palette);\n const actorSW = 2.5;\n\n g.append('circle')\n .attr('cx', cx)\n .attr('cy', headY)\n .attr('r', headR)\n .attr('fill', 'none')\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx)\n .attr('y1', bodyTopY)\n .attr('x2', cx)\n .attr('y2', bodyBottomY)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx - armSpan)\n .attr('y1', bodyTopY + 5)\n .attr('x2', cx + armSpan)\n .attr('y2', bodyTopY + 5)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx)\n .attr('y1', bodyBottomY)\n .attr('x2', cx - legSpan)\n .attr('y2', legY)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n\n g.append('line')\n .attr('x1', cx)\n .attr('y1', bodyBottomY)\n .attr('x2', cx + legSpan)\n .attr('y2', legY)\n .attr('stroke', s)\n .attr('stroke-width', actorSW);\n}\n\nfunction renderDatabaseParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Cylinder fitting within W x H\n const ry = 7;\n const topY = ry;\n const bodyH = H - ry * 2;\n const f = fill(palette, isDark);\n const s = stroke(palette);\n\n // Bottom ellipse (drawn first — rect will cover its top arc)\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY + bodyH)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Filled body (no stroke) to hide the top arc of the bottom ellipse\n g.append('rect')\n .attr('class', 'participant-body')\n .attr('x', -W / 2)\n .attr('y', topY)\n .attr('width', W)\n .attr('height', bodyH)\n .attr('fill', f)\n .attr('stroke', 'none');\n\n // Side lines\n g.append('line')\n .attr('x1', -W / 2)\n .attr('y1', topY)\n .attr('x2', -W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n g.append('line')\n .attr('x1', W / 2)\n .attr('y1', topY)\n .attr('x2', W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Top ellipse cap (drawn last, on top)\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n}\n\nfunction renderQueueParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Horizontal cylinder (pipe) — like database rotated 90 degrees\n const rx = 10;\n const leftX = -W / 2 + rx;\n const bodyW = W - rx * 2;\n const f = fill(palette, isDark);\n const s = stroke(palette);\n\n // Right ellipse (back face, drawn first — rect will cover its left arc)\n g.append('ellipse')\n .attr('cx', leftX + bodyW)\n .attr('cy', H / 2)\n .attr('rx', rx)\n .attr('ry', H / 2)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Body rect (no stroke) to hide left arc of right ellipse\n g.append('rect')\n .attr('class', 'participant-body')\n .attr('x', leftX)\n .attr('y', 0)\n .attr('width', bodyW)\n .attr('height', H)\n .attr('fill', f)\n .attr('stroke', 'none');\n\n // Top and bottom lines\n g.append('line')\n .attr('x1', leftX)\n .attr('y1', 0)\n .attr('x2', leftX + bodyW)\n .attr('y2', 0)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n g.append('line')\n .attr('x1', leftX)\n .attr('y1', H)\n .attr('x2', leftX + bodyW)\n .attr('y2', H)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n\n // Left ellipse (front face, drawn last)\n g.append('ellipse')\n .attr('cx', leftX)\n .attr('cy', H / 2)\n .attr('rx', rx)\n .attr('ry', H / 2)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n}\n\nfunction renderCacheParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Dashed cylinder — variation of database to convey ephemeral storage\n const ry = 7;\n const topY = ry;\n const bodyH = H - ry * 2;\n const f = fill(palette, isDark);\n const s = stroke(palette);\n const dash = '4 3';\n\n // Bottom ellipse (back face)\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY + bodyH)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n\n g.append('rect')\n .attr('class', 'participant-body')\n .attr('x', -W / 2)\n .attr('y', topY)\n .attr('width', W)\n .attr('height', bodyH)\n .attr('fill', f)\n .attr('stroke', 'none');\n\n g.append('line')\n .attr('x1', -W / 2)\n .attr('y1', topY)\n .attr('x2', -W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n g.append('line')\n .attr('x1', W / 2)\n .attr('y1', topY)\n .attr('x2', W / 2)\n .attr('y2', topY + bodyH)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n\n // Top ellipse cap\n g.append('ellipse')\n .attr('cx', 0)\n .attr('cy', topY)\n .attr('rx', W / 2)\n .attr('ry', ry)\n .attr('fill', f)\n .attr('stroke', s)\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', dash);\n}\n\nfunction renderNetworkingParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Hexagon fitting within W x H\n const inset = 16;\n const points = [\n `${-W / 2 + inset},0`,\n `${W / 2 - inset},0`,\n `${W / 2},${H / 2}`,\n `${W / 2 - inset},${H}`,\n `${-W / 2 + inset},${H}`,\n `${-W / 2},${H / 2}`,\n ].join(' ');\n g.append('polygon')\n .attr('points', points)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW);\n}\n\nfunction renderFrontendParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Monitor shape fitting within W x H\n const screenH = H - 10;\n const s = stroke(palette);\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', screenH)\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', s)\n .attr('stroke-width', SW);\n // Stand\n g.append('line')\n .attr('x1', 0)\n .attr('y1', screenH)\n .attr('x2', 0)\n .attr('y2', H - 2)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n // Base\n g.append('line')\n .attr('x1', -14)\n .attr('y1', H - 2)\n .attr('x2', 14)\n .attr('y2', H - 2)\n .attr('stroke', s)\n .attr('stroke-width', SW);\n}\n\nfunction renderExternalParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n // Dashed border rectangle\n g.append('rect')\n .attr('x', -W / 2)\n .attr('y', 0)\n .attr('width', W)\n .attr('height', H)\n .attr('rx', 2)\n .attr('ry', 2)\n .attr('fill', fill(palette, isDark))\n .attr('stroke', stroke(palette))\n .attr('stroke-width', SW)\n .attr('stroke-dasharray', '6 3');\n}\n\nfunction renderGatewayParticipant(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n palette: PaletteColors,\n isDark: boolean\n): void {\n renderRectParticipant(g, palette, isDark);\n}\n\n// ============================================================\n// Collapsible Section Support\n// ============================================================\n\nexport interface SectionMessageGroup {\n section: import('./parser').SequenceSection;\n messageIndices: number[]; // indices into messages[]\n}\n\nexport interface SequenceRenderOptions {\n collapsedSections?: Set<number>; // keyed by section lineNumber\n expandedNoteLines?: Set<number>; // keyed by note lineNumber; undefined = all expanded (CLI default)\n exportWidth?: number; // Explicit width for CLI/export rendering (bypasses getBoundingClientRect)\n}\n\n/**\n * Group messages by the top-level section that precedes them.\n * Messages before the first section are ungrouped (always visible).\n * Only top-level sections are collapsible — sections inside blocks are excluded.\n */\nexport function groupMessagesBySection(\n elements: SequenceElement[],\n messages: SequenceMessage[]\n): SectionMessageGroup[] {\n const groups: SectionMessageGroup[] = [];\n let currentGroup: SectionMessageGroup | null = null;\n\n // Recursively collect all message indices from an element subtree\n const collectIndices = (els: SequenceElement[]): number[] => {\n const indices: number[] = [];\n for (const el of els) {\n if (isSequenceBlock(el)) {\n indices.push(\n ...collectIndices(el.children),\n ...collectIndices(el.elseChildren)\n );\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n indices.push(...collectIndices(branch.children));\n }\n }\n } else if (isSequenceSection(el) || isSequenceNote(el)) {\n // Sections and notes inside blocks are not messages — skip\n continue;\n } else {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n return indices;\n };\n\n for (const el of elements) {\n if (isSequenceSection(el)) {\n // Start a new group for this top-level section\n currentGroup = { section: el, messageIndices: [] };\n groups.push(currentGroup);\n } else if (currentGroup) {\n // Collect messages from this element into the current group\n if (isSequenceBlock(el)) {\n currentGroup.messageIndices.push(...collectIndices([el]));\n } else if (!isSequenceNote(el)) {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) currentGroup.messageIndices.push(idx);\n }\n }\n // Messages before the first section are ungrouped — skip\n }\n\n return groups;\n}\n\n// ============================================================\n// Render Sequence Builder (stack-based return placement)\n// ============================================================\n\nexport interface RenderStep {\n type: 'call' | 'return';\n from: string;\n to: string;\n label: string;\n messageIndex: number;\n async?: boolean;\n}\n\n/**\n * Build an ordered render sequence from flat messages.\n * Uses a call stack to infer where returns should be placed:\n * returns appear after all nested sub-calls complete.\n */\nexport function buildRenderSequence(messages: SequenceMessage[]): RenderStep[] {\n const steps: RenderStep[] = [];\n const stack: {\n from: string;\n to: string;\n returnLabel?: string;\n messageIndex: number;\n }[] = [];\n\n for (let mi = 0; mi < messages.length; mi++) {\n const msg = messages[mi];\n // Pop returns for callees that are no longer the sender\n while (stack.length > 0) {\n const top = stack[stack.length - 1];\n if (top.to === msg.from) break; // callee is still working\n stack.pop();\n steps.push({\n type: 'return',\n from: top.to,\n to: top.from,\n label: top.returnLabel || '',\n messageIndex: top.messageIndex,\n });\n }\n\n // Emit call\n steps.push({\n type: 'call',\n from: msg.from,\n to: msg.to,\n label: msg.label,\n messageIndex: mi,\n ...(msg.async ? { async: true } : {}),\n });\n\n // Async messages: no return arrow, no activation on target\n if (msg.async) {\n continue;\n }\n\n if (msg.from === msg.to) {\n // Self-call: immediately emit return (completes instantly)\n steps.push({\n type: 'return',\n from: msg.to,\n to: msg.from,\n label: msg.returnLabel || '',\n messageIndex: mi,\n });\n } else {\n // Push onto stack for pending return\n stack.push({\n from: msg.from,\n to: msg.to,\n returnLabel: msg.returnLabel,\n messageIndex: mi,\n });\n }\n }\n\n // Flush remaining returns\n while (stack.length > 0) {\n const top = stack.pop()!;\n steps.push({\n type: 'return',\n from: top.to,\n to: top.from,\n label: top.returnLabel || '',\n messageIndex: top.messageIndex,\n });\n }\n\n return steps;\n}\n\n// ============================================================\n// Activation Computation\n// ============================================================\n\nexport interface Activation {\n participantId: string;\n startStep: number;\n endStep: number;\n depth: number;\n}\n\n/**\n * Compute activation rectangles from render steps.\n * Each call pushes onto the callee's stack; each return pops it.\n */\nexport function computeActivations(steps: RenderStep[]): Activation[] {\n const activations: Activation[] = [];\n // Per-participant stack of open activations (step index)\n const stacks = new Map<string, number[]>();\n\n const getStack = (id: string): number[] => {\n if (!stacks.has(id)) stacks.set(id, []);\n return stacks.get(id)!;\n };\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n if (step.type === 'call') {\n const s = getStack(step.to);\n s.push(i);\n } else {\n // return: step.from is the callee returning\n const s = getStack(step.from);\n if (s.length > 0) {\n const startIdx = s.pop()!;\n activations.push({\n participantId: step.from,\n startStep: startIdx,\n endStep: i,\n depth: s.length,\n });\n }\n }\n }\n\n return activations;\n}\n\n// ============================================================\n// Position Override Sorting\n// ============================================================\n\n/**\n * Reorder participants based on explicit `position` overrides.\n * Positive positions are 0-based from the left; negative positions count from the right (-1 = last).\n * Unpositioned participants maintain their relative order, filling remaining slots.\n */\nexport function applyPositionOverrides(\n participants: SequenceParticipant[]\n): SequenceParticipant[] {\n if (!participants.some((p) => p.position !== undefined)) return participants;\n\n const total = participants.length;\n const positioned: { participant: SequenceParticipant; index: number }[] = [];\n const unpositioned: SequenceParticipant[] = [];\n\n for (const p of participants) {\n if (p.position !== undefined) {\n // Resolve negative: -1 → last, -2 → second-to-last\n let idx = p.position < 0 ? total + p.position : p.position;\n // Clamp to valid range\n idx = Math.max(0, Math.min(total - 1, idx));\n positioned.push({ participant: p, index: idx });\n } else {\n unpositioned.push(p);\n }\n }\n\n // Sort positioned by target index for deterministic placement\n positioned.sort((a, b) => a.index - b.index);\n\n // Place positioned participants, resolving conflicts by finding nearest free slot\n const result: (SequenceParticipant | null)[] = new Array(total).fill(null);\n const usedIndices = new Set<number>();\n\n for (const { participant, index } of positioned) {\n let idx = index;\n if (usedIndices.has(idx)) {\n // Find nearest free slot\n for (let offset = 1; offset < total; offset++) {\n if (idx + offset < total && !usedIndices.has(idx + offset)) {\n idx = idx + offset;\n break;\n }\n if (idx - offset >= 0 && !usedIndices.has(idx - offset)) {\n idx = idx - offset;\n break;\n }\n }\n }\n result[idx] = participant;\n usedIndices.add(idx);\n }\n\n // Fill remaining slots with unpositioned participants in order\n let uIdx = 0;\n for (let i = 0; i < total; i++) {\n if (result[i] === null) {\n result[i] = unpositioned[uIdx++];\n }\n }\n\n return result as SequenceParticipant[];\n}\n\n// Group Ordering\n// ============================================================\n\n/**\n * Reorder participants so that members of the same group are adjacent.\n * Groups appear in declaration order, followed by ungrouped participants.\n */\nexport function applyGroupOrdering(\n participants: SequenceParticipant[],\n groups: SequenceGroup[]\n): SequenceParticipant[] {\n if (groups.length === 0) return participants;\n\n const groupedIds = new Set(groups.flatMap((g) => g.participantIds));\n const result: SequenceParticipant[] = [];\n const placed = new Set<string>();\n\n // Place grouped participants in group declaration order\n for (const group of groups) {\n for (const id of group.participantIds) {\n const p = participants.find((pp) => pp.id === id);\n if (p && !placed.has(id)) {\n result.push(p);\n placed.add(id);\n }\n }\n }\n\n // Append ungrouped participants in their original order\n for (const p of participants) {\n if (!groupedIds.has(p.id) && !placed.has(p.id)) {\n result.push(p);\n placed.add(p.id);\n }\n }\n\n return result;\n}\n\n// Main Renderer\n// ============================================================\n\n/**\n * Render a sequence diagram into the given container element.\n */\nexport function renderSequenceDiagram(\n container: HTMLDivElement,\n parsed: ParsedSequenceDgmo,\n palette: PaletteColors,\n isDark: boolean,\n _onNavigateToLine?: (line: number) => void,\n options?: SequenceRenderOptions\n): void {\n // Clear previous content\n d3Selection.select(container).selectAll('*').remove();\n\n const { title, messages, elements, groups, options: parsedOptions } = parsed;\n const collapsedSections = options?.collapsedSections;\n const expandedNoteLines = options?.expandedNoteLines;\n const collapseNotesDisabled = parsedOptions['collapse-notes']?.toLowerCase() === 'no';\n // A note is expanded if: expandedNoteLines is undefined (CLI/export),\n // collapse-notes: no is set, or the note's lineNumber is in the set.\n const isNoteExpanded = (note: SequenceNote): boolean =>\n expandedNoteLines === undefined || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);\n const participants = applyPositionOverrides(\n applyGroupOrdering(parsed.participants, groups)\n );\n if (participants.length === 0) return;\n\n const activationsOff = parsedOptions.activations?.toLowerCase() === 'off';\n\n // Build hidden message set for collapse support\n const hiddenMsgIndices = new Set<number>();\n if (collapsedSections && collapsedSections.size > 0) {\n const sectionGroups = groupMessagesBySection(elements, messages);\n for (const grp of sectionGroups) {\n if (collapsedSections.has(grp.section.lineNumber)) {\n for (const idx of grp.messageIndices) {\n hiddenMsgIndices.add(idx);\n }\n }\n }\n }\n\n // Build render sequence with stack-based return placement\n // Run on ALL messages first (preserves call stack correctness), then filter\n const allRenderSteps = buildRenderSequence(messages);\n let renderSteps =\n hiddenMsgIndices.size > 0\n ? allRenderSteps.filter((s) => !hiddenMsgIndices.has(s.messageIndex))\n : allRenderSteps;\n // Drop unlabeled returns — they add visual noise without conveying information.\n // Labeled returns (explicit <- value) are kept.\n renderSteps = renderSteps.filter(\n (s) => s.type === 'call' || s.label\n );\n const activations = activationsOff ? [] : computeActivations(renderSteps);\n const stepSpacing = 35;\n\n // --- Block-aware Y spacing ---\n // Extra spacing constants for block boundaries\n const BLOCK_HEADER_SPACE = 30; // Extra space for frame label above first message in a block\n const BLOCK_AFTER_SPACE = 15; // Extra space after a block ends (before next sibling)\n const FRAME_PADDING_TOP = 42; // Vertical padding from frame top to first message\n\n // Build maps from messageIndex to render step indices (needed early for spacing)\n const msgToFirstStep = new Map<number, number>();\n const msgToLastStep = new Map<number, number>();\n renderSteps.forEach((step, si) => {\n if (!msgToFirstStep.has(step.messageIndex)) {\n msgToFirstStep.set(step.messageIndex, si);\n }\n msgToLastStep.set(step.messageIndex, si);\n });\n\n // Map a note to the first render-step index of its preceding message\n // (the forward/call arrow, not the return arrow).\n // If the note's closest preceding message is hidden (collapsed section), return -1\n // so the note is hidden along with its section.\n const findAssociatedFirstStep = (note: SequenceNote): number => {\n // First find the closest preceding message (ignoring hidden filter)\n let closestMsgIndex = -1;\n let closestLine = -1;\n for (let mi = 0; mi < messages.length; mi++) {\n if (\n messages[mi].lineNumber < note.lineNumber &&\n messages[mi].lineNumber > closestLine\n ) {\n closestLine = messages[mi].lineNumber;\n closestMsgIndex = mi;\n }\n }\n // If the closest preceding message is hidden, hide the note too\n if (closestMsgIndex >= 0 && hiddenMsgIndices.has(closestMsgIndex)) {\n return -1;\n }\n if (closestMsgIndex < 0) return -1;\n return msgToFirstStep.get(closestMsgIndex) ?? -1;\n };\n\n // Find the first visible message index in an element subtree\n const findFirstMsgIndex = (els: SequenceElement[]): number => {\n for (const el of els) {\n if (isSequenceBlock(el)) {\n const idx = findFirstMsgIndex(el.children);\n if (idx >= 0) return idx;\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n const branchIdx = findFirstMsgIndex(branch.children);\n if (branchIdx >= 0) return branchIdx;\n }\n }\n const elseIdx = findFirstMsgIndex(el.elseChildren);\n if (elseIdx >= 0) return elseIdx;\n } else if (!isSequenceSection(el) && !isSequenceNote(el)) {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0 && !hiddenMsgIndices.has(idx)) return idx;\n }\n }\n return -1;\n };\n\n // Section layout constants\n const SECTION_TOP_PAD = 35; // space above section divider line (matches stepSpacing)\n const SECTION_BOTTOM_PAD = 45; // space below section divider line before next content\n\n // Block spacing via extraBeforeMsg (sections handled separately below)\n const extraBeforeMsg = new Map<number, number>();\n const addExtra = (msgIdx: number, amount: number) => {\n extraBeforeMsg.set(msgIdx, (extraBeforeMsg.get(msgIdx) || 0) + amount);\n };\n\n const markBlockSpacing = (els: SequenceElement[]): void => {\n for (let i = 0; i < els.length; i++) {\n const el = els[i];\n if (isSequenceSection(el)) continue; // sections handled separately\n if (!isSequenceBlock(el)) continue;\n\n const firstIdx = findFirstMsgIndex(el.children);\n if (firstIdx >= 0) addExtra(firstIdx, BLOCK_HEADER_SPACE);\n\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n const firstBranchIdx = findFirstMsgIndex(branch.children);\n if (firstBranchIdx >= 0) addExtra(firstBranchIdx, BLOCK_HEADER_SPACE);\n markBlockSpacing(branch.children);\n }\n }\n\n const firstElseIdx = findFirstMsgIndex(el.elseChildren);\n if (firstElseIdx >= 0) addExtra(firstElseIdx, BLOCK_HEADER_SPACE);\n\n markBlockSpacing(el.children);\n markBlockSpacing(el.elseChildren);\n\n if (i + 1 < els.length) {\n const nextIdx = findFirstMsgIndex([els[i + 1]]);\n if (nextIdx >= 0) addExtra(nextIdx, BLOCK_AFTER_SPACE);\n }\n }\n };\n\n if (elements && elements.length > 0) {\n markBlockSpacing(elements);\n }\n\n // Note spacing — add vertical room after messages that have notes attached\n const NOTE_OFFSET_BELOW = 14; // gap between message arrow and top of note box\n // The next message label extends ~17px above its arrow line (8px offset + 9px cap height).\n // When notes share horizontal space with subsequent arrows, generous vertical clearance\n // is needed so note boxes don't visually cover message labels.\n const NOTE_TRAILING_GAP = 35;\n const computeNoteHeight = (text: string): number => {\n const lines = wrapTextLines(text, NOTE_CHARS_PER_LINE);\n return lines.length * NOTE_LINE_H + NOTE_PAD_V * 2;\n };\n let trailingNoteSpace = 0; // extra space for notes at the end with no following message\n const markNoteSpacing = (els: SequenceElement[]): void => {\n for (let i = 0; i < els.length; i++) {\n const el = els[i];\n if (isSequenceNote(el)) {\n // Total vertical extent of notes from the message arrow:\n // NOTE_OFFSET_BELOW (gap above first note)\n // + each note's height + NOTE_OFFSET_BELOW (inter-note gap)\n // + NOTE_TRAILING_GAP (gap below last note — clears next message label)\n let totalExtent = NOTE_OFFSET_BELOW;\n let j = i;\n while (j < els.length && isSequenceNote(els[j])) {\n const note = els[j] as SequenceNote;\n const noteH = isNoteExpanded(note)\n ? computeNoteHeight(note.text)\n : COLLAPSED_NOTE_H;\n totalExtent += noteH + NOTE_OFFSET_BELOW;\n j++;\n }\n // Replace the final inter-note gap with the larger trailing gap\n totalExtent += NOTE_TRAILING_GAP - NOTE_OFFSET_BELOW;\n // Only reserve space beyond the existing stepSpacing gap\n let extraNeeded = Math.max(0, totalExtent - stepSpacing);\n // Scan forward past sections, blocks, and other non-message elements to find next message\n let nextMsgIdx = -1;\n for (let k = j; k < els.length; k++) {\n nextMsgIdx = findFirstMsgIndex([els[k]]);\n if (nextMsgIdx >= 0) break;\n }\n // If a block follows, its frame extends FRAME_PADDING_TOP above the first\n // message but only BLOCK_HEADER_SPACE is reserved. Add the difference so\n // the note doesn't overlap the frame.\n if (j < els.length && isSequenceBlock(els[j])) {\n extraNeeded += FRAME_PADDING_TOP - BLOCK_HEADER_SPACE;\n }\n if (nextMsgIdx >= 0) {\n addExtra(nextMsgIdx, extraNeeded);\n } else {\n // Notes at the end — reserve only the excess beyond stepSpacing\n trailingNoteSpace = Math.max(trailingNoteSpace, extraNeeded);\n }\n // Skip over the consecutive notes we just processed\n i = j - 1;\n } else if (isSequenceBlock(el)) {\n markNoteSpacing(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n markNoteSpacing(branch.children);\n }\n }\n markNoteSpacing(el.elseChildren);\n }\n }\n };\n if (elements && elements.length > 0) {\n markNoteSpacing(elements);\n }\n\n // --- Section-aware Y layout ---\n // Sections get their own Y positions computed from content above them (not anchored\n // to messages below). This ensures toggling collapse/expand doesn't move the divider.\n\n // Walk top-level elements to build section regions\n interface SectionRegion {\n section: import('./parser').SequenceSection;\n msgIndices: number[]; // message indices belonging to this section\n }\n const preSectionMsgIndices: number[] = [];\n const sectionRegions: SectionRegion[] = [];\n {\n const collectMsgIndicesFromBlock = (\n block: import('./parser').SequenceBlock\n ): number[] => {\n const indices: number[] = [];\n for (const child of block.children) {\n if (isSequenceBlock(child)) {\n indices.push(...collectMsgIndicesFromBlock(child));\n } else if (!isSequenceSection(child) && !isSequenceNote(child)) {\n const idx = messages.indexOf(child as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n if (block.elseIfBranches) {\n for (const branch of block.elseIfBranches) {\n for (const child of branch.children) {\n if (isSequenceBlock(child)) {\n indices.push(...collectMsgIndicesFromBlock(child));\n } else if (!isSequenceSection(child) && !isSequenceNote(child)) {\n const idx = messages.indexOf(child as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n }\n }\n for (const child of block.elseChildren) {\n if (isSequenceBlock(child)) {\n indices.push(...collectMsgIndicesFromBlock(child));\n } else if (!isSequenceSection(child) && !isSequenceNote(child)) {\n const idx = messages.indexOf(child as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n return indices;\n };\n\n let currentTarget = preSectionMsgIndices;\n for (const el of elements) {\n if (isSequenceSection(el)) {\n const region: SectionRegion = { section: el, msgIndices: [] };\n sectionRegions.push(region);\n currentTarget = region.msgIndices;\n } else if (isSequenceBlock(el)) {\n currentTarget.push(...collectMsgIndicesFromBlock(el));\n } else {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) currentTarget.push(idx);\n }\n }\n }\n\n // Build mapping from original (all) render step index → filtered step index\n const allMsgToFirstStep = new Map<number, number>();\n allRenderSteps.forEach((step, si) => {\n if (!allMsgToFirstStep.has(step.messageIndex)) {\n allMsgToFirstStep.set(step.messageIndex, si);\n }\n });\n\n const originalToFiltered = new Map<number, number>();\n {\n let fi = 0;\n for (let oi = 0; oi < allRenderSteps.length; oi++) {\n const step = allRenderSteps[oi];\n if (\n !hiddenMsgIndices.has(step.messageIndex) &&\n (step.type === 'call' || step.label)\n ) {\n originalToFiltered.set(oi, fi);\n fi++;\n }\n }\n }\n\n // For each section, find the filtered step index where its padding should be inserted\n const findFilteredInsertionPoint = (origStep: number): number | null => {\n for (let i = origStep; i < allRenderSteps.length; i++) {\n const fi = originalToFiltered.get(i);\n if (fi !== undefined) return fi;\n }\n return null;\n };\n\n // Map: filtered step index → sections to insert before it (in document order)\n const sectionsBeforeStep = new Map<\n number,\n import('./parser').SequenceSection[]\n >();\n const trailingSections: import('./parser').SequenceSection[] = [];\n\n for (const region of sectionRegions) {\n if (region.msgIndices.length === 0) {\n trailingSections.push(region.section);\n continue;\n }\n const firstMsgIdx = region.msgIndices[0];\n const origStep = allMsgToFirstStep.get(firstMsgIdx);\n if (origStep === undefined) {\n trailingSections.push(region.section);\n continue;\n }\n const filteredStep = findFilteredInsertionPoint(origStep);\n if (filteredStep === null) {\n trailingSections.push(region.section);\n continue;\n }\n const existing = sectionsBeforeStep.get(filteredStep) || [];\n existing.push(region.section);\n sectionsBeforeStep.set(filteredStep, existing);\n }\n\n // Section message counts for collapsed labels\n const sectionMsgCounts = new Map<number, number>();\n for (const region of sectionRegions) {\n sectionMsgCounts.set(region.section.lineNumber, region.msgIndices.length);\n }\n\n // Group box layout constants (needed early for Y offset)\n const GROUP_PADDING_X = 15;\n const GROUP_PADDING_TOP = 22;\n const GROUP_PADDING_BOTTOM = 8;\n const GROUP_LABEL_SIZE = 11;\n\n // Compute cumulative Y positions for each step, with section dividers as stable anchors\n const titleOffset = title ? TITLE_HEIGHT : 0;\n const groupOffset =\n groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;\n const participantStartY =\n TOP_MARGIN + titleOffset + PARTICIPANT_Y_OFFSET + groupOffset;\n const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;\n const hasActors = participants.some((p) => p.type === 'actor');\n const messageStartOffset = MESSAGE_START_OFFSET + (hasActors ? 20 : 0);\n const stepYPositions: number[] = [];\n const sectionYPositions = new Map<number, number>(); // section lineNumber → Y\n let layoutEndY: number; // final Y after all steps and trailing sections\n {\n let curY = lifelineStartY0 + messageStartOffset;\n for (let i = 0; i < renderSteps.length; i++) {\n // Insert section padding before this step if needed\n const sections = sectionsBeforeStep.get(i);\n if (sections) {\n for (const sec of sections) {\n curY += SECTION_TOP_PAD;\n sectionYPositions.set(sec.lineNumber, curY);\n curY += SECTION_BOTTOM_PAD;\n }\n }\n\n const step = renderSteps[i];\n // Add extra spacing before the first render step of a flagged message (block spacing)\n if (msgToFirstStep.get(step.messageIndex) === i) {\n const extra = extraBeforeMsg.get(step.messageIndex) || 0;\n curY += extra;\n }\n stepYPositions.push(curY);\n curY += stepSpacing;\n }\n // Handle trailing sections (after all steps)\n for (const sec of trailingSections) {\n curY += SECTION_TOP_PAD;\n sectionYPositions.set(sec.lineNumber, curY);\n curY += SECTION_BOTTOM_PAD;\n }\n // Extend for trailing notes that have no following message\n curY += trailingNoteSpace;\n layoutEndY = curY;\n }\n\n // Helper: compute Y for a step index\n const stepY = (i: number) => stepYPositions[i];\n\n // Compute absolute Y positions for each note element\n const noteYMap = new Map<SequenceNote, number>();\n {\n const computeNotePositions = (els: SequenceElement[]): void => {\n for (let i = 0; i < els.length; i++) {\n const el = els[i];\n if (isSequenceNote(el)) {\n const si = findAssociatedFirstStep(el);\n if (si < 0) continue;\n // Check if there's a preceding note that we should stack below\n const prevNote = i > 0 && isSequenceNote(els[i - 1]) ? (els[i - 1] as SequenceNote) : null;\n const prevNoteY = prevNote ? noteYMap.get(prevNote) : undefined;\n let noteTopY: number;\n if (prevNoteY !== undefined && prevNote) {\n // Stack below previous note\n const prevNoteH = isNoteExpanded(prevNote)\n ? computeNoteHeight(prevNote.text)\n : COLLAPSED_NOTE_H;\n noteTopY = prevNoteY + prevNoteH + NOTE_OFFSET_BELOW;\n } else {\n // First note after a message\n noteTopY = stepY(si) + NOTE_OFFSET_BELOW;\n }\n noteYMap.set(el, noteTopY);\n } else if (isSequenceBlock(el)) {\n computeNotePositions(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n computeNotePositions(branch.children);\n }\n }\n computeNotePositions(el.elseChildren);\n }\n }\n };\n if (elements && elements.length > 0) {\n computeNotePositions(elements);\n }\n }\n\n // Ensure contentBottomY accounts for all note extents\n let contentBottomY =\n renderSteps.length > 0\n ? Math.max(\n stepYPositions[stepYPositions.length - 1] + stepSpacing,\n layoutEndY\n )\n : layoutEndY;\n for (const [note, noteTopY] of noteYMap) {\n const noteH = isNoteExpanded(note) ? computeNoteHeight(note.text) : COLLAPSED_NOTE_H;\n contentBottomY = Math.max(contentBottomY, noteTopY + noteH + NOTE_TRAILING_GAP);\n }\n const messageAreaHeight = contentBottomY - lifelineStartY0;\n const lifelineLength = messageAreaHeight + LIFELINE_TAIL;\n const totalWidth = Math.max(\n participants.length * PARTICIPANT_GAP,\n PARTICIPANT_BOX_WIDTH + 40\n );\n const totalHeight =\n participantStartY +\n PARTICIPANT_BOX_HEIGHT +\n Math.max(lifelineLength, 40) +\n 40;\n\n const containerWidth = options?.exportWidth ?? container.getBoundingClientRect().width;\n const svgWidth = Math.max(totalWidth, containerWidth);\n\n // Center the diagram horizontally\n const diagramWidth = participants.length * PARTICIPANT_GAP;\n const offsetX =\n Math.max(0, (svgWidth - diagramWidth) / 2) + PARTICIPANT_GAP / 2;\n\n // Build participant x-position lookup\n const participantX = new Map<string, number>();\n participants.forEach((p, i) => {\n participantX.set(p.id, offsetX + i * PARTICIPANT_GAP);\n });\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', '100%')\n .attr('height', totalHeight)\n .attr('viewBox', `0 0 ${svgWidth} ${totalHeight}`)\n .attr('preserveAspectRatio', 'xMidYMin meet')\n .attr('class', 'sequence-diagram')\n .style('font-family', FONT_FAMILY);\n\n // Define arrowhead markers\n const defs = svg.append('defs');\n\n // Filled arrowhead for call arrows\n defs\n .append('marker')\n .attr('id', 'seq-arrowhead')\n .attr('viewBox', `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`)\n .attr('refX', ARROWHEAD_SIZE)\n .attr('refY', ARROWHEAD_SIZE / 2)\n .attr('markerWidth', ARROWHEAD_SIZE)\n .attr('markerHeight', ARROWHEAD_SIZE)\n .attr('orient', 'auto')\n .append('polygon')\n .attr(\n 'points',\n `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`\n )\n .attr('fill', palette.text);\n\n // Open arrowhead for return arrows\n defs\n .append('marker')\n .attr('id', 'seq-arrowhead-open')\n .attr('viewBox', `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`)\n .attr('refX', ARROWHEAD_SIZE)\n .attr('refY', ARROWHEAD_SIZE / 2)\n .attr('markerWidth', ARROWHEAD_SIZE)\n .attr('markerHeight', ARROWHEAD_SIZE)\n .attr('orient', 'auto')\n .append('polyline')\n .attr(\n 'points',\n `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`\n )\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1.2);\n\n // Open arrowhead for async (fire-and-forget) arrows — same as return but text color\n defs\n .append('marker')\n .attr('id', 'seq-arrowhead-async')\n .attr('viewBox', `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`)\n .attr('refX', ARROWHEAD_SIZE)\n .attr('refY', ARROWHEAD_SIZE / 2)\n .attr('markerWidth', ARROWHEAD_SIZE)\n .attr('markerHeight', ARROWHEAD_SIZE)\n .attr('orient', 'auto')\n .append('polyline')\n .attr(\n 'points',\n `0,0 ${ARROWHEAD_SIZE},${ARROWHEAD_SIZE / 2} 0,${ARROWHEAD_SIZE}`\n )\n .attr('fill', 'none')\n .attr('stroke', palette.text)\n .attr('stroke-width', 1.2);\n\n // Render title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', svgWidth / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', 20)\n .attr('font-weight', 'bold')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n }\n }\n\n // Render group boxes (behind participant shapes)\n for (const group of groups) {\n if (group.participantIds.length === 0) continue;\n\n // Find X bounds from member participant positions\n const memberXs = group.participantIds\n .map((id) => participantX.get(id))\n .filter((x): x is number => x !== undefined);\n if (memberXs.length === 0) continue;\n\n const minX =\n Math.min(...memberXs) - PARTICIPANT_BOX_WIDTH / 2 - GROUP_PADDING_X;\n const maxX =\n Math.max(...memberXs) + PARTICIPANT_BOX_WIDTH / 2 + GROUP_PADDING_X;\n const boxY = participantStartY - GROUP_PADDING_TOP;\n const boxH =\n PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;\n\n // Group box background\n const resolvedGroupColor = group.color\n ? resolveColor(group.color, palette)\n : undefined;\n const fillColor = resolvedGroupColor\n ? mix(resolvedGroupColor, isDark ? palette.surface : palette.bg, 10)\n : isDark\n ? palette.surface\n : palette.bg;\n const strokeColor = resolvedGroupColor || palette.textMuted;\n\n svg\n .append('rect')\n .attr('x', minX)\n .attr('y', boxY)\n .attr('width', maxX - minX)\n .attr('height', boxH)\n .attr('rx', 6)\n .attr('fill', fillColor)\n .attr('stroke', strokeColor)\n .attr('stroke-width', 1)\n .attr('stroke-opacity', 0.5)\n .attr('class', 'group-box')\n .attr('data-group-line', String(group.lineNumber));\n\n // Group label\n svg\n .append('text')\n .attr('x', minX + 8)\n .attr('y', boxY + GROUP_LABEL_SIZE + 4)\n .attr('fill', strokeColor)\n .attr('font-size', GROUP_LABEL_SIZE)\n .attr('font-weight', 'bold')\n .attr('opacity', 0.7)\n .attr('class', 'group-label')\n .attr('data-group-line', String(group.lineNumber))\n .text(group.name);\n }\n\n // Render each participant\n const lifelineStartY = lifelineStartY0;\n participants.forEach((participant, index) => {\n const cx = offsetX + index * PARTICIPANT_GAP;\n const cy = participantStartY;\n\n renderParticipant(svg, participant, cx, cy, palette, isDark);\n\n // Render lifeline\n svg\n .append('line')\n .attr('x1', cx)\n .attr('y1', lifelineStartY)\n .attr('x2', cx)\n .attr('y2', lifelineStartY + lifelineLength)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '6 4')\n .attr('class', 'lifeline');\n });\n\n // Render block frames (behind everything else)\n const FRAME_PADDING_X = 30;\n // FRAME_PADDING_TOP declared earlier (near BLOCK_HEADER_SPACE)\n const FRAME_PADDING_BOTTOM = 15;\n const FRAME_LABEL_HEIGHT = 18;\n\n // Collect message indices from an element subtree\n const collectMsgIndices = (els: SequenceElement[]): number[] => {\n const indices: number[] = [];\n for (const el of els) {\n if (isSequenceBlock(el)) {\n indices.push(\n ...collectMsgIndices(el.children),\n ...collectMsgIndices(el.elseChildren)\n );\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n indices.push(...collectMsgIndices(branch.children));\n }\n }\n } else if (!isSequenceSection(el) && !isSequenceNote(el)) {\n const idx = messages.indexOf(el as SequenceMessage);\n if (idx >= 0) indices.push(idx);\n }\n }\n return indices;\n };\n\n // Collect deferred draws (rendered after activations so they appear on top)\n const deferredLabels: Array<{\n x: number;\n y: number;\n text: string;\n bold: boolean;\n italic: boolean;\n blockLine?: number;\n }> = [];\n const deferredLines: Array<{\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n }> = [];\n\n // Recursive block renderer — draws borders/dividers now, defers label text\n const renderBlockFrames = (els: SequenceElement[], depth: number): void => {\n for (const el of els) {\n if (!isSequenceBlock(el)) continue;\n\n const ifIndices = collectMsgIndices(el.children);\n const elseIfBranchData: { label: string; indices: number[] }[] = [];\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n elseIfBranchData.push({\n label: branch.label,\n indices: collectMsgIndices(branch.children),\n });\n }\n }\n const elseIndices = collectMsgIndices(el.elseChildren);\n const allIndices = [\n ...ifIndices,\n ...elseIfBranchData.flatMap((b) => b.indices),\n ...elseIndices,\n ];\n if (allIndices.length === 0) continue;\n\n // Find render step range\n let minStep = Infinity;\n let maxStep = -Infinity;\n for (const mi of allIndices) {\n const first = msgToFirstStep.get(mi);\n const last = msgToLastStep.get(mi);\n if (first !== undefined) minStep = Math.min(minStep, first);\n if (last !== undefined) maxStep = Math.max(maxStep, last);\n }\n if (minStep === Infinity) continue;\n\n // Find participant X range\n const involved = new Set<string>();\n for (const mi of allIndices) {\n involved.add(messages[mi].from);\n involved.add(messages[mi].to);\n }\n let minPX = Infinity;\n let maxPX = -Infinity;\n for (const pid of involved) {\n const px = participantX.get(pid);\n if (px !== undefined) {\n minPX = Math.min(minPX, px);\n maxPX = Math.max(maxPX, px);\n }\n }\n\n const frameX = minPX - FRAME_PADDING_X;\n const frameY = stepY(minStep) - FRAME_PADDING_TOP;\n const frameW = maxPX - minPX + FRAME_PADDING_X * 2;\n const frameH =\n stepY(maxStep) -\n stepY(minStep) +\n FRAME_PADDING_TOP +\n FRAME_PADDING_BOTTOM;\n\n // Frame border\n svg\n .append('rect')\n .attr('x', frameX)\n .attr('y', frameY)\n .attr('width', frameW)\n .attr('height', frameH)\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '2 3')\n .attr('rx', 3)\n .attr('ry', 3)\n .attr('class', 'block-frame')\n .attr('data-block-line', String(el.lineNumber));\n\n // Defer label text (rendered on top of activations later)\n deferredLabels.push({\n x: frameX + 6,\n y: frameY + FRAME_LABEL_HEIGHT - 4,\n text: `${el.type} ${el.label}`,\n bold: true,\n italic: false,\n blockLine: el.lineNumber,\n });\n\n // Else-if dividers\n for (const branchData of elseIfBranchData) {\n if (branchData.indices.length > 0) {\n let firstBranchStep = Infinity;\n for (const mi of branchData.indices) {\n const first = msgToFirstStep.get(mi);\n if (first !== undefined)\n firstBranchStep = Math.min(firstBranchStep, first);\n }\n if (firstBranchStep < Infinity) {\n const dividerY = stepY(firstBranchStep) - stepSpacing / 2;\n deferredLines.push({\n x1: frameX,\n y1: dividerY,\n x2: frameX + frameW,\n y2: dividerY,\n });\n deferredLabels.push({\n x: frameX + 6,\n y: dividerY + 14,\n text: `else if ${branchData.label}`,\n bold: false,\n italic: true,\n });\n }\n }\n }\n\n // Else divider\n if (elseIndices.length > 0) {\n let firstElseStep = Infinity;\n for (const mi of elseIndices) {\n const first = msgToFirstStep.get(mi);\n if (first !== undefined)\n firstElseStep = Math.min(firstElseStep, first);\n }\n if (firstElseStep < Infinity) {\n const dividerY = stepY(firstElseStep) - stepSpacing / 2;\n deferredLines.push({\n x1: frameX,\n y1: dividerY,\n x2: frameX + frameW,\n y2: dividerY,\n });\n deferredLabels.push({\n x: frameX + 6,\n y: dividerY + 14,\n text: 'else',\n bold: false,\n italic: true,\n });\n }\n }\n\n // Recurse into nested blocks\n renderBlockFrames(el.children, depth + 1);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n renderBlockFrames(branch.children, depth + 1);\n }\n }\n renderBlockFrames(el.elseChildren, depth + 1);\n }\n };\n\n if (elements && elements.length > 0) {\n renderBlockFrames(elements, 0);\n }\n\n // Render activation rectangles (behind arrows)\n const ACTIVATION_WIDTH = 10;\n const ACTIVATION_NEST_OFFSET = 6;\n activations.forEach((act) => {\n const px = participantX.get(act.participantId);\n if (px === undefined) return;\n\n const x = px - ACTIVATION_WIDTH / 2 + act.depth * ACTIVATION_NEST_OFFSET;\n const y1 = stepY(act.startStep);\n const y2 = stepY(act.endStep);\n\n // Collect message line numbers covered by this activation\n const coveredLines: number[] = [];\n for (let si = act.startStep; si <= act.endStep; si++) {\n const step = renderSteps[si];\n const msg = messages[step.messageIndex];\n if (msg) coveredLines.push(msg.lineNumber);\n }\n\n // Opaque background to mask the lifeline\n svg\n .append('rect')\n .attr('x', x)\n .attr('y', y1)\n .attr('width', ACTIVATION_WIDTH)\n .attr('height', y2 - y1)\n .attr('fill', isDark ? palette.surface : palette.bg);\n\n const actFill = mix(palette.primary, isDark ? palette.surface : palette.bg, isDark ? 15 : 30);\n svg\n .append('rect')\n .attr('x', x)\n .attr('y', y1)\n .attr('width', ACTIVATION_WIDTH)\n .attr('height', y2 - y1)\n .attr('fill', actFill)\n .attr('stroke', palette.primary)\n .attr('stroke-width', 1)\n .attr('stroke-opacity', 0.5)\n .attr('data-participant-id', act.participantId)\n .attr('data-msg-lines', coveredLines.join(','))\n .attr('data-line-number', coveredLines[0] ?? '')\n .attr('class', 'activation');\n });\n\n // Render deferred else dividers (on top of activations)\n for (const ln of deferredLines) {\n svg\n .append('line')\n .attr('x1', ln.x1)\n .attr('y1', ln.y1)\n .attr('x2', ln.x2)\n .attr('y2', ln.y2)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '2 3');\n }\n\n // Render deferred block labels (on top of activations)\n for (const lbl of deferredLabels) {\n const t = svg\n .append('text')\n .attr('x', lbl.x)\n .attr('y', lbl.y)\n .attr('fill', palette.text)\n .attr('font-size', 11)\n .attr('class', 'block-label')\n .text(lbl.text);\n if (lbl.bold) t.attr('font-weight', 'bold');\n if (lbl.italic) t.attr('font-style', 'italic');\n if (lbl.blockLine !== undefined)\n t.attr('data-block-line', String(lbl.blockLine));\n }\n\n // Helper: find max active activation depth for a participant at a step\n const activeDepthAt = (pid: string, stepIdx: number): number => {\n let maxDepth = -1;\n for (const act of activations) {\n if (\n act.participantId === pid &&\n act.startStep <= stepIdx &&\n stepIdx <= act.endStep &&\n act.depth > maxDepth\n ) {\n maxDepth = act.depth;\n }\n }\n return maxDepth;\n };\n\n // Helper: compute arrow endpoint X, snapping to activation box edge\n const arrowEdgeX = (\n pid: string,\n stepIdx: number,\n side: 'left' | 'right'\n ): number => {\n const px = participantX.get(pid)!;\n const depth = activeDepthAt(pid, stepIdx);\n if (depth < 0) return px;\n const offset = depth * ACTIVATION_NEST_OFFSET;\n return side === 'right'\n ? px + ACTIVATION_WIDTH / 2 + offset\n : px - ACTIVATION_WIDTH / 2 + offset;\n };\n\n // Render section dividers\n const leftmostX = Math.min(...Array.from(participantX.values()));\n const rightmostX = Math.max(...Array.from(participantX.values()));\n const sectionLineX1 = leftmostX - PARTICIPANT_BOX_WIDTH / 2 - 10;\n const sectionLineX2 = rightmostX + PARTICIPANT_BOX_WIDTH / 2 + 10;\n\n for (const region of sectionRegions) {\n const sec = region.section;\n const secY = sectionYPositions.get(sec.lineNumber);\n if (secY === undefined) continue;\n\n const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;\n const lineColor = sec.color\n ? resolveColor(sec.color, palette)\n : palette.textMuted;\n\n // Wrap section elements in a <g> for toggle.\n // IMPORTANT: only the <g> carries data-line-number / data-section —\n // children must NOT have them, otherwise the click walk-up resolves\n // to a line-number navigation before reaching data-section-toggle.\n const HIT_AREA_HEIGHT = 36;\n const sectionG = svg\n .append('g')\n .attr('data-section-toggle', '')\n .attr('data-line-number', String(sec.lineNumber))\n .attr('data-section', '')\n .attr('tabindex', '0')\n .attr('role', 'button')\n .attr('aria-expanded', String(!isCollapsed));\n\n // Full-width tinted band\n const BAND_HEIGHT = 22;\n const bandX = sectionLineX1 - 10;\n const bandWidth = sectionLineX2 - sectionLineX1 + 20;\n const bandOpacity = isCollapsed\n ? (isDark ? 0.35 : 0.25)\n : (isDark ? 0.1 : 0.08);\n sectionG\n .append('rect')\n .attr('x', bandX)\n .attr('y', secY - BAND_HEIGHT / 2)\n .attr('width', bandWidth)\n .attr('height', BAND_HEIGHT)\n .attr('fill', lineColor)\n .attr('opacity', bandOpacity)\n .attr('rx', 2)\n .attr('class', 'section-divider');\n\n // Build display label\n const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;\n const labelText = isCollapsed\n ? `${sec.label} (${msgCount} ${msgCount === 1 ? 'message' : 'messages'})`\n : sec.label;\n\n // Collapsed sections use white text for contrast against the darker band\n const labelColor = isCollapsed ? '#ffffff' : lineColor;\n\n // Chevron indicator\n const chevronSpace = 14;\n const labelX = (sectionLineX1 + sectionLineX2) / 2;\n const chevronX = labelX - (labelText.length * 3.5 + 8 + chevronSpace / 2);\n const chevronY = secY;\n if (isCollapsed) {\n // Right-pointing triangle ▶\n sectionG\n .append('path')\n .attr(\n 'd',\n `M ${chevronX} ${chevronY - 4} L ${chevronX + 6} ${chevronY} L ${chevronX} ${chevronY + 4} Z`\n )\n .attr('fill', labelColor)\n .attr('class', 'section-chevron');\n } else {\n // Down-pointing triangle ▼\n sectionG\n .append('path')\n .attr(\n 'd',\n `M ${chevronX - 1} ${chevronY - 3} L ${chevronX + 7} ${chevronY - 3} L ${chevronX + 3} ${chevronY + 3} Z`\n )\n .attr('fill', labelColor)\n .attr('class', 'section-chevron');\n }\n\n // Centered label text\n sectionG\n .append('text')\n .attr('x', labelX + chevronSpace / 2)\n .attr('y', secY + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', labelColor)\n .attr('font-size', 11)\n .attr('font-weight', 'bold')\n .attr('class', 'section-label')\n .text(labelText);\n }\n\n // Render steps (calls and returns in stack-inferred order)\n const SELF_CALL_WIDTH = 30;\n const SELF_CALL_HEIGHT = 25;\n renderSteps.forEach((step, i) => {\n const fromX = participantX.get(step.from);\n const toX = participantX.get(step.to);\n if (fromX === undefined || toX === undefined) return;\n\n const y = stepY(i);\n\n if (step.type === 'call') {\n if (step.from === step.to) {\n // Self-call: loopback arrow from right edge of activation\n const x = arrowEdgeX(step.from, i, 'right');\n svg\n .append('path')\n .attr(\n 'd',\n `M ${x} ${y} H ${x + SELF_CALL_WIDTH} V ${y + SELF_CALL_HEIGHT} H ${x}`\n )\n .attr('fill', 'none')\n .attr('stroke', palette.text)\n .attr('stroke-width', 1.2)\n .attr('marker-end', 'url(#seq-arrowhead)')\n .attr('class', 'message-arrow self-call')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n\n if (step.label) {\n const labelEl = svg\n .append('text')\n .attr('x', x + SELF_CALL_WIDTH + 5)\n .attr('y', y + SELF_CALL_HEIGHT / 2 + 4)\n .attr('text-anchor', 'start')\n .attr('fill', palette.text)\n .attr('font-size', 12)\n .attr('class', 'message-label')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n renderInlineText(labelEl, step.label, palette);\n }\n } else {\n // Normal call arrow — snap to activation box edges\n const goingRight = fromX < toX;\n const x1 = arrowEdgeX(step.from, i, goingRight ? 'right' : 'left');\n const x2 = arrowEdgeX(step.to, i, goingRight ? 'left' : 'right');\n\n const markerRef = step.async\n ? 'url(#seq-arrowhead-async)'\n : 'url(#seq-arrowhead)';\n svg\n .append('line')\n .attr('x1', x1)\n .attr('y1', y)\n .attr('x2', x2)\n .attr('y2', y)\n .attr('stroke', palette.text)\n .attr('stroke-width', 1.2)\n .attr('marker-end', markerRef)\n .attr('class', 'message-arrow')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n\n if (step.label) {\n const midX = (x1 + x2) / 2;\n const labelEl = svg\n .append('text')\n .attr('x', midX)\n .attr('y', y - 8)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', 12)\n .attr('class', 'message-label')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n renderInlineText(labelEl, step.label, palette);\n }\n }\n } else {\n if (step.from === step.to) {\n // Self-call return — already handled by the loopback path, skip\n return;\n }\n // Return arrow — snap to activation box edges\n const goingRight = fromX < toX;\n const x1 = arrowEdgeX(step.from, i, goingRight ? 'right' : 'left');\n const x2 = arrowEdgeX(step.to, i, goingRight ? 'left' : 'right');\n\n svg\n .append('line')\n .attr('x1', x1)\n .attr('y1', y)\n .attr('x2', x2)\n .attr('y2', y)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '6 4')\n .attr('marker-end', 'url(#seq-arrowhead-open)')\n .attr('class', 'return-arrow')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n\n if (step.label) {\n const midX = (x1 + x2) / 2;\n const labelEl = svg\n .append('text')\n .attr('x', midX)\n .attr('y', y - 6)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.textMuted)\n .attr('font-size', 11)\n .attr('class', 'message-label')\n .attr(\n 'data-line-number',\n String(messages[step.messageIndex].lineNumber)\n )\n .attr('data-msg-index', String(step.messageIndex));\n renderInlineText(labelEl, step.label, palette);\n }\n }\n });\n\n // Render notes — folded-corner boxes attached to participant lifelines\n const noteFill = isDark\n ? mix(palette.surface, palette.bg, 50)\n : mix(palette.bg, palette.surface, 15);\n\n const collapsedNoteFill = mix(palette.textMuted, palette.bg, 15);\n\n const renderNoteElements = (els: SequenceElement[]): void => {\n for (const el of els) {\n if (isSequenceNote(el)) {\n const px = participantX.get(el.participantId);\n if (px === undefined) continue;\n const noteTopY = noteYMap.get(el);\n if (noteTopY === undefined) continue;\n\n const expanded = isNoteExpanded(el);\n const isRight = el.position === 'right';\n\n if (expanded) {\n // --- Expanded note: full folded-corner box with wrapped text ---\n const wrappedLines = wrapTextLines(el.text, NOTE_CHARS_PER_LINE);\n const noteH = wrappedLines.length * NOTE_LINE_H + NOTE_PAD_V * 2;\n const maxLineLen = Math.max(...wrappedLines.map((l) => l.length));\n const noteW = Math.min(\n NOTE_MAX_W,\n Math.max(80, maxLineLen * NOTE_CHAR_W + NOTE_PAD_H * 2 + NOTE_FOLD)\n );\n const noteX = isRight\n ? px + ACTIVATION_WIDTH + NOTE_GAP\n : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;\n\n const noteG = svg\n .append('g')\n .attr('class', 'note')\n .attr('data-note-toggle', '')\n .attr('data-line-number', String(el.lineNumber))\n .attr('data-line-end', String(el.endLineNumber));\n\n // Folded-corner path\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX} ${noteTopY}`,\n `L ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,\n `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,\n `L ${noteX + noteW} ${noteTopY + noteH}`,\n `L ${noteX} ${noteTopY + noteH}`,\n 'Z',\n ].join(' ')\n )\n .attr('fill', noteFill)\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-box');\n\n // Fold triangle\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,\n `L ${noteX + noteW - NOTE_FOLD} ${noteTopY + NOTE_FOLD}`,\n `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,\n ].join(' ')\n )\n .attr('fill', 'none')\n .attr('stroke', palette.textMuted)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-fold');\n\n // Render text with inline markdown\n wrappedLines.forEach((line, li) => {\n const textY =\n noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;\n const isBullet = line.startsWith('- ');\n const bulletIndent = isBullet ? 10 : 0;\n const displayLine = isBullet ? line.slice(2) : line;\n const textEl = noteG\n .append('text')\n .attr('x', noteX + NOTE_PAD_H + bulletIndent)\n .attr('y', textY)\n .attr('fill', palette.text)\n .attr('font-size', NOTE_FONT_SIZE)\n .attr('class', 'note-text');\n\n if (isBullet) {\n noteG\n .append('text')\n .attr('x', noteX + NOTE_PAD_H)\n .attr('y', textY)\n .attr('fill', palette.text)\n .attr('font-size', NOTE_FONT_SIZE)\n .text('\\u2022');\n }\n\n renderInlineText(textEl, displayLine, palette, NOTE_FONT_SIZE);\n });\n } else {\n // --- Collapsed note: compact indicator ---\n const cFold = 6;\n const noteX = isRight\n ? px + ACTIVATION_WIDTH + NOTE_GAP\n : px - ACTIVATION_WIDTH - NOTE_GAP - COLLAPSED_NOTE_W;\n\n const noteG = svg\n .append('g')\n .attr('class', 'note note-collapsed')\n .attr('data-note-toggle', '')\n .attr('data-line-number', String(el.lineNumber))\n .attr('data-line-end', String(el.endLineNumber))\n .style('cursor', 'pointer');\n\n // Small folded-corner rectangle\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX} ${noteTopY}`,\n `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,\n `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`,\n `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + COLLAPSED_NOTE_H}`,\n `L ${noteX} ${noteTopY + COLLAPSED_NOTE_H}`,\n 'Z',\n ].join(' ')\n )\n .attr('fill', collapsedNoteFill)\n .attr('stroke', palette.border)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-box');\n\n // Fold triangle\n noteG\n .append('path')\n .attr(\n 'd',\n [\n `M ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,\n `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY + cFold}`,\n `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`,\n ].join(' ')\n )\n .attr('fill', 'none')\n .attr('stroke', palette.border)\n .attr('stroke-width', 0.75)\n .attr('class', 'note-fold');\n\n // \"...\" text\n noteG\n .append('text')\n .attr('x', noteX + COLLAPSED_NOTE_W / 2)\n .attr('y', noteTopY + COLLAPSED_NOTE_H / 2 + 3)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.textMuted)\n .attr('font-size', 9)\n .attr('class', 'note-text')\n .text('\\u2026');\n }\n } else if (isSequenceBlock(el)) {\n renderNoteElements(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n renderNoteElements(branch.children);\n }\n }\n renderNoteElements(el.elseChildren);\n }\n }\n };\n\n if (elements && elements.length > 0) {\n renderNoteElements(elements);\n }\n}\n\n/**\n * Build a mapping from each note's lineNumber to the lineNumber of its\n * associated message (the last message before the note in document order).\n * Used by the app to expand notes when cursor is on the associated message.\n */\nexport function buildNoteMessageMap(elements: SequenceElement[]): Map<number, number> {\n const map = new Map<number, number>();\n let lastMessageLine = -1;\n\n const walk = (els: SequenceElement[]): void => {\n for (const el of els) {\n if (isSequenceNote(el)) {\n if (lastMessageLine >= 0) {\n map.set(el.lineNumber, lastMessageLine);\n }\n } else if (isSequenceBlock(el)) {\n walk(el.children);\n if (el.elseIfBranches) {\n for (const branch of el.elseIfBranches) {\n walk(branch.children);\n }\n }\n walk(el.elseChildren);\n } else if (!isSequenceSection(el)) {\n // It's a message\n const msg = el as SequenceMessage;\n lastMessageLine = msg.lineNumber;\n }\n }\n };\n walk(elements);\n return map;\n}\n\nfunction renderParticipant(\n svg: d3Selection.Selection<SVGSVGElement, unknown, null, undefined>,\n participant: SequenceParticipant,\n cx: number,\n cy: number,\n palette: PaletteColors,\n isDark: boolean\n): void {\n const g = svg\n .append('g')\n .attr('transform', `translate(${cx}, ${cy})`)\n .attr('class', 'participant')\n .attr('data-participant-id', participant.id);\n\n // Render shape based on type\n switch (participant.type) {\n case 'actor':\n renderActorParticipant(g, palette);\n break;\n case 'database':\n renderDatabaseParticipant(g, palette, isDark);\n break;\n case 'service':\n renderServiceParticipant(g, palette, isDark);\n break;\n case 'queue':\n renderQueueParticipant(g, palette, isDark);\n break;\n case 'cache':\n renderCacheParticipant(g, palette, isDark);\n break;\n case 'networking':\n renderNetworkingParticipant(g, palette, isDark);\n break;\n case 'frontend':\n renderFrontendParticipant(g, palette, isDark);\n break;\n case 'external':\n renderExternalParticipant(g, palette, isDark);\n break;\n case 'gateway':\n renderGatewayParticipant(g, palette, isDark);\n break;\n default:\n renderRectParticipant(g, palette, isDark);\n break;\n }\n\n // Render label — below the shape for actors, centered inside for others\n const isActor = participant.type === 'actor';\n g.append('text')\n .attr('x', 0)\n .attr(\n 'y',\n isActor ? PARTICIPANT_BOX_HEIGHT + 14 : PARTICIPANT_BOX_HEIGHT / 2 + 5\n )\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', 13)\n .attr('font-weight', 500)\n .text(participant.label);\n}\n","import * as d3Scale from 'd3-scale';\nimport * as d3Selection from 'd3-selection';\nimport * as d3Shape from 'd3-shape';\nimport * as d3Array from 'd3-array';\nimport cloud from 'd3-cloud';\nimport { FONT_FAMILY } from './fonts';\nimport { injectBranding } from './branding';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport type D3ChartType =\n | 'slope'\n | 'wordcloud'\n | 'arc'\n | 'timeline'\n | 'venn'\n | 'quadrant'\n | 'sequence';\n\nexport interface D3DataItem {\n label: string;\n values: number[];\n color: string | null;\n lineNumber: number;\n}\n\nexport interface WordCloudWord {\n text: string;\n weight: number;\n lineNumber: number;\n}\n\nexport type WordCloudRotate = 'none' | 'mixed' | 'angled';\n\nexport interface WordCloudOptions {\n rotate: WordCloudRotate;\n max: number;\n minSize: number;\n maxSize: number;\n}\n\nconst DEFAULT_CLOUD_OPTIONS: WordCloudOptions = {\n rotate: 'none',\n max: 0,\n minSize: 14,\n maxSize: 80,\n};\n\nexport interface ArcLink {\n source: string;\n target: string;\n value: number;\n color: string | null;\n lineNumber: number;\n}\n\nexport type ArcOrder = 'appearance' | 'name' | 'group' | 'degree';\n\nexport interface ArcNodeGroup {\n name: string;\n nodes: string[];\n color: string | null;\n lineNumber: number;\n}\n\nexport type TimelineSort = 'time' | 'group';\n\nexport interface TimelineEvent {\n date: string;\n endDate: string | null;\n label: string;\n group: string | null;\n lineNumber: number;\n uncertain?: boolean;\n}\n\nexport interface TimelineGroup {\n name: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface TimelineEra {\n startDate: string;\n endDate: string;\n label: string;\n color: string | null;\n}\n\nexport interface TimelineMarker {\n date: string;\n label: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface VennSet {\n name: string;\n size: number;\n color: string | null;\n label: string | null;\n lineNumber: number;\n}\n\nexport interface VennOverlap {\n sets: string[];\n size: number;\n label: string | null;\n lineNumber: number;\n}\n\nexport interface QuadrantLabel {\n text: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface QuadrantPoint {\n label: string;\n x: number;\n y: number;\n lineNumber: number;\n}\n\nexport interface QuadrantLabels {\n topRight: QuadrantLabel | null;\n topLeft: QuadrantLabel | null;\n bottomLeft: QuadrantLabel | null;\n bottomRight: QuadrantLabel | null;\n}\n\n/** Optional explicit dimensions for CLI/export rendering (bypasses DOM layout). */\nexport interface D3ExportDimensions {\n width?: number;\n height?: number;\n}\n\nexport interface ParsedD3 {\n type: D3ChartType | null;\n title: string | null;\n titleLineNumber: number | null;\n orientation: 'horizontal' | 'vertical';\n periods: string[];\n data: D3DataItem[];\n words: WordCloudWord[];\n cloudOptions: WordCloudOptions;\n links: ArcLink[];\n arcOrder: ArcOrder;\n arcNodeGroups: ArcNodeGroup[];\n timelineEvents: TimelineEvent[];\n timelineGroups: TimelineGroup[];\n timelineEras: TimelineEra[];\n timelineMarkers: TimelineMarker[];\n timelineSort: TimelineSort;\n timelineScale: boolean;\n timelineSwimlanes: boolean;\n vennSets: VennSet[];\n vennOverlaps: VennOverlap[];\n vennShowValues: boolean;\n // Quadrant chart fields\n quadrantLabels: QuadrantLabels;\n quadrantPoints: QuadrantPoint[];\n quadrantXAxis: [string, string] | null;\n quadrantXAxisLineNumber: number | null;\n quadrantYAxis: [string, string] | null;\n quadrantYAxisLineNumber: number | null;\n quadrantTitleLineNumber: number | null;\n diagnostics: DgmoError[];\n error: string | null;\n}\n\n// ============================================================\n// Color Imports\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { PaletteColors } from './palettes';\nimport { getSeriesColors } from './palettes';\nimport type { DgmoError } from './diagnostics';\nimport { makeDgmoError, formatDgmoError, suggest } from './diagnostics';\n\n// ============================================================\n// Timeline Date Helper\n// ============================================================\n\n/**\n * Converts a date string (YYYY, YYYY-MM, YYYY-MM-DD) to a fractional year number.\n */\nexport function parseTimelineDate(s: string): number {\n const parts = s.split('-').map((p) => parseInt(p, 10));\n const year = parts[0];\n const month = parts.length >= 2 ? parts[1] : 1;\n const day = parts.length >= 3 ? parts[2] : 1;\n return year + (month - 1) / 12 + (day - 1) / 365;\n}\n\n/**\n * Adds a duration to a date string and returns the resulting date string.\n * Supports: d (days), w (weeks), m (months), y (years)\n * Supports decimals up to 2 places (e.g., 1.25y = 1 year 3 months)\n * Preserves the precision of the input date (YYYY, YYYY-MM, or YYYY-MM-DD).\n */\nexport function addDurationToDate(\n startDate: string,\n amount: number,\n unit: 'd' | 'w' | 'm' | 'y'\n): string {\n const parts = startDate.split('-').map((p) => parseInt(p, 10));\n const year = parts[0];\n const month = parts.length >= 2 ? parts[1] : 1;\n const day = parts.length >= 3 ? parts[2] : 1;\n\n const date = new Date(year, month - 1, day);\n\n switch (unit) {\n case 'd':\n // Round days to nearest integer\n date.setDate(date.getDate() + Math.round(amount));\n break;\n case 'w':\n // Convert weeks to days, round to nearest integer\n date.setDate(date.getDate() + Math.round(amount * 7));\n break;\n case 'm': {\n // Add whole months, then remaining days\n const wholeMonths = Math.floor(amount);\n const fractionalDays = Math.round((amount - wholeMonths) * 30);\n date.setMonth(date.getMonth() + wholeMonths);\n if (fractionalDays > 0) {\n date.setDate(date.getDate() + fractionalDays);\n }\n break;\n }\n case 'y': {\n // Add whole years, then remaining months\n const wholeYears = Math.floor(amount);\n const fractionalMonths = Math.round((amount - wholeYears) * 12);\n date.setFullYear(date.getFullYear() + wholeYears);\n if (fractionalMonths > 0) {\n date.setMonth(date.getMonth() + fractionalMonths);\n }\n break;\n }\n }\n\n // Preserve original precision\n const endYear = date.getFullYear();\n const endMonth = String(date.getMonth() + 1).padStart(2, '0');\n const endDay = String(date.getDate()).padStart(2, '0');\n\n if (parts.length === 1) {\n return String(endYear);\n } else if (parts.length === 2) {\n return `${endYear}-${endMonth}`;\n } else {\n return `${endYear}-${endMonth}-${endDay}`;\n }\n}\n\n// ============================================================\n// Parser\n// ============================================================\n\n/**\n * Parses D3 chart text format into structured data.\n */\nexport function parseD3(content: string, palette?: PaletteColors): ParsedD3 {\n const result: ParsedD3 = {\n type: null,\n title: null,\n titleLineNumber: null,\n orientation: 'horizontal',\n periods: [],\n data: [],\n words: [],\n cloudOptions: { ...DEFAULT_CLOUD_OPTIONS },\n links: [],\n arcOrder: 'appearance',\n arcNodeGroups: [],\n timelineEvents: [],\n timelineGroups: [],\n timelineEras: [],\n timelineMarkers: [],\n timelineSort: 'time',\n timelineScale: true,\n timelineSwimlanes: false,\n vennSets: [],\n vennOverlaps: [],\n vennShowValues: false,\n quadrantLabels: {\n topRight: null,\n topLeft: null,\n bottomLeft: null,\n bottomRight: null,\n },\n quadrantPoints: [],\n quadrantXAxis: null,\n quadrantXAxisLineNumber: null,\n quadrantYAxis: null,\n quadrantYAxisLineNumber: null,\n quadrantTitleLineNumber: null,\n diagnostics: [],\n error: null,\n };\n\n const fail = (line: number, message: string): ParsedD3 => {\n const diag = makeDgmoError(line, message);\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n return result;\n };\n\n if (!content || !content.trim()) {\n return fail(0, 'Empty content');\n }\n\n const lines = content.split('\\n');\n const freeformLines: string[] = [];\n let currentArcGroup: string | null = null;\n let currentTimelineGroup: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines\n if (!line) continue;\n\n // ## Section headers for arc diagram node grouping (before # comment check)\n const sectionMatch = line.match(/^#{2,}\\s+(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/);\n if (sectionMatch) {\n if (result.type === 'arc') {\n const name = sectionMatch[1].trim();\n const color = sectionMatch[2]\n ? resolveColor(sectionMatch[2].trim(), palette)\n : null;\n result.arcNodeGroups.push({ name, nodes: [], color, lineNumber });\n currentArcGroup = name;\n } else if (result.type === 'timeline') {\n const name = sectionMatch[1].trim();\n const color = sectionMatch[2]\n ? resolveColor(sectionMatch[2].trim(), palette)\n : null;\n result.timelineGroups.push({ name, color, lineNumber });\n currentTimelineGroup = name;\n }\n continue;\n }\n\n // Skip comments\n if (line.startsWith('#') || line.startsWith('//')) {\n continue;\n }\n\n // Arc link line: source -> target(color): weight\n if (result.type === 'arc') {\n const linkMatch = line.match(\n /^(.+?)\\s*->\\s*(.+?)(?:\\(([^)]+)\\))?\\s*(?::\\s*(\\d+(?:\\.\\d+)?))?$/\n );\n if (linkMatch) {\n const source = linkMatch[1].trim();\n const target = linkMatch[2].trim();\n const linkColor = linkMatch[3]\n ? resolveColor(linkMatch[3].trim(), palette)\n : null;\n result.links.push({\n source,\n target,\n value: linkMatch[4] ? parseFloat(linkMatch[4]) : 1,\n color: linkColor,\n lineNumber,\n });\n // Assign nodes to current group (first-appearance wins)\n if (currentArcGroup !== null) {\n const group = result.arcNodeGroups.find(\n (g) => g.name === currentArcGroup\n );\n if (group) {\n const allGrouped = new Set(\n result.arcNodeGroups.flatMap((g) => g.nodes)\n );\n if (!allGrouped.has(source)) group.nodes.push(source);\n if (!allGrouped.has(target)) group.nodes.push(target);\n }\n }\n continue;\n }\n }\n\n // Timeline era lines: era YYYY->YYYY: Label (color)\n if (result.type === 'timeline') {\n const eraMatch = line.match(\n /^era\\s+(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*->\\s*(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/\n );\n if (eraMatch) {\n const colorAnnotation = eraMatch[4]?.trim() || null;\n result.timelineEras.push({\n startDate: eraMatch[1],\n endDate: eraMatch[2],\n label: eraMatch[3].trim(),\n color: colorAnnotation\n ? resolveColor(colorAnnotation, palette)\n : null,\n });\n continue;\n }\n\n // Timeline marker lines: marker YYYY: Label (color)\n const markerMatch = line.match(\n /^marker\\s+(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/\n );\n if (markerMatch) {\n const colorAnnotation = markerMatch[3]?.trim() || null;\n result.timelineMarkers.push({\n date: markerMatch[1],\n label: markerMatch[2].trim(),\n color: colorAnnotation\n ? resolveColor(colorAnnotation, palette)\n : null,\n lineNumber,\n });\n continue;\n }\n }\n\n // Timeline event lines: duration, range, or point\n if (result.type === 'timeline') {\n // Duration event: 2026-07-15->30d: description (d=days, w=weeks, m=months, y=years)\n // Supports decimals up to 2 places (e.g., 1.25y = 1 year 3 months)\n // Supports uncertain end with ? prefix (e.g., ->?3m fades out the last 20%)\n const durationMatch = line.match(\n /^(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*->\\s*(\\?)?(\\d+(?:\\.\\d{1,2})?)([dwmy])\\s*:\\s*(.+)$/\n );\n if (durationMatch) {\n const startDate = durationMatch[1];\n const uncertain = durationMatch[2] === '?';\n const amount = parseFloat(durationMatch[3]);\n const unit = durationMatch[4] as 'd' | 'w' | 'm' | 'y';\n const endDate = addDurationToDate(startDate, amount, unit);\n result.timelineEvents.push({\n date: startDate,\n endDate,\n label: durationMatch[5].trim(),\n group: currentTimelineGroup,\n lineNumber,\n uncertain,\n });\n continue;\n }\n\n // Range event: 1655->1667: description (supports uncertain end: 1655->?1667)\n const rangeMatch = line.match(\n /^(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*->\\s*(\\?)?(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+)$/\n );\n if (rangeMatch) {\n result.timelineEvents.push({\n date: rangeMatch[1],\n endDate: rangeMatch[3],\n label: rangeMatch[4].trim(),\n group: currentTimelineGroup,\n lineNumber,\n uncertain: rangeMatch[2] === '?',\n });\n continue;\n }\n\n // Point event: 1718: description\n const pointMatch = line.match(\n /^(\\d{4}(?:-\\d{2})?(?:-\\d{2})?)\\s*:\\s*(.+)$/\n );\n if (pointMatch) {\n result.timelineEvents.push({\n date: pointMatch[1],\n endDate: null,\n label: pointMatch[2].trim(),\n group: currentTimelineGroup,\n lineNumber,\n });\n continue;\n }\n }\n\n // Venn overlap line: \"A & B: size\" or \"A & B & C: size \\\"label\\\"\"\n if (result.type === 'venn') {\n const overlapMatch = line.match(\n /^(.+?&.+?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*(?:\"([^\"]*)\")?\\s*$/\n );\n if (overlapMatch) {\n const sets = overlapMatch[1]\n .split('&')\n .map((s) => s.trim())\n .filter(Boolean)\n .sort();\n const size = parseFloat(overlapMatch[2]);\n const label = overlapMatch[3] ?? null;\n result.vennOverlaps.push({ sets, size, label, lineNumber });\n continue;\n }\n\n // Venn set line: \"Name: size\" or \"Name(color): size \\\"label\\\"\"\n const setMatch = line.match(\n /^(.+?)(?:\\(([^)]+)\\))?\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*(?:\"([^\"]*)\")?\\s*$/\n );\n if (setMatch) {\n const name = setMatch[1].trim();\n const color = setMatch[2]\n ? resolveColor(setMatch[2].trim(), palette)\n : null;\n const size = parseFloat(setMatch[3]);\n const label = setMatch[4] ?? null;\n result.vennSets.push({ name, size, color, label, lineNumber });\n continue;\n }\n }\n\n // Quadrant-specific parsing\n if (result.type === 'quadrant') {\n // x-axis: Low, High\n const xAxisMatch = line.match(/^x-axis\\s*:\\s*(.+)/i);\n if (xAxisMatch) {\n const parts = xAxisMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.quadrantXAxis = [parts[0], parts[1]];\n result.quadrantXAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // y-axis: Low, High\n const yAxisMatch = line.match(/^y-axis\\s*:\\s*(.+)/i);\n if (yAxisMatch) {\n const parts = yAxisMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.quadrantYAxis = [parts[0], parts[1]];\n result.quadrantYAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // Quadrant position labels: top-right: Label (color)\n const quadrantLabelRe =\n /^(top-right|top-left|bottom-left|bottom-right)\\s*:\\s*(.+)/i;\n const quadrantMatch = line.match(quadrantLabelRe);\n if (quadrantMatch) {\n const position = quadrantMatch[1].toLowerCase();\n const labelPart = quadrantMatch[2].trim();\n // Check for color annotation: \"Label (color)\" or \"Label(color)\"\n const labelColorMatch = labelPart.match(/^(.+?)\\s*\\(([^)]+)\\)\\s*$/);\n const text = labelColorMatch ? labelColorMatch[1].trim() : labelPart;\n const color = labelColorMatch\n ? resolveColor(labelColorMatch[2].trim(), palette)\n : null;\n const label: QuadrantLabel = { text, color, lineNumber };\n\n if (position === 'top-right') result.quadrantLabels.topRight = label;\n else if (position === 'top-left') result.quadrantLabels.topLeft = label;\n else if (position === 'bottom-left')\n result.quadrantLabels.bottomLeft = label;\n else if (position === 'bottom-right')\n result.quadrantLabels.bottomRight = label;\n continue;\n }\n\n // Data points: Label: x, y\n const pointMatch = line.match(\n /^(.+?):\\s*([0-9]*\\.?[0-9]+)\\s*,\\s*([0-9]*\\.?[0-9]+)\\s*$/\n );\n if (pointMatch) {\n const label = pointMatch[1].trim();\n // Skip if it looks like a quadrant position keyword\n const lowerLabel = label.toLowerCase();\n if (\n lowerLabel !== 'top-right' &&\n lowerLabel !== 'top-left' &&\n lowerLabel !== 'bottom-left' &&\n lowerLabel !== 'bottom-right'\n ) {\n result.quadrantPoints.push({\n label,\n x: parseFloat(pointMatch[2]),\n y: parseFloat(pointMatch[3]),\n lineNumber,\n });\n }\n continue;\n }\n }\n\n // Check for metadata lines\n const colonIndex = line.indexOf(':');\n\n if (colonIndex !== -1) {\n const rawKey = line.substring(0, colonIndex).trim();\n const key = rawKey.toLowerCase();\n\n // Check for color annotation in raw key: \"Label(color)\"\n const colorMatch = rawKey.match(/^(.+?)\\(([^)]+)\\)\\s*$/);\n\n if (key === 'chart') {\n const value = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (\n value === 'slope' ||\n value === 'wordcloud' ||\n value === 'arc' ||\n value === 'timeline' ||\n value === 'venn' ||\n value === 'quadrant' ||\n value === 'sequence'\n ) {\n result.type = value;\n } else {\n const validD3Types = ['slope', 'wordcloud', 'arc', 'timeline', 'venn', 'quadrant', 'sequence'];\n let msg = `Unsupported chart type: ${value}. Supported types: ${validD3Types.join(', ')}`;\n const hint = suggest(value, validD3Types);\n if (hint) msg += `. ${hint}`;\n return fail(lineNumber, msg);\n }\n continue;\n }\n\n if (key === 'title') {\n result.title = line.substring(colonIndex + 1).trim();\n result.titleLineNumber = lineNumber;\n if (result.type === 'quadrant') {\n result.quadrantTitleLineNumber = lineNumber;\n }\n continue;\n }\n\n if (key === 'orientation') {\n // Only arc and timeline support orientation\n if (result.type === 'arc' || result.type === 'timeline') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'horizontal' || v === 'vertical') {\n result.orientation = v;\n }\n }\n continue;\n }\n\n if (key === 'order') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'name' || v === 'group' || v === 'degree') {\n result.arcOrder = v;\n }\n continue;\n }\n\n if (key === 'sort') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'time' || v === 'group') {\n result.timelineSort = v;\n }\n continue;\n }\n\n if (key === 'swimlanes') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'on') {\n result.timelineSwimlanes = true;\n } else if (v === 'off') {\n result.timelineSwimlanes = false;\n }\n continue;\n }\n\n if (key === 'values') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'off') {\n result.vennShowValues = false;\n } else if (v === 'on') {\n result.vennShowValues = true;\n }\n continue;\n }\n\n if (key === 'rotate') {\n const v = line\n .substring(colonIndex + 1)\n .trim()\n .toLowerCase();\n if (v === 'none' || v === 'mixed' || v === 'angled') {\n result.cloudOptions.rotate = v;\n }\n continue;\n }\n\n if (key === 'max') {\n const v = parseInt(line.substring(colonIndex + 1).trim(), 10);\n if (!isNaN(v) && v > 0) {\n result.cloudOptions.max = v;\n }\n continue;\n }\n\n if (key === 'size') {\n const v = line.substring(colonIndex + 1).trim();\n const parts = v.split(',').map((s) => parseInt(s.trim(), 10));\n if (\n parts.length === 2 &&\n parts.every((n) => !isNaN(n) && n > 0) &&\n parts[0] < parts[1]\n ) {\n result.cloudOptions.minSize = parts[0];\n result.cloudOptions.maxSize = parts[1];\n }\n continue;\n }\n\n // Data line: \"Label: value1, value2\" or \"Label(color): value1, value2\"\n const labelPart = colorMatch ? colorMatch[1].trim() : rawKey;\n const colorPart = colorMatch\n ? resolveColor(colorMatch[2].trim(), palette)\n : null;\n const valuePart = line.substring(colonIndex + 1).trim();\n const values = valuePart.split(',').map((v) => v.trim());\n\n // Check if this looks like a data line (values should be numeric)\n const numericValues: number[] = [];\n let allNumeric = true;\n for (const v of values) {\n const num = parseFloat(v);\n if (isNaN(num)) {\n allNumeric = false;\n break;\n }\n numericValues.push(num);\n }\n\n if (allNumeric && numericValues.length > 0) {\n // For wordcloud, single numeric value = word weight\n if (result.type === 'wordcloud' && numericValues.length === 1) {\n result.words.push({\n text: labelPart,\n weight: numericValues[0],\n lineNumber,\n });\n } else {\n result.data.push({\n label: labelPart,\n values: numericValues,\n color: colorPart,\n lineNumber,\n });\n }\n continue;\n }\n }\n\n // For wordcloud: collect non-metadata lines for freeform fallback\n if (result.type === 'wordcloud') {\n if (colonIndex === -1 && !line.includes(' ')) {\n // Single bare word — structured mode\n result.words.push({ text: line, weight: 10, lineNumber });\n } else {\n // Multi-word line or non-numeric colon line — freeform text\n freeformLines.push(line);\n }\n continue;\n }\n\n // Period line: comma-separated labels with no colon before first comma\n // e.g., \"2020, 2024\" or \"Q1 2023, Q2 2023, Q3 2023\"\n if (\n result.periods.length === 0 &&\n line.includes(',') &&\n !line.includes(':')\n ) {\n const periods = line\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n if (periods.length >= 2) {\n result.periods = periods;\n continue;\n }\n }\n }\n\n // Validation\n if (!result.type) {\n return fail(1, 'Missing required \"chart:\" line (e.g., \"chart: slope\")');\n }\n\n // Sequence diagrams are parsed by their own dedicated parser\n if (result.type === 'sequence') {\n return result;\n }\n\n const warn = (line: number, message: string): void => {\n result.diagnostics.push(makeDgmoError(line, message, 'warning'));\n };\n\n if (result.type === 'wordcloud') {\n // If no structured words were found, parse freeform text as word frequencies\n if (result.words.length === 0 && freeformLines.length > 0) {\n result.words = tokenizeFreeformText(freeformLines.join(' '));\n }\n if (result.words.length === 0) {\n warn(1, 'No words found. Add words as \"word: weight\", one per line, or paste freeform text');\n }\n // Apply max word limit (words are already sorted by weight desc for freeform)\n if (\n result.cloudOptions.max > 0 &&\n result.words.length > result.cloudOptions.max\n ) {\n result.words = result.words\n .slice()\n .sort((a, b) => b.weight - a.weight)\n .slice(0, result.cloudOptions.max);\n }\n return result;\n }\n\n if (result.type === 'arc') {\n if (result.links.length === 0) {\n warn(1, 'No links found. Add links as \"Source -> Target: weight\" (e.g., \"Alice -> Bob: 5\")');\n }\n // Validate arc ordering vs groups\n if (result.arcNodeGroups.length > 0) {\n if (result.arcOrder === 'name' || result.arcOrder === 'degree') {\n warn(1, `Cannot use \"order: ${result.arcOrder}\" with ## section headers. Use \"order: group\" or remove section headers.`);\n result.arcOrder = 'group';\n }\n if (result.arcOrder === 'appearance') {\n result.arcOrder = 'group';\n }\n }\n return result;\n }\n\n if (result.type === 'timeline') {\n if (result.timelineEvents.length === 0) {\n warn(1, 'No events found. Add events as \"YYYY: description\" or \"YYYY->YYYY: description\"');\n }\n return result;\n }\n\n if (result.type === 'venn') {\n if (result.vennSets.length < 2) {\n return fail(1, 'At least 2 sets are required. Add sets as \"Name: size\" (e.g., \"Math: 100\")');\n }\n if (result.vennSets.length > 3) {\n return fail(1, 'At most 3 sets are supported. Remove extra sets.');\n }\n // Validate overlap references and sizes — skip invalid overlaps\n const setMap = new Map(result.vennSets.map((s) => [s.name, s.size]));\n const validOverlaps = [];\n for (const ov of result.vennOverlaps) {\n let valid = true;\n for (const setName of ov.sets) {\n if (!setMap.has(setName)) {\n result.diagnostics.push(makeDgmoError(ov.lineNumber, `Overlap references unknown set \"${setName}\". Define it first as \"${setName}: <size>\"`));\n if (!result.error) result.error = formatDgmoError(result.diagnostics[result.diagnostics.length - 1]);\n valid = false;\n break;\n }\n }\n if (!valid) continue;\n const minSetSize = Math.min(...ov.sets.map((s) => setMap.get(s)!));\n if (ov.size > minSetSize) {\n warn(ov.lineNumber, `Overlap size ${ov.size} exceeds smallest constituent set size ${minSetSize}`);\n }\n validOverlaps.push(ov);\n }\n result.vennOverlaps = validOverlaps;\n return result;\n }\n\n if (result.type === 'quadrant') {\n if (result.quadrantPoints.length === 0) {\n warn(1, 'No data points found. Add points as \"Label: x, y\" (e.g., \"Item A: 0.5, 0.7\")');\n }\n return result;\n }\n\n // Slope chart validation\n if (result.periods.length < 2) {\n return fail(1, 'Missing or invalid periods line. Provide at least 2 comma-separated period labels (e.g., \"2020, 2024\")');\n }\n\n if (result.data.length === 0) {\n warn(1, 'No data lines found. Add data as \"Label: value1, value2\" (e.g., \"Apple: 25, 35\")');\n }\n\n // Validate value counts match period count — warn and skip mismatched items\n for (const item of result.data) {\n if (item.values.length !== result.periods.length) {\n warn(item.lineNumber, `Data item \"${item.label}\" has ${item.values.length} value(s) but ${result.periods.length} period(s) are defined`);\n }\n }\n result.data = result.data.filter(\n (item) => item.values.length === result.periods.length\n );\n\n return result;\n}\n\n// ============================================================\n// Freeform Text Tokenizer (for word cloud)\n// ============================================================\n\nconst STOP_WORDS = new Set([\n 'a',\n 'an',\n 'the',\n 'and',\n 'or',\n 'but',\n 'in',\n 'on',\n 'at',\n 'to',\n 'for',\n 'of',\n 'with',\n 'by',\n 'is',\n 'am',\n 'are',\n 'was',\n 'were',\n 'be',\n 'been',\n 'being',\n 'have',\n 'has',\n 'had',\n 'do',\n 'does',\n 'did',\n 'will',\n 'would',\n 'could',\n 'should',\n 'may',\n 'might',\n 'shall',\n 'can',\n 'it',\n 'its',\n 'this',\n 'that',\n 'these',\n 'those',\n 'i',\n 'me',\n 'my',\n 'we',\n 'us',\n 'our',\n 'you',\n 'your',\n 'he',\n 'him',\n 'his',\n 'she',\n 'her',\n 'they',\n 'them',\n 'their',\n 'what',\n 'which',\n 'who',\n 'whom',\n 'how',\n 'when',\n 'where',\n 'why',\n 'not',\n 'no',\n 'nor',\n 'so',\n 'if',\n 'then',\n 'than',\n 'too',\n 'very',\n 'just',\n 'about',\n 'up',\n 'out',\n 'from',\n 'into',\n 'over',\n 'after',\n 'before',\n 'between',\n 'under',\n 'again',\n 'there',\n 'here',\n 'all',\n 'each',\n 'every',\n 'both',\n 'few',\n 'more',\n 'most',\n 'other',\n 'some',\n 'such',\n 'only',\n 'own',\n 'same',\n 'also',\n 'as',\n 'because',\n 'until',\n 'while',\n 'during',\n 'through',\n]);\n\nfunction tokenizeFreeformText(text: string): WordCloudWord[] {\n const counts = new Map<string, number>();\n\n // Split on non-letter/non-apostrophe chars, lowercase everything\n const tokens = text\n .toLowerCase()\n .split(/[^a-zA-Z']+/)\n .filter(Boolean);\n\n for (const raw of tokens) {\n // Strip leading/trailing apostrophes\n const word = raw.replace(/^'+|'+$/g, '');\n if (word.length < 2 || STOP_WORDS.has(word)) continue;\n counts.set(word, (counts.get(word) ?? 0) + 1);\n }\n\n return Array.from(counts.entries())\n .map(([text, count]) => ({ text, weight: count, lineNumber: 0 }))\n .sort((a, b) => b.weight - a.weight);\n}\n\n// ============================================================\n// Slope Chart Renderer\n// ============================================================\n\nconst SLOPE_MARGIN = { top: 80, bottom: 40, left: 80 };\nconst SLOPE_LABEL_FONT_SIZE = 14;\nconst SLOPE_CHAR_WIDTH = 8; // approximate px per character at 14px\n\n/**\n * Renders a slope chart into the given container using D3.\n */\nexport function renderSlopeChart(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n // Clear existing content\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { periods, data, title } = parsed;\n if (data.length === 0 || periods.length < 2) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n // Compute right margin from the longest end-of-line label\n const maxLabelText = data.reduce((longest, item) => {\n const text = `${item.values[item.values.length - 1]} — ${item.label}`;\n return text.length > longest.length ? text : longest;\n }, '');\n const estimatedLabelWidth = maxLabelText.length * SLOPE_CHAR_WIDTH;\n const maxRightMargin = Math.floor(width * 0.35);\n const rightMargin = Math.min(\n Math.max(estimatedLabelWidth + 30, 120),\n maxRightMargin\n );\n\n const innerWidth = width - SLOPE_MARGIN.left - rightMargin;\n const innerHeight = height - SLOPE_MARGIN.top - SLOPE_MARGIN.bottom;\n\n // Theme colors\n const textColor = palette.text;\n const mutedColor = palette.border;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n // Scales\n const allValues = data.flatMap((d) => d.values);\n const [minVal, maxVal] = d3Array.extent(allValues) as [number, number];\n const valuePadding = (maxVal - minVal) * 0.1 || 1;\n\n const yScale = d3Scale\n .scaleLinear()\n .domain([minVal - valuePadding, maxVal + valuePadding])\n .range([innerHeight, 0]);\n\n const xScale = d3Scale\n .scalePoint<string>()\n .domain(periods)\n .range([0, innerWidth])\n .padding(0);\n\n // SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${SLOPE_MARGIN.left},${SLOPE_MARGIN.top})`);\n\n // Tooltip\n const tooltip = createTooltip(container, palette, isDark);\n\n // Title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // Period column headers\n for (const period of periods) {\n const x = xScale(period)!;\n g.append('text')\n .attr('x', x)\n .attr('y', -15)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '600')\n .text(period);\n\n // Vertical guide line\n g.append('line')\n .attr('x1', x)\n .attr('y1', 0)\n .attr('x2', x)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n }\n\n // Line generator\n const lineGen = d3Shape\n .line<number>()\n .x((_d, i) => xScale(periods[i])!)\n .y((d) => yScale(d));\n\n // Render each data series\n data.forEach((item, idx) => {\n const color = item.color ?? colors[idx % colors.length];\n\n // Wrap each series in a group with data-line-number for sync adapter\n const seriesG = g\n .append('g')\n .attr('class', 'slope-series')\n .attr('data-line-number', String(item.lineNumber));\n\n // Tooltip content – overall change for this series\n const firstVal = item.values[0];\n const lastVal = item.values[item.values.length - 1];\n const absChange = lastVal - firstVal;\n const pctChange = firstVal !== 0 ? (absChange / firstVal) * 100 : null;\n const sign = absChange > 0 ? '+' : '';\n const pctPart =\n pctChange !== null ? ` (${sign}${pctChange.toFixed(1)}%)` : '';\n const tipLines = [`${sign}${absChange}`];\n if (pctChange !== null) tipLines.push(`${sign}${pctChange.toFixed(1)}%`);\n const tipHtml = tipLines.join('<br>');\n\n // Line\n seriesG.append('path')\n .datum(item.values)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', 2.5)\n .attr('d', lineGen);\n\n // Invisible wider path for easier hover targeting\n seriesG.append('path')\n .datum(item.values)\n .attr('fill', 'none')\n .attr('stroke', 'transparent')\n .attr('stroke-width', 14)\n .attr('d', lineGen)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mousemove', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mouseleave', () => hideTooltip(tooltip))\n .on('click', () => {\n if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);\n });\n\n // Points and value labels\n item.values.forEach((val, i) => {\n const x = xScale(periods[i])!;\n const y = yScale(val);\n\n // Point circle\n seriesG.append('circle')\n .attr('cx', x)\n .attr('cy', y)\n .attr('r', 4)\n .attr('fill', color)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mousemove', (event: MouseEvent) =>\n showTooltip(tooltip, tipHtml, event)\n )\n .on('mouseleave', () => hideTooltip(tooltip))\n .on('click', () => {\n if (onClickItem && item.lineNumber) onClickItem(item.lineNumber);\n });\n\n // Value label — skip last point (shown in series label instead)\n const isFirst = i === 0;\n const isLast = i === periods.length - 1;\n if (!isLast) {\n seriesG.append('text')\n .attr('x', isFirst ? x - 10 : x)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', isFirst ? 'end' : 'middle')\n .attr('fill', textColor)\n .attr('font-size', '16px')\n .text(val.toString());\n }\n });\n\n // Series label with value at end of line — wraps if it exceeds available space\n const lastX = xScale(periods[periods.length - 1])!;\n const lastY = yScale(lastVal);\n const labelText = `${lastVal} — ${item.label}`;\n const availableWidth = rightMargin - 15;\n const maxChars = Math.floor(availableWidth / SLOPE_CHAR_WIDTH);\n\n const labelEl = seriesG\n .append('text')\n .attr('x', lastX + 10)\n .attr('y', lastY)\n .attr('text-anchor', 'start')\n .attr('fill', color)\n .attr('font-size', `${SLOPE_LABEL_FONT_SIZE}px`)\n .attr('font-weight', '500');\n\n if (labelText.length <= maxChars) {\n labelEl.attr('dy', '0.35em').text(labelText);\n } else {\n // Wrap into lines that fit the available width\n const words = labelText.split(/\\s+/);\n const lines: string[] = [];\n let current = '';\n for (const word of words) {\n const test = current ? `${current} ${word}` : word;\n if (test.length > maxChars && current) {\n lines.push(current);\n current = word;\n } else {\n current = test;\n }\n }\n if (current) lines.push(current);\n\n const lineHeight = SLOPE_LABEL_FONT_SIZE * 1.2;\n const totalHeight = (lines.length - 1) * lineHeight;\n const startDy = -totalHeight / 2;\n\n lines.forEach((line, li) => {\n labelEl\n .append('tspan')\n .attr('x', lastX + 10)\n .attr(\n 'dy',\n li === 0\n ? `${startDy + SLOPE_LABEL_FONT_SIZE * 0.35}px`\n : `${lineHeight}px`\n )\n .text(line);\n });\n }\n });\n}\n\n// ============================================================\n// Arc Node Ordering\n// ============================================================\n\n/**\n * Orders arc diagram nodes based on the selected ordering strategy.\n */\nexport function orderArcNodes(\n links: ArcLink[],\n order: ArcOrder,\n groups: ArcNodeGroup[]\n): string[] {\n // Collect all unique nodes in first-appearance order\n const nodeSet = new Set<string>();\n for (const link of links) {\n nodeSet.add(link.source);\n nodeSet.add(link.target);\n }\n const allNodes = Array.from(nodeSet);\n\n if (order === 'name') {\n return allNodes.slice().sort((a, b) => a.localeCompare(b));\n }\n\n if (order === 'degree') {\n const degree = new Map<string, number>();\n for (const node of allNodes) degree.set(node, 0);\n for (const link of links) {\n degree.set(link.source, degree.get(link.source)! + link.value);\n degree.set(link.target, degree.get(link.target)! + link.value);\n }\n return allNodes.slice().sort((a, b) => {\n const diff = degree.get(b)! - degree.get(a)!;\n return diff !== 0 ? diff : a.localeCompare(b);\n });\n }\n\n if (order === 'group') {\n if (groups.length > 0) {\n // Explicit groups: order by ## header order, appearance within each group\n const ordered: string[] = [];\n const placed = new Set<string>();\n for (const group of groups) {\n for (const node of group.nodes) {\n if (!placed.has(node)) {\n ordered.push(node);\n placed.add(node);\n }\n }\n }\n // Orphans at end in first-appearance order\n for (const node of allNodes) {\n if (!placed.has(node)) {\n ordered.push(node);\n placed.add(node);\n }\n }\n return ordered;\n }\n // No explicit groups: connectivity clustering via BFS\n const adj = new Map<string, Set<string>>();\n for (const node of allNodes) adj.set(node, new Set());\n for (const link of links) {\n adj.get(link.source)!.add(link.target);\n adj.get(link.target)!.add(link.source);\n }\n\n const degree = new Map<string, number>();\n for (const node of allNodes) degree.set(node, 0);\n for (const link of links) {\n degree.set(link.source, degree.get(link.source)! + link.value);\n degree.set(link.target, degree.get(link.target)! + link.value);\n }\n\n const visited = new Set<string>();\n const components: string[][] = [];\n\n const remaining = new Set(allNodes);\n while (remaining.size > 0) {\n // Pick highest-degree unvisited node as BFS root\n let root = '';\n let maxDeg = -1;\n for (const node of remaining) {\n if (degree.get(node)! > maxDeg) {\n maxDeg = degree.get(node)!;\n root = node;\n }\n }\n // BFS\n const component: string[] = [];\n const queue = [root];\n visited.add(root);\n remaining.delete(root);\n while (queue.length > 0) {\n const curr = queue.shift()!;\n component.push(curr);\n for (const neighbor of adj.get(curr)!) {\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n remaining.delete(neighbor);\n queue.push(neighbor);\n }\n }\n }\n components.push(component);\n }\n // Sort components by size descending\n components.sort((a, b) => b.length - a.length);\n return components.flat();\n }\n\n // 'appearance' — first-appearance order (default)\n return allNodes;\n}\n\n// ============================================================\n// Arc Diagram Renderer\n// ============================================================\n\nconst ARC_MARGIN = { top: 60, right: 40, bottom: 60, left: 40 };\n\n/**\n * Renders an arc diagram into the given container using D3.\n */\nexport function renderArcDiagram(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n _isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { links, title, orientation, arcOrder, arcNodeGroups } = parsed;\n if (links.length === 0) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const isVertical = orientation === 'vertical';\n const margin = isVertical\n ? {\n top: ARC_MARGIN.top,\n right: ARC_MARGIN.right,\n bottom: ARC_MARGIN.bottom,\n left: 120,\n }\n : ARC_MARGIN;\n\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n\n // Theme colors\n const textColor = palette.text;\n const mutedColor = palette.border;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n // Order nodes by selected strategy\n const nodes = orderArcNodes(links, arcOrder, arcNodeGroups);\n\n // Build node color map from group colors\n const nodeColorMap = new Map<string, string>();\n for (const group of arcNodeGroups) {\n if (group.color) {\n for (const node of group.nodes) {\n if (!nodeColorMap.has(node)) {\n nodeColorMap.set(node, group.color);\n }\n }\n }\n }\n\n // Build group-to-nodes lookup for group hover\n const groupNodeSets = new Map<string, Set<string>>();\n for (const group of arcNodeGroups) {\n groupNodeSets.set(group.name, new Set(group.nodes));\n }\n\n // Scales\n const values = links.map((l) => l.value);\n const [minVal, maxVal] = d3Array.extent(values) as [number, number];\n const strokeScale = d3Scale\n .scaleLinear()\n .domain([minVal, maxVal])\n .range([1.5, 6]);\n\n // SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n // Title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // Build adjacency map for hover interactions\n const neighbors = new Map<string, Set<string>>();\n for (const node of nodes) neighbors.set(node, new Set());\n for (const link of links) {\n neighbors.get(link.source)!.add(link.target);\n neighbors.get(link.target)!.add(link.source);\n }\n\n const FADE_OPACITY = 0.1;\n\n function handleMouseEnter(hovered: string) {\n const connected = neighbors.get(hovered)!;\n\n g.selectAll<SVGPathElement, unknown>('.arc-link').each(function () {\n const el = d3Selection.select(this);\n const src = el.attr('data-source');\n const tgt = el.attr('data-target');\n const isRelated = src === hovered || tgt === hovered;\n el.attr('stroke-opacity', isRelated ? 0.85 : FADE_OPACITY);\n });\n\n g.selectAll<SVGGElement, unknown>('.arc-node').each(function () {\n const el = d3Selection.select(this);\n const name = el.attr('data-node');\n const isRelated = name === hovered || connected.has(name!);\n el.attr('opacity', isRelated ? 1 : FADE_OPACITY);\n });\n }\n\n function handleMouseLeave() {\n g.selectAll<SVGPathElement, unknown>('.arc-link').attr(\n 'stroke-opacity',\n 0.7\n );\n g.selectAll<SVGGElement, unknown>('.arc-node').attr('opacity', 1);\n g.selectAll<SVGRectElement, unknown>('.arc-group-band').attr(\n 'fill-opacity',\n 0.06\n );\n g.selectAll<SVGTextElement, unknown>('.arc-group-label').attr(\n 'fill-opacity',\n 0.5\n );\n }\n\n function handleGroupEnter(groupName: string) {\n const members = groupNodeSets.get(groupName);\n if (!members) return;\n\n g.selectAll<SVGPathElement, unknown>('.arc-link').each(function () {\n const el = d3Selection.select(this);\n const isRelated =\n members.has(el.attr('data-source')!) ||\n members.has(el.attr('data-target')!);\n el.attr('stroke-opacity', isRelated ? 0.85 : FADE_OPACITY);\n });\n\n g.selectAll<SVGGElement, unknown>('.arc-node').each(function () {\n const el = d3Selection.select(this);\n el.attr('opacity', members.has(el.attr('data-node')!) ? 1 : FADE_OPACITY);\n });\n\n g.selectAll<SVGRectElement, unknown>('.arc-group-band').each(function () {\n const el = d3Selection.select(this);\n el.attr(\n 'fill-opacity',\n el.attr('data-group') === groupName ? 0.18 : 0.03\n );\n });\n\n g.selectAll<SVGTextElement, unknown>('.arc-group-label').each(function () {\n const el = d3Selection.select(this);\n el.attr('fill-opacity', el.attr('data-group') === groupName ? 1 : 0.2);\n });\n }\n\n if (isVertical) {\n // Vertical layout: nodes along Y axis, arcs curve to the right\n const yScale = d3Scale\n .scalePoint<string>()\n .domain(nodes)\n .range([0, innerHeight])\n .padding(0.5);\n\n const baseX = innerWidth / 2;\n\n // Group bands (shaded regions bounding grouped nodes)\n if (arcNodeGroups.length > 0) {\n const bandPad = (yScale.step?.() ?? 20) * 0.4;\n const bandHalfW = 60;\n for (const group of arcNodeGroups) {\n const groupNodes = group.nodes.filter((n) => nodes.includes(n));\n if (groupNodes.length === 0) continue;\n const positions = groupNodes.map((n) => yScale(n)!);\n const minY = Math.min(...positions) - bandPad;\n const maxY = Math.max(...positions) + bandPad;\n const bandColor = group.color ?? mutedColor;\n\n g.append('rect')\n .attr('class', 'arc-group-band')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', baseX - bandHalfW)\n .attr('y', minY)\n .attr('width', bandHalfW * 2)\n .attr('height', maxY - minY)\n .attr('rx', 4)\n .attr('fill', textColor)\n .attr('fill-opacity', 0.06)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n\n g.append('text')\n .attr('class', 'arc-group-label')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', baseX - bandHalfW + 6)\n .attr('y', minY + 14)\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .attr('fill-opacity', 0.5)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .text(group.name)\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n }\n }\n\n // Dashed vertical baseline\n g.append('line')\n .attr('x1', baseX)\n .attr('y1', 0)\n .attr('x2', baseX)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n // Arcs\n links.forEach((link, idx) => {\n const y1 = yScale(link.source)!;\n const y2 = yScale(link.target)!;\n const midY = (y1 + y2) / 2;\n const distance = Math.abs(y2 - y1);\n const controlX = baseX + distance * 0.4;\n const color = link.color ?? colors[idx % colors.length];\n\n g.append('path')\n .attr('class', 'arc-link')\n .attr('data-source', link.source)\n .attr('data-target', link.target)\n .attr('data-line-number', String(link.lineNumber))\n .attr('d', `M ${baseX},${y1} Q ${controlX},${midY} ${baseX},${y2}`)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', strokeScale(link.value))\n .attr('stroke-opacity', 0.7)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('click', () => {\n if (onClickItem && link.lineNumber) onClickItem(link.lineNumber);\n });\n });\n\n // Node circles and labels\n for (const node of nodes) {\n const y = yScale(node)!;\n const nodeColor = nodeColorMap.get(node) ?? textColor;\n // Find the first link involving this node (for line number and click target)\n const nodeLink = links.find((l) => l.source === node || l.target === node);\n\n const nodeG = g\n .append('g')\n .attr('class', 'arc-node')\n .attr('data-node', node)\n .attr('data-line-number', nodeLink?.lineNumber ? String(nodeLink.lineNumber) : null)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleMouseEnter(node))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem && nodeLink?.lineNumber)\n onClickItem(nodeLink.lineNumber);\n });\n\n nodeG\n .append('circle')\n .attr('cx', baseX)\n .attr('cy', y)\n .attr('r', 5)\n .attr('fill', nodeColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n\n // Label to the left of baseline\n nodeG\n .append('text')\n .attr('x', baseX - 14)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'end')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(node);\n }\n } else {\n // Horizontal layout (default): nodes along X axis, arcs curve upward\n const xScale = d3Scale\n .scalePoint<string>()\n .domain(nodes)\n .range([0, innerWidth])\n .padding(0.5);\n\n const baseY = innerHeight / 2;\n\n // Group bands (shaded regions bounding grouped nodes)\n if (arcNodeGroups.length > 0) {\n const bandPad = (xScale.step?.() ?? 20) * 0.4;\n const bandHalfH = 40;\n for (const group of arcNodeGroups) {\n const groupNodes = group.nodes.filter((n) => nodes.includes(n));\n if (groupNodes.length === 0) continue;\n const positions = groupNodes.map((n) => xScale(n)!);\n const minX = Math.min(...positions) - bandPad;\n const maxX = Math.max(...positions) + bandPad;\n const bandColor = group.color ?? mutedColor;\n\n g.append('rect')\n .attr('class', 'arc-group-band')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', minX)\n .attr('y', baseY - bandHalfH)\n .attr('width', maxX - minX)\n .attr('height', bandHalfH * 2)\n .attr('rx', 4)\n .attr('fill', textColor)\n .attr('fill-opacity', 0.06)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n\n g.append('text')\n .attr('class', 'arc-group-label')\n .attr('data-group', group.name)\n .attr('data-line-number', String(group.lineNumber))\n .attr('x', (minX + maxX) / 2)\n .attr('y', baseY + bandHalfH - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .attr('fill-opacity', 0.5)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .text(group.name)\n .on('mouseenter', () => handleGroupEnter(group.name))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem) onClickItem(group.lineNumber);\n });\n }\n }\n\n // Dashed horizontal baseline\n g.append('line')\n .attr('x1', 0)\n .attr('y1', baseY)\n .attr('x2', innerWidth)\n .attr('y2', baseY)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n // Arcs\n links.forEach((link, idx) => {\n const x1 = xScale(link.source)!;\n const x2 = xScale(link.target)!;\n const midX = (x1 + x2) / 2;\n const distance = Math.abs(x2 - x1);\n const controlY = baseY - distance * 0.4;\n const color = link.color ?? colors[idx % colors.length];\n\n g.append('path')\n .attr('class', 'arc-link')\n .attr('data-source', link.source)\n .attr('data-target', link.target)\n .attr('data-line-number', String(link.lineNumber))\n .attr('d', `M ${x1},${baseY} Q ${midX},${controlY} ${x2},${baseY}`)\n .attr('fill', 'none')\n .attr('stroke', color)\n .attr('stroke-width', strokeScale(link.value))\n .attr('stroke-opacity', 0.7)\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('click', () => {\n if (onClickItem && link.lineNumber) onClickItem(link.lineNumber);\n });\n });\n\n // Node circles and labels\n for (const node of nodes) {\n const x = xScale(node)!;\n const nodeColor = nodeColorMap.get(node) ?? textColor;\n // Find the first link involving this node (for line number and click target)\n const nodeLink = links.find((l) => l.source === node || l.target === node);\n\n const nodeG = g\n .append('g')\n .attr('class', 'arc-node')\n .attr('data-node', node)\n .attr('data-line-number', nodeLink?.lineNumber ? String(nodeLink.lineNumber) : null)\n .style('cursor', 'pointer')\n .on('mouseenter', () => handleMouseEnter(node))\n .on('mouseleave', handleMouseLeave)\n .on('click', () => {\n if (onClickItem && nodeLink?.lineNumber)\n onClickItem(nodeLink.lineNumber);\n });\n\n nodeG\n .append('circle')\n .attr('cx', x)\n .attr('cy', baseY)\n .attr('r', 5)\n .attr('fill', nodeColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n\n // Label below baseline\n nodeG\n .append('text')\n .attr('x', x)\n .attr('y', baseY + 20)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(node);\n }\n }\n}\n\n// ============================================================\n// Timeline Era Bands\n// ============================================================\n\nfunction getEraColors(palette: PaletteColors): string[] {\n return [\n palette.colors.blue,\n palette.colors.green,\n palette.colors.yellow,\n palette.colors.orange,\n palette.colors.purple,\n ];\n}\n\n/**\n * Renders semi-transparent era background bands behind timeline events.\n */\nfunction renderEras(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n eras: TimelineEra[],\n scale: d3Scale.ScaleLinear<number, number>,\n isVertical: boolean,\n innerWidth: number,\n innerHeight: number,\n onEnter: (eraStart: number, eraEnd: number) => void,\n onLeave: () => void,\n hasScale: boolean = false,\n tooltip: HTMLDivElement | null = null,\n palette?: PaletteColors\n): void {\n const eraColors = palette\n ? getEraColors(palette)\n : ['#5e81ac', '#a3be8c', '#ebcb8b', '#d08770', '#b48ead'];\n eras.forEach((era, i) => {\n const startVal = parseTimelineDate(era.startDate);\n const endVal = parseTimelineDate(era.endDate);\n const start = scale(startVal);\n const end = scale(endVal);\n const color = era.color || eraColors[i % eraColors.length];\n\n const eraG = g\n .append('g')\n .attr('class', 'tl-era')\n .attr('data-era-start', String(startVal))\n .attr('data-era-end', String(endVal))\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n onEnter(startVal, endVal);\n if (tooltip) showTooltip(tooltip, buildEraTooltipHtml(era), event);\n })\n .on('mouseleave', function () {\n onLeave();\n if (tooltip) hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n if (tooltip) showTooltip(tooltip, buildEraTooltipHtml(era), event);\n });\n\n if (isVertical) {\n const y = Math.min(start, end);\n const h = Math.abs(end - start);\n eraG\n .append('rect')\n .attr('x', 0)\n .attr('y', y)\n .attr('width', innerWidth)\n .attr('height', h)\n .attr('fill', color)\n .attr('opacity', 0.08);\n eraG\n .append('text')\n .attr('x', 6)\n .attr('y', y + 18)\n .attr('text-anchor', 'start')\n .attr('fill', color)\n .attr('font-size', '13px')\n .attr('font-weight', '600')\n .attr('opacity', 0.8)\n .text(era.label);\n } else {\n const x = Math.min(start, end);\n const w = Math.abs(end - start);\n // When scale is on, extend the shading above the chart area\n // so the label sits above the scale marks but inside the band.\n const rectTop = hasScale ? -48 : 0;\n eraG\n .append('rect')\n .attr('x', x)\n .attr('y', rectTop)\n .attr('width', w)\n .attr('height', innerHeight - rectTop)\n .attr('fill', color)\n .attr('opacity', 0.08);\n eraG\n .append('text')\n .attr('x', x + w / 2)\n .attr('y', hasScale ? -32 : 18)\n .attr('text-anchor', 'middle')\n .attr('fill', color)\n .attr('font-size', '13px')\n .attr('font-weight', '600')\n .attr('opacity', 0.8)\n .text(era.label);\n }\n });\n}\n\n/**\n * Renders timeline markers as dashed vertical lines with diamond indicators and labels.\n */\nfunction renderMarkers(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n markers: TimelineMarker[],\n scale: d3Scale.ScaleLinear<number, number>,\n isVertical: boolean,\n innerWidth: number,\n innerHeight: number,\n _hasScale: boolean = false,\n tooltip: HTMLDivElement | null = null,\n palette?: PaletteColors\n): void {\n // Default marker color - bright orange/red that \"pops\"\n const defaultColor = palette?.accent || '#d08770';\n\n markers.forEach((marker) => {\n const dateVal = parseTimelineDate(marker.date);\n const pos = scale(dateVal);\n const color = marker.color || defaultColor;\n const lineOpacity = 0.5;\n const diamondSize = 5;\n\n const markerG = g\n .append('g')\n .attr('class', 'tl-marker')\n .attr('data-marker-date', String(dateVal))\n .attr('data-line-number', String(marker.lineNumber))\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n if (tooltip) {\n showTooltip(tooltip, formatDateLabel(marker.date), event);\n }\n })\n .on('mouseleave', function () {\n if (tooltip) hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n if (tooltip) {\n showTooltip(tooltip, formatDateLabel(marker.date), event);\n }\n });\n\n if (isVertical) {\n // Vertical orientation: horizontal dashed line across the chart\n markerG\n .append('line')\n .attr('x1', 0)\n .attr('y1', pos)\n .attr('x2', innerWidth)\n .attr('y2', pos)\n .attr('stroke', color)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '6 4')\n .attr('opacity', lineOpacity);\n\n // Label above diamond\n markerG\n .append('text')\n .attr('x', -diamondSize - 8)\n .attr('y', pos - diamondSize - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', color)\n .attr('font-size', '11px')\n .attr('font-weight', '600')\n .text(marker.label);\n\n // Diamond at the left edge\n markerG\n .append('path')\n .attr(\n 'd',\n `M${-diamondSize - 8},${pos} l${diamondSize},-${diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} Z`\n )\n .attr('fill', color)\n .attr('opacity', 0.9);\n } else {\n // Horizontal orientation: vertical dashed line down the chart\n // Label above diamond, diamond below, then dashed line to chart bottom\n const labelY = 6;\n const diamondY = labelY + 14;\n\n // Label above diamond\n markerG\n .append('text')\n .attr('x', pos)\n .attr('y', labelY)\n .attr('text-anchor', 'middle')\n .attr('fill', color)\n .attr('font-size', '11px')\n .attr('font-weight', '600')\n .text(marker.label);\n\n // Diamond below label\n markerG\n .append('path')\n .attr(\n 'd',\n `M${pos},${diamondY - diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} l-${diamondSize},-${diamondSize} Z`\n )\n .attr('fill', color)\n .attr('opacity', 0.9);\n\n // Line starts from bottom of diamond and goes down to chart bottom\n markerG\n .append('line')\n .attr('x1', pos)\n .attr('y1', diamondY + diamondSize)\n .attr('x2', pos)\n .attr('y2', innerHeight)\n .attr('stroke', color)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '6 4')\n .attr('opacity', lineOpacity);\n }\n });\n}\n\n// ============================================================\n// Timeline Time Scale\n// ============================================================\n\nconst MONTH_ABBR = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n];\n\n/**\n * Converts a DSL date string (YYYY, YYYY-MM, YYYY-MM-DD) to a human-readable label.\n * '1718' → '1718'\n * '1718-05' → 'May 1718'\n * '1718-05-22' → 'May 22, 1718'\n */\nexport function formatDateLabel(dateStr: string): string {\n const parts = dateStr.split('-');\n const year = parts[0];\n if (parts.length === 1) return year;\n const month = MONTH_ABBR[parseInt(parts[1], 10) - 1];\n if (parts.length === 2) return `${month} ${year}`;\n const day = parseInt(parts[2], 10);\n return `${month} ${day}, ${year}`;\n}\n\n/**\n * Computes adaptive tick marks for a timeline scale.\n * - Multi-year spans → year ticks\n * - Within ~1 year → month ticks\n * - Within ~3 months → week ticks (1st, 8th, 15th, 22nd)\n *\n * Optional boundary parameters add ticks at exact data start/end:\n * - boundaryStart/boundaryEnd: numeric date values\n * - boundaryStartLabel/boundaryEndLabel: formatted labels for those dates\n */\nexport function computeTimeTicks(\n domainMin: number,\n domainMax: number,\n scale: d3Scale.ScaleLinear<number, number>,\n boundaryStart?: number,\n boundaryEnd?: number,\n boundaryStartLabel?: string,\n boundaryEndLabel?: string\n): { pos: number; label: string }[] {\n const minYear = Math.floor(domainMin);\n const maxYear = Math.floor(domainMax);\n const span = domainMax - domainMin;\n\n let ticks: { pos: number; label: string }[] = [];\n\n // Year ticks for multi-year spans (need at least 2 boundaries)\n const firstYear = Math.ceil(domainMin);\n const lastYear = Math.floor(domainMax);\n if (lastYear >= firstYear + 1) {\n // Decimate ticks for long spans so labels don't overlap\n const yearSpan = lastYear - firstYear;\n let step = 1;\n if (yearSpan > 80) step = 20;\n else if (yearSpan > 40) step = 10;\n else if (yearSpan > 20) step = 5;\n else if (yearSpan > 10) step = 2;\n\n // Align to step boundary so ticks land on round years (1700, 1710, …)\n const alignedFirst = Math.ceil(firstYear / step) * step;\n for (let y = alignedFirst; y <= lastYear; y += step) {\n ticks.push({ pos: scale(y), label: String(y) });\n }\n } else if (span > 0.25) {\n // Month ticks for spans > ~3 months\n const crossesYear = maxYear > minYear;\n for (let y = minYear; y <= maxYear + 1; y++) {\n for (let m = 1; m <= 12; m++) {\n const val = y + (m - 1) / 12;\n if (val > domainMax) break;\n if (val >= domainMin) {\n ticks.push({\n pos: scale(val),\n label: crossesYear\n ? `${MONTH_ABBR[m - 1]} '${String(y).slice(-2)}`\n : MONTH_ABBR[m - 1],\n });\n }\n }\n }\n } else {\n // Week ticks for spans ≤ ~3 months (1st, 8th, 15th, 22nd of each month)\n for (let y = minYear; y <= maxYear + 1; y++) {\n for (let m = 1; m <= 12; m++) {\n for (const d of [1, 8, 15, 22]) {\n const val = y + (m - 1) / 12 + (d - 1) / 365;\n if (val > domainMax) break;\n if (val >= domainMin) {\n ticks.push({\n pos: scale(val),\n label: `${MONTH_ABBR[m - 1]} ${d}`,\n });\n }\n }\n }\n }\n }\n\n // Add boundary ticks at exact data start/end if provided\n // When a boundary tick collides with a standard tick, replace the standard tick\n const collisionThreshold = 40; // pixels\n\n if (boundaryStart !== undefined && boundaryStartLabel) {\n const boundaryPos = scale(boundaryStart);\n // Remove any standard ticks that would collide with the start boundary\n ticks = ticks.filter(\n (t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold\n );\n ticks.unshift({ pos: boundaryPos, label: boundaryStartLabel });\n }\n\n if (boundaryEnd !== undefined && boundaryEndLabel) {\n const boundaryPos = scale(boundaryEnd);\n // Remove any standard ticks that would collide with the end boundary\n ticks = ticks.filter(\n (t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold\n );\n ticks.push({ pos: boundaryPos, label: boundaryEndLabel });\n }\n\n return ticks;\n}\n\n/**\n * Renders adaptive tick marks along the time axis.\n * Optional boundary parameters add ticks at exact data start/end.\n */\nfunction renderTimeScale(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n scale: d3Scale.ScaleLinear<number, number>,\n isVertical: boolean,\n innerWidth: number,\n innerHeight: number,\n textColor: string,\n boundaryStart?: number,\n boundaryEnd?: number,\n boundaryStartLabel?: string,\n boundaryEndLabel?: string\n): void {\n const [domainMin, domainMax] = scale.domain();\n const ticks = computeTimeTicks(\n domainMin,\n domainMax,\n scale,\n boundaryStart,\n boundaryEnd,\n boundaryStartLabel,\n boundaryEndLabel\n );\n if (ticks.length < 2) return;\n\n const tickLen = 6;\n const opacity = 0.4;\n\n const guideOpacity = 0.15;\n\n for (const tick of ticks) {\n if (isVertical) {\n // Guide line spanning full width\n g.append('line')\n .attr('x1', 0)\n .attr('y1', tick.pos)\n .attr('x2', innerWidth)\n .attr('y2', tick.pos)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', guideOpacity);\n\n // Left edge\n g.append('line')\n .attr('x1', -tickLen)\n .attr('y1', tick.pos)\n .attr('x2', 0)\n .attr('y2', tick.pos)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('x', -tickLen - 3)\n .attr('y', tick.pos)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'end')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n\n // Right edge\n g.append('line')\n .attr('x1', innerWidth)\n .attr('y1', tick.pos)\n .attr('x2', innerWidth + tickLen)\n .attr('y2', tick.pos)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('x', innerWidth + tickLen + 3)\n .attr('y', tick.pos)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n } else {\n // Guide line spanning full height\n g.append('line')\n .attr('class', 'tl-scale-tick')\n .attr('x1', tick.pos)\n .attr('y1', 0)\n .attr('x2', tick.pos)\n .attr('y2', innerHeight)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', guideOpacity);\n\n // Bottom edge\n g.append('line')\n .attr('class', 'tl-scale-tick')\n .attr('x1', tick.pos)\n .attr('y1', innerHeight)\n .attr('x2', tick.pos)\n .attr('y2', innerHeight + tickLen)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('class', 'tl-scale-tick')\n .attr('x', tick.pos)\n .attr('y', innerHeight + tickLen + 12)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n\n // Top edge\n g.append('line')\n .attr('class', 'tl-scale-tick')\n .attr('x1', tick.pos)\n .attr('y1', -tickLen)\n .attr('x2', tick.pos)\n .attr('y2', 0)\n .attr('stroke', textColor)\n .attr('stroke-width', 1)\n .attr('opacity', opacity);\n\n g.append('text')\n .attr('class', 'tl-scale-tick')\n .attr('x', tick.pos)\n .attr('y', -tickLen - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .attr('opacity', opacity)\n .text(tick.label);\n }\n }\n}\n\n// ============================================================\n// Timeline Event Date Scale Helpers\n// ============================================================\n\n/**\n * Shows event start/end dates on the scale, fading existing scale ticks.\n * For horizontal timelines, displays dates at the top of the scale.\n */\nfunction showEventDatesOnScale(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n scale: d3Scale.ScaleLinear<number, number>,\n startDate: string,\n endDate: string | null,\n innerHeight: number,\n accentColor: string\n): void {\n // Fade existing scale ticks\n g.selectAll('.tl-scale-tick').attr('opacity', 0.1);\n\n const tickLen = 6;\n const startPos = scale(parseTimelineDate(startDate));\n const startLabel = formatDateLabel(startDate);\n\n // Start date - top\n g.append('line')\n .attr('class', 'tl-event-date')\n .attr('x1', startPos)\n .attr('y1', -tickLen)\n .attr('x2', startPos)\n .attr('y2', innerHeight)\n .attr('stroke', accentColor)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', 0.6);\n\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', startPos)\n .attr('y', -tickLen - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(startLabel);\n\n // Start date - bottom\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', startPos)\n .attr('y', innerHeight + tickLen + 12)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(startLabel);\n\n if (endDate) {\n const endPos = scale(parseTimelineDate(endDate));\n const endLabel = formatDateLabel(endDate);\n\n // End date - top\n g.append('line')\n .attr('class', 'tl-event-date')\n .attr('x1', endPos)\n .attr('y1', -tickLen)\n .attr('x2', endPos)\n .attr('y2', innerHeight)\n .attr('stroke', accentColor)\n .attr('stroke-width', 1.5)\n .attr('stroke-dasharray', '4 4')\n .attr('opacity', 0.6);\n\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', endPos)\n .attr('y', -tickLen - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(endLabel);\n\n // End date - bottom\n g.append('text')\n .attr('class', 'tl-event-date')\n .attr('x', endPos)\n .attr('y', innerHeight + tickLen + 12)\n .attr('text-anchor', 'middle')\n .attr('fill', accentColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .text(endLabel);\n }\n}\n\n/**\n * Hides event dates and restores scale tick visibility.\n */\nfunction hideEventDatesOnScale(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>\n): void {\n // Remove event date elements\n g.selectAll('.tl-event-date').remove();\n\n // Restore scale tick visibility\n g.selectAll('.tl-scale-tick').each(function () {\n const el = d3Selection.select(this);\n // Restore original opacity based on element type\n const isDashed = el.attr('stroke-dasharray');\n el.attr('opacity', isDashed ? 0.15 : 0.4);\n });\n}\n\n// ============================================================\n// Timeline Tooltip Helpers\n// ============================================================\n\nfunction createTooltip(\n container: HTMLElement,\n palette: PaletteColors,\n isDark: boolean\n): HTMLDivElement {\n container.style.position = 'relative';\n\n // Reuse existing tooltip element if present (avoids DOM churn on re-renders)\n const existing = container.querySelector<HTMLDivElement>('[data-d3-tooltip]');\n if (existing) {\n existing.style.display = 'none';\n existing.style.background = palette.surface;\n existing.style.color = palette.text;\n existing.style.boxShadow = isDark\n ? '0 2px 6px rgba(0,0,0,0.3)'\n : '0 2px 6px rgba(0,0,0,0.12)';\n return existing;\n }\n\n const tip = document.createElement('div');\n tip.setAttribute('data-d3-tooltip', '');\n tip.style.position = 'absolute';\n tip.style.display = 'none';\n tip.style.pointerEvents = 'none';\n tip.style.background = palette.surface;\n tip.style.color = palette.text;\n tip.style.padding = '6px 10px';\n tip.style.borderRadius = '4px';\n tip.style.fontSize = '12px';\n tip.style.lineHeight = '1.4';\n tip.style.whiteSpace = 'nowrap';\n tip.style.zIndex = '10';\n tip.style.boxShadow = isDark\n ? '0 2px 6px rgba(0,0,0,0.3)'\n : '0 2px 6px rgba(0,0,0,0.12)';\n container.appendChild(tip);\n return tip;\n}\n\nfunction showTooltip(\n tooltip: HTMLDivElement,\n html: string,\n event: MouseEvent\n): void {\n tooltip.innerHTML = html;\n tooltip.style.display = 'block';\n const container = tooltip.parentElement!;\n const rect = container.getBoundingClientRect();\n let left = event.clientX - rect.left + 12;\n let top = event.clientY - rect.top - 28;\n // Clamp so tooltip stays inside the container\n const tipW = tooltip.offsetWidth;\n const tipH = tooltip.offsetHeight;\n if (left + tipW > rect.width) left = rect.width - tipW - 4;\n if (top < 0) top = event.clientY - rect.top + 16;\n if (top + tipH > rect.height) top = rect.height - tipH - 4;\n tooltip.style.left = `${left}px`;\n tooltip.style.top = `${top}px`;\n}\n\nfunction hideTooltip(tooltip: HTMLDivElement): void {\n tooltip.style.display = 'none';\n}\n\nfunction buildEventTooltipHtml(ev: TimelineEvent): string {\n const datePart = ev.endDate\n ? `${formatDateLabel(ev.date)} → ${formatDateLabel(ev.endDate)}`\n : formatDateLabel(ev.date);\n return `<strong>${ev.label}</strong><br>${datePart}`;\n}\n\nfunction buildEraTooltipHtml(era: TimelineEra): string {\n return `<strong>${era.label}</strong><br>${formatDateLabel(era.startDate)} → ${formatDateLabel(era.endDate)}`;\n}\n\n// ============================================================\n// Timeline Renderer\n// ============================================================\n\n/**\n * Renders a timeline chart into the given container using D3.\n * Supports horizontal (default) and vertical orientation.\n */\nexport function renderTimeline(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const {\n timelineEvents,\n timelineGroups,\n timelineEras,\n timelineMarkers,\n timelineSort,\n timelineScale,\n timelineSwimlanes,\n title,\n orientation,\n } = parsed;\n if (timelineEvents.length === 0) return;\n\n const tooltip = createTooltip(container, palette, isDark);\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const isVertical = orientation === 'vertical';\n\n // Theme colors\n const textColor = palette.text;\n const mutedColor = palette.border;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n // Assign colors to groups\n const groupColorMap = new Map<string, string>();\n timelineGroups.forEach((grp, i) => {\n groupColorMap.set(grp.name, grp.color ?? colors[i % colors.length]);\n });\n\n function eventColor(ev: TimelineEvent): string {\n if (ev.group && groupColorMap.has(ev.group)) {\n return groupColorMap.get(ev.group)!;\n }\n return textColor;\n }\n\n // Convert dates to numeric values and find boundary dates\n let minDate = Infinity;\n let maxDate = -Infinity;\n let earliestStartDateStr = '';\n let latestEndDateStr = '';\n\n for (const ev of timelineEvents) {\n const startNum = parseTimelineDate(ev.date);\n const endNum = ev.endDate ? parseTimelineDate(ev.endDate) : startNum;\n\n if (startNum < minDate) {\n minDate = startNum;\n earliestStartDateStr = ev.date;\n }\n if (endNum > maxDate) {\n maxDate = endNum;\n latestEndDateStr = ev.endDate ?? ev.date;\n }\n }\n const datePadding = (maxDate - minDate) * 0.05 || 0.5;\n\n const FADE_OPACITY = 0.1;\n\n // ------------------------------------------------------------------\n // Shared hover helpers (operate on CSS classes, orientation-agnostic)\n // ------------------------------------------------------------------\n\n function fadeToGroup(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n groupName: string\n ) {\n g.selectAll<SVGGElement, unknown>('.tl-event').each(function () {\n const el = d3Selection.select(this);\n const evGroup = el.attr('data-group');\n el.attr('opacity', evGroup === groupName ? 1 : FADE_OPACITY);\n });\n g.selectAll<SVGGElement, unknown>('.tl-legend-item, .tl-lane-header').each(\n function () {\n const el = d3Selection.select(this);\n const name = el.attr('data-group');\n el.attr('opacity', name === groupName ? 1 : FADE_OPACITY);\n }\n );\n g.selectAll<SVGGElement, unknown>('.tl-marker').attr(\n 'opacity',\n FADE_OPACITY\n );\n }\n\n function fadeToEra(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n eraStart: number,\n eraEnd: number\n ) {\n g.selectAll<SVGGElement, unknown>('.tl-event').each(function () {\n const el = d3Selection.select(this);\n const date = parseFloat(el.attr('data-date')!);\n const endDate = el.attr('data-end-date');\n const evEnd = endDate ? parseFloat(endDate) : date;\n const inside = evEnd >= eraStart && date <= eraEnd;\n el.attr('opacity', inside ? 1 : FADE_OPACITY);\n });\n g.selectAll<SVGGElement, unknown>('.tl-legend-item, .tl-lane-header').attr(\n 'opacity',\n FADE_OPACITY\n );\n g.selectAll<SVGGElement, unknown>('.tl-era').each(function () {\n const el = d3Selection.select(this);\n const s = parseFloat(el.attr('data-era-start')!);\n const e = parseFloat(el.attr('data-era-end')!);\n const isSelf = s === eraStart && e === eraEnd;\n el.attr('opacity', isSelf ? 1 : FADE_OPACITY);\n });\n g.selectAll<SVGGElement, unknown>('.tl-marker').each(function () {\n const el = d3Selection.select(this);\n const date = parseFloat(el.attr('data-marker-date')!);\n const inside = date >= eraStart && date <= eraEnd;\n el.attr('opacity', inside ? 1 : FADE_OPACITY);\n });\n }\n\n function fadeReset(\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>\n ) {\n g.selectAll<SVGGElement, unknown>(\n '.tl-event, .tl-legend-item, .tl-lane-header, .tl-marker'\n ).attr('opacity', 1);\n g.selectAll<SVGGElement, unknown>('.tl-era').attr('opacity', 1);\n }\n\n // ================================================================\n // VERTICAL orientation (time flows top→bottom)\n // ================================================================\n if (isVertical) {\n if (timelineSort === 'group' && timelineGroups.length > 0) {\n // === GROUPED: one column/lane per group, vertical ===\n const groupNames = timelineGroups.map((gr) => gr.name);\n const ungroupedEvents = timelineEvents.filter(\n (ev) => ev.group === null || !groupNames.includes(ev.group)\n );\n const laneNames =\n ungroupedEvents.length > 0 ? [...groupNames, '(Other)'] : groupNames;\n\n const laneCount = laneNames.length;\n const scaleMargin = timelineScale ? 40 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n const margin = {\n top: 104 + markerMargin,\n right: 40 + scaleMargin,\n bottom: 40,\n left: 60 + scaleMargin,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const laneWidth = innerWidth / laneCount;\n\n const yScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerHeight]);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n yScale,\n true,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n yScale,\n true,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n yScale,\n true,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n laneNames.forEach((laneName, laneIdx) => {\n const laneX = laneIdx * laneWidth;\n const laneColor = groupColorMap.get(laneName) ?? textColor;\n const laneCenter = laneX + laneWidth / 2;\n\n const headerG = g\n .append('g')\n .attr('class', 'tl-lane-header')\n .attr('data-group', laneName)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, laneName))\n .on('mouseleave', () => fadeReset(g));\n\n headerG\n .append('text')\n .attr('x', laneCenter)\n .attr('y', -15)\n .attr('text-anchor', 'middle')\n .attr('fill', laneColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .text(laneName);\n\n g.append('line')\n .attr('x1', laneCenter)\n .attr('y1', 0)\n .attr('x2', laneCenter)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n const laneEvents = timelineEvents.filter((ev) =>\n laneName === '(Other)'\n ? ev.group === null || !groupNames.includes(ev.group)\n : ev.group === laneName\n );\n\n for (const ev of laneEvents) {\n const y = yScale(parseTimelineDate(ev.date));\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', laneName)\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n fadeToGroup(g, laneName);\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('mouseleave', function () {\n fadeReset(g);\n hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const y2 = yScale(parseTimelineDate(ev.endDate));\n const rectH = Math.max(y2 - y, 4);\n\n let fill: string = laneColor;\n if (ev.uncertain) {\n const gradientId = `uncertain-vg-${ev.lineNumber}`;\n const defs =\n svg.select('defs').node() || svg.append('defs').node();\n d3Selection\n .select(defs as Element)\n .append('linearGradient')\n .attr('id', gradientId)\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '0%')\n .attr('y2', '100%')\n .selectAll('stop')\n .data([\n { offset: '0%', opacity: 1 },\n { offset: '80%', opacity: 1 },\n { offset: '100%', opacity: 0 },\n ])\n .enter()\n .append('stop')\n .attr('offset', (d) => d.offset)\n .attr('stop-color', laneColor)\n .attr('stop-opacity', (d) => d.opacity);\n fill = `url(#${gradientId})`;\n }\n\n evG\n .append('rect')\n .attr('x', laneCenter - 6)\n .attr('y', y)\n .attr('width', 12)\n .attr('height', rectH)\n .attr('rx', 4)\n .attr('fill', fill);\n evG\n .append('text')\n .attr('x', laneCenter + 14)\n .attr('y', y + rectH / 2)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .text(ev.label);\n } else {\n evG\n .append('circle')\n .attr('cx', laneCenter)\n .attr('cy', y)\n .attr('r', 4)\n .attr('fill', laneColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', laneCenter + 10)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '10px')\n .text(ev.label);\n }\n }\n });\n } else {\n // === TIME SORT, vertical: single vertical axis ===\n const scaleMargin = timelineScale ? 40 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n const margin = {\n top: 104 + markerMargin,\n right: 200,\n bottom: 40,\n left: 60 + scaleMargin,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const axisX = 20;\n\n const yScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerHeight]);\n\n const sorted = timelineEvents\n .slice()\n .sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n yScale,\n true,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n yScale,\n true,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n yScale,\n true,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n // Group legend\n if (timelineGroups.length > 0) {\n let legendX = 0;\n const legendY = -55;\n for (const grp of timelineGroups) {\n const color = groupColorMap.get(grp.name) ?? textColor;\n const itemG = g\n .append('g')\n .attr('class', 'tl-legend-item')\n .attr('data-group', grp.name)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, grp.name))\n .on('mouseleave', () => fadeReset(g));\n\n itemG\n .append('circle')\n .attr('cx', legendX)\n .attr('cy', legendY)\n .attr('r', 5)\n .attr('fill', color);\n\n itemG\n .append('text')\n .attr('x', legendX + 10)\n .attr('y', legendY)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(grp.name);\n\n legendX += grp.name.length * 7 + 30;\n }\n }\n\n g.append('line')\n .attr('x1', axisX)\n .attr('y1', 0)\n .attr('x2', axisX)\n .attr('y2', innerHeight)\n .attr('stroke', mutedColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '4,4');\n\n for (const ev of sorted) {\n const y = yScale(parseTimelineDate(ev.date));\n const color = eventColor(ev);\n\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', ev.group || '')\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('mouseleave', function () {\n fadeReset(g);\n hideTooltip(tooltip);\n })\n .on('mousemove', function (event: MouseEvent) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const y2 = yScale(parseTimelineDate(ev.endDate));\n const rectH = Math.max(y2 - y, 4);\n\n let fill: string = color;\n if (ev.uncertain) {\n const gradientId = `uncertain-v-${ev.lineNumber}`;\n const defs =\n svg.select('defs').node() || svg.append('defs').node();\n d3Selection\n .select(defs as Element)\n .append('linearGradient')\n .attr('id', gradientId)\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '0%')\n .attr('y2', '100%')\n .selectAll('stop')\n .data([\n { offset: '0%', opacity: 1 },\n { offset: '80%', opacity: 1 },\n { offset: '100%', opacity: 0 },\n ])\n .enter()\n .append('stop')\n .attr('offset', (d) => d.offset)\n .attr('stop-color', color)\n .attr('stop-opacity', (d) => d.opacity);\n fill = `url(#${gradientId})`;\n }\n\n evG\n .append('rect')\n .attr('x', axisX - 6)\n .attr('y', y)\n .attr('width', 12)\n .attr('height', rectH)\n .attr('rx', 4)\n .attr('fill', fill);\n evG\n .append('text')\n .attr('x', axisX + 16)\n .attr('y', y + rectH / 2)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(ev.label);\n } else {\n evG\n .append('circle')\n .attr('cx', axisX)\n .attr('cy', y)\n .attr('r', 4)\n .attr('fill', color)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', axisX + 16)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(ev.label);\n }\n\n // Date label to the left\n evG\n .append('text')\n .attr('x', axisX - 14)\n .attr(\n 'y',\n ev.endDate\n ? yScale(parseTimelineDate(ev.date)) +\n Math.max(\n yScale(parseTimelineDate(ev.endDate)) -\n yScale(parseTimelineDate(ev.date)),\n 4\n ) /\n 2\n : y\n )\n .attr('dy', '0.35em')\n .attr('text-anchor', 'end')\n .attr('fill', mutedColor)\n .attr('font-size', '10px')\n .text(ev.date + (ev.endDate ? `→${ev.endDate}` : ''));\n }\n }\n\n return; // vertical done\n }\n\n // ================================================================\n // HORIZONTAL orientation (default — time flows left→right)\n // Each event gets its own row, stacked vertically.\n // ================================================================\n\n const BAR_H = 22; // range bar thickness (tall enough for text inside)\n const GROUP_GAP = 12; // vertical gap between group swim-lanes\n\n if (timelineSort === 'group' && timelineGroups.length > 0) {\n // === GROUPED: swim-lanes stacked vertically, events on own rows ===\n const groupNames = timelineGroups.map((gr) => gr.name);\n const ungroupedEvents = timelineEvents.filter(\n (ev) => ev.group === null || !groupNames.includes(ev.group)\n );\n const laneNames =\n ungroupedEvents.length > 0 ? [...groupNames, '(Other)'] : groupNames;\n\n // Build lane data\n const lanes = laneNames.map((name) => ({\n name,\n events: timelineEvents.filter((ev) =>\n name === '(Other)'\n ? ev.group === null || !groupNames.includes(ev.group)\n : ev.group === name\n ),\n }));\n\n const totalEventRows = lanes.reduce((s, l) => s + l.events.length, 0);\n const scaleMargin = timelineScale ? 24 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n // Calculate left margin based on longest group name (~7px per char + padding)\n const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));\n const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);\n // Group-sorted doesn't need legend space (group names shown on left)\n const baseTopMargin = title ? 50 : 20;\n const margin = {\n top: baseTopMargin + (timelineScale ? 40 : 0) + markerMargin,\n right: 40,\n bottom: 40 + scaleMargin,\n left: dynamicLeftMargin,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const totalGaps = (lanes.length - 1) * GROUP_GAP;\n const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);\n\n const xScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerWidth]);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n xScale,\n false,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n xScale,\n false,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n xScale,\n false,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n // Offset events below marker area when markers are present\n let curY = markerMargin;\n\n // Render swimlane backgrounds first (so they appear behind events)\n // Extend into left margin to include group names\n if (timelineSwimlanes) {\n let swimY = markerMargin;\n lanes.forEach((lane, idx) => {\n const laneSpan = lane.events.length * rowH;\n // Alternate between light gray and transparent for visual separation\n const fillColor = idx % 2 === 0 ? textColor : 'transparent';\n g.append('rect')\n .attr('class', 'tl-swimlane')\n .attr('data-group', lane.name)\n .attr('x', -margin.left)\n .attr('y', swimY)\n .attr('width', innerWidth + margin.left)\n .attr('height', laneSpan + (idx < lanes.length - 1 ? GROUP_GAP : 0))\n .attr('fill', fillColor)\n .attr('opacity', 0.06);\n swimY += laneSpan + GROUP_GAP;\n });\n }\n\n for (const lane of lanes) {\n const laneColor = groupColorMap.get(lane.name) ?? textColor;\n const laneSpan = lane.events.length * rowH;\n\n // Group label — left of lane, vertically centred\n const group = timelineGroups.find((grp) => grp.name === lane.name);\n const headerG = g\n .append('g')\n .attr('class', 'tl-lane-header')\n .attr('data-group', lane.name)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, lane.name))\n .on('mouseleave', () => fadeReset(g))\n .on('click', () => {\n if (onClickItem && group?.lineNumber) onClickItem(group.lineNumber);\n });\n\n headerG\n .append('text')\n .attr('x', -margin.left + 10)\n .attr('y', curY + laneSpan / 2)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', laneColor)\n .attr('font-size', '12px')\n .attr('font-weight', '600')\n .text(lane.name);\n\n lane.events.forEach((ev, i) => {\n const y = curY + i * rowH + rowH / 2;\n const x = xScale(parseTimelineDate(ev.date));\n\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', lane.name)\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n fadeToGroup(g, lane.name);\n if (timelineScale) {\n showEventDatesOnScale(\n g,\n xScale,\n ev.date,\n ev.endDate,\n innerHeight,\n laneColor\n );\n } else {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('mouseleave', function () {\n fadeReset(g);\n if (timelineScale) {\n hideEventDatesOnScale(g);\n } else {\n hideTooltip(tooltip);\n }\n })\n .on('mousemove', function (event: MouseEvent) {\n if (!timelineScale) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const x2 = xScale(parseTimelineDate(ev.endDate));\n const rectW = Math.max(x2 - x, 4);\n // Estimate label width (~7px per char at 13px font) + padding\n const estLabelWidth = ev.label.length * 7 + 16;\n const labelFitsInside = rectW >= estLabelWidth;\n\n let fill: string = laneColor;\n if (ev.uncertain) {\n // Create gradient for uncertain end - fades last 20%\n const gradientId = `uncertain-${ev.lineNumber}`;\n const defs = svg.select('defs').node() || svg.append('defs').node();\n d3Selection\n .select(defs as Element)\n .append('linearGradient')\n .attr('id', gradientId)\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n .selectAll('stop')\n .data([\n { offset: '0%', opacity: 1 },\n { offset: '80%', opacity: 1 },\n { offset: '100%', opacity: 0 },\n ])\n .enter()\n .append('stop')\n .attr('offset', (d) => d.offset)\n .attr('stop-color', laneColor)\n .attr('stop-opacity', (d) => d.opacity);\n fill = `url(#${gradientId})`;\n }\n\n evG\n .append('rect')\n .attr('x', x)\n .attr('y', y - BAR_H / 2)\n .attr('width', rectW)\n .attr('height', BAR_H)\n .attr('rx', 4)\n .attr('fill', fill);\n\n if (labelFitsInside) {\n // Text inside bar - always white for readability\n evG\n .append('text')\n .attr('x', x + 8)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', '#ffffff')\n .attr('font-size', '14px')\n .attr('font-weight', '700')\n .text(ev.label);\n } else {\n // Text outside bar - check if it fits on left or must go right\n const wouldFlipLeft = x + rectW > innerWidth * 0.6;\n const labelFitsLeft = x - 6 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('text')\n .attr('x', flipLeft ? x - 6 : x + rectW + 6)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '13px')\n .text(ev.label);\n }\n } else {\n // Point event (no end date) - render as circle with label\n const estLabelWidth = ev.label.length * 7;\n // Only flip left if past 60% AND label fits without colliding with group name area\n const wouldFlipLeft = x > innerWidth * 0.6;\n const labelFitsLeft = x - 10 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('circle')\n .attr('cx', x)\n .attr('cy', y)\n .attr('r', 5)\n .attr('fill', laneColor)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', flipLeft ? x - 10 : x + 10)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .text(ev.label);\n }\n });\n\n curY += laneSpan + GROUP_GAP;\n }\n } else {\n // === TIME SORT, horizontal: each event on its own row ===\n const sorted = timelineEvents\n .slice()\n .sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));\n\n const scaleMargin = timelineScale ? 24 : 0;\n const markerMargin = timelineMarkers.length > 0 ? 30 : 0;\n const margin = {\n top: 104 + (timelineScale ? 40 : 0) + markerMargin,\n right: 40,\n bottom: 40 + scaleMargin,\n left: 60,\n };\n const innerWidth = width - margin.left - margin.right;\n const innerHeight = height - margin.top - margin.bottom;\n const rowH = Math.min(28, innerHeight / sorted.length);\n\n const xScale = d3Scale\n .scaleLinear()\n .domain([minDate - datePadding, maxDate + datePadding])\n .range([0, innerWidth]);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n const g = svg\n .append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n renderEras(\n g,\n timelineEras,\n xScale,\n false,\n innerWidth,\n innerHeight,\n (s, e) => fadeToEra(g, s, e),\n () => fadeReset(g),\n timelineScale,\n tooltip,\n palette\n );\n\n renderMarkers(\n g,\n timelineMarkers,\n xScale,\n false,\n innerWidth,\n innerHeight,\n timelineScale,\n tooltip,\n palette\n );\n\n if (timelineScale) {\n renderTimeScale(\n g,\n xScale,\n false,\n innerWidth,\n innerHeight,\n textColor,\n minDate,\n maxDate,\n formatDateLabel(earliestStartDateStr),\n formatDateLabel(latestEndDateStr)\n );\n }\n\n // Group legend at top-left\n if (timelineGroups.length > 0) {\n let legendX = 0;\n const legendY = timelineScale ? -75 : -55;\n for (const grp of timelineGroups) {\n const color = groupColorMap.get(grp.name) ?? textColor;\n const itemG = g\n .append('g')\n .attr('class', 'tl-legend-item')\n .attr('data-group', grp.name)\n .style('cursor', 'pointer')\n .on('mouseenter', () => fadeToGroup(g, grp.name))\n .on('mouseleave', () => fadeReset(g));\n\n itemG\n .append('circle')\n .attr('cx', legendX)\n .attr('cy', legendY)\n .attr('r', 5)\n .attr('fill', color);\n\n itemG\n .append('text')\n .attr('x', legendX + 10)\n .attr('y', legendY)\n .attr('dy', '0.35em')\n .attr('fill', textColor)\n .attr('font-size', '11px')\n .text(grp.name);\n\n legendX += grp.name.length * 7 + 30;\n }\n }\n\n sorted.forEach((ev, i) => {\n // Offset events below marker area when markers are present\n const y = markerMargin + i * rowH + rowH / 2;\n const x = xScale(parseTimelineDate(ev.date));\n const color = eventColor(ev);\n\n const evG = g\n .append('g')\n .attr('class', 'tl-event')\n .attr('data-group', ev.group || '')\n .attr('data-line-number', String(ev.lineNumber))\n .attr('data-date', String(parseTimelineDate(ev.date)))\n .attr(\n 'data-end-date',\n ev.endDate ? String(parseTimelineDate(ev.endDate)) : null\n )\n .style('cursor', 'pointer')\n .on('mouseenter', function (event: MouseEvent) {\n if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);\n if (timelineScale) {\n showEventDatesOnScale(\n g,\n xScale,\n ev.date,\n ev.endDate,\n innerHeight,\n color\n );\n } else {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('mouseleave', function () {\n fadeReset(g);\n if (timelineScale) {\n hideEventDatesOnScale(g);\n } else {\n hideTooltip(tooltip);\n }\n })\n .on('mousemove', function (event: MouseEvent) {\n if (!timelineScale) {\n showTooltip(tooltip, buildEventTooltipHtml(ev), event);\n }\n })\n .on('click', () => {\n if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);\n });\n\n if (ev.endDate) {\n const x2 = xScale(parseTimelineDate(ev.endDate));\n const rectW = Math.max(x2 - x, 4);\n // Estimate label width (~7px per char at 13px font) + padding\n const estLabelWidth = ev.label.length * 7 + 16;\n const labelFitsInside = rectW >= estLabelWidth;\n\n let fill: string = color;\n if (ev.uncertain) {\n // Create gradient for uncertain end - fades last 20%\n const gradientId = `uncertain-ts-${ev.lineNumber}`;\n const defs = svg.select('defs').node() || svg.append('defs').node();\n d3Selection\n .select(defs as Element)\n .append('linearGradient')\n .attr('id', gradientId)\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n .selectAll('stop')\n .data([\n { offset: '0%', opacity: 1 },\n { offset: '80%', opacity: 1 },\n { offset: '100%', opacity: 0 },\n ])\n .enter()\n .append('stop')\n .attr('offset', (d) => d.offset)\n .attr('stop-color', color)\n .attr('stop-opacity', (d) => d.opacity);\n fill = `url(#${gradientId})`;\n }\n\n evG\n .append('rect')\n .attr('x', x)\n .attr('y', y - BAR_H / 2)\n .attr('width', rectW)\n .attr('height', BAR_H)\n .attr('rx', 4)\n .attr('fill', fill);\n\n if (labelFitsInside) {\n // Text inside bar - always white for readability\n evG\n .append('text')\n .attr('x', x + 8)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', 'start')\n .attr('fill', '#ffffff')\n .attr('font-size', '14px')\n .attr('font-weight', '700')\n .text(ev.label);\n } else {\n // Text outside bar - check if it fits on left or must go right\n const wouldFlipLeft = x + rectW > innerWidth * 0.6;\n const labelFitsLeft = x - 6 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('text')\n .attr('x', flipLeft ? x - 6 : x + rectW + 6)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '13px')\n .text(ev.label);\n }\n } else {\n // Point event (no end date) - render as circle with label\n const estLabelWidth = ev.label.length * 7;\n // Only flip left if past 60% AND label fits without going off-chart\n const wouldFlipLeft = x > innerWidth * 0.6;\n const labelFitsLeft = x - 10 - estLabelWidth > 0;\n const flipLeft = wouldFlipLeft && labelFitsLeft;\n evG\n .append('circle')\n .attr('cx', x)\n .attr('cy', y)\n .attr('r', 5)\n .attr('fill', color)\n .attr('stroke', bgColor)\n .attr('stroke-width', 1.5);\n evG\n .append('text')\n .attr('x', flipLeft ? x - 10 : x + 10)\n .attr('y', y)\n .attr('dy', '0.35em')\n .attr('text-anchor', flipLeft ? 'end' : 'start')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .text(ev.label);\n }\n });\n }\n}\n\n// ============================================================\n// Word Cloud Helpers\n// ============================================================\n\nfunction getRotateFn(mode: WordCloudRotate): () => number {\n if (mode === 'mixed') return () => (Math.random() > 0.5 ? 0 : 90);\n if (mode === 'angled') return () => Math.round(Math.random() * 30 - 15);\n return () => 0;\n}\n\n// ============================================================\n// Word Cloud Renderer\n// ============================================================\n\n/**\n * Renders a word cloud into the given container using d3-cloud.\n */\nexport function renderWordCloud(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n _isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { words, title, cloudOptions } = parsed;\n if (words.length === 0) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const titleHeight = title ? 40 : 0;\n const cloudHeight = height - titleHeight;\n\n const textColor = palette.text;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n const { minSize, maxSize } = cloudOptions;\n const weights = words.map((w) => w.weight);\n const minWeight = Math.min(...weights);\n const maxWeight = Math.max(...weights);\n const range = maxWeight - minWeight || 1;\n\n const fontSize = (weight: number): number => {\n const t = (weight - minWeight) / range;\n return minSize + t * (maxSize - minSize);\n };\n\n const rotateFn = getRotateFn(cloudOptions.rotate);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n const g = svg\n .append('g')\n .attr(\n 'transform',\n `translate(${width / 2},${titleHeight + cloudHeight / 2})`\n );\n\n cloud<WordCloudWord & cloud.Word>()\n .size([width, cloudHeight])\n .words(words.map((w) => ({ ...w, size: fontSize(w.weight) })))\n .padding(4)\n .rotate(rotateFn)\n .fontSize((d) => d.size!)\n .font(FONT_FAMILY)\n .on('end', (layoutWords) => {\n g.selectAll('text')\n .data(layoutWords)\n .join('text')\n .style('font-size', (d) => `${d.size}px`)\n .style('font-family', FONT_FAMILY)\n .style('font-weight', '600')\n .style('fill', (_d, i) => colors[i % colors.length])\n .style('cursor', (d) =>\n onClickItem && (d as WordCloudWord).lineNumber ? 'pointer' : 'default'\n )\n .attr('text-anchor', 'middle')\n .attr(\n 'transform',\n (d) => `translate(${d.x},${d.y}) rotate(${d.rotate})`\n )\n .attr('data-line-number', (d) => {\n const ln = (d as WordCloudWord).lineNumber;\n return ln ? String(ln) : null;\n })\n .text((d) => d.text!)\n .on('click', (_event, d) => {\n const ln = (d as WordCloudWord).lineNumber;\n if (onClickItem && ln) onClickItem(ln);\n });\n })\n .start();\n}\n\n// ============================================================\n// Word Cloud Renderer (for export — returns Promise)\n// ============================================================\n\nfunction renderWordCloudAsync(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n _isDark: boolean,\n exportDims?: D3ExportDimensions\n): Promise<void> {\n return new Promise((resolve) => {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { words, title, cloudOptions } = parsed;\n if (words.length === 0) {\n resolve();\n return;\n }\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) {\n resolve();\n return;\n }\n\n const titleHeight = title ? 40 : 0;\n const cloudHeight = height - titleHeight;\n\n const textColor = palette.text;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n\n const { minSize, maxSize } = cloudOptions;\n const weights = words.map((w) => w.weight);\n const minWeight = Math.min(...weights);\n const maxWeight = Math.max(...weights);\n const range = maxWeight - minWeight || 1;\n\n const fontSize = (weight: number): number => {\n const t = (weight - minWeight) / range;\n return minSize + t * (maxSize - minSize);\n };\n\n const rotateFn = getRotateFn(cloudOptions.rotate);\n\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n }\n }\n\n const g = svg\n .append('g')\n .attr(\n 'transform',\n `translate(${width / 2},${titleHeight + cloudHeight / 2})`\n );\n\n cloud<WordCloudWord & cloud.Word>()\n .size([width, cloudHeight])\n .words(words.map((w) => ({ ...w, size: fontSize(w.weight) })))\n .padding(4)\n .rotate(rotateFn)\n .fontSize((d) => d.size!)\n .font(FONT_FAMILY)\n .on('end', (layoutWords) => {\n g.selectAll('text')\n .data(layoutWords)\n .join('text')\n .style('font-size', (d) => `${d.size}px`)\n .style('font-family', FONT_FAMILY)\n .style('font-weight', '600')\n .style('fill', (_d, i) => colors[i % colors.length])\n .attr('text-anchor', 'middle')\n .attr(\n 'transform',\n (d) => `translate(${d.x},${d.y}) rotate(${d.rotate})`\n )\n .text((d) => d.text!);\n resolve();\n })\n .start();\n });\n}\n\n// ============================================================\n// Venn Diagram Math Helpers\n// ============================================================\n\nfunction radiusFromArea(area: number): number {\n return Math.sqrt(area / Math.PI);\n}\n\nfunction circleOverlapArea(r1: number, r2: number, d: number): number {\n // No overlap\n if (d >= r1 + r2) return 0;\n // Full containment\n if (d + Math.min(r1, r2) <= Math.max(r1, r2)) {\n return Math.PI * Math.min(r1, r2) ** 2;\n }\n const part1 = r1 * r1 * Math.acos((d * d + r1 * r1 - r2 * r2) / (2 * d * r1));\n const part2 = r2 * r2 * Math.acos((d * d + r2 * r2 - r1 * r1) / (2 * d * r2));\n const part3 =\n 0.5 *\n Math.sqrt((-d + r1 + r2) * (d + r1 - r2) * (d - r1 + r2) * (d + r1 + r2));\n return part1 + part2 - part3;\n}\n\nfunction distanceForOverlap(\n r1: number,\n r2: number,\n targetArea: number\n): number {\n if (targetArea <= 0) return r1 + r2;\n const minR = Math.min(r1, r2);\n if (targetArea >= Math.PI * minR * minR) return Math.abs(r1 - r2);\n let lo = Math.abs(r1 - r2);\n let hi = r1 + r2;\n for (let i = 0; i < 64; i++) {\n const mid = (lo + hi) / 2;\n if (circleOverlapArea(r1, r2, mid) > targetArea) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n return (lo + hi) / 2;\n}\n\ninterface Point {\n x: number;\n y: number;\n}\n\ninterface Circle {\n x: number;\n y: number;\n r: number;\n}\n\nfunction thirdCirclePosition(\n ax: number,\n ay: number,\n dAC: number,\n bx: number,\n by: number,\n dBC: number\n): Point {\n const dx = bx - ax;\n const dy = by - ay;\n const dAB = Math.sqrt(dx * dx + dy * dy);\n if (dAB === 0) return { x: ax + dAC, y: ay };\n const cosA = (dAB * dAB + dAC * dAC - dBC * dBC) / (2 * dAB * dAC);\n const sinA = Math.sqrt(Math.max(0, 1 - cosA * cosA));\n const ux = dx / dAB;\n const uy = dy / dAB;\n // Place C above the AB line\n return {\n x: ax + dAC * (cosA * ux - sinA * uy),\n y: ay + dAC * (cosA * uy + sinA * ux),\n };\n}\n\nfunction fitCirclesToContainerAsymmetric(\n circles: Circle[],\n w: number,\n h: number,\n mLeft: number,\n mRight: number,\n mTop: number,\n mBottom: number\n): Circle[] {\n if (circles.length === 0) return [];\n let minX = Infinity,\n maxX = -Infinity,\n minY = Infinity,\n maxY = -Infinity;\n for (const c of circles) {\n minX = Math.min(minX, c.x - c.r);\n maxX = Math.max(maxX, c.x + c.r);\n minY = Math.min(minY, c.y - c.r);\n maxY = Math.max(maxY, c.y + c.r);\n }\n const bw = maxX - minX;\n const bh = maxY - minY;\n const availW = w - mLeft - mRight;\n const availH = h - mTop - mBottom;\n const scale = Math.min(availW / bw, availH / bh);\n const cx = (minX + maxX) / 2;\n const cy = (minY + maxY) / 2;\n const tx = mLeft + availW / 2;\n const ty = mTop + availH / 2;\n return circles.map((c) => ({\n x: (c.x - cx) * scale + tx,\n y: (c.y - cy) * scale + ty,\n r: c.r * scale,\n }));\n}\n\nfunction pointInCircle(p: Point, c: Circle): boolean {\n const dx = p.x - c.x;\n const dy = p.y - c.y;\n return dx * dx + dy * dy <= c.r * c.r + 1e-6;\n}\n\nfunction regionCentroid(circles: Circle[], inside: boolean[]): Point {\n // Deterministic 50×50 grid scan instead of random sampling\n const GRID = 50;\n let minX = Infinity,\n maxX = -Infinity,\n minY = Infinity,\n maxY = -Infinity;\n for (const c of circles) {\n minX = Math.min(minX, c.x - c.r);\n maxX = Math.max(maxX, c.x + c.r);\n minY = Math.min(minY, c.y - c.r);\n maxY = Math.max(maxY, c.y + c.r);\n }\n const stepX = (maxX - minX) / GRID;\n const stepY = (maxY - minY) / GRID;\n let sx = 0,\n sy = 0,\n count = 0;\n for (let gi = 0; gi <= GRID; gi++) {\n const x = minX + gi * stepX;\n for (let gj = 0; gj <= GRID; gj++) {\n const y = minY + gj * stepY;\n let match = true;\n for (let j = 0; j < circles.length; j++) {\n const isIn = pointInCircle({ x, y }, circles[j]);\n if (isIn !== inside[j]) {\n match = false;\n break;\n }\n }\n if (match) {\n sx += x;\n sy += y;\n count++;\n }\n }\n }\n if (count === 0) {\n // Fallback: centroid of the circles that should be \"inside\"\n let fx = 0,\n fy = 0,\n fc = 0;\n for (let j = 0; j < circles.length; j++) {\n if (inside[j]) {\n fx += circles[j].x;\n fy += circles[j].y;\n fc++;\n }\n }\n return { x: fx / (fc || 1), y: fy / (fc || 1) };\n }\n return { x: sx / count, y: sy / count };\n}\n\n// ============================================================\n// Venn Diagram Renderer\n// ============================================================\n\nexport function renderVenn(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const { vennSets, vennOverlaps, vennShowValues, title } = parsed;\n if (vennSets.length < 2) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const textColor = palette.text;\n const bgColor = palette.bg;\n const colors = getSeriesColors(palette);\n const titleHeight = title ? 40 : 0;\n\n // Compute radii\n const radii = vennSets.map((s) => radiusFromArea(s.size));\n\n // Build overlap map keyed by sorted set names\n const overlapMap = new Map<string, number>();\n for (const ov of vennOverlaps) {\n overlapMap.set(ov.sets.join('&'), ov.size);\n }\n\n // Layout circles\n let rawCircles: Circle[];\n const n = vennSets.length;\n\n if (n === 2) {\n const d = distanceForOverlap(\n radii[0],\n radii[1],\n overlapMap.get([vennSets[0].name, vennSets[1].name].sort().join('&')) ?? 0\n );\n rawCircles = [\n { x: -d / 2, y: 0, r: radii[0] },\n { x: d / 2, y: 0, r: radii[1] },\n ];\n } else {\n // 3 sets: place A and B, then compute C position\n const names = vennSets.map((s) => s.name);\n const pairKey = (i: number, j: number) =>\n [names[i], names[j]].sort().join('&');\n\n const dAB = distanceForOverlap(\n radii[0],\n radii[1],\n overlapMap.get(pairKey(0, 1)) ?? 0\n );\n const dAC = distanceForOverlap(\n radii[0],\n radii[2],\n overlapMap.get(pairKey(0, 2)) ?? 0\n );\n const dBC = distanceForOverlap(\n radii[1],\n radii[2],\n overlapMap.get(pairKey(1, 2)) ?? 0\n );\n\n const ax = -dAB / 2;\n const bx = dAB / 2;\n const cPos = thirdCirclePosition(ax, 0, dAC, bx, 0, dBC);\n\n rawCircles = [\n { x: ax, y: 0, r: radii[0] },\n { x: bx, y: 0, r: radii[1] },\n { x: cPos.x, y: cPos.y, r: radii[2] },\n ];\n }\n\n // Resolve colors for each set\n const setColors = vennSets.map(\n (s, i) => s.color ?? colors[i % colors.length]\n );\n\n // ── Layout-aware centering with label space ──\n // Estimate per-side label widths and compute asymmetric margins\n const clusterCx = rawCircles.reduce((s, c) => s + c.x, 0) / n;\n const clusterCy = rawCircles.reduce((s, c) => s + c.y, 0) / n;\n\n // Estimate which side each set label falls on\n let marginLeft = 30,\n marginRight = 30,\n marginTop = 30,\n marginBottom = 30;\n const stubLen = 20;\n const edgePad = 8;\n const labelTextPad = 4;\n\n for (let i = 0; i < n; i++) {\n const displayName = vennSets[i].label ?? vennSets[i].name;\n const estimatedWidth = displayName.length * 8.5 + stubLen + edgePad + labelTextPad;\n const dx = rawCircles[i].x - clusterCx;\n const dy = rawCircles[i].y - clusterCy;\n\n if (Math.abs(dx) >= Math.abs(dy)) {\n // Label exits left or right\n if (dx >= 0) marginRight = Math.max(marginRight, estimatedWidth);\n else marginLeft = Math.max(marginLeft, estimatedWidth);\n } else {\n // Label exits top or bottom\n const halfEstimate = estimatedWidth * 0.5;\n if (dy >= 0) marginBottom = Math.max(marginBottom, halfEstimate + 20);\n else marginTop = Math.max(marginTop, halfEstimate + 20);\n }\n }\n\n const drawH = height - titleHeight;\n const circles = fitCirclesToContainerAsymmetric(\n rawCircles,\n width,\n drawH,\n marginLeft,\n marginRight,\n marginTop,\n marginBottom\n ).map((c) => ({ ...c, y: c.y + titleHeight }));\n\n // SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n // Tooltip\n const tooltip = createTooltip(container, palette, isDark);\n\n // Title\n if (title) {\n const titleEl = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style('cursor', onClickItem && parsed.titleLineNumber ? 'pointer' : 'default')\n .text(title);\n\n if (parsed.titleLineNumber) {\n titleEl.attr('data-line-number', parsed.titleLineNumber);\n if (onClickItem) {\n titleEl\n .on('click', () => onClickItem(parsed.titleLineNumber!))\n .on('mouseenter', function () { d3Selection.select(this).attr('opacity', 0.7); })\n .on('mouseleave', function () { d3Selection.select(this).attr('opacity', 1); });\n }\n }\n }\n\n // ── Semi-transparent filled circles ──\n const circleEls: d3Selection.Selection<SVGCircleElement, unknown, null, undefined>[] = [];\n const circleGroup = svg.append('g');\n circles.forEach((c, i) => {\n const el = circleGroup\n .append('circle')\n .attr('cx', c.x)\n .attr('cy', c.y)\n .attr('r', c.r)\n .attr('fill', setColors[i])\n .attr('fill-opacity', 0.35)\n .attr('stroke', setColors[i])\n .attr('stroke-width', 2)\n .style('pointer-events', 'none') as d3Selection.Selection<\n SVGCircleElement,\n unknown,\n null,\n undefined\n >;\n circleEls.push(el);\n });\n\n // ── Labels ──\n // Global center of all circles (for projecting outward)\n const gcx = circles.reduce((s, c) => s + c.x, 0) / n;\n const gcy = circles.reduce((s, c) => s + c.y, 0) / n;\n\n // Helper: ray-circle exit distance (positive = forward along direction)\n function rayCircleExit(\n ox: number,\n oy: number,\n dx: number,\n dy: number,\n c: Circle\n ): number {\n const lx = ox - c.x;\n const ly = oy - c.y;\n const b = lx * dx + ly * dy;\n const det = b * b - (lx * lx + ly * ly - c.r * c.r);\n if (det < 0) return 0;\n return -b + Math.sqrt(det);\n }\n\n const labelGroup = svg.append('g').style('pointer-events', 'none');\n\n // ── Set name labels (inside exclusive region if they fit, else external leader line) ──\n // Helper: measure horizontal clearance at a point inside circle i but outside others\n function exclusiveHSpan(px: number, py: number, ci: number): number {\n // Start with full chord width of circle i at height py\n const dy = py - circles[ci].y;\n const halfChord = Math.sqrt(Math.max(0, circles[ci].r * circles[ci].r - dy * dy));\n let left = circles[ci].x - halfChord;\n let right = circles[ci].x + halfChord;\n // Subtract any overlapping circle chord that covers this y\n for (let j = 0; j < n; j++) {\n if (j === ci) continue;\n const djy = py - circles[j].y;\n if (Math.abs(djy) >= circles[j].r) continue; // circle j doesn't reach this y\n const hc = Math.sqrt(circles[j].r * circles[j].r - djy * djy);\n const jLeft = circles[j].x - hc;\n const jRight = circles[j].x + hc;\n // Clamp our span to exclude the overlap with circle j\n if (jLeft <= left && jRight >= right) return 0; // fully covered\n if (jLeft <= left && jRight > left) left = jRight;\n if (jRight >= right && jLeft < right) right = jLeft;\n }\n return Math.max(0, right - left);\n }\n\n // Font size scaling: 0.6 ch-width per character at a given font size\n const CH_RATIO = 0.6;\n const MIN_FONT = 10;\n const MAX_FONT = 22;\n const INTERNAL_PAD = 12;\n\n circles.forEach((c, i) => {\n const text = vennSets[i].label ?? vennSets[i].name;\n\n // Compute exclusive region centroid\n const inside = circles.map((_, j) => j === i);\n const centroid = regionCentroid(circles, inside);\n\n // Available width at centroid\n const availW = exclusiveHSpan(centroid.x, centroid.y, i);\n // Font size that makes text fill ~80% of available width\n const fitFont = Math.min(MAX_FONT, Math.max(MIN_FONT,\n (availW - INTERNAL_PAD * 2) / (text.length * CH_RATIO)));\n const estTextW = text.length * CH_RATIO * fitFont;\n\n const fitsInside = estTextW + INTERNAL_PAD * 2 < availW &&\n pointInCircle({ x: centroid.x, y: centroid.y - fitFont / 2 }, c) &&\n pointInCircle({ x: centroid.x, y: centroid.y + fitFont / 2 }, c);\n\n if (fitsInside) {\n labelGroup\n .append('text')\n .attr('x', centroid.x)\n .attr('y', centroid.y)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', textColor)\n .attr('font-size', `${Math.round(fitFont)}px`)\n .attr('font-weight', 'bold')\n .text(text);\n } else {\n // External label with leader line\n let dx = c.x - gcx;\n let dy = c.y - gcy;\n const mag = Math.sqrt(dx * dx + dy * dy);\n if (mag < 1e-6) {\n dx = 1;\n dy = 0;\n } else {\n dx /= mag;\n dy /= mag;\n }\n\n const exitX = c.x + dx * c.r;\n const exitY = c.y + dy * c.r;\n const edgeX = exitX + dx * edgePad;\n const edgeY = exitY + dy * edgePad;\n const stubEndX = edgeX + dx * stubLen;\n const stubEndY = edgeY + dy * stubLen;\n\n labelGroup\n .append('line')\n .attr('x1', edgeX)\n .attr('y1', edgeY)\n .attr('x2', stubEndX)\n .attr('y2', stubEndY)\n .attr('stroke', textColor)\n .attr('stroke-width', 1);\n\n const isRight = stubEndX >= gcx;\n const textAnchor = isRight ? 'start' : 'end';\n let textX = stubEndX + (isRight ? labelTextPad : -labelTextPad);\n const textY = stubEndY;\n\n const estW = text.length * 8.5;\n if (isRight) {\n textX = Math.min(textX, width - estW - 4);\n } else {\n textX = Math.max(textX, estW + 4);\n }\n\n labelGroup\n .append('text')\n .attr('x', textX)\n .attr('y', Math.max(14, Math.min(height - 4, textY)))\n .attr('text-anchor', textAnchor)\n .attr('dominant-baseline', 'central')\n .attr('fill', textColor)\n .attr('font-size', '14px')\n .attr('font-weight', 'bold')\n .text(text);\n }\n });\n\n // ── Overlap labels (inline at region centroid, scaled to fit) ──\n // Helper: horizontal span at y inside all circles in idxs, outside others\n function overlapHSpan(py: number, idxs: number[]): number {\n let left = -Infinity, right = Infinity;\n // Intersect chords of all \"inside\" circles\n for (const ci of idxs) {\n const dy = py - circles[ci].y;\n if (Math.abs(dy) >= circles[ci].r) return 0;\n const hc = Math.sqrt(circles[ci].r * circles[ci].r - dy * dy);\n left = Math.max(left, circles[ci].x - hc);\n right = Math.min(right, circles[ci].x + hc);\n }\n if (left >= right) return 0;\n // Subtract any \"outside\" circle that intrudes\n for (let j = 0; j < n; j++) {\n if (idxs.includes(j)) continue;\n const dy = py - circles[j].y;\n if (Math.abs(dy) >= circles[j].r) continue;\n const hc = Math.sqrt(circles[j].r * circles[j].r - dy * dy);\n const jLeft = circles[j].x - hc;\n const jRight = circles[j].x + hc;\n if (jLeft <= left && jRight >= right) return 0;\n if (jLeft <= left && jRight > left) left = jRight;\n if (jRight >= right && jLeft < right) right = jLeft;\n }\n return Math.max(0, right - left);\n }\n\n for (const ov of vennOverlaps) {\n const idxs = ov.sets.map((s) => vennSets.findIndex((vs) => vs.name === s));\n if (idxs.some((idx) => idx < 0)) continue;\n if (!ov.label) continue;\n\n const inside = circles.map((_, j) => idxs.includes(j));\n const centroid = regionCentroid(circles, inside);\n const text = ov.label;\n\n const availW = overlapHSpan(centroid.y, idxs);\n const fitFont = Math.min(MAX_FONT, Math.max(MIN_FONT,\n (availW - INTERNAL_PAD * 2) / (text.length * CH_RATIO)));\n\n labelGroup\n .append('text')\n .attr('x', centroid.x)\n .attr('y', centroid.y)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', textColor)\n .attr('font-size', `${Math.round(fitFont)}px`)\n .attr('font-weight', '600')\n .text(text);\n }\n\n // ── Invisible hover targets (full circles) + interactions ──\n const hoverGroup = svg.append('g');\n circles.forEach((c, i) => {\n const tipName = vennSets[i].label\n ? `${vennSets[i].label} (${vennSets[i].name})`\n : vennSets[i].name;\n const tipHtml = `<strong>${tipName}</strong><br>Size: ${vennSets[i].size}`;\n\n hoverGroup\n .append('circle')\n .attr('cx', c.x)\n .attr('cy', c.y)\n .attr('r', c.r)\n .attr('fill', 'transparent')\n .attr('data-line-number', String(vennSets[i].lineNumber))\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) => {\n circleEls.forEach((el, ci) => {\n el.attr('fill-opacity', ci === i ? 0.5 : 0.1);\n });\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mousemove', (event: MouseEvent) => {\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mouseleave', () => {\n circleEls.forEach((el) => {\n el.attr('fill-opacity', 0.35);\n });\n hideTooltip(tooltip);\n })\n .on('click', () => {\n if (onClickItem && vennSets[i].lineNumber)\n onClickItem(vennSets[i].lineNumber);\n });\n });\n}\n\n// ============================================================\n// Quadrant Chart Renderer\n// ============================================================\n\ntype QuadrantPosition =\n | 'top-right'\n | 'top-left'\n | 'bottom-left'\n | 'bottom-right';\n\n/**\n * Renders a quadrant chart using D3.\n * Displays 4 colored quadrant regions, axis labels, quadrant labels, and data points.\n */\nexport function renderQuadrant(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void,\n exportDims?: D3ExportDimensions\n): void {\n d3Selection.select(container).selectAll(':not([data-d3-tooltip])').remove();\n\n const {\n title,\n quadrantLabels,\n quadrantPoints,\n quadrantXAxis,\n quadrantYAxis,\n quadrantTitleLineNumber,\n quadrantXAxisLineNumber,\n quadrantYAxisLineNumber,\n } = parsed;\n\n if (quadrantPoints.length === 0) return;\n\n const width = exportDims?.width ?? container.clientWidth;\n const height = exportDims?.height ?? container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const textColor = palette.text;\n const mutedColor = palette.textMuted;\n const bgColor = palette.bg;\n const borderColor = palette.border;\n\n // Default quadrant colors with alpha\n const defaultColors = [\n palette.colors.blue,\n palette.colors.green,\n palette.colors.yellow,\n palette.colors.purple,\n ];\n\n // Margins\n const hasXAxis = !!quadrantXAxis;\n const hasYAxis = !!quadrantYAxis;\n const margin = { top: title ? 60 : 30, right: 30, bottom: hasXAxis ? 70 : 40, left: hasYAxis ? 80 : 40 };\n const chartWidth = width - margin.left - margin.right;\n const chartHeight = height - margin.top - margin.bottom;\n\n // Scales: data uses 0-1 range\n const xScale = d3Scale.scaleLinear().domain([0, 1]).range([0, chartWidth]);\n const yScale = d3Scale.scaleLinear().domain([0, 1]).range([chartHeight, 0]);\n\n // Create SVG\n const svg = d3Selection\n .select(container)\n .append('svg')\n .attr('width', width)\n .attr('height', height)\n .style('background', bgColor);\n\n // Tooltip\n const tooltip = createTooltip(container, palette, isDark);\n\n // Title\n if (title) {\n const titleText = svg\n .append('text')\n .attr('class', 'chart-title')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '20px')\n .attr('font-weight', '700')\n .style(\n 'cursor',\n onClickItem && quadrantTitleLineNumber ? 'pointer' : 'default'\n )\n .text(title);\n\n if (quadrantTitleLineNumber) {\n titleText.attr('data-line-number', quadrantTitleLineNumber);\n }\n\n if (onClickItem && quadrantTitleLineNumber) {\n titleText\n .on('click', () => onClickItem(quadrantTitleLineNumber))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n }\n }\n\n // Chart group (translated by margins)\n const chartG = svg\n .append('g')\n .attr('transform', `translate(${margin.left}, ${margin.top})`);\n\n // Mix two hex colors: pct=100 → all `a`, pct=0 → all `b`\n const mixHex = (a: string, b: string, pct: number): string => {\n const parse = (h: string) => {\n const r = h.replace('#', '');\n const f = r.length === 3 ? r[0]+r[0]+r[1]+r[1]+r[2]+r[2] : r;\n return [parseInt(f.substring(0,2),16), parseInt(f.substring(2,4),16), parseInt(f.substring(4,6),16)];\n };\n const [ar,ag,ab] = parse(a), [br,bg,bb] = parse(b), t = pct/100;\n const c = (x: number, y: number) => Math.round(x*t + y*(1-t)).toString(16).padStart(2,'0');\n return `#${c(ar,br)}${c(ag,bg)}${c(ab,bb)}`;\n };\n\n // Opaque quadrant fills using the assigned color directly\n const getQuadrantFill = (\n label: QuadrantLabel | null,\n defaultIdx: number\n ): string => {\n return label?.color ?? defaultColors[defaultIdx % defaultColors.length];\n };\n\n // Quadrant definitions: position, rect bounds, label position\n const quadrantDefs: {\n position: QuadrantPosition;\n x: number;\n y: number;\n w: number;\n h: number;\n labelX: number;\n labelY: number;\n label: QuadrantLabel | null;\n colorIdx: number;\n }[] = [\n {\n position: 'top-left',\n x: 0,\n y: 0,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: chartWidth / 4,\n labelY: chartHeight / 4,\n label: quadrantLabels.topLeft,\n colorIdx: 1, // green\n },\n {\n position: 'top-right',\n x: chartWidth / 2,\n y: 0,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: (chartWidth * 3) / 4,\n labelY: chartHeight / 4,\n label: quadrantLabels.topRight,\n colorIdx: 0, // blue\n },\n {\n position: 'bottom-left',\n x: 0,\n y: chartHeight / 2,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: chartWidth / 4,\n labelY: (chartHeight * 3) / 4,\n label: quadrantLabels.bottomLeft,\n colorIdx: 2, // yellow\n },\n {\n position: 'bottom-right',\n x: chartWidth / 2,\n y: chartHeight / 2,\n w: chartWidth / 2,\n h: chartHeight / 2,\n labelX: (chartWidth * 3) / 4,\n labelY: (chartHeight * 3) / 4,\n label: quadrantLabels.bottomRight,\n colorIdx: 3, // purple\n },\n ];\n\n // Draw quadrant rectangles\n const quadrantRects = chartG\n .selectAll('rect.quadrant')\n .data(quadrantDefs)\n .enter()\n .append('rect')\n .attr('class', 'quadrant')\n .attr('x', (d) => d.x)\n .attr('y', (d) => d.y)\n .attr('width', (d) => d.w)\n .attr('height', (d) => d.h)\n .attr('fill', (d) => getQuadrantFill(d.label, d.colorIdx))\n .attr('stroke', borderColor)\n .attr('stroke-width', 0.5);\n\n // White text for points; quadrant labels use a darkened shade of their fill\n const contrastColor = '#ffffff';\n const shadowColor = 'rgba(0,0,0,0.4)';\n\n // Darken the quadrant fill to create a watermark-style label color\n const getQuadrantLabelColor = (d: (typeof quadrantDefs)[number]): string => {\n const fill = getQuadrantFill(d.label, d.colorIdx);\n return mixHex('#000000', fill, 40);\n };\n\n // Scale label font size to fit within quadrant bounds, wrapping into multiple lines if needed\n const LABEL_MAX_FONT = 48;\n const LABEL_MIN_FONT = 14;\n const LABEL_PAD = 40;\n const CHAR_WIDTH_RATIO = 0.6;\n\n const estTextWidth = (text: string, fontSize: number): number =>\n text.length * fontSize * CHAR_WIDTH_RATIO;\n\n interface QuadrantLabelLayout {\n lines: string[];\n fontSize: number;\n }\n\n const quadrantLabelLayout = (text: string, qw: number, qh: number): QuadrantLabelLayout => {\n const availW = qw - LABEL_PAD;\n const availH = qh - LABEL_PAD;\n const words = text.split(/\\s+/);\n\n // Try single line first\n if (estTextWidth(text, LABEL_MAX_FONT) <= availW) {\n const fs = Math.min(LABEL_MAX_FONT, availH);\n return { lines: [text], fontSize: Math.max(LABEL_MIN_FONT, Math.round(fs)) };\n }\n\n // Try wrapping into 2+ lines: greedily pack words so each line fits availW\n const wrapLines = (fs: number): string[] => {\n const result: string[] = [];\n let cur = '';\n for (const w of words) {\n const trial = cur ? `${cur} ${w}` : w;\n if (estTextWidth(trial, fs) > availW && cur) {\n result.push(cur);\n cur = w;\n } else {\n cur = trial;\n }\n }\n if (cur) result.push(cur);\n return result;\n };\n\n // Binary-search for largest font size where wrapped text fits both width and height\n let lo = LABEL_MIN_FONT;\n let hi = LABEL_MAX_FONT;\n let bestLines = wrapLines(lo);\n let bestFs = lo;\n while (lo <= hi) {\n const mid = Math.round((lo + hi) / 2);\n const lines = wrapLines(mid);\n const totalH = lines.length * mid * 1.2; // line height ~1.2em\n const maxLineW = Math.max(...lines.map((l) => estTextWidth(l, mid)));\n if (maxLineW <= availW && totalH <= availH) {\n bestFs = mid;\n bestLines = lines;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return { lines: bestLines, fontSize: Math.max(LABEL_MIN_FONT, bestFs) };\n };\n\n // Draw quadrant labels (large, centered, darkened shade of fill — recedes behind points)\n // Pre-compute layout (lines + font size) for each quadrant label\n const qw = chartWidth / 2;\n const qh = chartHeight / 2;\n const quadrantDefsWithLabel = quadrantDefs.filter((d) => d.label !== null);\n const labelLayouts = new Map(\n quadrantDefsWithLabel.map((d) => [d.label!.text, quadrantLabelLayout(d.label!.text, qw, qh)])\n );\n\n const quadrantLabelTexts = chartG\n .selectAll('text.quadrant-label')\n .data(quadrantDefsWithLabel)\n .enter()\n .append('text')\n .attr('class', 'quadrant-label')\n .attr('x', (d) => d.labelX)\n .attr('y', (d) => d.labelY)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('fill', (d) => getQuadrantLabelColor(d))\n .attr('font-size', (d) => `${labelLayouts.get(d.label!.text)!.fontSize}px`)\n .attr('font-weight', '700')\n .attr('data-line-number', (d) =>\n d.label?.lineNumber ? String(d.label.lineNumber) : null\n )\n .style('cursor', (d) =>\n onClickItem && d.label?.lineNumber ? 'pointer' : 'default'\n )\n .each(function (d) {\n const layout = labelLayouts.get(d.label!.text)!;\n const el = d3Selection.select(this);\n if (layout.lines.length === 1) {\n el.text(layout.lines[0]);\n } else {\n // Multi-line: use tspan elements, offset from center\n const lineH = layout.fontSize * 1.2;\n const totalH = layout.lines.length * lineH;\n const startY = -totalH / 2 + lineH / 2;\n layout.lines.forEach((line, i) => {\n el.append('tspan')\n .attr('x', d.labelX)\n .attr('dy', i === 0 ? `${startY}px` : `${lineH}px`)\n .text(line);\n });\n }\n });\n\n if (onClickItem) {\n quadrantLabelTexts\n .on('click', (_, d) => {\n if (d.label?.lineNumber) onClickItem(d.label.lineNumber);\n })\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n }\n\n // X-axis labels — centered on left/right halves\n if (quadrantXAxis) {\n // Low label (centered on left half)\n const xLowLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', margin.left + chartWidth / 4)\n .attr('y', height - 20)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('data-line-number', quadrantXAxisLineNumber ? String(quadrantXAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantXAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantXAxis[0]);\n\n // High label (centered on right half)\n const xHighLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', margin.left + (chartWidth * 3) / 4)\n .attr('y', height - 20)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('data-line-number', quadrantXAxisLineNumber ? String(quadrantXAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantXAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantXAxis[1]);\n\n if (onClickItem && quadrantXAxisLineNumber) {\n [xLowLabel, xHighLabel].forEach((label) => {\n label\n .on('click', () => onClickItem(quadrantXAxisLineNumber))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n });\n }\n }\n\n // Y-axis labels — centered on top/bottom halves\n if (quadrantYAxis) {\n const yMidBottom = margin.top + (chartHeight * 3) / 4;\n const yMidTop = margin.top + chartHeight / 4;\n\n // Low label (centered on bottom half)\n const yLowLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', 22)\n .attr('y', yMidBottom)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('transform', `rotate(-90, 22, ${yMidBottom})`)\n .attr('data-line-number', quadrantYAxisLineNumber ? String(quadrantYAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantYAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantYAxis[0]);\n\n // High label (centered on top half)\n const yHighLabel = svg\n .append('text')\n .attr('class', 'quadrant-axis-label')\n .attr('x', 22)\n .attr('y', yMidTop)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('transform', `rotate(-90, 22, ${yMidTop})`)\n .attr('data-line-number', quadrantYAxisLineNumber ? String(quadrantYAxisLineNumber) : null)\n .style(\n 'cursor',\n onClickItem && quadrantYAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantYAxis[1]);\n\n if (onClickItem && quadrantYAxisLineNumber) {\n [yLowLabel, yHighLabel].forEach((label) => {\n label\n .on('click', () => onClickItem(quadrantYAxisLineNumber))\n .on('mouseenter', function () {\n d3Selection.select(this).attr('opacity', 0.7);\n })\n .on('mouseleave', function () {\n d3Selection.select(this).attr('opacity', 1);\n });\n });\n }\n }\n\n // Draw center cross lines\n chartG\n .append('line')\n .attr('x1', chartWidth / 2)\n .attr('y1', 0)\n .attr('x2', chartWidth / 2)\n .attr('y2', chartHeight)\n .attr('stroke', borderColor)\n .attr('stroke-width', 1);\n\n chartG\n .append('line')\n .attr('x1', 0)\n .attr('y1', chartHeight / 2)\n .attr('x2', chartWidth)\n .attr('y2', chartHeight / 2)\n .attr('stroke', borderColor)\n .attr('stroke-width', 1);\n\n // Get which quadrant a point belongs to\n const getPointQuadrant = (x: number, y: number): QuadrantPosition => {\n if (x >= 0.5 && y >= 0.5) return 'top-right';\n if (x < 0.5 && y >= 0.5) return 'top-left';\n if (x < 0.5 && y < 0.5) return 'bottom-left';\n return 'bottom-right';\n };\n\n // Draw data points (circles and labels)\n const pointsG = chartG.append('g').attr('class', 'points');\n\n quadrantPoints.forEach((point) => {\n const cx = xScale(point.x);\n const cy = yScale(point.y);\n const quadrant = getPointQuadrant(point.x, point.y);\n const quadDef = quadrantDefs.find((d) => d.position === quadrant);\n const pointColor =\n quadDef?.label?.color ?? defaultColors[quadDef?.colorIdx ?? 0];\n\n const pointG = pointsG.append('g').attr('class', 'point-group')\n .attr('data-line-number', String(point.lineNumber));\n\n // Circle with white fill and colored border for visibility on opaque quadrants\n pointG\n .append('circle')\n .attr('cx', cx)\n .attr('cy', cy)\n .attr('r', 6)\n .attr('fill', '#ffffff')\n .attr('stroke', pointColor)\n .attr('stroke-width', 2);\n\n // Label (contrasting color with shadow for readability)\n pointG\n .append('text')\n .attr('x', cx)\n .attr('y', cy - 10)\n .attr('text-anchor', 'middle')\n .attr('fill', contrastColor)\n .attr('font-size', '12px')\n .attr('font-weight', '700')\n .style('text-shadow', `0 1px 2px ${shadowColor}`)\n .text(point.label);\n\n // Interactivity\n const tipHtml = `<strong>${point.label}</strong><br>x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`;\n\n pointG\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) => {\n showTooltip(tooltip, tipHtml, event);\n pointG.select('circle').attr('r', 8);\n })\n .on('mousemove', (event: MouseEvent) => {\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mouseleave', () => {\n hideTooltip(tooltip);\n pointG.select('circle').attr('r', 6);\n })\n .on('click', () => {\n if (onClickItem && point.lineNumber) onClickItem(point.lineNumber);\n });\n });\n\n // Quadrant highlighting on hover and click-to-navigate\n quadrantRects\n .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', function (_, d) {\n // Dim other quadrants\n quadrantRects.attr('opacity', (qd) =>\n qd.position === d.position ? 1 : 0.3\n );\n quadrantLabelTexts.attr('opacity', (qd) =>\n qd.position === d.position ? 1 : 0.3\n );\n // Dim points not in this quadrant\n pointsG.selectAll('g.point-group').each(function (_, i) {\n const pt = quadrantPoints[i];\n const ptQuad = getPointQuadrant(pt.x, pt.y);\n d3Selection\n .select(this)\n .attr('opacity', ptQuad === d.position ? 1 : 0.2);\n });\n })\n .on('mouseleave', () => {\n quadrantRects.attr('opacity', 1);\n quadrantLabelTexts.attr('opacity', 1);\n pointsG.selectAll('g.point-group').attr('opacity', 1);\n })\n .on('click', (_, d) => {\n // Navigate to the quadrant label's line in the source\n if (onClickItem && d.label?.lineNumber) {\n onClickItem(d.label.lineNumber);\n }\n });\n}\n\n// ============================================================\n// Export Renderer\n// ============================================================\n\nconst EXPORT_WIDTH = 1200;\nconst EXPORT_HEIGHT = 800;\n\n/**\n * Renders a D3 chart to an SVG string for export.\n * Creates a detached DOM element, renders into it, extracts the SVG, then cleans up.\n */\nexport async function renderD3ForExport(\n content: string,\n theme: 'light' | 'dark' | 'transparent',\n palette?: PaletteColors,\n orgExportState?: {\n collapsedNodes?: Set<string>;\n activeTagGroup?: string | null;\n hiddenAttributes?: Set<string>;\n },\n options?: { branding?: boolean }\n): Promise<string> {\n // Flowchart and org chart use their own parser pipelines — intercept before parseD3()\n const { parseDgmoChartType } = await import('./dgmo-router');\n const detectedType = parseDgmoChartType(content);\n\n if (detectedType === 'org') {\n const { parseOrg } = await import('./org/parser');\n const { layoutOrg } = await import('./org/layout');\n const { collapseOrgTree } = await import('./org/collapse');\n const { renderOrg } = await import('./org/renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const orgParsed = parseOrg(content, effectivePalette);\n if (orgParsed.error || orgParsed.roots.length === 0) return '';\n\n // Apply interactive collapse state when provided\n const collapsedNodes = orgExportState?.collapsedNodes;\n const activeTagGroup = orgExportState?.activeTagGroup ?? null;\n const hiddenAttributes = orgExportState?.hiddenAttributes;\n\n const { parsed: effectiveParsed, hiddenCounts } =\n collapsedNodes && collapsedNodes.size > 0\n ? collapseOrgTree(orgParsed, collapsedNodes)\n : { parsed: orgParsed, hiddenCounts: new Map<string, number>() };\n\n const orgLayout = layoutOrg(\n effectiveParsed,\n hiddenCounts.size > 0 ? hiddenCounts : undefined,\n activeTagGroup,\n hiddenAttributes\n );\n\n // Size container to fit the diagram content\n const PADDING = 20;\n const titleOffset = effectiveParsed.title ? 30 : 0;\n const exportWidth = orgLayout.width + PADDING * 2;\n const exportHeight = orgLayout.height + PADDING * 2 + titleOffset;\n\n const container = document.createElement('div');\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderOrg(\n container,\n effectiveParsed,\n orgLayout,\n effectivePalette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight },\n activeTagGroup,\n hiddenAttributes\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n if (detectedType === 'class') {\n const { parseClassDiagram } = await import('./class/parser');\n const { layoutClassDiagram } = await import('./class/layout');\n const { renderClassDiagram } = await import('./class/renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const classParsed = parseClassDiagram(content, effectivePalette);\n if (classParsed.error || classParsed.classes.length === 0) return '';\n\n const classLayout = layoutClassDiagram(classParsed);\n const PADDING = 20;\n const titleOffset = classParsed.title ? 40 : 0;\n const exportWidth = classLayout.width + PADDING * 2;\n const exportHeight = classLayout.height + PADDING * 2 + titleOffset;\n\n const container = document.createElement('div');\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderClassDiagram(\n container,\n classParsed,\n classLayout,\n effectivePalette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n if (detectedType === 'er') {\n const { parseERDiagram } = await import('./er/parser');\n const { layoutERDiagram } = await import('./er/layout');\n const { renderERDiagram } = await import('./er/renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const erParsed = parseERDiagram(content, effectivePalette);\n if (erParsed.error || erParsed.tables.length === 0) return '';\n\n const erLayout = layoutERDiagram(erParsed);\n const PADDING = 20;\n const titleOffset = erParsed.title ? 40 : 0;\n const exportWidth = erLayout.width + PADDING * 2;\n const exportHeight = erLayout.height + PADDING * 2 + titleOffset;\n\n const container = document.createElement('div');\n container.style.width = `${exportWidth}px`;\n container.style.height = `${exportHeight}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderERDiagram(\n container,\n erParsed,\n erLayout,\n effectivePalette,\n isDark,\n undefined,\n { width: exportWidth, height: exportHeight }\n );\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n if (detectedType === 'flowchart') {\n const { parseFlowchart } = await import('./graph/flowchart-parser');\n const { layoutGraph } = await import('./graph/layout');\n const { renderFlowchart } = await import('./graph/flowchart-renderer');\n\n const isDark = theme === 'dark';\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n const fcParsed = parseFlowchart(content, effectivePalette);\n if (fcParsed.error || fcParsed.nodes.length === 0) return '';\n\n const layout = layoutGraph(fcParsed);\n const container = document.createElement('div');\n container.style.width = `${EXPORT_WIDTH}px`;\n container.style.height = `${EXPORT_HEIGHT}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n try {\n renderFlowchart(container, fcParsed, layout, effectivePalette, isDark, undefined, {\n width: EXPORT_WIDTH,\n height: EXPORT_HEIGHT,\n });\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n }\n\n const parsed = parseD3(content, palette);\n // Allow sequence diagrams through even if parseD3 errors —\n // sequence is parsed by its own dedicated parser (parseSequenceDgmo)\n // and may not have a \"chart:\" line (auto-detected from arrow syntax).\n if (parsed.error && parsed.type !== 'sequence') {\n // Check if content looks like a sequence diagram (has arrows but no chart: line)\n const looksLikeSequence = /->|~>|<-/.test(content);\n if (!looksLikeSequence) return '';\n parsed.type = 'sequence';\n }\n if (parsed.type === 'wordcloud' && parsed.words.length === 0) return '';\n if (parsed.type === 'slope' && parsed.data.length === 0) return '';\n if (parsed.type === 'arc' && parsed.links.length === 0) return '';\n if (parsed.type === 'timeline' && parsed.timelineEvents.length === 0)\n return '';\n if (parsed.type === 'venn' && parsed.vennSets.length < 2) return '';\n if (parsed.type === 'quadrant' && parsed.quadrantPoints.length === 0)\n return '';\n\n const isDark = theme === 'dark';\n\n // Fall back to Nord palette if none provided\n const { getPalette } = await import('./palettes');\n const effectivePalette =\n palette ?? (isDark ? getPalette('nord').dark : getPalette('nord').light);\n\n // Create a temporary offscreen container\n const container = document.createElement('div');\n container.style.width = `${EXPORT_WIDTH}px`;\n container.style.height = `${EXPORT_HEIGHT}px`;\n container.style.position = 'absolute';\n container.style.left = '-9999px';\n document.body.appendChild(container);\n\n const dims: D3ExportDimensions = { width: EXPORT_WIDTH, height: EXPORT_HEIGHT };\n\n try {\n if (parsed.type === 'sequence') {\n const { parseSequenceDgmo } = await import('./sequence/parser');\n const { renderSequenceDiagram } = await import('./sequence/renderer');\n const seqParsed = parseSequenceDgmo(content);\n if (seqParsed.error || seqParsed.participants.length === 0) return '';\n renderSequenceDiagram(container, seqParsed, effectivePalette, isDark, undefined, {\n exportWidth: EXPORT_WIDTH,\n });\n } else if (parsed.type === 'wordcloud') {\n await renderWordCloudAsync(container, parsed, effectivePalette, isDark, dims);\n } else if (parsed.type === 'arc') {\n renderArcDiagram(container, parsed, effectivePalette, isDark, undefined, dims);\n } else if (parsed.type === 'timeline') {\n renderTimeline(container, parsed, effectivePalette, isDark, undefined, dims);\n } else if (parsed.type === 'venn') {\n renderVenn(container, parsed, effectivePalette, isDark, undefined, dims);\n } else if (parsed.type === 'quadrant') {\n renderQuadrant(container, parsed, effectivePalette, isDark, undefined, dims);\n } else {\n renderSlopeChart(container, parsed, effectivePalette, isDark, undefined, dims);\n }\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n // Ensure all chart types have a consistent background\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n } else if (!svgEl.style.background) {\n svgEl.style.background = effectivePalette.bg;\n }\n\n // Add xmlns for standalone SVG\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n svgEl.style.fontFamily = FONT_FAMILY;\n\n const svgHtml = svgEl.outerHTML;\n if (options?.branding !== false) {\n const brandColor = theme === 'transparent' ? '#888' : effectivePalette.textMuted;\n return injectBranding(svgHtml, brandColor);\n }\n return svgHtml;\n } finally {\n document.body.removeChild(container);\n }\n}\n","// ============================================================\n// Diagnostics\n// ============================================================\n\nexport { makeDgmoError, formatDgmoError } from './diagnostics';\nexport type { DgmoError, DgmoSeverity } from './diagnostics';\n\n// ============================================================\n// Unified API\n// ============================================================\n\nexport { render } from './render';\n\n// ============================================================\n// Router\n// ============================================================\n\nexport {\n parseDgmoChartType,\n getDgmoFramework,\n parseDgmo,\n DGMO_CHART_TYPE_MAP,\n} from './dgmo-router';\nexport type { DgmoFramework } from './dgmo-router';\n\n// ============================================================\n// Parsers\n// ============================================================\n\nexport { parseChart } from './chart';\nexport type {\n ParsedChart,\n ChartType,\n ChartDataPoint,\n} from './chart';\n\nexport { parseEChart } from './echarts';\nexport type { ParsedEChart, EChartsChartType } from './echarts';\n\nexport {\n parseD3,\n orderArcNodes,\n parseTimelineDate,\n addDurationToDate,\n computeTimeTicks,\n formatDateLabel,\n} from './d3';\nexport type { ParsedD3, D3ChartType, D3ExportDimensions, ArcLink, ArcNodeGroup } from './d3';\n\nexport {\n parseSequenceDgmo,\n looksLikeSequence,\n isSequenceBlock,\n isSequenceNote,\n} from './sequence/parser';\nexport type {\n ParsedSequenceDgmo,\n SequenceParticipant,\n SequenceMessage,\n SequenceBlock,\n ElseIfBranch,\n SequenceSection,\n SequenceNote,\n SequenceElement,\n SequenceGroup,\n ParticipantType,\n} from './sequence/parser';\n\nexport {\n inferParticipantType,\n RULE_COUNT,\n} from './sequence/participant-inference';\n\nexport { parseQuadrant } from './dgmo-mermaid';\nexport type { ParsedQuadrant } from './dgmo-mermaid';\n\nexport { parseFlowchart, looksLikeFlowchart } from './graph/flowchart-parser';\n\nexport { parseClassDiagram, looksLikeClassDiagram } from './class/parser';\n\nexport type {\n ParsedClassDiagram,\n ClassNode,\n ClassMember,\n ClassRelationship,\n ClassModifier,\n MemberVisibility,\n RelationshipType,\n} from './class/types';\n\nexport { layoutClassDiagram } from './class/layout';\nexport type {\n ClassLayoutResult,\n ClassLayoutNode,\n ClassLayoutEdge,\n} from './class/layout';\n\nexport { renderClassDiagram, renderClassDiagramForExport } from './class/renderer';\n\nexport { parseERDiagram, looksLikeERDiagram } from './er/parser';\n\nexport type {\n ParsedERDiagram,\n ERTable,\n ERColumn,\n ERRelationship,\n ERConstraint,\n ERCardinality,\n} from './er/types';\n\nexport { layoutERDiagram } from './er/layout';\nexport type {\n ERLayoutResult,\n ERLayoutNode,\n ERLayoutEdge,\n} from './er/layout';\n\nexport { renderERDiagram, renderERDiagramForExport } from './er/renderer';\n\nexport type {\n ParsedGraph,\n GraphNode,\n GraphEdge,\n GraphGroup,\n GraphShape,\n GraphDirection,\n} from './graph/types';\n\nexport { parseOrg } from './org/parser';\nexport type {\n ParsedOrg,\n OrgNode,\n OrgTagGroup,\n OrgTagEntry,\n} from './org/parser';\n\nexport { layoutOrg } from './org/layout';\nexport type {\n OrgLayoutResult,\n OrgLayoutNode,\n OrgLayoutEdge,\n OrgContainerBounds,\n} from './org/layout';\n\nexport { renderOrg, renderOrgForExport } from './org/renderer';\n\nexport { collapseOrgTree } from './org/collapse';\nexport type { CollapsedOrgResult } from './org/collapse';\n\nexport { resolveOrgImports } from './org/resolver';\nexport type { ReadFileFn, ResolveImportsResult } from './org/resolver';\n\nexport { layoutGraph } from './graph/layout';\nexport type {\n LayoutResult,\n LayoutNode,\n LayoutEdge,\n LayoutGroup,\n} from './graph/layout';\n\nexport { renderFlowchart, renderFlowchartForExport } from './graph/flowchart-renderer';\n\n// ============================================================\n// Config Builders (produce framework-specific config objects)\n// ============================================================\n\nexport { buildEChartsOption, buildEChartsOptionFromChart, renderEChartsForExport } from './echarts';\nexport { buildMermaidQuadrant } from './dgmo-mermaid';\n\n// ============================================================\n// Renderers (produce SVG output)\n// ============================================================\n\nexport {\n renderSlopeChart,\n renderArcDiagram,\n renderTimeline,\n renderWordCloud,\n renderVenn,\n renderQuadrant,\n renderD3ForExport,\n} from './d3';\n\nexport {\n renderSequenceDiagram,\n buildRenderSequence,\n computeActivations,\n applyPositionOverrides,\n applyGroupOrdering,\n groupMessagesBySection,\n buildNoteMessageMap,\n} from './sequence/renderer';\nexport type {\n RenderStep,\n Activation,\n SectionMessageGroup,\n SequenceRenderOptions,\n} from './sequence/renderer';\n\n// ============================================================\n// Colors & Palettes\n// ============================================================\n\nexport { resolveColor, colorNames, nord, seriesColors } from './colors';\n\nexport {\n // Registry\n getPalette,\n getAvailablePalettes,\n registerPalette,\n isValidHex,\n // Utilities\n hexToHSL,\n hslToHex,\n hexToHSLString,\n mute,\n tint,\n shade,\n getSeriesColors,\n contrastText,\n // Palette definitions\n nordPalette,\n solarizedPalette,\n catppuccinPalette,\n rosePinePalette,\n gruvboxPalette,\n tokyoNightPalette,\n oneDarkPalette,\n boldPalette,\n // Mermaid bridge\n buildMermaidThemeVars,\n buildThemeCSS,\n} from './palettes';\n\nexport type { PaletteConfig, PaletteColors } from './palettes';\n\n// ============================================================\n// Sharing (URL encoding/decoding)\n// ============================================================\n\nexport { encodeDiagramUrl, decodeDiagramUrl } from './sharing';\nexport type {\n EncodeDiagramUrlOptions,\n EncodeDiagramUrlResult,\n DiagramViewState,\n DecodedDiagramUrl,\n} from './sharing';\n\n// ============================================================\n// Branding\n// ============================================================\n\nexport { injectBranding } from './branding';\n","import { renderD3ForExport } from './d3';\nimport { renderEChartsForExport } from './echarts';\nimport { parseDgmoChartType, getDgmoFramework } from './dgmo-router';\nimport { getPalette } from './palettes/registry';\n\n/**\n * Ensures DOM globals are available for D3 renderers.\n * No-ops in browser environments where `document` already exists.\n * Dynamically imports jsdom only in Node.js to avoid bundling it for browsers.\n */\nasync function ensureDom(): Promise<void> {\n if (typeof document !== 'undefined') return;\n\n const { JSDOM } = await import('jsdom');\n const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>');\n const win = dom.window;\n\n Object.defineProperty(globalThis, 'document', { value: win.document, configurable: true });\n Object.defineProperty(globalThis, 'window', { value: win, configurable: true });\n Object.defineProperty(globalThis, 'navigator', { value: win.navigator, configurable: true });\n Object.defineProperty(globalThis, 'HTMLElement', { value: win.HTMLElement, configurable: true });\n Object.defineProperty(globalThis, 'SVGElement', { value: win.SVGElement, configurable: true });\n}\n\n/**\n * Render DGMO source to an SVG string.\n *\n * Automatically detects the chart type, selects the appropriate renderer,\n * and returns a complete SVG document string.\n *\n * @param content - DGMO source text\n * @param options - Optional theme and palette settings\n * @returns SVG string, or empty string on error\n *\n * @example\n * ```ts\n * import { render } from '@diagrammo/dgmo';\n *\n * const svg = await render(`chart: pie\n * title: Languages\n * TypeScript: 45\n * Python: 30\n * Rust: 25`);\n * ```\n */\nexport async function render(\n content: string,\n options?: {\n theme?: 'light' | 'dark' | 'transparent';\n palette?: string;\n branding?: boolean;\n },\n): Promise<string> {\n const theme = options?.theme ?? 'light';\n const paletteName = options?.palette ?? 'nord';\n const branding = options?.branding ?? true;\n\n const paletteColors = getPalette(paletteName)[theme === 'dark' ? 'dark' : 'light'];\n\n const chartType = parseDgmoChartType(content);\n const framework = chartType ? getDgmoFramework(chartType) : null;\n\n if (framework === 'echart') {\n return renderEChartsForExport(content, theme, paletteColors, { branding });\n }\n\n // D3 and unknown/null frameworks both go through D3 renderer\n await ensureDom();\n return renderD3ForExport(content, theme, paletteColors, undefined, { branding });\n}\n","// ============================================================\n// .dgmo → Mermaid Translation Layer\n// Parses dgmo quadrant syntax and generates valid Mermaid code.\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { DgmoError } from './diagnostics';\nimport { makeDgmoError, formatDgmoError } from './diagnostics';\n\n// ============================================================\n// Types\n// ============================================================\n\ninterface QuadrantLabel {\n text: string;\n color: string | null;\n lineNumber: number;\n}\n\nexport interface ParsedQuadrant {\n title: string | null;\n titleLineNumber: number | null;\n xAxis: [string, string] | null;\n xAxisLineNumber: number | null;\n yAxis: [string, string] | null;\n yAxisLineNumber: number | null;\n quadrants: {\n topRight: QuadrantLabel | null;\n topLeft: QuadrantLabel | null;\n bottomLeft: QuadrantLabel | null;\n bottomRight: QuadrantLabel | null;\n };\n points: { label: string; x: number; y: number; lineNumber: number }[];\n diagnostics: DgmoError[];\n error: string | null;\n}\n\n// ============================================================\n// Parser\n// ============================================================\n\n/** Regex for quadrant label lines: `top-right: Promote (green)` */\nconst QUADRANT_LABEL_RE = /^(.+?)(?:\\s*\\(([^)]+)\\))?\\s*$/;\n\n/** Regex for data point lines: `Label: 0.9, 0.5` */\nconst DATA_POINT_RE = /^(.+?):\\s*([0-9]*\\.?[0-9]+)\\s*,\\s*([0-9]*\\.?[0-9]+)\\s*$/;\n\nconst QUADRANT_POSITIONS = new Set([\n 'top-right',\n 'top-left',\n 'bottom-left',\n 'bottom-right',\n]);\n\n/**\n * Parses a .dgmo quadrant document into a structured object.\n * Lines are processed sequentially; unknown lines are silently skipped.\n */\nexport function parseQuadrant(content: string): ParsedQuadrant {\n const result: ParsedQuadrant = {\n title: null,\n titleLineNumber: null,\n xAxis: null,\n xAxisLineNumber: null,\n yAxis: null,\n yAxisLineNumber: null,\n quadrants: {\n topRight: null,\n topLeft: null,\n bottomLeft: null,\n bottomRight: null,\n },\n points: [],\n diagnostics: [],\n error: null,\n };\n\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n const lineNumber = i + 1; // 1-indexed for editor\n\n // Skip empty lines and comments\n if (!line || line.startsWith('#') || line.startsWith('//')) continue;\n\n // Skip the chart: directive (already consumed by router)\n if (/^chart\\s*:/i.test(line)) continue;\n\n // title: <text>\n const titleMatch = line.match(/^title\\s*:\\s*(.+)/i);\n if (titleMatch) {\n result.title = titleMatch[1].trim();\n result.titleLineNumber = lineNumber;\n continue;\n }\n\n // x-axis: Low, High\n const xMatch = line.match(/^x-axis\\s*:\\s*(.+)/i);\n if (xMatch) {\n const parts = xMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.xAxis = [parts[0], parts[1]];\n result.xAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // y-axis: Low, High\n const yMatch = line.match(/^y-axis\\s*:\\s*(.+)/i);\n if (yMatch) {\n const parts = yMatch[1].split(',').map((s) => s.trim());\n if (parts.length >= 2) {\n result.yAxis = [parts[0], parts[1]];\n result.yAxisLineNumber = lineNumber;\n }\n continue;\n }\n\n // Quadrant position labels: top-right: Label (color)\n const posMatch = line.match(\n /^(top-right|top-left|bottom-left|bottom-right)\\s*:\\s*(.+)/i\n );\n if (posMatch) {\n const position = posMatch[1].toLowerCase();\n const labelMatch = posMatch[2].match(QUADRANT_LABEL_RE);\n if (labelMatch) {\n const label: QuadrantLabel = {\n text: labelMatch[1].trim(),\n color: labelMatch[2] ? resolveColor(labelMatch[2].trim()) : null,\n lineNumber,\n };\n if (position === 'top-right') result.quadrants.topRight = label;\n else if (position === 'top-left') result.quadrants.topLeft = label;\n else if (position === 'bottom-left')\n result.quadrants.bottomLeft = label;\n else if (position === 'bottom-right')\n result.quadrants.bottomRight = label;\n }\n continue;\n }\n\n // Data points: Label: x, y\n const pointMatch = line.match(DATA_POINT_RE);\n if (pointMatch) {\n // Make sure this isn't a quadrant position keyword\n const key = pointMatch[1].trim().toLowerCase();\n if (!QUADRANT_POSITIONS.has(key)) {\n result.points.push({\n label: pointMatch[1].trim(),\n x: parseFloat(pointMatch[2]),\n y: parseFloat(pointMatch[3]),\n lineNumber,\n });\n }\n continue;\n }\n }\n\n if (result.points.length === 0) {\n const diag = makeDgmoError(1, 'No data points found. Add lines like: Label: 0.5, 0.7');\n result.diagnostics.push(diag);\n result.error = formatDgmoError(diag);\n }\n\n return result;\n}\n\n// ============================================================\n// Mermaid Builder\n// ============================================================\n\n/**\n * Generates valid Mermaid quadrantChart syntax from a parsed quadrant.\n * Returns a string ready for the Mermaid renderer.\n */\nexport function buildMermaidQuadrant(\n parsed: ParsedQuadrant,\n options: {\n isDark?: boolean;\n textColor?: string;\n mutedTextColor?: string;\n } = {}\n): string {\n const { isDark = false, textColor, mutedTextColor } = options;\n const lines: string[] = [];\n\n // %%{init}%% block — fill colors with reduced opacity + text color overrides\n const fillAlpha = isDark ? '30' : '55';\n const primaryText = textColor ?? (isDark ? '#d0d0d0' : '#333333');\n const quadrantLabelText = mutedTextColor ?? (isDark ? '#888888' : '#666666');\n\n const colorMap: Record<string, string> = {};\n if (parsed.quadrants.topRight?.color)\n colorMap.quadrant1Fill = parsed.quadrants.topRight.color + fillAlpha;\n if (parsed.quadrants.topLeft?.color)\n colorMap.quadrant2Fill = parsed.quadrants.topLeft.color + fillAlpha;\n if (parsed.quadrants.bottomLeft?.color)\n colorMap.quadrant3Fill = parsed.quadrants.bottomLeft.color + fillAlpha;\n if (parsed.quadrants.bottomRight?.color)\n colorMap.quadrant4Fill = parsed.quadrants.bottomRight.color + fillAlpha;\n\n // Quadrant labels use muted color, points use primary text color\n colorMap.quadrant1TextFill = quadrantLabelText;\n colorMap.quadrant2TextFill = quadrantLabelText;\n colorMap.quadrant3TextFill = quadrantLabelText;\n colorMap.quadrant4TextFill = quadrantLabelText;\n colorMap.quadrantPointTextFill = primaryText;\n colorMap.quadrantXAxisTextFill = primaryText;\n colorMap.quadrantYAxisTextFill = primaryText;\n colorMap.quadrantTitleFill = primaryText;\n\n const vars = JSON.stringify(colorMap);\n lines.push(`%%{init: {\"themeVariables\": ${vars}}}%%`);\n\n lines.push('quadrantChart');\n\n if (parsed.title) {\n lines.push(` title ${parsed.title}`);\n }\n\n if (parsed.xAxis) {\n lines.push(` x-axis ${parsed.xAxis[0]} --> ${parsed.xAxis[1]}`);\n }\n\n if (parsed.yAxis) {\n lines.push(` y-axis ${parsed.yAxis[0]} --> ${parsed.yAxis[1]}`);\n }\n\n // Helper to quote labels that need it (contain spaces or special chars)\n const quote = (s: string): string => (/[\\s,:[\\]]/.test(s) ? `\"${s}\"` : s);\n\n // Quadrant labels: 1=top-right, 2=top-left, 3=bottom-left, 4=bottom-right\n if (parsed.quadrants.topRight) {\n lines.push(` quadrant-1 ${quote(parsed.quadrants.topRight.text)}`);\n }\n if (parsed.quadrants.topLeft) {\n lines.push(` quadrant-2 ${quote(parsed.quadrants.topLeft.text)}`);\n }\n if (parsed.quadrants.bottomLeft) {\n lines.push(` quadrant-3 ${quote(parsed.quadrants.bottomLeft.text)}`);\n }\n if (parsed.quadrants.bottomRight) {\n lines.push(` quadrant-4 ${quote(parsed.quadrants.bottomRight.text)}`);\n }\n\n // Data points\n for (const point of parsed.points) {\n lines.push(` ${quote(point.label)}: [${point.x}, ${point.y}]`);\n }\n\n return lines.join('\\n');\n}\n","import type { DgmoError } from '../diagnostics';\nimport { makeDgmoError } from '../diagnostics';\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Async or sync file reader. Receives an absolute path, returns content.\n * Throwing means \"file not found\".\n */\nexport type ReadFileFn = (path: string) => string | Promise<string>;\n\nexport interface ResolveImportsResult {\n content: string;\n diagnostics: DgmoError[];\n}\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst MAX_DEPTH = 10;\nconst IMPORT_RE = /^(\\s+)import:\\s+(.+\\.dgmo)\\s*$/i;\nconst TAGS_RE = /^tags:\\s+(.+\\.dgmo)\\s*$/i;\nconst HEADER_RE = /^(chart|title)\\s*:/i;\nconst OPTION_RE = /^[a-z][a-z0-9-]*\\s*:/i;\nconst GROUP_HEADING_RE = /^##\\s+/;\n\n// ============================================================\n// Path Helpers (pure string ops — no Node `path` dependency)\n// ============================================================\n\nfunction dirname(filePath: string): string {\n const last = filePath.lastIndexOf('/');\n return last > 0 ? filePath.substring(0, last) : '/';\n}\n\nfunction resolvePath(base: string, relative: string): string {\n const parts = dirname(base).split('/');\n for (const seg of relative.split('/')) {\n if (seg === '..') {\n if (parts.length > 1) parts.pop();\n } else if (seg !== '.' && seg !== '') {\n parts.push(seg);\n }\n }\n return parts.join('/') || '/';\n}\n\n// ============================================================\n// Tag Group Extraction\n// ============================================================\n\ninterface TagGroupBlock {\n name: string; // lowercased for comparison\n lines: string[]; // raw lines including heading + entries\n}\n\n/**\n * Extract ## tag group blocks from content lines.\n * Returns blocks in order, each with its heading + indented entries.\n */\nfunction extractTagGroups(lines: string[]): TagGroupBlock[] {\n const blocks: TagGroupBlock[] = [];\n let current: TagGroupBlock | null = null;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (GROUP_HEADING_RE.test(trimmed)) {\n // Extract group name (everything after \"## \" up to optional alias/color)\n const nameMatch = trimmed.match(/^##\\s+(.+?)(?:\\s+alias\\s+\\w+)?(?:\\s*\\([^)]+\\))?\\s*$/);\n const name = nameMatch ? nameMatch[1].trim().toLowerCase() : trimmed.substring(3).trim().toLowerCase();\n current = { name, lines: [line] };\n blocks.push(current);\n } else if (current) {\n if (trimmed === '' || trimmed.startsWith('//')) {\n // Blank line or comment ends the tag group\n current = null;\n } else if (line.match(/^\\s+/)) {\n // Indented = tag entry\n current.lines.push(line);\n } else {\n // Non-indented non-heading = end of tag group\n current = null;\n }\n }\n }\n\n return blocks;\n}\n\n// ============================================================\n// Header Stripping\n// ============================================================\n\ninterface ParsedHeader {\n /** Lines that are NOT header/tags/tag-groups — the \"content\" body */\n contentLines: string[];\n tagGroups: TagGroupBlock[];\n tagsDirective: string | null;\n}\n\n/**\n * Separate an imported file into header (stripped) and content body.\n * Also extracts tag groups and tags: directive for merging.\n */\nfunction parseFileHeader(lines: string[]): ParsedHeader {\n const tagGroups = extractTagGroups(lines);\n const tagGroupLineSet = new Set<number>();\n for (const group of tagGroups) {\n // Find where this group starts in lines\n for (let i = 0; i < lines.length; i++) {\n if (lines[i] === group.lines[0]) {\n for (let j = 0; j < group.lines.length; j++) {\n tagGroupLineSet.add(i + j);\n }\n break;\n }\n }\n }\n\n let tagsDirective: string | null = null;\n const contentLines: string[] = [];\n let headerDone = false;\n\n for (let i = 0; i < lines.length; i++) {\n // Skip tag group lines\n if (tagGroupLineSet.has(i)) continue;\n\n const trimmed = lines[i].trim();\n\n // Skip blank/comment lines in header region\n if (!headerDone && (trimmed === '' || trimmed.startsWith('//'))) continue;\n\n // Header lines\n if (!headerDone) {\n if (HEADER_RE.test(trimmed)) continue;\n\n const tagsMatch = trimmed.match(TAGS_RE);\n if (tagsMatch) {\n tagsDirective = tagsMatch[1].trim();\n continue;\n }\n\n // Other option-like header lines (non-indented key: value)\n if (OPTION_RE.test(trimmed) && !trimmed.startsWith('##') && !lines[i].match(/^\\s/)) {\n // Check it's not a content line (node with metadata)\n const key = trimmed.split(':')[0].trim().toLowerCase();\n if (key !== 'chart' && key !== 'title' && !trimmed.includes('|')) {\n continue;\n }\n }\n\n headerDone = true;\n }\n\n contentLines.push(lines[i]);\n }\n\n return { contentLines, tagGroups, tagsDirective };\n}\n\n// ============================================================\n// Main Resolver\n// ============================================================\n\n/**\n * Pre-processes org chart content, resolving `tags:` and `import:` directives.\n *\n * @param content - Raw .dgmo file content\n * @param filePath - Absolute path of the file (for relative path resolution)\n * @param readFileFn - Function to read files (sync or async)\n * @returns Merged content with all imports resolved + diagnostics\n */\nexport async function resolveOrgImports(\n content: string,\n filePath: string,\n readFileFn: ReadFileFn,\n): Promise<ResolveImportsResult> {\n const diagnostics: DgmoError[] = [];\n const result = await resolveFile(content, filePath, readFileFn, diagnostics, new Set([filePath]), 0);\n return { content: result, diagnostics };\n}\n\nasync function resolveFile(\n content: string,\n filePath: string,\n readFileFn: ReadFileFn,\n diagnostics: DgmoError[],\n ancestorChain: Set<string>,\n depth: number,\n): Promise<string> {\n const lines = content.split('\\n');\n\n // ---- Step 1: Identify header, tags directive, inline tag groups ----\n const headerLines: string[] = [];\n let tagsDirective: string | null = null;\n const inlineTagGroups = extractTagGroups(lines);\n const bodyStartIndex = findBodyStart(lines);\n\n // Collect header lines (chart:, title:, options, tags:)\n for (let i = 0; i < bodyStartIndex; i++) {\n const trimmed = lines[i].trim();\n if (trimmed === '' || trimmed.startsWith('//')) {\n headerLines.push(lines[i]);\n continue;\n }\n if (GROUP_HEADING_RE.test(trimmed)) continue; // skip inline tag group headings\n if (lines[i] !== trimmed) continue; // skip tag group entries (indented lines)\n\n const tagsMatch = trimmed.match(TAGS_RE);\n if (tagsMatch) {\n tagsDirective = tagsMatch[1].trim();\n continue;\n }\n\n headerLines.push(lines[i]);\n }\n\n // ---- Step 2: Resolve tags: directive ----\n let tagsFileGroups: TagGroupBlock[] = [];\n if (tagsDirective) {\n const tagsPath = resolvePath(filePath, tagsDirective);\n try {\n const tagsContent = await readFileFn(tagsPath);\n const tagsLines = tagsContent.split('\\n');\n tagsFileGroups = extractTagGroups(tagsLines);\n } catch {\n diagnostics.push(\n makeDgmoError(0, `Tags file not found: ${tagsDirective}`)\n );\n }\n }\n\n // ---- Step 3: Resolve import: directives in body ----\n const bodyLines = lines.slice(bodyStartIndex);\n const resolvedBodyLines: string[] = [];\n const importedTagGroups: TagGroupBlock[] = [];\n\n for (let i = 0; i < bodyLines.length; i++) {\n const line = bodyLines[i];\n const lineNumber = bodyStartIndex + i + 1; // 1-based for diagnostics\n const importMatch = line.match(IMPORT_RE);\n\n if (!importMatch) {\n // Pass through — skip inline tag group lines (already extracted above)\n const trimmed = line.trim();\n if (GROUP_HEADING_RE.test(trimmed) || (inlineTagGroups.length > 0 && isTagGroupEntry(line, bodyLines, i))) {\n continue;\n }\n resolvedBodyLines.push(line);\n continue;\n }\n\n const indent = importMatch[1];\n const importRelPath = importMatch[2].trim();\n const importAbsPath = resolvePath(filePath, importRelPath);\n\n // Depth check\n if (depth >= MAX_DEPTH) {\n diagnostics.push(\n makeDgmoError(lineNumber, `Import depth limit exceeded (${MAX_DEPTH}): ${importRelPath}`)\n );\n continue;\n }\n\n // Circular check\n if (ancestorChain.has(importAbsPath)) {\n const chain = [...ancestorChain, importAbsPath].map(p => p.split('/').pop()).join(' -> ');\n diagnostics.push(\n makeDgmoError(lineNumber, `Circular import detected: ${chain}`)\n );\n continue;\n }\n\n // Read imported file\n let importedContent: string;\n try {\n importedContent = await readFileFn(importAbsPath);\n } catch {\n diagnostics.push(\n makeDgmoError(lineNumber, `Import file not found: ${importRelPath}`)\n );\n continue;\n }\n\n // Recurse to resolve nested imports\n const nestedChain = new Set(ancestorChain);\n nestedChain.add(importAbsPath);\n const resolved = await resolveFile(\n importedContent,\n importAbsPath,\n readFileFn,\n diagnostics,\n nestedChain,\n depth + 1,\n );\n\n // Strip header, extract tag groups from resolved content\n const resolvedLines = resolved.split('\\n');\n const parsed = parseFileHeader(resolvedLines);\n\n // Collect tag groups from imported file (lowest priority)\n for (const group of parsed.tagGroups) {\n importedTagGroups.push(group);\n }\n\n // Re-indent and insert content lines\n const importedContentLines = parsed.contentLines.filter(\n (l) => l.trim() !== '' // skip trailing blank lines\n );\n\n // Trim trailing empty lines but keep internal structure\n let lastNonEmpty = importedContentLines.length - 1;\n while (lastNonEmpty >= 0 && importedContentLines[lastNonEmpty].trim() === '') {\n lastNonEmpty--;\n }\n const trimmedImported = importedContentLines.slice(0, lastNonEmpty + 1);\n\n for (const importedLine of trimmedImported) {\n if (importedLine.trim() === '') {\n resolvedBodyLines.push('');\n } else {\n resolvedBodyLines.push(indent + importedLine);\n }\n }\n }\n\n // ---- Step 4: Merge tag groups with precedence ----\n // Priority: inline > tags file > imported files\n const mergedGroups = mergeTagGroups(inlineTagGroups, tagsFileGroups, importedTagGroups);\n\n // ---- Step 5: Rebuild output ----\n const outputLines: string[] = [];\n\n // Header lines (chart:, title:, options — no tags: or tag groups)\n for (const line of headerLines) {\n outputLines.push(line);\n }\n\n // Merged tag groups\n if (mergedGroups.length > 0) {\n // Ensure blank line before tag groups if header has content\n if (outputLines.length > 0 && outputLines[outputLines.length - 1].trim() !== '') {\n outputLines.push('');\n }\n for (const group of mergedGroups) {\n for (const line of group.lines) {\n outputLines.push(line);\n }\n outputLines.push(''); // blank line between groups\n }\n }\n\n // Body content\n // Ensure blank line separator\n if (resolvedBodyLines.length > 0 && outputLines.length > 0 && outputLines[outputLines.length - 1].trim() !== '') {\n outputLines.push('');\n }\n for (const line of resolvedBodyLines) {\n outputLines.push(line);\n }\n\n return outputLines.join('\\n');\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\n/**\n * Find the index where the body (non-header, non-tag-group content) starts.\n */\nfunction findBodyStart(lines: string[]): number {\n let inTagGroup = false;\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n if (trimmed === '' || trimmed.startsWith('//')) {\n if (inTagGroup) inTagGroup = false;\n continue;\n }\n\n // Tag group heading\n if (GROUP_HEADING_RE.test(trimmed)) {\n inTagGroup = true;\n continue;\n }\n\n // Tag group entry (indented under heading)\n if (inTagGroup && lines[i].match(/^\\s+/)) {\n continue;\n }\n\n if (inTagGroup) {\n inTagGroup = false;\n }\n\n // Header directives\n if (HEADER_RE.test(trimmed)) continue;\n if (TAGS_RE.test(trimmed)) continue;\n\n // Option-like lines (non-indented key: value before content)\n if (OPTION_RE.test(trimmed) && !lines[i].match(/^\\s/) && !trimmed.includes('|')) {\n const key = trimmed.split(':')[0].trim().toLowerCase();\n if (key !== 'chart' && key !== 'title') {\n continue;\n }\n }\n\n // This is the first body line\n return i;\n }\n\n return lines.length;\n}\n\n/**\n * Check if a line is a tag group entry (indented line under a ## heading).\n */\nfunction isTagGroupEntry(line: string, allLines: string[], index: number): boolean {\n if (!line.match(/^\\s+/)) return false;\n // Walk backwards to find the nearest non-blank, non-comment, non-entry line\n for (let i = index - 1; i >= 0; i--) {\n const prev = allLines[i].trim();\n if (prev === '' || prev.startsWith('//')) continue;\n if (GROUP_HEADING_RE.test(prev)) return true;\n if (allLines[i].match(/^\\s+/)) continue; // another entry\n return false;\n }\n return false;\n}\n\n/**\n * Merge tag groups from three sources with priority:\n * inline (highest) > tags file > imported files (lowest).\n *\n * On name conflict (case-insensitive), higher priority wins.\n * New groups from lower priority are added.\n */\nfunction mergeTagGroups(\n inline: TagGroupBlock[],\n tagsFile: TagGroupBlock[],\n imported: TagGroupBlock[],\n): TagGroupBlock[] {\n const seen = new Map<string, TagGroupBlock>();\n\n // Inline first (highest priority)\n for (const group of inline) {\n seen.set(group.name, group);\n }\n\n // Tags file (medium priority — only add if not overridden)\n for (const group of tagsFile) {\n if (!seen.has(group.name)) {\n seen.set(group.name, group);\n }\n }\n\n // Imported files (lowest priority — only add if not present)\n for (const group of imported) {\n if (!seen.has(group.name)) {\n seen.set(group.name, group);\n }\n }\n\n return Array.from(seen.values());\n}\n","import {\n compressToEncodedURIComponent,\n decompressFromEncodedURIComponent,\n} from 'lz-string';\n\nconst DEFAULT_BASE_URL = 'https://diagrammo.app/view';\nconst COMPRESSED_SIZE_LIMIT = 8192; // 8 KB\n\nexport interface DiagramViewState {\n activeTagGroup?: string;\n}\n\nexport interface DecodedDiagramUrl {\n dsl: string;\n viewState: DiagramViewState;\n}\n\nexport interface EncodeDiagramUrlOptions {\n baseUrl?: string;\n viewState?: DiagramViewState;\n}\n\nexport type EncodeDiagramUrlResult =\n | { url: string; error?: undefined }\n | { url?: undefined; error: 'too-large'; compressedSize: number; limit: number };\n\n/**\n * Compress a DGMO DSL string into a shareable URL.\n * Returns `{ url }` on success, or `{ error: 'too-large', compressedSize, limit }` if the\n * compressed payload exceeds the 8 KB limit.\n */\nexport function encodeDiagramUrl(\n dsl: string,\n options?: EncodeDiagramUrlOptions,\n): EncodeDiagramUrlResult {\n const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;\n const compressed = compressToEncodedURIComponent(dsl);\n const byteSize = new TextEncoder().encode(compressed).byteLength;\n\n if (byteSize > COMPRESSED_SIZE_LIMIT) {\n return { error: 'too-large', compressedSize: byteSize, limit: COMPRESSED_SIZE_LIMIT };\n }\n\n let hash = `dgmo=${compressed}`;\n\n if (options?.viewState?.activeTagGroup) {\n hash += `&tag=${encodeURIComponent(options.viewState.activeTagGroup)}`;\n }\n\n return { url: `${baseUrl}#${hash}` };\n}\n\n/**\n * Decode a DGMO DSL string and view state from a URL hash.\n * Accepts any of:\n * - `#dgmo=<payload>&tag=<name>`\n * - `dgmo=<payload>`\n * - `<bare payload>`\n *\n * Returns `{ dsl, viewState }`. The DSL is empty string on invalid input.\n */\nexport function decodeDiagramUrl(hash: string): DecodedDiagramUrl {\n const empty: DecodedDiagramUrl = { dsl: '', viewState: {} };\n if (!hash) return empty;\n\n let raw = hash;\n\n // Strip leading '#'\n if (raw.startsWith('#')) {\n raw = raw.slice(1);\n }\n\n // Split on '&' to separate dgmo payload from extra params.\n // lz-string's compressToEncodedURIComponent alphabet (A-Za-z0-9+-$) never\n // produces '&', so this split is safe.\n const parts = raw.split('&');\n let payload = parts[0];\n\n // Parse extra params (e.g. tag=Location)\n const viewState: DiagramViewState = {};\n for (let i = 1; i < parts.length; i++) {\n const eq = parts[i].indexOf('=');\n if (eq === -1) continue;\n const key = parts[i].slice(0, eq);\n const val = decodeURIComponent(parts[i].slice(eq + 1));\n if (key === 'tag' && val) {\n viewState.activeTagGroup = val;\n }\n }\n\n // Strip 'dgmo=' prefix\n if (payload.startsWith('dgmo=')) {\n payload = payload.slice(5);\n }\n\n if (!payload) return { dsl: '', viewState };\n\n try {\n const result = decompressFromEncodedURIComponent(payload);\n return { dsl: result ?? '', viewState };\n } catch {\n return { dsl: '', viewState };\n }\n}\n"],"mappings":"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AEA;AAEA;AA1IA,IAAM,wBAA0C;AAAA,MAC9C,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AA02BA,IAAM,aAAa,oBAAI,IAAI;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAA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","names":["line","p","q","line","measureIndent","line","parser_exports","measureIndent","line","init_parser","parser_exports","measureIndent","line","REL_KEYWORD_RE","init_parser","line","line","getPalette","parser_exports","measureIndent","line","extractColor","COLOR_SUFFIX_RE","GROUP_HEADING_RE","indent","init_parser","line","parsed","STANDARD_CHART_TYPES","init_parser","h","countDescendants","fill","stroke","CONTAINER_META_LINE_HEIGHT","HEADER_HEIGHT","SEPARATOR_GAP","META_LINE_HEIGHT","LEGEND_PAD","LEGEND_HEADER_H","EYE_ICON_GAP","LEGEND_DOT_R","LEGEND_DOT_TEXT_GAP","LEGEND_MAX_PER_ROW","LEGEND_ENTRY_GAP","LEGEND_ENTRY_H","init_parser","layout_exports","CHAR_WIDTH","dagre","init_layout","renderer_exports","mix","nodeFill","nodeStroke","DIAGRAM_PADDING","MAX_SCALE","EDGE_STROKE_WIDTH","fill","stroke","NODE_STROKE_WIDTH","COMPARTMENT_PADDING_Y","MEMBER_LINE_HEIGHT","d3Selection","init_renderer","init_parser","init_layout","layout_exports","computeNodeDimensions","MIN_WIDTH","CHAR_WIDTH","PADDING_X","HEADER_BASE","COMPARTMENT_PADDING_Y","MEMBER_LINE_HEIGHT","SEPARATOR_HEIGHT","dagre","import_dagre","init_layout","renderer_exports","mix","EDGE_STROKE_WIDTH","EDGE_LABEL_FONT_SIZE","DIAGRAM_PADDING","MAX_SCALE","seriesColors","lineGenerator","fill","stroke","NODE_STROKE_WIDTH","COMPARTMENT_PADDING_Y","MEMBER_PADDING_X","MEMBER_LINE_HEIGHT","d3Selection","d3Shape","init_renderer","init_parser","init_layout","layout_exports","dagre","import_dagre","init_layout","mix","nodeFill","nodeStroke","NODE_STROKE_WIDTH","DIAGRAM_PADDING","MAX_SCALE","lineGenerator","EDGE_STROKE_WIDTH","EDGE_LABEL_FONT_SIZE","d3Selection","d3Shape","init_layout","renderer_exports","line","mix","TITLE_HEIGHT","d3Selection","init_renderer","line","text","fill","cloud","qw","qh","_","parseDgmoChartType","parseOrg","layoutOrg","collapseOrgTree","renderOrg","isDark","getPalette","effectivePalette","container","parseClassDiagram","layoutClassDiagram","renderClassDiagram","parseERDiagram","layoutERDiagram","renderERDiagram","parseFlowchart","layoutGraph","renderFlowchart","looksLikeSequence","parseSequenceDgmo","renderSequenceDiagram","d3Selection","d3Shape","line","init_parser","init_layout","init_renderer","OPTION_RE","GROUP_HEADING_RE","line","init_layout","init_renderer"]}