@diagrammo/dgmo 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sequence/participant-inference.ts","../src/sequence/parser.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/renderer.ts","../src/index.ts","../src/dgmo-router.ts","../src/chartjs.ts","../src/echarts.ts","../src/d3.ts","../src/dgmo-mermaid.ts"],"sourcesContent":["// ============================================================\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 * 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 // ── 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\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\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\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\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\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 // 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\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\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];\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 SequenceBlock {\n kind: 'block';\n type: 'if' | 'loop' | 'parallel';\n label: string;\n children: SequenceElement[];\n elseChildren: SequenceElement[];\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\nexport type SequenceElement = SequenceMessage | SequenceBlock | SequenceSection;\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\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 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\" or \"## Backend(blue)\"\nconst GROUP_HEADING_PATTERN = /^##\\s+(\\S+?)(?:\\((\\w+)\\))?$/;\n\n// Section divider pattern — \"== Label ==\" or \"== Label(color) ==\"\nconst SECTION_PATTERN = /^==\\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/**\n * Extract return label from a message label string.\n * Priority: `<-` syntax first, then UML `method(): return` syntax.\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 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 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\n // Group parsing state — tracks the active ## group heading\n let activeGroup: SequenceGroup | null = null;\n\n // Block parsing state\n const blockStack: {\n block: SequenceBlock;\n indent: number;\n inElse: boolean;\n }[] = [];\n const currentContainer = (): SequenceElement[] => {\n if (blockStack.length === 0) return result.elements;\n const top = blockStack[blockStack.length - 1];\n return top.inElse ? top.block.elseChildren : top.block.children;\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\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 activeGroup = {\n name: groupMatch[1],\n color: groupMatch[2] || 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\n if (trimmed.startsWith('#') || trimmed.startsWith('//')) continue;\n\n // Parse section dividers — \"== Label ==\" or \"== Label(color) ==\"\n const sectionMatch = trimmed.match(SECTION_PATTERN);\n if (sectionMatch) {\n const labelRaw = sectionMatch[1].trim();\n const colorMatch = labelRaw.match(/^(.+?)\\((\\w+)\\)$/);\n const section: SequenceSection = {\n kind: 'section',\n label: colorMatch ? colorMatch[1].trim() : labelRaw,\n color: colorMatch ? colorMatch[2] : 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 const colonIndex = trimmed.indexOf(':');\n if (colonIndex > 0 && !trimmed.includes('->') && !trimmed.includes('~>')) {\n const key = trimmed.substring(0, colonIndex).trim().toLowerCase();\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 if (key === 'title') {\n result.title = value;\n continue;\n }\n\n // Store other options\n result.options[key] = value;\n continue;\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 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 activeGroup.participantIds.push(id);\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 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 activeGroup.participantIds.push(id);\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 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 activeGroup.participantIds.push(id);\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 if (\n indent === top.indent &&\n trimmed.toLowerCase() === 'else' &&\n top.block.type === 'if'\n )\n break;\n blockStack.pop();\n }\n\n // Parse message lines first — arrows take priority over keywords\n // Detect async prefix: \"async A -> B: msg\"\n let isAsync = false;\n let arrowLine = trimmed;\n const asyncPrefixMatch = trimmed.match(/^async\\s+(.+)$/i);\n if (asyncPrefixMatch) {\n isAsync = true;\n arrowLine = asyncPrefixMatch[1];\n }\n\n // Match ~> (async arrow) or -> (sync arrow)\n const asyncArrowMatch = arrowLine.match(\n /^(\\S+)\\s*~>\\s*([^\\s:]+)\\s*(?::\\s*(.+))?$/\n );\n const syncArrowMatch = arrowLine.match(\n /^(\\S+)\\s*->\\s*([^\\s:]+)\\s*(?::\\s*(.+))?$/\n );\n const arrowMatch = asyncArrowMatch || syncArrowMatch;\n if (asyncArrowMatch) isAsync = true;\n\n if (arrowMatch) {\n const from = arrowMatch[1];\n const to = arrowMatch[2];\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 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 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 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' keyword (only applies to 'if' blocks)\n if (trimmed.toLowerCase() === 'else') {\n if (\n blockStack.length > 0 &&\n blockStack[blockStack.length - 1].indent === indent &&\n blockStack[blockStack.length - 1].block.type === 'if'\n ) {\n blockStack[blockStack.length - 1].inElse = true;\n }\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('#') || trimmed.startsWith('//')) return false;\n return ARROW_PATTERN.test(trimmed);\n });\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","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: '#000000',\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 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// Sequence Diagram SVG Renderer\n// ============================================================\n\nimport * as d3Selection from 'd3-selection';\nimport type { PaletteColors } from '../palettes';\nimport { resolveColor } from '../colors';\nimport type {\n ParsedSequenceDgmo,\n SequenceElement,\n SequenceGroup,\n SequenceMessage,\n SequenceParticipant,\n} from './parser';\nimport { isSequenceBlock, isSequenceSection } 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// Shared fill/stroke helpers\nconst fill = (palette: PaletteColors, isDark: boolean): string =>\n `color-mix(in srgb, ${palette.primary} ${isDark ? '15%' : '30%'}, ${isDark ? palette.surface : palette.bg})`;\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// 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): void {\n // Clear previous content\n d3Selection.select(container).selectAll('*').remove();\n\n const { title, messages, elements, groups, options } = parsed;\n const participants = applyPositionOverrides(\n applyGroupOrdering(parsed.participants, groups)\n );\n if (participants.length === 0) return;\n\n const activationsOff = options.activations?.toLowerCase() === 'off';\n\n // Build render sequence with stack-based return placement\n const renderSteps = buildRenderSequence(messages);\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\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 // Find the first 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 } else if (!isSequenceSection(el)) {\n const idx = messages.indexOf(el);\n if (idx >= 0) return idx;\n }\n }\n return -1;\n };\n\n // Compute extra Y offset needed before each message\n const SECTION_SPACING = 40;\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 // Track sections mapped to the message index they precede\n const sectionBeforeMsg = new Map<\n number,\n import('./parser').SequenceSection[]\n >();\n\n const markElementSpacing = (els: SequenceElement[]): void => {\n for (let i = 0; i < els.length; i++) {\n const el = els[i];\n\n // Handle sections — add spacing before the next message\n if (isSequenceSection(el)) {\n // Find the next message after this section\n const nextMsgIdx =\n i + 1 < els.length ? findFirstMsgIndex(els.slice(i + 1)) : -1;\n if (nextMsgIdx >= 0) {\n addExtra(nextMsgIdx, SECTION_SPACING);\n const existing = sectionBeforeMsg.get(nextMsgIdx) || [];\n existing.push(el);\n sectionBeforeMsg.set(nextMsgIdx, existing);\n }\n continue;\n }\n\n if (!isSequenceBlock(el)) continue;\n\n // First message in this block needs header space\n const firstIdx = findFirstMsgIndex(el.children);\n if (firstIdx >= 0) addExtra(firstIdx, BLOCK_HEADER_SPACE);\n\n // First message in else section needs header space\n const firstElseIdx = findFirstMsgIndex(el.elseChildren);\n if (firstElseIdx >= 0) addExtra(firstElseIdx, BLOCK_HEADER_SPACE);\n\n // Recurse into nested blocks and sections\n markElementSpacing(el.children);\n markElementSpacing(el.elseChildren);\n\n // Next sibling after this block needs after-block spacing\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 markElementSpacing(elements);\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\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 {\n let curY = lifelineStartY0 + messageStartOffset;\n for (let i = 0; i < renderSteps.length; i++) {\n const step = renderSteps[i];\n // Add extra spacing before the first render step of a flagged message\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 }\n\n const messageAreaHeight =\n renderSteps.length > 0\n ? stepYPositions[stepYPositions.length - 1] -\n lifelineStartY0 +\n stepSpacing\n : 0;\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 { width: containerWidth } = container.getBoundingClientRect();\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(\n 'font-family',\n 'Inter, system-ui, Avenir, Helvetica, Arial, sans-serif'\n );\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 svg\n .append('text')\n .attr('x', svgWidth / 2)\n .attr('y', TOP_MARGIN + TITLE_HEIGHT * 0.7)\n .attr('text-anchor', 'middle')\n .attr('fill', palette.text)\n .attr('font-size', 16)\n .attr('font-weight', 'bold')\n .text(title);\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 ? `color-mix(in srgb, ${resolvedGroupColor} 10%, ${isDark ? palette.surface : palette.bg})`\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 // Helper: compute Y for a step index\n const stepY = (i: number) => stepYPositions[i];\n\n // Render block frames (behind everything else)\n const FRAME_PADDING_X = 30;\n const FRAME_PADDING_TOP = 42;\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 } else if (!isSequenceSection(el)) {\n const idx = messages.indexOf(el);\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 elseIndices = collectMsgIndices(el.elseChildren);\n const allIndices = [...ifIndices, ...elseIndices];\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 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 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 // 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 = `color-mix(in srgb, ${palette.primary} ${isDark ? '15%' : '30%'}, ${isDark ? palette.surface : palette.bg})`;\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('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 [msgIdx, secs] of sectionBeforeMsg.entries()) {\n const firstStep = msgToFirstStep.get(msgIdx);\n if (firstStep === undefined) continue;\n const nextY = stepY(firstStep);\n\n for (let si = 0; si < secs.length; si++) {\n const sec = secs[si];\n const secY = nextY - SECTION_SPACING / 2 + si * 20;\n const lineColor = sec.color\n ? resolveColor(sec.color, palette)\n : palette.textMuted;\n\n // Horizontal divider line\n svg\n .append('line')\n .attr('x1', sectionLineX1)\n .attr('y1', secY)\n .attr('x2', sectionLineX2)\n .attr('y2', secY)\n .attr('stroke', lineColor)\n .attr('stroke-width', 1)\n .attr('stroke-dasharray', '6 3')\n .attr('opacity', 0.6)\n .attr('class', 'section-divider')\n .attr('data-line-number', String(sec.lineNumber))\n .attr('data-section', '');\n\n // Label background knockout\n const labelText = sec.label;\n const labelWidth = labelText.length * 7 + 16;\n const labelX = (sectionLineX1 + sectionLineX2) / 2;\n svg\n .append('rect')\n .attr('x', labelX - labelWidth / 2)\n .attr('y', secY - 8)\n .attr('width', labelWidth)\n .attr('height', 16)\n .attr('fill', isDark ? palette.surface : palette.bg)\n .attr('class', 'section-label-bg')\n .attr('data-line-number', String(sec.lineNumber))\n .attr('data-section', '');\n\n // Centered label text\n svg\n .append('text')\n .attr('x', labelX)\n .attr('y', secY + 4)\n .attr('text-anchor', 'middle')\n .attr('fill', lineColor)\n .attr('font-size', 11)\n .attr('font-weight', 'bold')\n .attr('class', 'section-label')\n .attr('data-line-number', String(sec.lineNumber))\n .attr('data-section', '')\n .text(labelText);\n }\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 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 .text(step.label);\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 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 .text(step.label);\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 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 .text(step.label);\n }\n }\n });\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// 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 { parseChartJs } from './chartjs';\nexport type {\n ParsedChartJs,\n ChartJsChartType,\n ChartJsDataPoint,\n} from './chartjs';\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, ArcLink, ArcNodeGroup } from './d3';\n\nexport {\n parseSequenceDgmo,\n looksLikeSequence,\n isSequenceBlock,\n} from './sequence/parser';\nexport type {\n ParsedSequenceDgmo,\n SequenceParticipant,\n SequenceMessage,\n SequenceBlock,\n SequenceSection,\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\n// ============================================================\n// Config Builders (produce framework-specific config objects)\n// ============================================================\n\nexport { buildChartJsConfig } from './chartjs';\nexport { buildEChartsOption } 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} from './sequence/renderer';\nexport type { RenderStep, Activation } 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// .dgmo Unified Format — Chart Type Router\n// ============================================================\n\nimport { looksLikeSequence } from './sequence/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 = 'chartjs' | 'echart' | 'd3' | 'mermaid';\n\n/**\n * Maps every supported chart type string to its backing framework.\n *\n * Chart.js: standard chart types (bar, line, pie, etc.)\n * ECharts: scatter, flow/relationship diagrams, math, heatmap\n * D3: slope, wordcloud, arc diagram, timeline\n */\nexport const DGMO_CHART_TYPE_MAP: Record<string, DgmoFramework> = {\n // Chart.js\n bar: 'chartjs',\n line: 'chartjs',\n 'multi-line': 'chartjs',\n area: 'chartjs',\n pie: 'chartjs',\n doughnut: 'chartjs',\n radar: 'chartjs',\n 'polar-area': 'chartjs',\n 'bar-stacked': 'chartjs',\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};\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 sequence chart type when content contains arrow patterns\n if (looksLikeSequence(content)) return 'sequence';\n\n return null;\n}\n","import type { ChartConfiguration } from 'chart.js';\nimport 'chartjs-plugin-datalabels';\n\n// ============================================================\n// Types\n// ============================================================\n\nexport type ChartJsChartType =\n | 'bar'\n | 'line'\n | 'pie'\n | 'doughnut'\n | 'area'\n | 'polar-area'\n | 'radar'\n | 'bar-stacked';\n\nexport interface ChartJsDataPoint {\n label: string;\n value: number;\n extraValues?: number[];\n color?: string;\n lineNumber: number;\n}\n\nexport interface ParsedChartJs {\n type: ChartJsChartType;\n title?: string;\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 data: ChartJsDataPoint[];\n error?: string;\n}\n\n// ============================================================\n// Nord Colors for Charts\n// ============================================================\n\nimport { resolveColor } from './colors';\nimport type { PaletteColors } from './palettes';\nimport { getSeriesColors } from './palettes';\n\n// ============================================================\n// Parser\n// ============================================================\n\nconst VALID_TYPES = new Set<ChartJsChartType>([\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, ChartJsChartType> = {\n 'multi-line': 'line',\n};\n\n/**\n * Parses the simple chartjs 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 parseChartJs(\n content: string,\n palette?: PaletteColors\n): ParsedChartJs {\n const lines = content.split('\\n');\n const result: ParsedChartJs = {\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 ChartJsChartType;\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 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 === '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\n// ============================================================\n// Chart.js Config Builder\n// ============================================================\n\n/**\n * Converts parsed chartjs data to a Chart.js configuration object.\n */\nexport function buildChartJsConfig(\n parsed: ParsedChartJs,\n palette: PaletteColors,\n _isDark: boolean\n): ChartConfiguration {\n const textColor = palette.text;\n const gridColor = palette.border + '80';\n const crosshairColor = palette.border + '60';\n const colors = getSeriesColors(palette);\n\n // Plugin: draws a vertical line at the hovered x-position on line/area charts\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const verticalCrosshairPlugin: any = {\n id: 'verticalCrosshair',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n afterDraw(chart: any) {\n const tooltip = chart.tooltip;\n if (!tooltip || !tooltip.getActiveElements().length) return;\n const { ctx, chartArea } = chart;\n const x = tooltip.caretX;\n ctx.save();\n ctx.beginPath();\n ctx.moveTo(x, chartArea.top);\n ctx.lineTo(x, chartArea.bottom);\n ctx.lineWidth = 1;\n ctx.strokeStyle = crosshairColor;\n ctx.stroke();\n ctx.restore();\n },\n };\n\n const labels = parsed.data.map((d) => d.label);\n const values = parsed.data.map((d) => d.value);\n const perPointColors = parsed.data.map(\n (d, i) => d.color ?? colors[i % colors.length]\n );\n\n const titlePlugin = parsed.title\n ? {\n display: true as const,\n text: parsed.title,\n color: textColor,\n font: { size: 18, weight: 'bold' as const },\n padding: { bottom: 16 },\n }\n : { display: false as const };\n\n const tooltipConfig = {\n backgroundColor: palette.surface,\n titleColor: palette.text,\n bodyColor: palette.text,\n borderColor: palette.border,\n borderWidth: 1,\n };\n\n // Resolve `label:` to the value axis (Y for vertical, X for horizontal)\n const isHorizontalChart = parsed.orientation === 'horizontal';\n const resolvedXLabel =\n parsed.xlabel ?? (isHorizontalChart ? parsed.label : undefined);\n const resolvedYLabel =\n parsed.ylabel ?? (isHorizontalChart ? undefined : parsed.label);\n\n // Axis title configs (used by chart types with x/y scales)\n const xAxisTitle = resolvedXLabel\n ? { display: true, text: resolvedXLabel, color: textColor }\n : undefined;\n const yAxisTitle = resolvedYLabel\n ? { display: true, text: resolvedYLabel, color: textColor }\n : undefined;\n\n // Radar chart\n if (parsed.type === 'radar') {\n const radarColor =\n parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n // Subtle grid color for concentric reference lines drawn on top\n const radarGridColor = palette.border + '60';\n\n // Plugin: draws concentric polygon grid lines ON TOP of the data area.\n // This makes the reference shapes visible even with solid fill.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const radarGridOverlayPlugin: any = {\n id: 'radarGridOverlay',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n afterDatasetsDraw(chart: any) {\n const scale = chart.scales.r;\n if (!scale) return;\n const ticks = scale.ticks as { value: number }[];\n if (!ticks || ticks.length < 1) return;\n\n const { ctx } = chart;\n const pointCount = chart.data.labels?.length ?? 0;\n if (pointCount < 3) return;\n\n ctx.save();\n ctx.strokeStyle = radarGridColor;\n ctx.lineWidth = 1;\n\n // Draw concentric polygon lines for each tick\n for (let i = 0; i < ticks.length; i++) {\n const dist = scale.getDistanceFromCenterForValue(\n ticks[i].value\n ) as number;\n if (dist <= 0) continue;\n\n ctx.beginPath();\n for (let p = 0; p < pointCount; p++) {\n const pos = scale.getPointPosition(p, dist);\n if (p === 0) ctx.moveTo(pos.x, pos.y);\n else ctx.lineTo(pos.x, pos.y);\n }\n ctx.closePath();\n ctx.stroke();\n }\n\n // Draw angle lines from center to each point\n const outerDist = scale.getDistanceFromCenterForValue(\n ticks[ticks.length - 1].value\n ) as number;\n for (let p = 0; p < pointCount; p++) {\n const pos = scale.getPointPosition(p, outerDist);\n ctx.beginPath();\n ctx.moveTo(scale.xCenter, scale.yCenter);\n ctx.lineTo(pos.x, pos.y);\n ctx.stroke();\n }\n\n ctx.restore();\n },\n };\n\n return {\n type: 'radar',\n data: {\n labels,\n datasets: [\n {\n label: parsed.series ?? 'Value',\n data: values,\n backgroundColor: radarColor,\n borderColor: 'transparent',\n borderWidth: 0,\n pointBackgroundColor: radarColor,\n pointRadius: 5,\n },\n ],\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n plugins: {\n legend: { display: false },\n title: titlePlugin,\n tooltip: tooltipConfig,\n datalabels: {\n display: true,\n color: textColor,\n backgroundColor: palette.bg + 'cc',\n borderRadius: 3,\n padding: { top: 2, bottom: 2, left: 4, right: 4 },\n font: { size: 11, weight: 'bold' as const },\n anchor: 'center' as const,\n align: 'center' as const,\n formatter: (value: number) => value.toString(),\n },\n },\n scales: {\n r: {\n beginAtZero: true,\n ticks: {\n // Hide tick labels - we show actual values on data points instead\n display: false,\n },\n grid: {\n // Hide default grid - we draw it on top via plugin\n display: false,\n },\n angleLines: {\n // Hide default angle lines - we draw them on top via plugin\n display: false,\n },\n pointLabels: {\n color: textColor,\n font: { size: 12, weight: 'bold' as const },\n },\n },\n },\n },\n plugins: [radarGridOverlayPlugin],\n } as ChartConfiguration;\n }\n\n // Polar Area chart (styled like pie/doughnut: outer labels, no legend)\n if (parsed.type === 'polar-area') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const polarConnectorPlugin: any = {\n id: 'polarConnectorLines',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n afterDatasetsDraw(chart: any) {\n const meta = chart.getDatasetMeta(0);\n if (!meta?.data?.length) return;\n\n const { ctx } = chart;\n ctx.save();\n ctx.strokeStyle = textColor;\n ctx.lineWidth = 1;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n meta.data.forEach((arc: any) => {\n const {\n startAngle,\n endAngle,\n outerRadius,\n x: cx,\n y: cy,\n } = arc.getProps(['startAngle', 'endAngle', 'outerRadius', 'x', 'y']);\n const midAngle = (startAngle + endAngle) / 2;\n const r1 = outerRadius + 2;\n const r2 = outerRadius + 14;\n\n ctx.beginPath();\n ctx.moveTo(\n cx + Math.cos(midAngle) * r1,\n cy + Math.sin(midAngle) * r1\n );\n ctx.lineTo(\n cx + Math.cos(midAngle) * r2,\n cy + Math.sin(midAngle) * r2\n );\n ctx.stroke();\n });\n\n ctx.restore();\n },\n };\n\n const polarTitlePlugin = parsed.title\n ? {\n display: true as const,\n text: parsed.title,\n color: textColor,\n font: { size: 18, weight: 'bold' as const },\n padding: { bottom: 24 },\n }\n : { display: false as const };\n\n return {\n type: 'polarArea',\n data: {\n labels,\n datasets: [\n {\n label: parsed.series ?? 'Value',\n data: values,\n backgroundColor: perPointColors,\n borderWidth: 0,\n },\n ],\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n layout: { padding: { top: 10, bottom: 40, left: 60, right: 60 } },\n plugins: {\n legend: { display: false },\n title: polarTitlePlugin,\n tooltip: tooltipConfig,\n datalabels: {\n display: true,\n color: textColor,\n font: { weight: 'bold' as const },\n formatter: (_value: number, ctx: { dataIndex: number }) =>\n labels[ctx.dataIndex] ?? '',\n anchor: 'end' as const,\n align: 'end' as const,\n offset: 16,\n },\n },\n scales: {\n r: {\n ticks: { display: false },\n grid: { color: gridColor },\n },\n },\n },\n plugins: [polarConnectorPlugin],\n } as ChartConfiguration;\n }\n\n // Pie / Doughnut chart\n if (parsed.type === 'pie' || parsed.type === 'doughnut') {\n // Inline plugin to draw connector lines from each slice to its outer label\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const pieConnectorPlugin: any = {\n id: 'pieConnectorLines',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n afterDatasetsDraw(chart: any) {\n const meta = chart.getDatasetMeta(0);\n if (!meta?.data?.length) return;\n\n const { ctx } = chart;\n ctx.save();\n ctx.strokeStyle = textColor;\n ctx.lineWidth = 1;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n meta.data.forEach((arc: any) => {\n const {\n startAngle,\n endAngle,\n outerRadius,\n x: cx,\n y: cy,\n } = arc.getProps(['startAngle', 'endAngle', 'outerRadius', 'x', 'y']);\n const midAngle = (startAngle + endAngle) / 2;\n const r1 = outerRadius + 2;\n const r2 = outerRadius + 14;\n\n ctx.beginPath();\n ctx.moveTo(\n cx + Math.cos(midAngle) * r1,\n cy + Math.sin(midAngle) * r1\n );\n ctx.lineTo(\n cx + Math.cos(midAngle) * r2,\n cy + Math.sin(midAngle) * r2\n );\n ctx.stroke();\n });\n\n ctx.restore();\n },\n };\n\n const pieTitlePlugin = parsed.title\n ? {\n display: true as const,\n text: parsed.title,\n color: textColor,\n font: { size: 18, weight: 'bold' as const },\n padding: { bottom: 24 },\n }\n : { display: false as const };\n\n return {\n type: parsed.type,\n data: {\n labels,\n datasets: [\n {\n label: parsed.series ?? 'Value',\n data: values,\n backgroundColor: perPointColors,\n borderWidth: 0,\n },\n ],\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n // radius is valid for pie/doughnut at runtime but not in the strict type\n radius: '70%',\n layout: { padding: { top: 10, bottom: 40, left: 60, right: 60 } },\n plugins: {\n legend: { display: false },\n title: pieTitlePlugin,\n tooltip: tooltipConfig,\n datalabels: {\n display: true,\n color: textColor,\n font: { weight: 'bold' as const },\n formatter: (_value: number, ctx: { dataIndex: number }) =>\n labels[ctx.dataIndex] ?? '',\n anchor: 'end' as const,\n align: 'end' as const,\n offset: 16,\n },\n },\n },\n plugins: [pieConnectorPlugin],\n } as ChartConfiguration;\n }\n\n // Multi-series: bar-stacked, or line with multiple series\n const isMultiSeries =\n parsed.type === 'bar-stacked' ||\n (parsed.type === 'line' && parsed.seriesNames);\n if (isMultiSeries) {\n const seriesNames = parsed.seriesNames ?? ['Value'];\n const isHorizontal = parsed.orientation === 'horizontal';\n const isMultiLine = parsed.type === 'line';\n\n // Transpose row-based data into per-series datasets\n const datasets = seriesNames.map((name, seriesIdx) => {\n const data = parsed.data.map((dp) => {\n if (seriesIdx === 0) return dp.value;\n return dp.extraValues?.[seriesIdx - 1] ?? 0;\n });\n\n const color =\n parsed.seriesNameColors?.[seriesIdx] ??\n colors[seriesIdx % colors.length];\n\n if (isMultiLine) {\n return {\n label: name,\n data,\n borderColor: color,\n backgroundColor: color + '40',\n borderWidth: 3,\n pointBackgroundColor: color,\n pointRadius: 4,\n tension: 0,\n fill: false,\n };\n }\n\n return {\n label: name,\n data,\n backgroundColor: color,\n borderColor: color,\n borderWidth: 1,\n };\n });\n\n const scaleOptions = isMultiLine\n ? {\n x: {\n grid: { color: gridColor },\n ticks: { color: textColor },\n ...(xAxisTitle && { title: xAxisTitle }),\n },\n y: {\n grid: { color: gridColor },\n ticks: { color: textColor },\n ...(yAxisTitle && { title: yAxisTitle }),\n },\n }\n : {\n x: {\n stacked: true as const,\n grid: { color: gridColor },\n ticks: { color: textColor },\n ...(xAxisTitle && { title: xAxisTitle }),\n },\n y: {\n stacked: true as const,\n grid: { color: gridColor },\n ticks: { color: textColor },\n ...(yAxisTitle && { title: yAxisTitle }),\n },\n };\n\n return {\n type: isMultiLine ? 'line' : 'bar',\n data: {\n labels,\n datasets,\n },\n options: {\n indexAxis: isHorizontal ? 'y' : 'x',\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n plugins: {\n legend: { position: 'top' as const, labels: { color: textColor } },\n title: titlePlugin,\n tooltip: tooltipConfig,\n datalabels: { display: false },\n },\n ...(isMultiLine\n ? { interaction: { mode: 'index' as const, intersect: false } }\n : {}),\n scales: scaleOptions,\n },\n ...(isMultiLine ? { plugins: [verticalCrosshairPlugin] } : {}),\n } as ChartConfiguration;\n }\n\n // Bar, line, area\n const isHorizontal = parsed.orientation === 'horizontal';\n const isLine = parsed.type === 'line' || parsed.type === 'area';\n const isArea = parsed.type === 'area';\n const lineColor =\n parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;\n\n return {\n type: isLine ? 'line' : 'bar',\n data: {\n labels,\n datasets: [\n {\n label: parsed.series ?? 'Value',\n data: values,\n backgroundColor: isLine\n ? isArea\n ? lineColor + '40'\n : lineColor\n : perPointColors,\n borderColor: isLine ? lineColor : undefined,\n borderWidth: isLine ? 3 : 0,\n pointBackgroundColor: isLine ? lineColor : undefined,\n pointRadius: isLine ? 4 : undefined,\n tension: isLine ? 0 : undefined,\n fill: isArea ? true : undefined,\n },\n ],\n },\n options: {\n indexAxis: isHorizontal ? 'y' : 'x',\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n ...(isLine && !isArea\n ? { interaction: { mode: 'index' as const, intersect: false } }\n : {}),\n plugins: {\n legend: { display: false },\n title: titlePlugin,\n tooltip: tooltipConfig,\n datalabels: { display: false },\n },\n scales: {\n x: {\n grid: { color: gridColor },\n ticks: { color: textColor },\n ...(xAxisTitle && { title: xAxisTitle }),\n },\n y: {\n grid: { color: gridColor },\n ticks: { color: textColor },\n ...(yAxisTitle && { title: yAxisTitle }),\n },\n },\n },\n ...(isLine && !isArea ? { plugins: [verticalCrosshairPlugin] } : {}),\n };\n}\n","import type { EChartsOption } from 'echarts';\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 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 } from './palettes';\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 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 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 textStyle: {\n color: textColor,\n fontSize: 18,\n fontWeight: 'bold' as const,\n fontFamily: 'system-ui, -apple-system, sans-serif',\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 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 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 },\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 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 };\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: '3%',\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 },\n splitLine: {\n lineStyle: {\n color: palette.overlay,\n },\n },\n },\n yAxis: {\n type: 'value',\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n },\n splitLine: {\n lineStyle: {\n color: palette.overlay,\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 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 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: '3%',\n right: '4%',\n bottom: hasCategories ? '15%' : '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: 30,\n nameTextStyle: {\n color: textColor,\n fontSize: 12,\n },\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n },\n splitLine: {\n lineStyle: {\n color: palette.overlay,\n },\n },\n },\n yAxis: {\n type: 'value',\n name: parsed.ylabel,\n nameLocation: 'middle',\n nameGap: 40,\n nameTextStyle: {\n color: textColor,\n fontSize: 12,\n },\n axisLine: {\n lineStyle: { color: axisLineColor },\n },\n axisLabel: {\n color: textColor,\n },\n splitLine: {\n lineStyle: {\n color: palette.overlay,\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 },\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 },\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.bg,\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: textColor,\n },\n emphasis: {\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 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","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';\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\nexport interface ParsedD3 {\n type: D3ChartType | null;\n title: string | 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 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 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 = 12;\nconst SLOPE_CHAR_WIDTH = 7; // approximate px per character at 12px\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): 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 = container.clientWidth;\n const 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 + 20, 100),\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.overlay;\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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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', '13px')\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 // 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 tipHtml =\n `<strong>${item.label}</strong><br>` +\n `${periods[0]}: ${firstVal} → ${periods[periods.length - 1]}: ${lastVal}<br>` +\n `Change: ${sign}${absChange}${pctPart}`;\n\n // Line\n g.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 g.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 g.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 g.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', '12px')\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 = g\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): 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 = container.clientWidth;\n const 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.overlay;\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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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.08\n );\n g.selectAll<SVGTextElement, unknown>('.arc-group-label').attr(\n 'fill-opacity',\n 0.7\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('x', baseX - bandHalfW)\n .attr('y', minY)\n .attr('width', bandHalfW * 2)\n .attr('height', maxY - minY)\n .attr('rx', 4)\n .attr('fill', bandColor)\n .attr('fill-opacity', 0.08)\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('x', baseX - bandHalfW + 6)\n .attr('y', minY + 12)\n .attr('fill', bandColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .attr('fill-opacity', 0.7)\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('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\n const nodeLink = onClickItem\n ? links.find((l) => l.source === node || l.target === node)\n : undefined;\n\n const nodeG = g\n .append('g')\n .attr('class', 'arc-node')\n .attr('data-node', node)\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('x', minX)\n .attr('y', baseY - bandHalfH)\n .attr('width', maxX - minX)\n .attr('height', bandHalfH * 2)\n .attr('rx', 4)\n .attr('fill', bandColor)\n .attr('fill-opacity', 0.08)\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('x', (minX + maxX) / 2)\n .attr('y', baseY + bandHalfH - 4)\n .attr('text-anchor', 'middle')\n .attr('fill', bandColor)\n .attr('font-size', '10px')\n .attr('font-weight', '600')\n .attr('fill-opacity', 0.7)\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('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\n const nodeLink = onClickItem\n ? links.find((l) => l.source === node || l.target === node)\n : undefined;\n\n const nodeG = g\n .append('g')\n .attr('class', 'arc-node')\n .attr('data-node', node)\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 .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 for (let y = firstYear; y <= lastYear; y++) {\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): 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 = container.clientWidth;\n const 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.overlay;\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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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-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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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-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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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-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', '13px')\n .attr('font-weight', '500')\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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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-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', '13px')\n .attr('font-weight', '500')\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): 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 = container.clientWidth;\n const 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.overlay;\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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 28)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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('system-ui, -apple-system, sans-serif')\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', 'system-ui, -apple-system, sans-serif')\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 .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): 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 = container.clientWidth;\n const 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.overlay;\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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 28)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\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('system-ui, -apple-system, sans-serif')\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', 'system-ui, -apple-system, sans-serif')\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 fitCirclesToContainer(\n circles: Circle[],\n w: number,\n h: number,\n margin: 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 - 2 * margin;\n const availH = h - 2 * margin;\n const scale = Math.min(availW / bw, availH / bh) * 0.85;\n const cx = (minX + maxX) / 2;\n const cy = (minY + maxY) / 2;\n const tx = w / 2;\n const ty = h / 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 // Sample points and average those matching the region\n const N = 500;\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 let sx = 0,\n sy = 0,\n count = 0;\n for (let i = 0; i < N; i++) {\n const x = minX + Math.random() * (maxX - minX);\n const y = minY + Math.random() * (maxY - minY);\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 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\nfunction blendColors(hexColors: string[]): string {\n let r = 0,\n g = 0,\n b = 0;\n for (const hex of hexColors) {\n const h = hex.replace('#', '');\n r += parseInt(h.substring(0, 2), 16);\n g += parseInt(h.substring(2, 4), 16);\n b += parseInt(h.substring(4, 6), 16);\n }\n const n = hexColors.length;\n return `#${Math.round(r / n)\n .toString(16)\n .padStart(2, '0')}${Math.round(g / n)\n .toString(16)\n .padStart(2, '0')}${Math.round(b / n)\n .toString(16)\n .padStart(2, '0')}`;\n}\n\nfunction circlePathD(cx: number, cy: number, r: number): string {\n return `M${cx - r},${cy} A${r},${r} 0 1,0 ${cx + r},${cy} A${r},${r} 0 1,0 ${cx - r},${cy} Z`;\n}\n\nexport function renderVenn(\n container: HTMLDivElement,\n parsed: ParsedD3,\n palette: PaletteColors,\n isDark: boolean,\n onClickItem?: (lineNumber: number) => void\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 = container.clientWidth;\n const height = container.clientHeight;\n if (width <= 0 || height <= 0) return;\n\n const textColor = palette.text;\n const bgColor = palette.overlay;\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 const drawH = height - titleHeight;\n const labelMargin = 100; // extra margin for external labels\n const circles = fitCirclesToContainer(\n rawCircles,\n width,\n drawH,\n labelMargin\n ).map((c) => ({ ...c, y: c.y + titleHeight }));\n\n // Resolve colors for each set\n const setColors = vennSets.map(\n (s, i) => s.color ?? colors[i % colors.length]\n );\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 svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', 28)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .text(title);\n }\n\n // ── Clip-path definitions ──\n // For each circle: a clip-path to include it, and one to exclude it (hole)\n const defs = svg.append('defs');\n const pad = 20;\n circles.forEach((c, i) => {\n // Include clip: just the circle\n defs\n .append('clipPath')\n .attr('id', `venn-in-${i}`)\n .append('circle')\n .attr('cx', c.x)\n .attr('cy', c.y)\n .attr('r', c.r);\n\n // Exclude clip: large rect with circle punched out via evenodd\n defs\n .append('clipPath')\n .attr('id', `venn-out-${i}`)\n .append('path')\n .attr(\n 'd',\n `M${-pad},${-pad} H${width + pad} V${height + pad} H${-pad} Z ` +\n circlePathD(c.x, c.y, c.r)\n )\n .attr('clip-rule', 'evenodd');\n });\n\n // Helper: nest clip-path groups and append a filled rect\n function drawClippedRegion(\n parent: d3Selection.Selection<SVGGElement, unknown, null, undefined>,\n clipIds: string[],\n fill: string\n ): d3Selection.Selection<SVGGElement, unknown, null, undefined> {\n let g = parent;\n for (const id of clipIds) {\n g = g\n .append('g')\n .attr('clip-path', `url(#${id})`) as d3Selection.Selection<\n SVGGElement,\n unknown,\n null,\n undefined\n >;\n }\n g.append('rect')\n .attr('x', -pad)\n .attr('y', -pad)\n .attr('width', width + 2 * pad)\n .attr('height', height + 2 * pad)\n .attr('fill', fill);\n return g;\n }\n\n // ── Draw opaque regions ──\n // Track region groups by which circle indices they relate to (for hover dimming)\n const regionGroups: {\n g: d3Selection.Selection<SVGGElement, unknown, null, undefined>;\n circleIdxs: number[];\n }[] = [];\n\n // Exclusive regions: inside circle i, outside all others\n const regionsParent = svg.append('g');\n for (let i = 0; i < n; i++) {\n const clips = [`venn-in-${i}`];\n for (let j = 0; j < n; j++) {\n if (j !== i) clips.push(`venn-out-${j}`);\n }\n const g = regionsParent.append('g') as d3Selection.Selection<\n SVGGElement,\n unknown,\n null,\n undefined\n >;\n drawClippedRegion(g, clips, setColors[i]);\n regionGroups.push({ g, circleIdxs: [i] });\n }\n\n // Pairwise overlap regions (excluding any third circle)\n const pairIndices: [number, number][] = [];\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n pairIndices.push([i, j]);\n }\n }\n for (const [i, j] of pairIndices) {\n const clips = [`venn-in-${i}`, `venn-in-${j}`];\n for (let k = 0; k < n; k++) {\n if (k !== i && k !== j) clips.push(`venn-out-${k}`);\n }\n const blended = blendColors([setColors[i], setColors[j]]);\n const g = regionsParent.append('g') as d3Selection.Selection<\n SVGGElement,\n unknown,\n null,\n undefined\n >;\n drawClippedRegion(g, clips, blended);\n regionGroups.push({ g, circleIdxs: [i, j] });\n }\n\n // Triple overlap region (if 3 sets)\n if (n === 3) {\n const clips = [`venn-in-0`, `venn-in-1`, `venn-in-2`];\n const blended = blendColors([setColors[0], setColors[1], setColors[2]]);\n const g = regionsParent.append('g') as d3Selection.Selection<\n SVGGElement,\n unknown,\n null,\n undefined\n >;\n drawClippedRegion(g, clips, blended);\n regionGroups.push({ g, circleIdxs: [0, 1, 2] });\n }\n\n // ── Circle outlines ──\n const outlineGroup = svg.append('g');\n circles.forEach((c, i) => {\n outlineGroup\n .append('circle')\n .attr('cx', c.x)\n .attr('cy', c.y)\n .attr('r', c.r)\n .attr('fill', 'none')\n .attr('stroke', setColors[i])\n .attr('stroke-width', 2)\n .style('pointer-events', 'none');\n });\n\n // ── External labels with leader lines (pie-chart style) ──\n interface LabelEntry {\n centroid: Point;\n text: string;\n involvedIdxs: number[]; // which circle indices this label belongs to\n }\n const labelEntries: LabelEntry[] = [];\n\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 // Set name labels (exclusive regions)\n circles.forEach((_c, i) => {\n const inside = circles.map((_, j) => j === i);\n const centroid = regionCentroid(circles, inside);\n const displayName = vennSets[i].label ?? vennSets[i].name;\n const text = vennShowValues\n ? `${displayName} (${vennSets[i].size})`\n : displayName;\n labelEntries.push({ centroid, text, involvedIdxs: [i] });\n });\n\n // Overlap labels\n for (const ov of vennOverlaps) {\n const idxs = ov.sets.map((s) => vennSets.findIndex((vs) => vs.name === s));\n if (idxs.some((i) => i < 0)) continue;\n if (!ov.label && !vennShowValues) continue;\n\n const inside = circles.map((_, j) => idxs.includes(j));\n const centroid = regionCentroid(circles, inside);\n let text = '';\n if (ov.label && vennShowValues) text = `${ov.label} (${ov.size})`;\n else if (ov.label) text = ov.label;\n else text = String(ov.size);\n labelEntries.push({ centroid, text, involvedIdxs: idxs });\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 stubLen = 20;\n const edgePad = 8; // clearance from circle edge\n const labelGroup = svg.append('g').style('pointer-events', 'none');\n\n for (const entry of labelEntries) {\n const { centroid, text } = entry;\n\n // Direction from global center to centroid\n let dx = centroid.x - gcx;\n let dy = centroid.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 // Exit at the farthest circle edge so the label lands in white space\n let exitT = 0;\n for (const c of circles) {\n const t = rayCircleExit(centroid.x, centroid.y, dx, dy, c);\n if (t > exitT) exitT = t;\n }\n\n // Edge point: outside the exit boundary with padding\n const edgeX = centroid.x + dx * (exitT + edgePad);\n const edgeY = centroid.y + dy * (exitT + edgePad);\n\n // Stub end point\n const stubX = edgeX + dx * stubLen;\n const stubY = edgeY + dy * stubLen;\n\n // For overlap regions (2+ sets), draw leader from centroid into the region\n // For exclusive regions (single set), just draw from edge outward\n const isOverlap = entry.involvedIdxs.length > 1;\n const lineStartX = isOverlap ? centroid.x : edgeX;\n const lineStartY = isOverlap ? centroid.y : edgeY;\n\n labelGroup\n .append('line')\n .attr('x1', lineStartX)\n .attr('y1', lineStartY)\n .attr('x2', stubX)\n .attr('y2', stubY)\n .attr('stroke', textColor)\n .attr('stroke-width', 1);\n\n // Text positioned right after the stub\n const isRight = stubX >= gcx;\n const textAnchor = isRight ? 'start' : 'end';\n const textX = stubX + (isRight ? 4 : -4);\n\n labelGroup\n .append('text')\n .attr('x', textX)\n .attr('y', stubY)\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 // ── 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 .style('cursor', onClickItem ? 'pointer' : 'default')\n .on('mouseenter', (event: MouseEvent) => {\n for (const rg of regionGroups) {\n rg.g.style('opacity', rg.circleIdxs.includes(i) ? '1' : '0.25');\n }\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mousemove', (event: MouseEvent) => {\n showTooltip(tooltip, tipHtml, event);\n })\n .on('mouseleave', () => {\n for (const rg of regionGroups) {\n rg.g.style('opacity', '1');\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): 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 = container.clientWidth;\n const 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.overlay;\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 margin = { top: title ? 60 : 30, right: 30, bottom: 50, left: 60 };\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('x', width / 2)\n .attr('y', 30)\n .attr('text-anchor', 'middle')\n .attr('fill', textColor)\n .attr('font-size', '18px')\n .attr('font-weight', '700')\n .style(\n 'cursor',\n onClickItem && quadrantTitleLineNumber ? 'pointer' : 'default'\n )\n .text(title);\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 // Get fill color for each quadrant (solid, no transparency)\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 // Contrast color for text/points on colored backgrounds\n const contrastColor = isDark ? '#ffffff' : '#333333';\n const shadowColor = isDark ? 'rgba(0,0,0,0.3)' : 'rgba(255,255,255,0.5)';\n\n // Draw quadrant labels (large, centered, contrasting color for readability)\n const quadrantLabelTexts = chartG\n .selectAll('text.quadrant-label')\n .data(quadrantDefs.filter((d) => d.label !== null))\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', contrastColor)\n .attr('font-size', '16px')\n .attr('font-weight', '600')\n .style('text-shadow', `0 1px 2px ${shadowColor}`)\n .style('cursor', (d) =>\n onClickItem && d.label?.lineNumber ? 'pointer' : 'default'\n )\n .text((d) => d.label!.text);\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\n if (quadrantXAxis) {\n // Low label (left)\n const xLowLabel = svg\n .append('text')\n .attr('x', margin.left)\n .attr('y', height - 15)\n .attr('text-anchor', 'start')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .style(\n 'cursor',\n onClickItem && quadrantXAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantXAxis[0]);\n\n // High label (right)\n const xHighLabel = svg\n .append('text')\n .attr('x', width - margin.right)\n .attr('y', height - 15)\n .attr('text-anchor', 'end')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .style(\n 'cursor',\n onClickItem && quadrantXAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantXAxis[1]);\n\n // Arrow in the middle\n svg\n .append('text')\n .attr('x', width / 2)\n .attr('y', height - 15)\n .attr('text-anchor', 'middle')\n .attr('fill', mutedColor)\n .attr('font-size', '12px')\n .text('→');\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\n if (quadrantYAxis) {\n // Low label (bottom)\n const yLowLabel = svg\n .append('text')\n .attr('x', 15)\n .attr('y', height - margin.bottom)\n .attr('text-anchor', 'start')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .attr('transform', `rotate(-90, 15, ${height - margin.bottom})`)\n .style(\n 'cursor',\n onClickItem && quadrantYAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantYAxis[0]);\n\n // High label (top)\n const yHighLabel = svg\n .append('text')\n .attr('x', 15)\n .attr('y', margin.top)\n .attr('text-anchor', 'end')\n .attr('fill', textColor)\n .attr('font-size', '12px')\n .attr('transform', `rotate(-90, 15, ${margin.top})`)\n .style(\n 'cursor',\n onClickItem && quadrantYAxisLineNumber ? 'pointer' : 'default'\n )\n .text(quadrantYAxis[1]);\n\n // Arrow in the middle\n svg\n .append('text')\n .attr('x', 15)\n .attr('y', height / 2)\n .attr('text-anchor', 'middle')\n .attr('fill', mutedColor)\n .attr('font-size', '12px')\n .attr('transform', `rotate(-90, 15, ${height / 2})`)\n .text('→');\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\n // Circle (contrasting fill with colored border for visibility)\n pointG\n .append('circle')\n .attr('cx', cx)\n .attr('cy', cy)\n .attr('r', 6)\n .attr('fill', contrastColor)\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', '11px')\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): Promise<string> {\n const parsed = parseD3(content, palette);\n if (parsed.error) return '';\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 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);\n } else if (parsed.type === 'wordcloud') {\n await renderWordCloudAsync(container, parsed, effectivePalette, isDark);\n } else if (parsed.type === 'arc') {\n renderArcDiagram(container, parsed, effectivePalette, isDark);\n } else if (parsed.type === 'timeline') {\n renderTimeline(container, parsed, effectivePalette, isDark);\n } else if (parsed.type === 'venn') {\n renderVenn(container, parsed, effectivePalette, isDark);\n } else if (parsed.type === 'quadrant') {\n renderQuadrant(container, parsed, effectivePalette, isDark);\n } else {\n renderSlopeChart(container, parsed, effectivePalette, isDark);\n }\n\n const svgEl = container.querySelector('svg');\n if (!svgEl) return '';\n\n // For transparent theme, remove the background\n if (theme === 'transparent') {\n svgEl.style.background = 'none';\n }\n\n // Add xmlns for standalone SVG\n svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n\n return svgEl.outerHTML;\n } finally {\n document.body.removeChild(container);\n }\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"],"mappings":"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","names":["line","p","q","line","isHorizontal","d3Selection","line","text","fill","cloud","_","getPalette","parseSequenceDgmo","renderSequenceDiagram","line"]}