compasso 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +86 -5
  2. package/dist/{chunk-WJYYBGZW.js → chunk-2NDET6O5.js} +3 -3
  3. package/dist/{chunk-WJYYBGZW.js.map → chunk-2NDET6O5.js.map} +1 -1
  4. package/dist/{chunk-LR7BXUWM.js → chunk-3RGYLVTN.js} +3 -3
  5. package/dist/{chunk-LR7BXUWM.js.map → chunk-3RGYLVTN.js.map} +1 -1
  6. package/dist/chunk-BM7UJBK5.js +680 -0
  7. package/dist/chunk-BM7UJBK5.js.map +1 -0
  8. package/dist/chunk-DVLWT565.js +372 -0
  9. package/dist/chunk-DVLWT565.js.map +1 -0
  10. package/dist/{chunk-IPE7JZO5.js → chunk-JBDA7E2O.js} +3 -3
  11. package/dist/{chunk-IPE7JZO5.js.map → chunk-JBDA7E2O.js.map} +1 -1
  12. package/dist/chunk-MIJTBYX2.js +982 -0
  13. package/dist/chunk-MIJTBYX2.js.map +1 -0
  14. package/dist/{chunk-PGUMLTIM.js → chunk-PJHLWSGD.js} +3 -3
  15. package/dist/{chunk-PGUMLTIM.js.map → chunk-PJHLWSGD.js.map} +1 -1
  16. package/dist/{chunk-M4WA6ME7.js → chunk-RDH4XHA2.js} +3 -3
  17. package/dist/{chunk-M4WA6ME7.js.map → chunk-RDH4XHA2.js.map} +1 -1
  18. package/dist/{chunk-TAE2UB7D.js → chunk-WEHUSHVI.js} +4 -40
  19. package/dist/chunk-WEHUSHVI.js.map +1 -0
  20. package/dist/{chunk-FYBABYC7.js → chunk-Z66YUOUM.js} +3 -3
  21. package/dist/{chunk-FYBABYC7.js.map → chunk-Z66YUOUM.js.map} +1 -1
  22. package/dist/core/index.cjs +217 -0
  23. package/dist/core/index.cjs.map +1 -1
  24. package/dist/core/index.d.cts +79 -3
  25. package/dist/core/index.d.ts +79 -3
  26. package/dist/core/index.js +1 -1
  27. package/dist/ecomap/index.js +2 -2
  28. package/dist/fault-tree/index.d.cts +2 -2
  29. package/dist/fault-tree/index.d.ts +2 -2
  30. package/dist/fault-tree/index.js +2 -2
  31. package/dist/fishbone/index.js +2 -2
  32. package/dist/genogram/index.d.cts +2 -2
  33. package/dist/genogram/index.d.ts +2 -2
  34. package/dist/genogram/index.js +2 -2
  35. package/dist/geometry-P-XGqGe7.d.cts +8 -0
  36. package/dist/geometry-P-XGqGe7.d.ts +8 -0
  37. package/dist/grid-BMgUSly1.d.cts +79 -0
  38. package/dist/grid-BMgUSly1.d.ts +79 -0
  39. package/dist/index.cjs +2263 -380
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +10 -3
  42. package/dist/index.d.ts +10 -3
  43. package/dist/index.js +10 -8
  44. package/dist/labels-Br8yjc3C.d.cts +29 -0
  45. package/dist/labels-Br8yjc3C.d.ts +29 -0
  46. package/dist/labels-D1v1RWZd.d.cts +97 -0
  47. package/dist/labels-D1v1RWZd.d.ts +97 -0
  48. package/dist/layered-DmZluAqe.d.cts +72 -0
  49. package/dist/layered-DmZluAqe.d.ts +72 -0
  50. package/dist/locales/pt-br.cjs +53 -0
  51. package/dist/locales/pt-br.cjs.map +1 -1
  52. package/dist/locales/pt-br.d.cts +7 -1
  53. package/dist/locales/pt-br.d.ts +7 -1
  54. package/dist/locales/pt-br.js +50 -1
  55. package/dist/locales/pt-br.js.map +1 -1
  56. package/dist/org-chart/index.cjs +38 -36
  57. package/dist/org-chart/index.cjs.map +1 -1
  58. package/dist/org-chart/index.d.cts +5 -31
  59. package/dist/org-chart/index.d.ts +5 -31
  60. package/dist/org-chart/index.js +2 -2
  61. package/dist/pedigree/index.d.cts +2 -2
  62. package/dist/pedigree/index.d.ts +2 -2
  63. package/dist/pedigree/index.js +2 -2
  64. package/dist/phylo/index.d.cts +2 -2
  65. package/dist/phylo/index.d.ts +2 -2
  66. package/dist/phylo/index.js +2 -2
  67. package/dist/prisma/index.cjs +882 -0
  68. package/dist/prisma/index.cjs.map +1 -0
  69. package/dist/prisma/index.d.cts +174 -0
  70. package/dist/prisma/index.d.ts +174 -0
  71. package/dist/prisma/index.js +4 -0
  72. package/dist/prisma/index.js.map +1 -0
  73. package/dist/{text-DuO_PwYw.d.cts → text-DDVzpwPZ.d.cts} +1 -8
  74. package/dist/{text-DuO_PwYw.d.ts → text-DDVzpwPZ.d.ts} +1 -8
  75. package/dist/uml/index.cjs +1214 -0
  76. package/dist/uml/index.cjs.map +1 -0
  77. package/dist/uml/index.d.cts +189 -0
  78. package/dist/uml/index.d.ts +189 -0
  79. package/dist/uml/index.js +4 -0
  80. package/dist/uml/index.js.map +1 -0
  81. package/package.json +28 -2
  82. package/dist/chunk-SD4NTRBM.js +0 -171
  83. package/dist/chunk-SD4NTRBM.js.map +0 -1
  84. package/dist/chunk-TAE2UB7D.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/xml.ts","../src/core/roman.ts","../src/core/geometry.ts","../src/core/text.ts","../src/core/legend.ts","../src/core/stroke.ts","../src/core/annotation.ts","../src/genogram/types.ts","../src/genogram/labels.ts","../src/genogram/kinship.ts","../src/genogram/layout.ts","../src/genogram/svg.ts","../src/genogram/render.ts","../src/ecomap/render.ts","../src/fault-tree/types.ts","../src/fault-tree/labels.ts","../src/fault-tree/validate.ts","../src/fault-tree/layout.ts","../src/fault-tree/svg.ts","../src/fault-tree/render.ts","../src/fishbone/render.ts","../src/pedigree/types.ts","../src/pedigree/labels.ts","../src/pedigree/validate.ts","../src/pedigree/layout.ts","../src/pedigree/svg.ts","../src/pedigree/render.ts","../src/phylo/labels.ts","../src/phylo/validate.ts","../src/phylo/layout.ts","../src/phylo/svg.ts","../src/phylo/render.ts","../src/org-chart/types.ts","../src/org-chart/labels.ts","../src/org-chart/validate.ts","../src/org-chart/layout.ts","../src/org-chart/svg.ts","../src/org-chart/render.ts"],"names":["pathData","PADDING","EDGE_INK","round","w","h","GRAPH_BLOCKING","lines","last","GLYPH_STROKE","LABEL_FILL","pts","elementSvg","arrowHead","sortIssues","H_GAP","CORRIDOR","shapeForSex","GLYPH_ATTRS","nodeSvg","MINI_ATTRS","listIds","allocateLanes","ORG_BOX_PAD_Y"],"mappings":"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","file":"index.cjs","sourcesContent":["// XML/SVG escaping — every interpolated text in an emitted SVG MUST pass through\n// this. Diagram labels are typically user/author-controlled, and the SVG string may\n// be injected via innerHTML in a browser or embedded as vectors in a PDF — an\n// unescaped label is an XSS / `</svg>`-breakout vector on every surface at once.\n\n/** Escapes a string for use in SVG/XML text content AND attribute values. */\nexport function xmlEscape(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n","// Roman numeral formatting for level/generation labels (pedigree generation rows\n// I, II, III…; any leveled diagram). Standard subtractive notation, valid for\n// integers 1..3999. A renderer must NEVER crash on a weird generation index, so\n// out-of-range / non-integer inputs fall back to the Arabic number as a string\n// rather than throwing or emitting nonsense like \"MMMM…\". Pure + deterministic.\n\nconst ROMAN_TABLE: ReadonlyArray<readonly [number, string]> = [\n [1000, \"M\"],\n [900, \"CM\"],\n [500, \"D\"],\n [400, \"CD\"],\n [100, \"C\"],\n [90, \"XC\"],\n [50, \"L\"],\n [40, \"XL\"],\n [10, \"X\"],\n [9, \"IX\"],\n [5, \"V\"],\n [4, \"IV\"],\n [1, \"I\"],\n];\n\n/** Uppercase Roman numeral for an integer in 1..3999 (1→\"I\", 4→\"IV\", 1990→\"MCMXC\").\n * Out of range or non-integer → the Arabic number as a string (graceful fallback). */\nexport function romanNumeral(n: number): string {\n if (!Number.isInteger(n) || n < 1 || n > 3999) return String(n);\n let remaining = n;\n let out = \"\";\n for (const [value, symbol] of ROMAN_TABLE) {\n while (remaining >= value) {\n out += symbol;\n remaining -= value;\n }\n }\n return out;\n}\n","// Shared geometry primitives.\n\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** \"M x y L x y …\" path data from a polyline. */\nexport function pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n","// Pure, deterministic text metrics — no DOM, no canvas, no font files. Every layout\n// in this library reserves space from these estimates and every emitter draws with\n// the same constants, so what is proven collision-free is what is drawn.\n\n/**\n * Conservative per-character advance, as a fraction of the font size. The pure module\n * can't measure real glyphs (no DOM/canvas), so it estimates width = chars * font *\n * CHAR_W. It is deliberately a touch WIDER than Helvetica's ~0.5 average advance: a\n * layout reserves slightly more room than the text needs, so the real render always\n * fits inside its reserved box.\n */\nexport const CHAR_W = 0.6;\n\n/** Pure, deterministic width estimate for a single line of text at `fontPx`. */\nexport function estimateTextWidth(text: string, fontPx: number): number {\n return text.length * fontPx * CHAR_W;\n}\n\n/**\n * Wraps a label onto up to `maxLines` lines (default 2) so long labels don't sprawl.\n * Greedy word fill; each line capped at `perLine` chars (…-truncated only if a line\n * still overflows). The LAST allowed line absorbs every remaining word before the cap\n * applies — words are never dropped mid-label, only visibly elided. Pure + shared so\n * every renderer wraps identically. The full text is always kept elsewhere (the\n * node's `label`, an SVG <title>, or a side list), so nothing is silently lost.\n *\n * INVARIANT: with the default `maxLines` the output is byte-identical to the\n * historical two-line implementation (pinned by test/core/text.test.ts) — both\n * shipped renderers wrap through here.\n */\nexport function wrapLabel(label: string, perLine: number, maxLines = 2): string[] {\n if (label.length <= perLine) return [label];\n const cap = (s: string): string =>\n s.length > perLine ? s.slice(0, Math.max(1, perLine - 1)) + \"…\" : s;\n const lines: string[] = [\"\"];\n for (const word of label.split(/\\s+/)) {\n const last = lines.length - 1;\n const current = lines[last]!;\n if (current === \"\" || (current + \" \" + word).length <= perLine) {\n lines[last] = current === \"\" ? word : `${current} ${word}`;\n } else if (lines.length < maxLines) {\n lines.push(word);\n } else {\n lines[last] = `${current} ${word}`;\n }\n }\n // A trailing-whitespace \"word\" (\"a b \".split(/\\s+/) → [\"a\",\"b\",\"\"]) may open a line\n // it never fills; the historical code dropped that empty line, so this does too.\n if (lines.length > 1 && lines[lines.length - 1] === \"\") lines.pop();\n return lines.map(cap);\n}\n\n/**\n * House \"balanced\" wrap policy (extracted verbatim from the ecomap's tie-label wrap,\n * itself mirroring the genogram's): per-line budget `min(26, max(14, ceil(len/2)+2))`\n * splits a medium label into two roughly even lines instead of one long + one short,\n * then the greedy `wrapLabel` fill (and its `maxLines` semantics) applies. The shipped\n * renderers keep their local copies for now — new modules consume this one; migrating\n * them is a separate provably-zero-change refactor.\n */\nexport function wrapLabelBalanced(label: string, maxLines?: number): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(label.length / 2) + 2));\n return wrapLabel(label, perLine, maxLines);\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept by the caller. */\nexport function clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n/** Font stack shared by every emitter; PDF embedders typically map it onto Helvetica. */\nexport const FONT_FAMILY = \"Helvetica, Arial, sans-serif\";\n","// Shared legend machinery — the exact row format the genogram and ecomap emitters\n// currently duplicate character-for-character (`<g data-compasso-legend=\"true\">` with\n// swatch-closure rows). Extracted so new diagram modules don't add a third copy;\n// the two shipped emitters keep their local blocks for now (migrating them is a\n// separate, provably-zero-change refactor — pinned byte-for-byte against the ecomap's\n// emitted legend in test/core/legend.test.ts).\n//\n// The caller stays in charge of the HONESTY RULE half: it decides WHICH entries exist\n// (used-keys-only) and what each swatch draws; this module only owns the row geometry,\n// the text emission (xmlEscape — labels may come from caller-supplied packs), and the\n// width/height bookkeeping both renderers compute identically.\n\nimport { FONT_FAMILY, estimateTextWidth } from \"./text\";\nimport { xmlEscape } from \"./xml\";\n\n// Row metrics shared by every legend in the library. Exported because swatch builders\n// need them (a line swatch spans LEGEND_SWATCH_W; a glyph swatch centers on it).\nexport const LEGEND_ROW_H = 18;\nexport const LEGEND_PAD = 16;\nexport const LEGEND_SWATCH_W = 22;\nexport const LEGEND_GAP = 14;\nexport const LEGEND_FONT = 11;\n\n// Legend text ink — the zinc glyph stroke both shipped emitters use for legend labels.\nconst LEGEND_TEXT_FILL = \"#52525b\";\n\nexport interface LegendEntry {\n /**\n * Swatch markup builder, called with the swatch's left x and the row's center y.\n * The builder owns its own escaping/rounding (it typically reuses the module's\n * glyph/line emitters); it should draw within LEGEND_SWATCH_W of x.\n */\n swatch: (x: number, yCenter: number) => string;\n /** Display label (escaped here; verbatim pack text in, escaped SVG out). */\n label: string;\n}\n\nexport interface LegendBlock {\n /** `<g data-compasso-legend=\"true\">…</g>` — empty string when there are no entries. */\n svg: string;\n /** Minimum canvas width the legend needs; callers take `max(width, block.width)`. */\n width: number;\n /** New total canvas height including the legend; callers assign it directly. */\n height: number;\n}\n\n/**\n * Emits the legend group for the given entries below `startY` (the diagram's current\n * height). Pure + deterministic; coordinates are interpolated exactly as the shipped\n * emitters do. Zero entries (used-keys-only found nothing) → no markup, zero width\n * contribution, height unchanged — safe to call unconditionally.\n */\nexport function legendBlock(entries: readonly LegendEntry[], startY: number): LegendBlock {\n if (entries.length === 0) return { svg: \"\", width: 0, height: startY };\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${LEGEND_TEXT_FILL}\">${xmlEscape(entry.label)}</text>`\n );\n });\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n return {\n svg: `<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`,\n width: LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD,\n height: startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2,\n };\n}\n","// Edge line styles — a neutral, presentation-only style for a relationship line.\n// NOT a judgment: a deterministic, lexical hint derived from the author's own quality\n// word. The literal word always rides the element's <title>, so a style never replaces\n// what was said. Unknown/ambiguous quality → \"plain\".\n\nexport type EdgeLineStyle = \"plain\" | \"close\" | \"distant\" | \"conflict\" | \"cutoff\";\n\n/** Stroke attributes per style — shared by every renderer so SVG and PDF match. */\nexport interface EdgeStroke {\n width: number;\n /** SVG dash array / PDF dash pattern as [dash, gap]; null = solid. */\n dash: [number, number] | null;\n opacity: number;\n}\n\nexport const EDGE_STROKE: Record<EdgeLineStyle, EdgeStroke> = {\n plain: { width: 1.5, dash: null, opacity: 0.6 },\n close: { width: 3, dash: null, opacity: 0.85 },\n distant: { width: 1.5, dash: [4, 4], opacity: 0.55 },\n conflict: { width: 2, dash: [2, 2], opacity: 0.75 },\n cutoff: { width: 1.5, dash: [6, 5], opacity: 0.4 },\n};\n\n/**\n * A pluggable lexicon mapping free-text quality words onto line styles. Needles are\n * diacritic-free, lowercase substrings of the author's own words; `negations` are\n * whole words that flip the meaning of the very word a needle would match (\"not\n * close\"), so their presence makes the matcher abstain to \"plain\" rather than risk\n * an inverted visual. Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface QualityLexicon {\n buckets: readonly { style: Exclude<EdgeLineStyle, \"plain\">; needles: readonly string[] }[];\n negations: readonly string[];\n}\n\n// English default. Conservative stems: each needle is a substring match on the\n// normalized text, and the SINGLE-BUCKET rule below keeps competing signals honest.\n// \"no\" alone is deliberately NOT a negation: \"no contact\" is a genuine cutoff signal.\nexport const QUALITY_LEXICON_EN: QualityLexicon = {\n buckets: [\n {\n style: \"close\",\n needles: [\"close\", \"warm\", \"support\", \"lov\", \"affection\", \"caring\", \"tight\", \"harmon\", \"healthy\"],\n },\n {\n style: \"distant\",\n needles: [\"distant\", \"detach\", \"absent\", \"cold\", \"drift\"],\n },\n {\n style: \"conflict\",\n needles: [\"conflict\", \"fight\", \"tens\", \"difficult\", \"hostil\", \"violen\", \"abus\", \"aggress\", \"complicat\", \"toxic\", \"argu\"],\n },\n {\n style: \"cutoff\",\n needles: [\"estrang\", \"cut off\", \"cutoff\", \"no contact\", \"broken off\", \"sever\"],\n },\n ],\n negations: [\"not\", \"never\", \"no longer\", \"hardly\"],\n};\n\n/** Lowercase + strip diacritics so matching ignores accents. */\nexport function normalizeText(text: string): string {\n return text.normalize(\"NFD\").replace(/[̀-ͯ]/g, \"\").toLowerCase();\n}\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Maps a free-text relationship quality to a neutral line style. Deterministic and\n * conservative: returns a specific style ONLY when exactly one lexical bucket matches;\n * null/empty/ambiguous/negated/unknown all fall back to \"plain\". The caller still\n * keeps the verbatim quality word, so nothing the author said is ever lost.\n */\nexport function qualityLineStyle(\n quality: string | null,\n lexicon: QualityLexicon = QUALITY_LEXICON_EN,\n): EdgeLineStyle {\n if (quality === null) return \"plain\";\n const haystack = normalizeText(quality);\n if (haystack.trim() === \"\") return \"plain\";\n\n if (lexicon.negations.length > 0) {\n const negation = new RegExp(`\\\\b(${lexicon.negations.map(escapeRegExp).join(\"|\")})\\\\b`);\n if (negation.test(haystack)) return \"plain\";\n }\n\n const matched: EdgeLineStyle[] = [];\n for (const { style, needles } of lexicon.buckets) {\n if (needles.some((n) => haystack.includes(n))) matched.push(style);\n }\n return matched.length === 1 ? matched[0]! : \"plain\";\n}\n","// A discreet, NEUTRAL \"this element was annotated by the caller\" marker, shared by every\n// diagram family. compasso never decides what an annotation MEANS — the caller asserts the\n// `annotated` flag from its own domain knowledge and supplies the legend label; the library\n// only draws a standardised mark. Pure presentation: literal SVG primitives, no <defs>, no\n// <marker>, no CSS. The mark is a DECORATION drawn inside an element's existing <g> (like a\n// genogram deceased slash) — never a layout box or routed segment, so it cannot create or\n// hide an overlap. Ink is the shared zinc-600 glyph stroke (#52525b) for cross-family unity.\nimport { LEGEND_SWATCH_W } from \"./legend\";\nimport type { Point } from \"./geometry\";\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport const ANNOTATION_INK = \"#52525b\";\nconst DOT_R = 3;\nconst TICK_HALF = 3;\n\n/**\n * A small filled dot marking an annotated NODE. Pass the point where it should sit — callers\n * place it at the node's upper-right (inset), the conventional \"has a note\" corner.\n */\nexport function annotationDot(cx: number, cy: number): string {\n return `<circle cx=\"${round(cx)}\" cy=\"${round(cy)}\" r=\"${DOT_R}\" fill=\"${ANNOTATION_INK}\" fill-opacity=\"0.6\"/>`;\n}\n\n/**\n * A short tick perpendicular to an annotated EDGE at the midpoint of its middle segment.\n * Org-chart / genogram polylines are axis-aligned, so the perpendicular is trivial; a tick on\n * a near-diagonal falls back to a vertical mark. Returns \"\" for a degenerate (<2-point) path.\n */\nexport function annotationTick(points: readonly Point[]): string {\n if (points.length < 2) return \"\";\n const i = Math.floor((points.length - 1) / 2);\n const a = points[i]!;\n const b = points[i + 1] ?? points[i]!;\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const horizontal = Math.abs(a.y - b.y) <= Math.abs(a.x - b.x);\n const x1 = horizontal ? mx : mx - TICK_HALF;\n const x2 = horizontal ? mx : mx + TICK_HALF;\n const y1 = horizontal ? my - TICK_HALF : my;\n const y2 = horizontal ? my + TICK_HALF : my;\n return `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${ANNOTATION_INK}\" stroke-width=\"1.5\"/>`;\n}\n\n/** Legend swatch for the annotation row: the same dot, centred in the swatch column. */\nexport function annotationSwatch(x: number, yCenter: number): string {\n return annotationDot(x + LEGEND_SWATCH_W / 2, yCenter);\n}\n","// Genogram input model — declared facts only. compasso draws EXACTLY what the caller\n// declares and NEVER synthesizes structure: two declared parents without a declared\n// union never merge into a couple; a \"coparental\" union draws no couple element; a\n// free-text relationship never silently becomes kinship. Collection doctrine (who may\n// assert a fact, how it was captured) is the caller's concern — this is a renderer.\n\n/** Sex marker for a genogram node (standard notation: square/circle/diamond). */\nexport type PersonSex = \"male\" | \"female\" | \"unknown\";\n\n/** A genogram node. `generation` is relative (0 = index person; negative = older). */\nexport interface Person {\n id: number;\n label: string;\n sex: PersonSex;\n deceased: boolean;\n generation: number | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/**\n * CLOSED status vocabulary for a declared union. Notable semantics:\n * - \"coparental\": the two were NEVER a couple and have child(ren) together;\n * - \"unknown\": a union was declared, but its type was not;\n * - widowhood is NOT a status — death lives on Person.deceased and never\n * alters the declared status;\n * - no value for \"not stated\": the union simply is not passed in.\n */\nexport const UNION_STATUSES = [\n \"married\",\n \"cohabiting\",\n \"dating\",\n \"separated\",\n \"divorced\",\n \"coparental\",\n \"unknown\",\n] as const;\n\nexport type UnionStatus = (typeof UNION_STATUSES)[number];\n\n/**\n * A declared couple bond between two people. The pair is unordered and expected\n * normalized to personAId < personBId with ONE union per pair (duplicates are the\n * caller's to resolve). `quality` is the author's verbatim wording about the bond.\n */\nexport interface Union {\n id: number;\n /** Always the smaller person id (normalized pair). */\n personAId: number;\n personBId: number;\n status: UnionStatus;\n quality: string | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/**\n * A declared parentage link: parent → child, one row PER DECLARED genitor (two\n * genitors = two links, each individually stated — never promoted from a union).\n */\nexport interface ParentLink {\n id: number;\n parentId: number;\n childId: number;\n quality: string | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/**\n * A typed free-text edge between two people. `type` and `quality` are verbatim\n * labels. This carries NON-STRUCTURAL ties only (closeness, conflict…) — unions\n * and parentage are first-class above.\n */\nexport interface Relationship {\n id: number;\n fromPersonId: number;\n toPersonId: number;\n type: string;\n quality: string | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/** Input to the genogram render pipeline. */\nexport interface GenogramInput {\n people: Person[];\n unions: Union[];\n parentLinks: ParentLink[];\n relationships: Relationship[];\n}\n\n/** Node glyph shapes (standard notation: square = male, circle = female, diamond = unknown). */\nexport type NodeShape = \"square\" | \"circle\" | \"diamond\";\n","// Display vocabularies — every human-readable string the genogram emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n\nimport type { EdgeLineStyle } from \"../core\";\nimport type { NodeShape, UnionStatus } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface GenogramTitleLabels {\n unionStatus: Record<UnionStatus, string>;\n /** Title prefix for a parent→child descent (\"parent of\"). */\n parentage: string;\n}\n\nexport const GENOGRAM_TITLE_LABELS_EN: GenogramTitleLabels = {\n unionStatus: {\n married: \"married\",\n cohabiting: \"cohabiting\",\n dating: \"dating\",\n separated: \"separated\",\n divorced: \"divorced\",\n coparental: \"co-parents (never a couple)\",\n unknown: \"union (type not stated)\",\n },\n parentage: \"parent of\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface GenogramSvgLabels {\n shapes: Record<NodeShape, string>;\n deceased: string;\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the group of people with no drawn connection. */\n isolated: string;\n ariaLabel: string;\n}\n\nexport const GENOGRAM_SVG_LABELS_EN: GenogramSvgLabels = {\n shapes: {\n square: \"Man\",\n circle: \"Woman\",\n diamond: \"Sex not stated\",\n },\n deceased: \"Deceased\",\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n isolated: \"No recorded ancestry\",\n ariaLabel: \"Family map (genogram)\",\n};\n","// Relationship → MAP class (presentation only). A genogram draws only the structural\n// SKELETON: declared unions + parent links. A free-text `relationship` becomes a map\n// LINE only when it is NON-parentage. Kinship that is READ FROM THE TREE (grandparent/\n// sibling/uncle/cousin/nephew…) draws NOTHING — it is already implied by the descent/\n// union structure, so a dedicated line would only duplicate and clutter. A DIRECT\n// parentage word (mother/father/child) with no declared parent link is PROMOTED to a\n// descent (oriented by declared generation) so the person is not orphaned. NOTHING here\n// synthesizes undeclared structure: derived kinship draws nothing at all, and promotion\n// only ORIENTS an already-declared parent-child word. The verbatim \"type · quality\" of\n// EVERY relationship is the caller's to keep showing in its own lists.\n\nimport { normalizeText } from \"../core\";\n\nexport type RelationshipMapClass = \"derived\" | \"parentage\" | \"bond\";\n\n/**\n * A pluggable kinship vocabulary. Tokens are diacritic-free, lowercase, matched WHOLE\n * (so a token never matches inside another word) after splitting the type on\n * non-alphanumerics (\"half-brother\" → [\"half\",\"brother\"]). Checked DERIVED-first, so\n * \"brother on my father's side\" reads as a sibling, never as a parent. These lists are\n * closed and conservative — an unrecognized word stays a non-structural bond (the\n * honest default). Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface KinshipLexicon {\n /** Kinship read from the tree (sibling/grandparent/uncle/cousin…): never a line. */\n derived: ReadonlySet<string>;\n /** Direct parentage words (mother/father/son…): promotable to a descent. */\n parentage: ReadonlySet<string>;\n /** Parentage words whose FROM endpoint is the CHILD — used only to orient a\n * promotion when declared generations do not decide it. */\n childWords: ReadonlySet<string>;\n}\n\nexport const KINSHIP_EN: KinshipLexicon = {\n derived: new Set([\n \"brother\", \"brothers\", \"sister\", \"sisters\", \"sibling\", \"siblings\",\n \"grandmother\", \"grandfather\", \"grandma\", \"grandpa\", \"granny\", \"grandad\",\n \"granddad\", \"grandparent\", \"grandparents\",\n \"grandson\", \"granddaughter\", \"grandchild\", \"grandchildren\",\n \"uncle\", \"uncles\", \"aunt\", \"aunts\", \"auntie\",\n \"cousin\", \"cousins\",\n \"nephew\", \"nephews\", \"niece\", \"nieces\",\n ]),\n parentage: new Set([\n \"mother\", \"mothers\", \"mom\", \"mum\", \"father\", \"fathers\", \"dad\",\n \"parent\", \"parents\",\n \"son\", \"sons\", \"daughter\", \"daughters\",\n ]),\n childWords: new Set([\"son\", \"sons\", \"daughter\", \"daughters\"]),\n};\n\n/** Lowercase + accent-stripped tokens of a free-text relationship type. */\nexport function relationshipTypeTokens(type: string): string[] {\n return normalizeText(type).split(/[^a-z0-9]+/).filter((t) => t !== \"\");\n}\n\n/**\n * Classifies a free-text relationship `type` for the MAP. Pure + deterministic.\n * Derived kinship is checked first so a compound like \"brother on my father's side\"\n * is read as a sibling (derived), never promoted as a parent. The verbatim word is\n * unaffected — this decides only whether the tie becomes a line, and which kind.\n */\nexport function classifyRelationshipType(\n type: string,\n kinship: KinshipLexicon = KINSHIP_EN,\n): RelationshipMapClass {\n const toks = relationshipTypeTokens(type);\n if (toks.some((t) => kinship.derived.has(t))) return \"derived\";\n if (toks.some((t) => kinship.parentage.has(t))) return \"parentage\";\n return \"bond\";\n}\n","// PURE genogram layout — the single source of truth for positioning and glyph/edge\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so it loads\n// identically in browsers, server runtimes and test environments, and the same input\n// always yields the same layout. Anything with a side effect belongs elsewhere.\n//\n// HONESTY RULE: this module only POSITIONS and ROUTES the facts the caller declared. It\n// computes NO score, interpretation, prognosis or diagnosis, and it NEVER synthesizes\n// undeclared structure: a `coparental` union draws no couple element; two declared\n// parents WITHOUT a declared union never merge into a couple-bar descent (each gets its\n// own descent); free-text `relationships` stay non-structural bonds. Shapes follow the\n// standard genogram convention (square = male, circle = female, diamond = unknown; a\n// diagonal stroke marks deceased). The verbatim \"type · quality\" / status label is\n// ALWAYS kept on every routed element's <title>, so a style never replaces what was said.\n//\n// LAYOUT — orthogonal (McGoldrick) and overlap-proof BY CONSTRUCTION (not by luck). The\n// diagram is a grid: people sit in COLUMNS inside generation ROWS; the empty bands\n// BETWEEN columns (GUTTERS) and BETWEEN rows (CORRIDORS) are the only places routing\n// segments live, each in a numbered LANE allocated by interval-overlap so two segments\n// in the same lane can never overlap. Every consecutive pair of waypoints is axis-aligned\n// (horizontal or vertical) — there are NO diagonals and NO text on map edges (the\n// verbatim text rides the <title> and the caller's side lists). Glyphs and their labels\n// live entirely inside their columns; gutters and corridors are content-free by\n// construction, so a routed segment can never cross a glyph or a label box.\n//\n// PROVENANCE: descends from the production genogram renderer the author wrote for the\n// Ventory project (same copyright holder); developed independently of any third-party\n// diagram engine.\nimport {\n CHAR_W,\n clampLabel,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n wrapLabelBalanced,\n EDGE_STROKE,\n type EdgeLineStyle,\n type EdgeStroke,\n type Point,\n type QualityLexicon,\n} from \"../core\";\nimport { GENOGRAM_TITLE_LABELS_EN, type GenogramTitleLabels } from \"./labels\";\nimport {\n classifyRelationshipType,\n relationshipTypeTokens,\n KINSHIP_EN,\n type KinshipLexicon,\n type RelationshipMapClass,\n} from \"./kinship\";\nimport type {\n NodeShape,\n ParentLink,\n Person,\n PersonSex,\n Relationship,\n Union,\n} from \"./types\";\n\n// Re-exports so callers (and the emitter) can reach the full vocabulary through this\n// module, mirroring the original single-file layout.\nexport { CHAR_W, estimateTextWidth, qualityLineStyle, wrapLabel, EDGE_STROKE };\nexport type { EdgeLineStyle, EdgeStroke, Point, QualityLexicon };\nexport { classifyRelationshipType, relationshipTypeTokens, KINSHIP_EN };\nexport type { KinshipLexicon, RelationshipMapClass };\nexport type { NodeShape };\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\nexport const NODE_SIZE = 56;\nconst PADDING = 32;\n/** Min horizontal gap between two adjacent columns' content boxes (a gutter's base). */\nconst COL_PAD = 30;\n/** Gap from a glyph's bottom to the top of its first label line. */\nconst LABEL_GAP_TOP = 8;\n/** Base height of a routing corridor (before lanes widen it). */\nconst CORRIDOR_BASE = 24;\n/** Vertical/horizontal spacing between two routing lanes in a corridor/gutter. */\nconst LANE_H = 8;\n/** Vertical drop between successive serial-union (remarriage) bars below the glyph row,\n * so 2+ unions on one person never read as one continuous rail (McGoldrick, FIX B). */\nconst UNION_STAGGER = 12;\n/** Horizontal offset (from glyph center, toward the partner) of a dipped union-bar's stub,\n * so a person in two serial unions gets two distinct stub columns (FIX B). < NODE_SIZE/2. */\nconst STUB_X_OFF = 14;\n/** Extra horizontal separation placed before an isolated-people group (SPEC). */\nconst ISOLATED_GUTTER_EXTRA = 2 * COL_PAD;\n\n// ── Type metrics (shared by layout AND both renderers, so geometry == render) ──\n/** Node label font size (px). The live SVG renders at this size; the PDF scales it. */\nexport const LABEL_FONT = 12;\n/** Line height for stacked node-label lines (px). */\nexport const LABEL_LINE_H = 14;\n/** Edge label font size (px) — kept for the shared metrics contract (invariant #9). */\nexport const EDGE_FONT = 11;\n// CHAR_W / estimateTextWidth live in ../core (re-exported above): the overlap-proof\n// guarantee depends on layout and emitters sharing these exact metrics.\n\n// ── Namespaced element ids (kept stable so data-edge-id stays traceable, §7.2) ──\n// relationships keep their own id; unions live at 1_000_000+id; parent links at\n// 2_000_000+id; PROMOTED descents (a direct-parentage free-text relationship drawn as a\n// descent — see classifyRelationshipType) at 3_000_000+rel id. Four disjoint blocks, so a\n// promoted descent never collides with a real parent link and every edge stays traceable\n// to its source. Deterministic, and visible in the overlap harness / data-edge-id.\nexport const UNION_REL_ID_BASE = 1_000_000;\nexport const PARENT_REL_ID_BASE = 2_000_000;\nexport const PROMOTED_REL_ID_BASE = 3_000_000;\n\n// ── Node glyphs ──────────────────────────────────────────────────────────────\nfunction shapeForSex(sex: PersonSex): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Edge line styles ─────────────────────────────────────────────────────────\n// EdgeLineStyle / EDGE_STROKE / qualityLineStyle live in ../core (re-exported above):\n// a neutral, presentation-only style for a NON-STRUCTURAL bond line, lexically hinted\n// from the author's own quality word — never a judgment, verbatim word always kept.\n\n/**\n * Per-edge VISUAL union style applied at emission (§7.2 / FIX 3) — the McGoldrick\n * notation for a declared union TYPE, WITHOUT touching the layout or the patient's\n * words. `coparental` never gets one (it draws no edge). Defined here (not in\n * fallback-svg) so a routed element can carry it and the emitter stays free of layout\n * cycles; fallback-svg re-exports it for the existing call sites.\n */\nexport interface UnionEdgeStyle {\n /** Inline stroke-dasharray [dash, gap] on the bar; absent = solid (e.g. casado). */\n dash?: readonly [number, number];\n /** Diagonal status slashes at the midpoint: 1 = separação, 2 = divórcio. */\n slashes?: 0 | 1 | 2;\n}\n\n// ── Relationship → MAP class ───────────────────────────────────────────────────\n// classifyRelationshipType / relationshipTypeTokens / KinshipLexicon live in ./kinship\n// (re-exported above): derived kinship draws NOTHING, direct parentage may be PROMOTED\n// to a descent, everything else stays a non-structural bond. Node labels wrap through\n// core's `wrapLabelBalanced` (the house balanced policy) and clamp through core's\n// `clampLabel` — both shared with every other emitter, so what is reserved is what is\n// drawn. wrapLabel/wrapLabelBalanced/clampLabel all live in ../core.\n\n// ── Positioned layout ────────────────────────────────────────────────────────\n\nexport interface GenogramNode {\n personId: number;\n /** Full, verbatim label (used for tooltips/aria — never truncated). */\n label: string;\n shape: NodeShape;\n deceased: boolean;\n /** Caller-declared: this node was annotated. Mirrors Person.annotated — never interpreted. */\n annotated: boolean;\n /** Center of the node. */\n cx: number;\n cy: number;\n /** Side length (square) / diameter (circle) / width (diamond). */\n size: number;\n /** Pre-wrapped display lines (already capped for the requested density). */\n labelLines: string[];\n /** Y of the TOP of the first label line's box (each next line is +LABEL_LINE_H). */\n labelTop: number;\n}\n\n/** A routed map element — the orthogonal replacement for the old straight `GenogramEdge`. */\nexport type GenogramElementKind =\n | \"union-bar\" // adjacent same-row partners: straight H bar, glyph-edge to glyph-edge\n | \"union-elbow\" // non-adjacent / cross-row partners: orthogonal route\n | \"descent\" // parent(s) → child plumbing segment(s)\n | \"sibling-bar\" // one shared H bar per union child-group (≥1 children)\n | \"bond\"; // non-structural relationship, orthogonal route\n\nexport interface GenogramElement {\n kind: GenogramElementKind;\n /** Source row ids for traceability; merged bonds carry every merged rel id. */\n relIds: number[];\n /** data-edge-id value: highest relId (matches latestUnionPerPair's highest-wins). */\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n /** Polyline; EVERY consecutive pair is axis-aligned (H or V). */\n points: Point[];\n /** Verbatim titles (one per source row), joined for the <title>. */\n titles: string[];\n lineStyle: EdgeLineStyle; // bonds only; structural elements are \"plain\"\n unionStyle?: UnionEdgeStyle; // union-bar / union-elbow: dash + slashes\n dotted?: boolean; // lone-parent / coparental descents\n /** Caller-declared: this edge was annotated. Propagated from the source input row(s). */\n annotated: boolean;\n}\n\nexport interface GenogramLayout {\n width: number;\n height: number;\n nodes: GenogramNode[];\n elements: GenogramElement[];\n /** People with NO drawn structural/bond connection — grouped to the side and labeled\n * \"Sem ascendência registrada\" so a loose glyph is never left unexplained. */\n isolatedPersonIds: number[];\n}\n\n// ── Internal working types ─────────────────────────────────────────────────────\n\n/**\n * A parent→child descent to draw — either a DECLARED parent_link (real) or a PROMOTED\n * direct-parentage relationship (no declared link existed for the pair). `edgeId` is\n * pre-namespaced (real: PARENT_REL_ID_BASE+link id; promoted: PROMOTED_REL_ID_BASE+rel id),\n * so both flow through the same descent machinery and stay traceable in data-edge-id.\n */\ninterface LayoutLink {\n parentId: number;\n childId: number;\n quality: string | null;\n edgeId: number;\n annotated: boolean;\n}\n\ninterface Measured {\n person: Person;\n lines: string[];\n /** max(NODE_SIZE, widest wrapped line) — the horizontal footprint. */\n contentW: number;\n}\n\n/** A vertical segment living in a gutter, awaiting a lane. */\ninterface GutterReq {\n gutter: number; // gutter index g in [-1, colCount-1]\n side: -1 | 0 | 1; // -1 hug left column, +1 hug right column, 0 center (union spine)\n rowLo: number; // continuous row coordinate (row r → r; corridor k → k+0.5)\n rowHi: number;\n lane: number; // filled by the allocator\n}\n\n/** A horizontal segment living in a corridor, awaiting a lane. Its pixel x-interval is\n * resolved AFTER the column/gutter geometry is fixed, so the lane allocator can use the\n * EXACT extent (a u-index proxy collapses for within-one-gutter spans). */\ninterface CorridorReq {\n corridor: number; // corridor index k in [0, rowCount-1] (k = below row k)\n xRange: () => [number, number]; // pixel [xMin, xMax], resolved post-column-geometry\n lane: number;\n}\n\n/** A sideways glyph departure stub, awaiting a height slot. */\ninterface StubReq {\n personId: number;\n side: -1 | 1;\n slot: number; // height slot index, filled below\n}\n\n/** An arrival into a glyph TOP, awaiting an x-offset slot. */\ninterface ArrivalReq {\n personId: number;\n slot: number;\n}\n\n/** A planned element: its kind/metadata + a builder that resolves to pixel points. */\ninterface PlannedElement {\n kind: GenogramElementKind;\n relIds: number[];\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n titles: string[];\n lineStyle: EdgeLineStyle;\n unionStyle?: UnionEdgeStyle;\n dotted?: boolean;\n annotated: boolean;\n build: () => Point[];\n}\n\n// Height slots for stacked departures from one glyph side (avoid y=cy so a union bar at\n// cy is never crossed). Within ±(NODE_SIZE/2 − 4) so the stub stays on the glyph edge.\nconst STUB_OFFSETS = [9, -9, 18, -18, 26, -26] as const;\n/** Max |x-offset| for an arrival into a glyph TOP (kept inside the top edge half-width). */\nconst ARRIVAL_HALF = NODE_SIZE / 2 - 8;\n\nfunction stubOffset(slot: number): number {\n return STUB_OFFSETS[Math.min(slot, STUB_OFFSETS.length - 1)]!;\n}\n/** Spread arrivals across a glyph TOP so each lands on a distinct x — slot 0 stays\n * CENTERED (the primary descent), later arrivals alternate to either side. For any\n * fan-in count, no two verticals share a column (overlap-proof). */\nfunction arrivalOffset(slot: number, total: number): number {\n if (slot === 0 || total <= 1) return 0;\n const step = Math.min(12, ARRIVAL_HALF / Math.max(1, Math.ceil((total - 1) / 2)));\n const sign = slot % 2 === 1 ? -1 : 1;\n return sign * Math.ceil(slot / 2) * step;\n}\n\n/** Allocate lanes for a set of intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so collinear segments may abut). */\nfunction allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n\n/**\n * Deterministic, overlap-proof ORTHOGONAL layout (pure function of the inputs — same\n * data always yields the same geometry). People are grouped by `generation` (null trails\n * as a bottom row), rows ordered oldest-on-top. Declared structure is drawn as McGoldrick\n * elements: same-row adjacent unions as straight bars, couples-with-children as a shared\n * sibling bar, lone/co-parental genitors as dotted descents, and free-text relationships\n * as orthogonally-routed bonds — NEVER promoting a bond into structure.\n *\n * @param unions caller-deduped (one per pair) declared couple bonds.\n * @param parentLinks declared parent→child links (one row per declared genitor).\n * @param relationships non-structural ties (drawn as bonds).\n * @param opts.maxLabelChars cap each node's DISPLAY label to this many chars (compact\n * preview); the full verbatim text is still exposed on `node.label`.\n * @param opts.kinship / opts.qualityLexicon / opts.titleLabels — locale packs (English\n * defaults; see `compasso/locales/pt-br`).\n */\nexport interface GenogramLayoutOptions {\n maxLabelChars?: number;\n kinship?: KinshipLexicon;\n qualityLexicon?: QualityLexicon;\n titleLabels?: GenogramTitleLabels;\n}\n\nexport function computeGenogramLayout(\n people: Person[],\n unions: Union[],\n parentLinks: ParentLink[],\n relationships: Relationship[],\n opts: GenogramLayoutOptions = {},\n): GenogramLayout {\n const kinship = opts.kinship ?? KINSHIP_EN;\n const titleLabels = opts.titleLabels ?? GENOGRAM_TITLE_LABELS_EN;\n if (people.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], isolatedPersonIds: [] };\n }\n\n const ids = new Set(people.map((p) => p.id));\n const pairKey = (a: number, b: number): string => `${Math.min(a, b)}|${Math.max(a, b)}`;\n const genById = new Map<number, number | null>(people.map((p) => [p.id, p.generation]));\n\n // Sanitize structural inputs (drop self/missing endpoints — keep declared facts only).\n const validUnions = unions\n .filter((u) => ids.has(u.personAId) && ids.has(u.personBId) && u.personAId !== u.personBId)\n .sort((a, b) => a.id - b.id);\n const coupleUnions = validUnions.filter((u) => u.status !== \"coparental\");\n const validLinks = parentLinks\n .filter((l) => ids.has(l.parentId) && ids.has(l.childId) && l.parentId !== l.childId)\n .sort((a, b) => a.id - b.id);\n const validRels = relationships\n .filter((r) => ids.has(r.fromPersonId) && ids.has(r.toPersonId) && r.fromPersonId !== r.toPersonId)\n .sort((a, b) => a.id - b.id);\n\n // ── SKELETON-ONLY (presentation): classify each free-text relationship for the MAP ─────\n // - \"derived\" (avó/irmão/tio/…): READ from the tree → draws NOTHING here.\n // - \"parentage\" (mãe/pai/filho/…): a declared parent-child word → PROMOTED to a descent\n // when no parent_link already declares the pair (else a duplicate, dropped\n // from the map); never a bond.\n // - \"bond\" (everything else): a non-structural tie → drawn as a bond, as before.\n // The verbatim \"type · quality\" of EVERY relationship still rides the dossier side lists.\n const relClass = new Map<number, RelationshipMapClass>(\n validRels.map((r) => [r.id, classifyRelationshipType(r.type, kinship)]),\n );\n const bondRels = validRels.filter((r) => relClass.get(r.id) === \"bond\");\n const parentageRels = validRels.filter((r) => relClass.get(r.id) === \"parentage\");\n\n // Effective descents = declared parent_links (real) + promoted parentage relationships.\n const realLinks: LayoutLink[] = validLinks.map((l) => ({\n parentId: l.parentId,\n childId: l.childId,\n quality: l.quality,\n edgeId: PARENT_REL_ID_BASE + l.id,\n annotated: l.annotated ?? false,\n }));\n const declaredPairs = new Set(validLinks.map((l) => pairKey(l.parentId, l.childId)));\n const promotedByPair = new Map<string, LayoutLink>();\n for (const r of parentageRels) {\n const key = pairKey(r.fromPersonId, r.toPersonId);\n if (declaredPairs.has(key)) continue; // already a declared parent_link → no double-draw\n if (promotedByPair.has(key)) continue; // same pair stated twice → one descent (id-order)\n // Orient parent→child by DECLARED generation (older = parent). When generations do not\n // decide (equal or null), fall back to the parentage WORD + the declared from/to:\n // mãe/pai → from is the parent; filho/filha → from is the child. Either way nothing is\n // invented — both endpoints and the parent-child nature were declared; only the arrow.\n const ga = genById.get(r.fromPersonId) ?? null;\n const gb = genById.get(r.toPersonId) ?? null;\n let parentId: number;\n let childId: number;\n if (ga !== null && gb !== null && ga !== gb) {\n [parentId, childId] = ga < gb ? [r.fromPersonId, r.toPersonId] : [r.toPersonId, r.fromPersonId];\n } else {\n const fromIsChild = relationshipTypeTokens(r.type).some((t) => kinship.childWords.has(t));\n [parentId, childId] = fromIsChild ? [r.toPersonId, r.fromPersonId] : [r.fromPersonId, r.toPersonId];\n }\n if (parentId === childId) continue;\n promotedByPair.set(key, { parentId, childId, quality: r.quality, edgeId: PROMOTED_REL_ID_BASE + r.id, annotated: r.annotated ?? false });\n }\n const allLinks: LayoutLink[] = [...realLinks, ...promotedByPair.values()].sort((a, b) => a.edgeId - b.edgeId);\n\n // Declared (non-coparental) union lookup by unordered pair → union.\n const coupleByPair = new Map<string, Union>();\n for (const u of coupleUnions) coupleByPair.set(pairKey(u.personAId, u.personBId), u);\n\n // Parents per child and links per (parent,child) — real links + promoted descents.\n const parentsOf = new Map<number, number[]>();\n const linkOf = new Map<string, LayoutLink>();\n for (const l of allLinks) {\n const arr = parentsOf.get(l.childId) ?? [];\n if (!arr.includes(l.parentId)) arr.push(l.parentId);\n parentsOf.set(l.childId, arr);\n linkOf.set(`${l.parentId}>${l.childId}`, l);\n }\n\n // A person is ISOLATED when they have NO drawn connection: no union, no descent (real or\n // promoted), and no bond. A relationship suppressed from the map (derived kinship like\n // \"minha tia\", read from the tree) does NOT count as a tie — so such a person is grouped\n // to the side and labeled \"Sem ascendência registrada\", never left as a loose glyph.\n const hasTie = new Set<number>();\n for (const u of validUnions) {\n hasTie.add(u.personAId);\n hasTie.add(u.personBId);\n }\n for (const l of allLinks) {\n hasTie.add(l.parentId);\n hasTie.add(l.childId);\n }\n for (const r of bondRels) {\n hasTie.add(r.fromPersonId);\n hasTie.add(r.toPersonId);\n }\n const isIsolated = (id: number): boolean => !hasTie.has(id);\n\n // ── Pass 1a: rows by declared generation (null last), oldest on top ──────────────\n const byGen = new Map<number | null, Person[]>();\n for (const p of people) {\n const bucket = byGen.get(p.generation);\n if (bucket === undefined) byGen.set(p.generation, [p]);\n else bucket.push(p);\n }\n const genKeys = [...byGen.keys()].sort((a, b) => {\n if (a === null) return 1;\n if (b === null) return -1;\n return a - b;\n });\n const rowCount = genKeys.length;\n const rowOfPerson = new Map<number, number>();\n genKeys.forEach((g, r) => byGen.get(g)!.forEach((p) => rowOfPerson.set(p.id, r)));\n\n // ── Pass 1b: couple BLOCKS per row (connected components of same-row couple unions),\n // linearized so partners land adjacent; then barycenter ordering; isolated rightmost.\n type Block = number[]; // person ids, left-to-right\n const rowBlocks: Block[][] = genKeys.map((g, r) => {\n const members = byGen.get(g)!.map((p) => p.id);\n // adjacency from same-row couple unions\n const adj = new Map<number, number[]>();\n for (const id of members) adj.set(id, []);\n for (const u of coupleUnions) {\n if (rowOfPerson.get(u.personAId) === r && rowOfPerson.get(u.personBId) === r) {\n adj.get(u.personAId)!.push(u.personBId);\n adj.get(u.personBId)!.push(u.personAId);\n }\n }\n for (const id of members) adj.get(id)!.sort((a, b) => a - b);\n // connected components\n const seen = new Set<number>();\n const blocks: Block[] = [];\n for (const start of [...members].sort((a, b) => a - b)) {\n if (seen.has(start)) continue;\n const comp: number[] = [];\n const stack = [start];\n seen.add(start);\n while (stack.length > 0) {\n const n = stack.pop()!;\n comp.push(n);\n for (const m of adj.get(n)!) if (!seen.has(m)) { seen.add(m); stack.push(m); }\n }\n blocks.push(linearizeBlock(comp, adj));\n }\n return blocks;\n });\n\n // Barycenter sweeps (downward then upward), gated on rowCount ≥ 2. Aesthetic only —\n // it reorders blocks to align children under parents; it never moves anyone off a row.\n const flattened = (): Map<number, number> => {\n const pos = new Map<number, number>();\n for (const blocks of rowBlocks) {\n let c = 0;\n for (const b of blocks) for (const id of b) pos.set(id, c++);\n }\n return pos;\n };\n const structuralNeighbors = (id: number): number[] => {\n const out: { id: number; w: number }[] = [];\n // Barycenter ordering uses NON-coparental unions only (SPEC Pass 1 / FIX E): a\n // coparental pair draws no couple bar, so it must exert no ordering attraction either.\n for (const u of coupleUnions) {\n if (u.personAId === id) out.push({ id: u.personBId, w: 1 });\n else if (u.personBId === id) out.push({ id: u.personAId, w: 1 });\n }\n for (const l of allLinks) {\n if (l.childId === id) out.push({ id: l.parentId, w: 1 });\n else if (l.parentId === id) out.push({ id: l.childId, w: 1 });\n }\n for (const rl of bondRels) {\n if (rl.fromPersonId === id) out.push({ id: rl.toPersonId, w: 0.5 });\n else if (rl.toPersonId === id) out.push({ id: rl.fromPersonId, w: 0.5 });\n }\n return out.map((o) => o.id);\n };\n const neighborWeight = (id: number, other: number): number => {\n let w = 0;\n // NON-coparental unions only — same FIX E rationale as structuralNeighbors.\n for (const u of coupleUnions) if ((u.personAId === id && u.personBId === other) || (u.personBId === id && u.personAId === other)) w = Math.max(w, 1);\n for (const l of allLinks) if ((l.childId === id && l.parentId === other) || (l.parentId === id && l.childId === other)) w = Math.max(w, 1);\n for (const rl of bondRels) if ((rl.fromPersonId === id && rl.toPersonId === other) || (rl.toPersonId === id && rl.fromPersonId === other)) w = Math.max(w, 0.5);\n return w;\n };\n const sweep = (r: number, ref: number): void => {\n const pos = flattened();\n const blocks = rowBlocks[r]!;\n const bcOf = (b: Block): number => {\n let sum = 0;\n let wsum = 0;\n for (const id of b) {\n for (const nb of structuralNeighbors(id)) {\n if (rowOfPerson.get(nb) !== ref) continue;\n const w = neighborWeight(id, nb);\n sum += (pos.get(nb) ?? 0) * w;\n wsum += w;\n }\n }\n return wsum === 0 ? Number.POSITIVE_INFINITY : sum / wsum;\n };\n const keyed = blocks.map((b) => ({ b, bc: bcOf(b), minId: Math.min(...b) }));\n keyed.sort((x, y) => (x.bc !== y.bc ? x.bc - y.bc : x.minId - y.minId));\n rowBlocks[r] = keyed.map((k) => k.b);\n };\n if (rowCount >= 2) {\n for (let r = 1; r < rowCount; r++) sweep(r, r - 1);\n for (let r = rowCount - 2; r >= 0; r--) sweep(r, r + 1);\n }\n\n // Isolated people drift fully right: stable-partition each row so isolated singleton\n // blocks trail the connected ones (ordered by id). No connector is ever drawn for them.\n for (let r = 0; r < rowCount; r++) {\n const blocks = rowBlocks[r]!;\n const connected = blocks.filter((b) => !(b.length === 1 && isIsolated(b[0]!)));\n const isolated = blocks.filter((b) => b.length === 1 && isIsolated(b[0]!)).sort((a, b) => a[0]! - b[0]!);\n rowBlocks[r] = [...connected, ...isolated];\n }\n\n // ── Pass 1c: assign (row, col) to every person via the global column grid ─────────\n const colOf = new Map<number, number>();\n let colCount = 0;\n for (let r = 0; r < rowCount; r++) {\n let c = 0;\n for (const b of rowBlocks[r]!) for (const id of b) colOf.set(id, c++);\n colCount = Math.max(colCount, c);\n }\n const colOrThrow = (id: number): number => colOf.get(id)!;\n\n // Column where the isolated-only tail begins (extra gutter sits just before it).\n let isolatedTailCol = colCount; // none by default\n {\n const peopleAtCol: number[][] = Array.from({ length: colCount }, () => []);\n for (const p of people) peopleAtCol[colOrThrow(p.id)]!.push(p.id);\n for (let c = colCount - 1; c >= 1; c--) {\n const all = peopleAtCol[c]!;\n if (all.length > 0 && all.every((id) => isIsolated(id))) isolatedTailCol = c;\n else break;\n }\n }\n\n // ── Pass 2 prep: measure labels; column widths; per-row label heights ─────────────\n const measured = new Map<number, Measured>();\n for (const p of people) {\n const lines = wrapLabelBalanced(clampLabel(p.label, opts.maxLabelChars));\n const contentW = Math.max(NODE_SIZE, lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, LABEL_FONT)), 0));\n measured.set(p.id, { person: p, lines, contentW });\n }\n const colWidth: number[] = Array.from({ length: colCount }, () => NODE_SIZE);\n for (const p of people) {\n const c = colOrThrow(p.id);\n colWidth[c] = Math.max(colWidth[c]!, measured.get(p.id)!.contentW);\n }\n const rowMaxLines: number[] = Array.from({ length: rowCount }, () => 1);\n for (const p of people) {\n const r = rowOfPerson.get(p.id)!;\n rowMaxLines[r] = Math.max(rowMaxLines[r]!, measured.get(p.id)!.lines.length);\n }\n\n // ── Pass 2: route every element symbolically and register lane/slot requests ──────\n const planned: PlannedElement[] = [];\n const gutterReqs: GutterReq[] = [];\n const corridorReqs: CorridorReq[] = [];\n const stubCount = new Map<string, number>(); // `${id}:${side}` → slots used\n const arrivalCount = new Map<number, number>(); // id → arrival slots used\n\n const newStub = (personId: number, side: -1 | 1): StubReq => {\n const key = `${personId}:${side}`;\n const slot = stubCount.get(key) ?? 0;\n stubCount.set(key, slot + 1);\n return { personId, side, slot };\n };\n const newArrival = (personId: number): ArrivalReq => {\n const slot = arrivalCount.get(personId) ?? 0;\n arrivalCount.set(personId, slot + 1);\n return { personId, slot };\n };\n const departSide = (srcId: number, dstId: number): -1 | 1 => {\n const sc = colOrThrow(srcId);\n const dc = colOrThrow(dstId);\n if (dc > sc) return 1;\n if (dc < sc) return -1;\n return sc < colCount - 1 ? 1 : -1;\n };\n // The gutter a connector departs INTO, and which side of it the departing column is on.\n const gutterFor = (srcCol: number, side: -1 | 1): { gutter: number; gSide: -1 | 1 } =>\n side === 1\n ? { gutter: srcCol, gSide: -1 } // depart right → gutter to the right; src is its LEFT column\n : { gutter: srcCol - 1, gSide: 1 }; // depart left → gutter to the left; src is its RIGHT column\n\n // A cross-row connector: sideways stub from the UPPER node, gutter drop, corridor cross,\n // arrival into the LOWER glyph TOP. Returns a builder closure over the resolved geo.\n // Robust to either argument order: it routes from whichever node is in the SHALLOWER\n // (upper) declared generation, so a parent declared in a YOUNGER generation than the\n // child (srcRow > dstRow) still gets a valid, non-negative, in-range corridor and an\n // ordered gutter span instead of a negative index (FIX D-1). Normal upper→lower calls\n // are unchanged: the upper node is the source and corridor = lowerRow − 1 as before.\n const planConnector = (\n srcId: number,\n dstId: number,\n arrivalAtCenter: boolean,\n ): (() => Point[]) => {\n const srcRow = rowOfPerson.get(srcId)!;\n const dstRow = rowOfPerson.get(dstId)!;\n // Departure is always from the upper node; arrival into the lower node's TOP edge.\n const [upperId, lowerId] = srcRow <= dstRow ? [srcId, dstId] : [dstId, srcId];\n const upperRow = rowOfPerson.get(upperId)!;\n const lowerRow = rowOfPerson.get(lowerId)!;\n const side = departSide(upperId, lowerId);\n const { gutter, gSide } = gutterFor(colOrThrow(upperId), side);\n const stub = newStub(upperId, side);\n // Corridor just above the lower row, clamped in-range (degenerate same-row → band 0).\n const corridor = Math.max(0, Math.min(rowCount - 1, lowerRow - 1));\n const gReq: GutterReq = {\n gutter,\n side: gSide,\n rowLo: Math.min(upperRow, corridor + 0.5),\n rowHi: Math.max(upperRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(gReq);\n const arrival = arrivalAtCenter ? null : newArrival(lowerId);\n const arrivalX = (): number =>\n geo.cx(colOrThrow(lowerId)) + (arrival ? arrivalOffset(arrival.slot, arrivalCount.get(lowerId) ?? 1) : 0);\n const cReq: CorridorReq = {\n corridor,\n xRange: () => {\n const gx = geo.gutterLaneX(gReq);\n const ax = arrivalX();\n return [Math.min(gx, ax), Math.max(gx, ax)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const sy = geo.cy(upperRow) + stubOffset(stub.slot);\n const sEdge = side === 1 ? geo.glyphRight(upperId) : geo.glyphLeft(upperId);\n const gx = geo.gutterLaneX(gReq);\n const cyCorr = geo.corridorLaneY(cReq);\n const ax = arrivalX();\n const topY = geo.cy(lowerRow) - NODE_SIZE / 2;\n return [\n { x: sEdge, y: sy },\n { x: gx, y: sy },\n { x: gx, y: cyCorr },\n { x: ax, y: cyCorr },\n { x: ax, y: topY },\n ];\n };\n };\n\n // A same-row connector (U under the row): both endpoints leave sideways toward each\n // other, drop into the corridor below the row, and cross there.\n const planUConnector = (aId: number, bId: number): (() => Point[]) => {\n const row = rowOfPerson.get(aId)!;\n const [leftId, rightId] = colOrThrow(aId) <= colOrThrow(bId) ? [aId, bId] : [bId, aId];\n const stubL = newStub(leftId, 1);\n const stubR = newStub(rightId, -1);\n const gL = gutterFor(colOrThrow(leftId), 1);\n const gR = gutterFor(colOrThrow(rightId), -1);\n const gReqL: GutterReq = { gutter: gL.gutter, side: gL.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n const gReqR: GutterReq = { gutter: gR.gutter, side: gR.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n gutterReqs.push(gReqL, gReqR);\n const cReq: CorridorReq = {\n corridor: row,\n xRange: () => {\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n return [Math.min(xL, xR), Math.max(xL, xR)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const yL = geo.cy(row) + stubOffset(stubL.slot);\n const yR = geo.cy(row) + stubOffset(stubR.slot);\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n const cyCorr = geo.corridorLaneY(cReq);\n return [\n { x: geo.glyphRight(leftId), y: yL },\n { x: xL, y: yL },\n { x: xL, y: cyCorr },\n { x: xR, y: cyCorr },\n { x: xR, y: yR },\n { x: geo.glyphLeft(rightId), y: yR },\n ];\n };\n };\n\n const unionTitle = (u: Union): string =>\n u.quality !== null\n ? `${titleLabels.unionStatus[u.status]} · ${u.quality}`\n : titleLabels.unionStatus[u.status];\n const linkTitle = (l: { quality: string | null }): string =>\n l.quality !== null ? `${titleLabels.parentage} · ${l.quality}` : titleLabels.parentage;\n\n // 2a. Unions: same-row adjacent → bar; otherwise → elbow. (coparental drew nothing.)\n // McGoldrick SERIAL-UNION staggering (FIX B): when a person is in 2+ same-row union-bars\n // (remarriage), the bars would all sit at glyph-center cy and read as ONE continuous\n // rail. So within each connected chain of adjacent bars (components sharing a person),\n // the LOWEST union id stays at cy (level 0) and every other bar DIPS to a distinct depth\n // below the row's glyphs (level k → glyph bottom + k·UNION_STAGGER), drawn as a 3-seg\n // elbow (stub-down from each partner's glyph bottom → across → stub-up). The dip depth\n // is reserved in the row band (`rowDipDepth`) so labels never collide.\n const unionIsBar = new Map<number, boolean>();\n const barUnions = coupleUnions.filter(\n (u) =>\n rowOfPerson.get(u.personAId) === rowOfPerson.get(u.personBId) &&\n Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1,\n );\n // Per row, connected components of adjacent bar-unions (sharing a person), each ordered\n // by union id; index 0 → level 0 (cy), index k → dip level k. Deterministic.\n const unionDipLevel = new Map<number, number>(); // union id → dip level (0 = at cy)\n const rowDipLevels: number[] = Array.from({ length: rowCount }, () => 0);\n {\n const byRow = new Map<number, Union[]>();\n for (const u of barUnions) {\n const r = rowOfPerson.get(u.personAId)!;\n (byRow.get(r) ?? byRow.set(r, []).get(r)!).push(u);\n }\n for (const [r, rowUnions] of byRow) {\n // person → adjacent bar-unions on this row\n const unionsOfPerson = new Map<number, Union[]>();\n for (const u of rowUnions) {\n (unionsOfPerson.get(u.personAId) ?? unionsOfPerson.set(u.personAId, []).get(u.personAId)!).push(u);\n (unionsOfPerson.get(u.personBId) ?? unionsOfPerson.set(u.personBId, []).get(u.personBId)!).push(u);\n }\n const seen = new Set<number>();\n // Stable component discovery: walk unions in ascending id; BFS the shared-person graph.\n for (const start of [...rowUnions].sort((a, b) => a.id - b.id)) {\n if (seen.has(start.id)) continue;\n const comp: Union[] = [];\n const stack = [start];\n seen.add(start.id);\n while (stack.length > 0) {\n const u = stack.pop()!;\n comp.push(u);\n for (const pid of [u.personAId, u.personBId]) {\n for (const nb of unionsOfPerson.get(pid) ?? []) {\n if (!seen.has(nb.id)) {\n seen.add(nb.id);\n stack.push(nb);\n }\n }\n }\n }\n comp.sort((a, b) => a.id - b.id);\n comp.forEach((u, i) => unionDipLevel.set(u.id, i));\n rowDipLevels[r] = Math.max(rowDipLevels[r]!, comp.length - 1);\n }\n }\n }\n\n for (const u of coupleUnions) {\n const aRow = rowOfPerson.get(u.personAId)!;\n const bRow = rowOfPerson.get(u.personBId)!;\n const adjacent =\n aRow === bRow && Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1;\n unionIsBar.set(u.id, adjacent);\n const edgeId = UNION_REL_ID_BASE + u.id;\n if (adjacent) {\n const [leftId, rightId] = colOrThrow(u.personAId) < colOrThrow(u.personBId)\n ? [u.personAId, u.personBId]\n : [u.personBId, u.personAId];\n const dipLevel = unionDipLevel.get(u.id) ?? 0;\n planned.push({\n kind: \"union-bar\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n annotated: u.annotated ?? false,\n build: () => {\n const cy = geo.cy(rowOfPerson.get(leftId)!);\n if (dipLevel === 0) {\n // First bar of the chain: the classic straight bar at glyph-center cy.\n return [\n { x: geo.glyphRight(leftId), y: cy },\n { x: geo.glyphLeft(rightId), y: cy },\n ];\n }\n // Dipped bar: stub-down from each partner's glyph BOTTOM to the dipped Y, across.\n // The stubs leave the glyph bottom OFFSET toward the partner (left partner →\n // right-of-center, right partner → left-of-center), so a person in two serial\n // unions (one on each side) gets two distinct stub columns that never overlap.\n const y = geo.unionDipY(rowOfPerson.get(leftId)!, dipLevel);\n const bottom = cy + NODE_SIZE / 2;\n const lx = geo.cx(colOrThrow(leftId)) + STUB_X_OFF; // partner is to the right\n const rx = geo.cx(colOrThrow(rightId)) - STUB_X_OFF; // partner is to the left\n return [\n { x: lx, y: bottom },\n { x: lx, y },\n { x: rx, y },\n { x: rx, y: bottom },\n ];\n },\n });\n } else {\n const sameRow = aRow === bRow;\n const build = sameRow\n ? planUConnector(u.personAId, u.personBId)\n : (() => {\n const [up, lo] = aRow < bRow ? [u.personAId, u.personBId] : [u.personBId, u.personAId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"union-elbow\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n annotated: u.annotated ?? false,\n build,\n });\n }\n }\n\n // 2b. Descents. Decide, per child, the single declared COUPLE pair (if any) whose\n // union is an adjacent bar; that pair gets the shared sibling-bar descent, every\n // other declared genitor gets a dotted lone descent. No declared couple → all\n // dotted (Caso B / co-parental): each genitor its own descent, never a bar.\n const coupleChildrenByUnion = new Map<number, number[]>(); // union id → children\n const loneLinks: LayoutLink[] = [];\n for (const childId of [...parentsOf.keys()].sort((a, b) => a - b)) {\n const parents = [...parentsOf.get(childId)!].sort((a, b) => a - b);\n const couplePairUnions = parents\n .flatMap((p, i) => parents.slice(i + 1).map((q) => coupleByPair.get(pairKey(p, q))))\n .filter((u): u is Union => u !== undefined && unionIsBar.get(u.id) === true);\n if (couplePairUnions.length === 1) {\n const u = couplePairUnions[0]!;\n const arr = coupleChildrenByUnion.get(u.id) ?? [];\n arr.push(childId);\n coupleChildrenByUnion.set(u.id, arr);\n const couplePeople = new Set([u.personAId, u.personBId]);\n for (const p of parents) if (!couplePeople.has(p)) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n } else {\n for (const p of parents) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n }\n }\n\n // Couple descents (processed first, by union id): one shared sibling-bar per child-row\n // group, a center spine from the bar, and a vertical drop to each child's glyph TOP.\n for (const u of coupleUnions) {\n const children = coupleChildrenByUnion.get(u.id);\n if (children === undefined || children.length === 0) continue;\n const leftId = colOrThrow(u.personAId) < colOrThrow(u.personBId) ? u.personAId : u.personBId;\n const interGutter = colOrThrow(leftId); // gutter between the two adjacent partners\n const parentRow = rowOfPerson.get(u.personAId)!;\n // A couple descent must leave the union BAR, so on a dipped (serial-union) bar the\n // spine starts at the dipped bar's Y, not the glyph-center cy (FIX B).\n const uDipLevel = unionDipLevel.get(u.id) ?? 0;\n const spineStartY = (): number =>\n uDipLevel === 0 ? geo.cy(parentRow) : geo.unionDipY(parentRow, uDipLevel);\n // Group children by their row (almost always one row).\n const byChildRow = new Map<number, number[]>();\n for (const c of children) {\n const cr = rowOfPerson.get(c)!;\n (byChildRow.get(cr) ?? byChildRow.set(cr, []).get(cr)!).push(c);\n }\n for (const childRow of [...byChildRow.keys()].sort((a, b) => a - b)) {\n const groupKids = byChildRow.get(childRow)!.sort((a, b) => colOrThrow(a) - colOrThrow(b));\n // Corridor just above the child row; clamped in-range so a degenerate \"couple + child\n // all on generation 0\" (childRow === 0) routes in band 0 instead of corridor[-1]\n // (undefined) — defensive, no fixture triggers it (FIX D-2).\n const corridor = Math.max(0, Math.min(rowCount - 1, childRow - 1));\n // The descent lives in ONE corridor lane shared by the spine, sibling bar and the\n // child drops, spanning the spine column and every child column.\n const sibSpan = (): number[] => [geo.gutterCenterX(interGutter), ...groupKids.map((c) => geo.cx(colOrThrow(c)))];\n const sibReq: CorridorReq = {\n corridor,\n xRange: () => {\n const xs = sibSpan();\n return [Math.min(...xs), Math.max(...xs)];\n },\n lane: 0,\n };\n corridorReqs.push(sibReq);\n const spineReq: GutterReq = {\n gutter: interGutter,\n side: 0,\n rowLo: Math.min(parentRow, corridor + 0.5), // ordered (FIX D-2): never inverted\n rowHi: Math.max(parentRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(spineReq);\n const aId = (c: number): number => linkOf.get(`${u.personAId}>${c}`)!.edgeId;\n // The A-side element (spine / sibling-bar / single-child elbow) carries the SAME\n // A-side link(s) its relIds/titles track, so its annotation must come from THAT link —\n // hardcoding false silently drops the marker for a child of a couple (B-side drop\n // propagates; A-side did not). Mirrors childDrop's `annotated: link.annotated`.\n const aLinkAnnotated = (c: number): boolean => linkOf.get(`${u.personAId}>${c}`)!.annotated ?? false;\n // A child drop represents ONE declared parentage link (the given parent → c). Its\n // data-edge-id AND its <title> both come from THAT link, so the verbatim parentage\n // (incl. any quality word) matches what the drop's id declares (FIX C-1) — never a\n // hardcoded B-side title under an A-side id.\n const childDrop = (c: number, parentId: number): void => {\n const link = linkOf.get(`${parentId}>${c}`)!;\n const edgeId = link.edgeId;\n const arr = newArrival(c); // couples are processed first → claims the CENTER slot\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: null,\n toPersonId: c,\n titles: [linkTitle(link)],\n lineStyle: \"plain\",\n annotated: link.annotated,\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const x = geo.cx(colOrThrow(c)) + arrivalOffset(arr.slot, arrivalCount.get(c) ?? 1);\n return [\n { x, y },\n { x, y: geo.cy(rowOfPerson.get(c)!) - NODE_SIZE / 2 },\n ];\n },\n });\n };\n\n if (groupKids.length === 1) {\n // Single child: spine + bar-to-child is ONE elbow (parent A's link), the drop is\n // the other (parent B's link) — exactly two data-edge-id groups, one per declared\n // parentage (the verify-sweep 1:1 traceability contract), same pixels as a bar.\n const c = groupKids[0]!;\n planned.push({\n kind: \"descent\",\n relIds: [aId(c)],\n edgeId: aId(c),\n fromPersonId: null,\n toPersonId: null,\n titles: [linkTitle(linkOf.get(`${u.personAId}>${c}`)!)],\n lineStyle: \"plain\",\n annotated: aLinkAnnotated(c),\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const sx = geo.gutterCenterX(interGutter);\n const cx = geo.cx(colOrThrow(c));\n return [\n { x: sx, y: spineStartY() },\n { x: sx, y: sy },\n { x: cx, y: sy },\n ];\n },\n });\n childDrop(c, u.personBId);\n } else {\n // ≥2 children: one shared sibling bar + one spine + a drop per child. Each child's\n // drop carries its B-side parentage id; the sibling bar carries A[0] (and traces\n // every remaining A-side link in relIds), the spine carries A[1] — distinct\n // data-edge-id per group, every declared link present in relIds.\n const aLinks = groupKids.map((c) => aId(c));\n // The verbatim A-side parentage title for child c (incl. any quality word).\n const aLinkTitle = (c: number): string => linkTitle(linkOf.get(`${u.personAId}>${c}`)!);\n planned.push({\n kind: \"sibling-bar\",\n relIds: [aLinks[0]!, ...aLinks.slice(2)],\n edgeId: aLinks[0]!,\n fromPersonId: null,\n toPersonId: null,\n // Carry the verbatim title of EVERY A-side link this bar represents, so no\n // declared quality word is dropped from the drawn element (FIX C-2 / SPEC inv #4).\n titles: [aLinkTitle(groupKids[0]!), ...groupKids.slice(2).map(aLinkTitle)],\n lineStyle: \"plain\",\n annotated: [groupKids[0]!, ...groupKids.slice(2)].some(aLinkAnnotated),\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const xs = sibSpan();\n return [\n { x: Math.min(...xs), y },\n { x: Math.max(...xs), y },\n ];\n },\n });\n planned.push({\n kind: \"descent\",\n relIds: [aLinks[1]!],\n edgeId: aLinks[1]!,\n fromPersonId: null,\n toPersonId: null,\n titles: [aLinkTitle(groupKids[1]!)], // the A-side link this spine carries, verbatim\n lineStyle: \"plain\",\n annotated: aLinkAnnotated(groupKids[1]!),\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const x = geo.gutterCenterX(interGutter);\n return [\n { x, y: spineStartY() },\n { x, y: sy },\n ];\n },\n });\n for (const c of groupKids) childDrop(c, u.personBId);\n }\n }\n }\n\n // Lone / co-parental descents (dotted), by edge id (real before promoted, deterministic).\n for (const l of [...loneLinks].sort((a, b) => a.edgeId - b.edgeId)) {\n const edgeId = l.edgeId;\n const pRow = rowOfPerson.get(l.parentId)!;\n const cRow = rowOfPerson.get(l.childId)!;\n const build = pRow === cRow\n ? planUConnector(l.parentId, l.childId)\n : planConnector(l.parentId, l.childId, false);\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: l.parentId,\n toPersonId: l.childId,\n titles: [linkTitle(l)],\n lineStyle: \"plain\",\n dotted: true,\n annotated: l.annotated,\n build,\n });\n }\n\n // 2c. Bonds (free-text relationships), with the honesty-safe merge: same unordered\n // pair AND same computed lineStyle merge into one drawn element; different styles\n // draw separately (merging would have to pick one side's style).\n const bondGroups = new Map<string, { relIds: number[]; titles: string[]; style: EdgeLineStyle; aId: number; bId: number; annotated: boolean }>();\n for (const r of bondRels) {\n const style = qualityLineStyle(r.quality, opts.qualityLexicon);\n const lo = Math.min(r.fromPersonId, r.toPersonId);\n const hi = Math.max(r.fromPersonId, r.toPersonId);\n const key = `${lo}|${hi}|${style}`;\n const title = r.quality !== null ? `${r.type} · ${r.quality}` : r.type;\n const g = bondGroups.get(key);\n if (g === undefined) {\n bondGroups.set(key, { relIds: [r.id], titles: [title], style, aId: r.fromPersonId, bId: r.toPersonId, annotated: r.annotated ?? false });\n } else {\n g.relIds.push(r.id);\n g.titles.push(title);\n if (r.annotated) g.annotated = true; // any annotated member → whole group annotated\n }\n }\n const bondList = [...bondGroups.values()].sort((a, b) => Math.max(...a.relIds) - Math.max(...b.relIds));\n for (const g of bondList) {\n const aRow = rowOfPerson.get(g.aId)!;\n const bRow = rowOfPerson.get(g.bId)!;\n const build = aRow === bRow\n ? planUConnector(g.aId, g.bId)\n : (() => {\n const [up, lo] = aRow < bRow ? [g.aId, g.bId] : [g.bId, g.aId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"bond\",\n relIds: g.relIds,\n edgeId: Math.max(...g.relIds),\n fromPersonId: g.aId,\n toPersonId: g.bId,\n titles: g.titles,\n lineStyle: g.style,\n annotated: g.annotated,\n build,\n });\n }\n\n // ── Pass 3: staged geometry so corridor lanes are allocated on EXACT pixel x ───────\n // Mutable geometry state, filled stage by stage; the build/xRange closures (created in\n // Pass 2) read it through `geo` at call time only — never before its stage fills it.\n const colCenterX: number[] = [];\n const colLeftX: number[] = [];\n const colRightX: number[] = [];\n const rowCenterY: number[] = [];\n const rowLabelTopY: number[] = [];\n const corridorTopY: number[] = [];\n const dims = { width: 0 };\n const gutterLaneCount = new Map<string, number>(); // `${gutter}:${side}` → count\n const corridorLaneCount: number[] = Array.from({ length: rowCount }, () => 0);\n const laneCount = (gutter: number, side: -1 | 0 | 1): number => gutterLaneCount.get(`${gutter}:${side}`) ?? 0;\n\n const geo = {\n cx: (c: number): number => colCenterX[c]!,\n cy: (r: number): number => rowCenterY[r]!,\n glyphRight: (id: number): number => colCenterX[colOrThrow(id)]! + NODE_SIZE / 2,\n glyphLeft: (id: number): number => colCenterX[colOrThrow(id)]! - NODE_SIZE / 2,\n gutterCenterX: (g: number): number => {\n const left = g < 0 ? PADDING : colRightX[g]!;\n const right = g >= colCount - 1 ? dims.width - PADDING : colLeftX[g + 1]!;\n return (left + right) / 2;\n },\n gutterLaneX: (req: GutterReq): number => {\n const left = req.gutter < 0 ? PADDING : colRightX[req.gutter]!;\n const right = req.gutter >= colCount - 1 ? dims.width - PADDING : colLeftX[req.gutter + 1]!;\n const lCount = laneCount(req.gutter, -1);\n if (req.side === -1) return left + (req.lane + 1) * LANE_H; // hug left, stack rightward\n if (req.side === 0) return left + (lCount + req.lane + 1) * LANE_H; // center group (spine)\n return right - (req.lane + 1) * LANE_H; // hug right, stack leftward\n },\n corridorLaneY: (req: CorridorReq): number =>\n corridorTopY[req.corridor]! + CORRIDOR_BASE / 2 + req.lane * LANE_H,\n /** Y of a dipped serial-union bar (level ≥ 1): below the row's glyph bottom edge. */\n unionDipY: (r: number, level: number): number =>\n rowCenterY[r]! + NODE_SIZE / 2 + level * UNION_STAGGER,\n };\n\n // Stage 1 — gutter lanes: per (gutter, side), by row-span interval. Left-hug and\n // right-hug stacks sit on opposite sides; the center group is the union spine.\n const gutterGroups = new Map<string, GutterReq[]>();\n for (const req of gutterReqs) {\n const k = `${req.gutter}:${req.side}`;\n (gutterGroups.get(k) ?? gutterGroups.set(k, []).get(k)!).push(req);\n }\n for (const [k, reqs] of gutterGroups) {\n gutterLaneCount.set(\n k,\n allocateLanes(reqs.map((req) => ({ lo: req.rowLo, hi: req.rowHi, set: (lane: number) => (req.lane = lane) }))),\n );\n }\n\n // Stage 2 — column geometry from gutter lane counts (+ the isolated extra gutter).\n const gutterWidth = (g: number): number => {\n const lanes = laneCount(g, -1) + laneCount(g, 0) + laneCount(g, 1);\n const extra = g === isolatedTailCol - 1 ? ISOLATED_GUTTER_EXTRA : 0;\n if (g === -1 || g === colCount - 1) return lanes > 0 ? COL_PAD + lanes * LANE_H + extra : extra;\n return COL_PAD + lanes * LANE_H + extra;\n };\n let cursorX = PADDING + gutterWidth(-1);\n for (let c = 0; c < colCount; c++) {\n colLeftX[c] = cursorX;\n colCenterX[c] = cursorX + colWidth[c]! / 2;\n cursorX += colWidth[c]!;\n colRightX[c] = cursorX;\n cursorX += gutterWidth(c);\n }\n dims.width = cursorX + PADDING;\n\n // Stage 3 — corridor lanes on EXACT pixel x-ranges (columns are now placed, so a\n // within-one-gutter span is measured precisely — no collapsing u-index proxy).\n const corridorGroups = new Map<number, CorridorReq[]>();\n for (const req of corridorReqs) (corridorGroups.get(req.corridor) ?? corridorGroups.set(req.corridor, []).get(req.corridor)!).push(req);\n for (const [k, reqs] of corridorGroups) {\n corridorLaneCount[k] = allocateLanes(\n reqs.map((req) => {\n const [lo, hi] = req.xRange();\n return { lo, hi, set: (lane: number) => (req.lane = lane) };\n }),\n );\n }\n\n // Stage 4 — row geometry from corridor lane counts.\n const corridorHeight = (k: number): number => {\n const lanes = corridorLaneCount[k] ?? 0;\n if (lanes > 0) return CORRIDOR_BASE + lanes * LANE_H;\n return k < rowCount - 1 ? CORRIDOR_BASE : 0; // interior rows always keep a gap\n };\n // Reserve a band BELOW each row's glyphs for its dipped serial-union bars (FIX B), so\n // labels sit below the deepest dip and never collide. 0 when the row has no remarriage.\n const rowDipReserve = (r: number): number =>\n rowDipLevels[r]! > 0 ? rowDipLevels[r]! * UNION_STAGGER + 6 : 0;\n let cursorY = PADDING;\n for (let r = 0; r < rowCount; r++) {\n rowCenterY[r] = cursorY + NODE_SIZE / 2;\n rowLabelTopY[r] = cursorY + NODE_SIZE + rowDipReserve(r) + LABEL_GAP_TOP;\n cursorY = rowLabelTopY[r]! + rowMaxLines[r]! * LABEL_LINE_H;\n corridorTopY[r] = cursorY;\n cursorY += corridorHeight(r);\n }\n const width = dims.width;\n const height = cursorY + PADDING;\n\n // ── Build nodes + finalize elements ──────────────────────────────────────────────\n const nodes: GenogramNode[] = [...people]\n .sort((a, b) => a.id - b.id)\n .map((p) => {\n const m = measured.get(p.id)!;\n const r = rowOfPerson.get(p.id)!;\n const c = colOrThrow(p.id);\n return {\n personId: p.id,\n label: p.label,\n shape: shapeForSex(p.sex),\n deceased: p.deceased,\n annotated: p.annotated ?? false,\n cx: colCenterX[c]!,\n cy: rowCenterY[r]!,\n size: NODE_SIZE,\n labelLines: m.lines,\n labelTop: rowLabelTopY[r]!,\n };\n });\n\n const elements: GenogramElement[] = planned.map((pl) => ({\n kind: pl.kind,\n relIds: pl.relIds,\n edgeId: pl.edgeId,\n fromPersonId: pl.fromPersonId,\n toPersonId: pl.toPersonId,\n points: pl.build(),\n titles: pl.titles,\n lineStyle: pl.lineStyle,\n annotated: pl.annotated,\n ...(pl.unionStyle !== undefined ? { unionStyle: pl.unionStyle } : {}),\n ...(pl.dotted ? { dotted: true } : {}),\n }));\n\n // People with no drawn connection (only-suppressed/derived ties, or none at all).\n const isolatedPersonIds = people\n .filter((p) => isIsolated(p.id))\n .map((p) => p.id)\n .sort((a, b) => a - b);\n\n return { width, height, nodes, elements, isolatedPersonIds };\n}\n\n/** Linearize a connected couple-component so partners land adjacent. A simple path is\n * walked from its lowest-id endpoint (→ a clean chain); anything else is DFS-ordered\n * from the lowest id (hub gets two adjacent partners; the rest become union-elbows). */\nfunction linearizeBlock(comp: number[], adj: Map<number, number[]>): number[] {\n if (comp.length <= 1) return [...comp];\n const inComp = new Set(comp);\n const degree = (id: number): number => adj.get(id)!.filter((n) => inComp.has(n)).length;\n const endpoints = comp.filter((id) => degree(id) === 1).sort((a, b) => a - b);\n const edgeCount = comp.reduce((s, id) => s + degree(id), 0) / 2;\n const isPath = edgeCount === comp.length - 1 && endpoints.length === 2;\n const order: number[] = [];\n const seen = new Set<number>();\n if (isPath) {\n let cur: number | undefined = endpoints[0]!;\n while (cur !== undefined) {\n order.push(cur);\n seen.add(cur);\n cur = adj.get(cur)!.filter((n) => inComp.has(n)).sort((a, b) => a - b).find((n) => !seen.has(n));\n }\n return order;\n }\n const stack = [Math.min(...comp)];\n while (stack.length > 0) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n order.push(n);\n for (const m of adj.get(n)!.filter((x) => inComp.has(x)).sort((a, b) => b - a)) {\n if (!seen.has(m)) stack.push(m);\n }\n }\n return order;\n}\n","// Genogram SVG emitter — turns a computed GenogramLayout (./layout.ts, the pure\n// orthogonal declared-generation layout) into a SELF-CONTAINED SVG string.\n//\n// Two hard requirements:\n// - XML-ESCAPING of EVERY interpolated text. Labels are author-controlled and the\n// SVG string may be injected via innerHTML in a browser or embedded as vectors in\n// a PDF — an unescaped label is an XSS/`</svg>`-breakout vector on every surface.\n// - LITERAL presentation attributes (hex colors, inline stroke-dasharray, an explicit\n// font-family). A standalone SVG inside a PDF has no stylesheet, no `currentColor`.\n//\n// It is deliberately PURE (string in, string out) and DETERMINISTIC (same layout → same\n// SVG), and it draws EXACTLY what the layout computed: node centers and the routed\n// orthogonal polylines are consumed verbatim, never recomputed (the overlap harness\n// proves the layout; this emitter is pinned to it). Decoration hooks for callers: one\n// `<g data-individual-id=\"p<id>\">` per person with a direct-child `<title>` and bare\n// rect/circle/polygon glyph; `data-edge-id` on every routed group.\n//\n// HONESTY RULE: presentation only. There is ZERO text on map edges — the verbatim\n// \"type · quality\" / status label lives in each routed group's <title> (and the\n// caller's side lists). The one styling decision the CALLER may make is\n// `unionStyleByRelId`: a per-edge VISUAL override applied at emission — a\n// stroke-dasharray and/or McGoldrick status slashes — giving each declared union TYPE\n// the full notation (married solid, cohabiting/dating dashed, separated one slash,\n// divorced two) without the layout fabricating any quality text.\nimport { FONT_FAMILY, LEGEND_SWATCH_W, annotationDot, annotationSwatch, annotationTick, legendBlock, xmlEscape, type LegendEntry } from \"../core\";\nimport {\n EDGE_STROKE,\n LABEL_FONT,\n LABEL_LINE_H,\n type GenogramElement,\n type GenogramLayout,\n type NodeShape,\n type Point,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { GENOGRAM_SVG_LABELS_EN, type GenogramSvgLabels } from \"./labels\";\n\n// Re-export so callers can reach the union-notation type through the emitter module.\nexport type { UnionEdgeStyle } from \"./layout\";\nexport { xmlEscape };\n\n// Literal ink colors (zinc ramp, matching the app shell on white — the PDF page).\nconst GLYPH_STROKE = \"#52525b\";\nconst NODE_LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Structural (union / descent / sibling-bar) stroke — neutral, solid.\nconst STRUCT_WIDTH = 1.5;\nconst STRUCT_OPACITY = 0.75;\n// Dotted descent (lone-parent / co-parental): the visual kin of schematex's secondary.\nconst DOTTED_DASH: readonly [number, number] = [2, 3];\nconst DOTTED_OPACITY = 0.55;\n\n// Legend row geometry + the used-keys-only block now come from core (`legendBlock`);\n// only the glyph/line swatch closures below stay module-specific (LEGEND_SWATCH_W from\n// core sizes them). The legend ink (#52525b) is the core LEGEND_TEXT_FILL, identical to\n// this emitter's GLYPH_STROKE — so migrating onto core changes zero bytes.\n\nexport interface GenogramSvgOptions {\n /**\n * Per-edge VISUAL union style (edgeId → {dash?, slashes?}), applied at emission.\n * Gives each declared union TYPE its own McGoldrick notation. Overrides any\n * `unionStyle` already on the element.\n */\n unionStyleByRelId?: ReadonlyMap<number, UnionEdgeStyle>;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: GenogramSvgLabels;\n /**\n * Legend label for annotated elements. When provided AND at least one element or node is\n * annotated, a legend row is added (used-keys-only). The library supplies no default —\n * the caller owns the wording (domain-agnostic).\n */\n annotationLabel?: string;\n}\n\n/** Glyph markup for one shape centered at (cx, cy) with the given half-size. */\nfunction glyphSvg(shape: NodeShape, cx: number, cy: number, half: number): string {\n const stroke = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n if (shape === \"square\") {\n return `<rect x=\"${cx - half}\" y=\"${cy - half}\" width=\"${half * 2}\" height=\"${half * 2}\" rx=\"4\" ${stroke}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${stroke}/>`;\n }\n return `<polygon points=\"${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}\" ${stroke}/>`;\n}\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\n/** The longest horizontal segment of a polyline (for placing union-elbow slashes). */\nfunction longestHSegment(points: Point[]): [Point, Point] {\n let best: [Point, Point] = [points[0]!, points[points.length - 1]!];\n let bestLen = -1;\n for (let i = 0; i + 1 < points.length; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n if (a.y === b.y) {\n const len = Math.abs(b.x - a.x);\n if (len > bestLen) {\n bestLen = len;\n best = [a, b];\n }\n }\n }\n return best;\n}\n\n/**\n * McGoldrick status slashes at the midpoint of a segment (1 = separação, 2 = divórcio),\n * drawn in screen-space \"/\" orientation and offset along the segment for the two divorce\n * strokes. Same ink/width as the bar so the mark reads as part of it.\n */\nfunction slashMarks(a: Point, b: Point, count: 1 | 2, width: number): string {\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n const HALF = 7; // slash half-length\n const STEP = 4; // along-segment offset between the two divorce slashes\n const offsets = count === 1 ? [0] : [-STEP, STEP];\n return offsets\n .map((o) => {\n const px = mx + ux * o;\n const py = my + uy * o;\n return `<line x1=\"${px - HALF}\" y1=\"${py + HALF}\" x2=\"${px + HALF}\" y2=\"${py - HALF}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\"/>`;\n })\n .join(\"\");\n}\n\n/** Resolve a union element's effective McGoldrick style (override wins over element). */\nfunction resolveUnionStyle(\n el: GenogramElement,\n override: ReadonlyMap<number, UnionEdgeStyle>,\n): UnionEdgeStyle {\n return override.get(el.edgeId) ?? el.unionStyle ?? {};\n}\n\n/** Emits one routed element as a `<g data-edge-id>` group (≥3 points → path, else line),\n * with the verbatim titles in a <title> and ZERO text. */\nfunction elementSvg(el: GenogramElement, override: ReadonlyMap<number, UnionEdgeStyle>): string {\n const title = `<title>${xmlEscape(el.titles.join(\"\\n\"))}</title>`;\n const pts = el.points;\n const drawLine = (dash: readonly [number, number] | null, width: number, opacity: number): string => {\n const dashAttr = dash === null ? \"\" : ` stroke-dasharray=\"${dash[0]} ${dash[1]}\"`;\n if (pts.length === 2) {\n return `<line x1=\"${pts[0]!.x}\" y1=\"${pts[0]!.y}\" x2=\"${pts[1]!.x}\" y2=\"${pts[1]!.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n }\n return `<path d=\"${pathData(pts)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n };\n\n const tick = el.annotated ? annotationTick(el.points) : \"\";\n\n if (el.kind === \"union-bar\" || el.kind === \"union-elbow\") {\n const style = resolveUnionStyle(el, override);\n const body: string[] = [drawLine(style.dash ?? null, STRUCT_WIDTH, STRUCT_OPACITY)];\n const slashes = style.slashes ?? 0;\n if (slashes === 1 || slashes === 2) {\n // A straight 2-point bar uses its own segment; a dipped serial-union bar (3-seg\n // elbow, FIX B) and any union-elbow ride the LONGEST horizontal segment so the\n // separado/divorciado slashes land on the across part, never on a vertical stub.\n const [a, b] = pts.length === 2 ? [pts[0]!, pts[1]!] : longestHSegment(pts);\n body.push(slashMarks(a, b, slashes, STRUCT_WIDTH));\n }\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body.join(\"\")}${tick}</g>`;\n }\n\n if (el.kind === \"descent\" || el.kind === \"sibling-bar\") {\n const dash = el.dotted ? DOTTED_DASH : null;\n const opacity = el.dotted ? DOTTED_OPACITY : STRUCT_OPACITY;\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(dash, STRUCT_WIDTH, opacity)}${tick}</g>`;\n }\n\n // bond\n const ink = EDGE_STROKE[el.lineStyle];\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(ink.dash, ink.width, ink.opacity)}${tick}</g>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed genogram layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal; there is NO text on map edges.\n */\nexport function genogramLayoutSvg(layout: GenogramLayout, opts: GenogramSvgOptions = {}): string {\n const override = opts.unionStyleByRelId ?? new Map<number, UnionEdgeStyle>();\n const labels = opts.labels ?? GENOGRAM_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // ── Routed elements first so nodes sit on top (same stacking as the JSX render). ───\n for (const el of layout.elements) parts.push(elementSvg(el, override));\n\n // ── Nodes: glyph + deceased mark + wrapped label, hook-compatible with schematex. ─\n for (const node of layout.nodes) {\n const half = node.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(node.label)}</title>`,\n glyphSvg(node.shape, node.cx, node.cy, half),\n ];\n if (node.deceased) {\n pieces.push(\n `<line x1=\"${node.cx - half}\" y1=\"${node.cy - half}\" x2=\"${node.cx + half}\" y2=\"${node.cy + half}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n );\n }\n if (node.annotated) {\n pieces.push(annotationDot(node.cx + 0.7 * half, node.cy - 0.7 * half));\n }\n const tspans = node.labelLines\n .map(\n (line, i) =>\n `<tspan x=\"${node.cx}\" y=\"${node.labelTop + 10 + i * LABEL_LINE_H}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${LABEL_FONT}\" fill=\"${NODE_LABEL_FILL}\">${tspans}</text>`,\n );\n parts.push(`<g data-individual-id=\"p${node.personId}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal pt-BR legend: only entries actually used. ──────────────────────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: LegendEntry[] = [];\n\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({\n swatch: (x, y) => glyphSvg(shape, x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.shapes[shape],\n });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({\n swatch: (x, y) =>\n glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6) +\n `<line x1=\"${x + LEGEND_SWATCH_W / 2 - 6}\" y1=\"${y - 6}\" x2=\"${x + LEGEND_SWATCH_W / 2 + 6}\" y2=\"${y + 6}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n label: labels.deceased,\n });\n }\n\n // NOTE (deliberate, gate-tested): the fallback legend carries NO union-TYPE or\n // dotted-descent entry. Each declared union's type and each co-parenthood fact lives\n // VERBATIM in the element's <title> and in the dossier's structured side lists (the\n // psychologist's authoritative reading) — duplicating it as a legend key is the\n // \"known, documented gap\" pinned by test/verify-pdf.test.ts §(e). The dash/slash\n // notation itself stays on the drawn bars; only the legend stays minimal.\n\n // Bond styles actually used.\n const stylesUsed = new Set(layout.elements.filter((e) => e.kind === \"bond\").map((e) => e.lineStyle));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n\n // Unconnected glyphs (a person whose only declared tie is derived kinship like \"minha\n // tia\" — read from the tree, never a line — or who was mentioned with no tie at all)\n // sit grouped to the side with NO connector. This entry labels that group so a loose\n // glyph is never left unexplained; the verbatim tie still lives in the dossier list.\n if (layout.isolatedPersonIds.length > 0) {\n entries.push({\n swatch: (x, y) => glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.isolated,\n });\n }\n\n // Annotation marker — only when the caller supplied a label AND at least one element/node is annotated.\n if (\n opts.annotationLabel !== undefined &&\n (layout.nodes.some((n) => n.annotated) || layout.elements.some((e) => e.annotated))\n ) {\n entries.push({\n swatch: (x, y) => annotationSwatch(x, y),\n label: opts.annotationLabel,\n });\n }\n\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call genogram render: input → self-contained SVG string. Thin, honest wiring:\n// dedupe unions per pair, compute the pure layout, give each declared union TYPE its\n// McGoldrick notation as a per-edge visual override, emit. Callers needing finer\n// control use computeGenogramLayout + genogramLayoutSvg directly.\n\nimport {\n UNION_REL_ID_BASE,\n computeGenogramLayout,\n type GenogramLayout,\n type GenogramLayoutOptions,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { genogramLayoutSvg } from \"./svg\";\nimport type { GenogramSvgLabels } from \"./labels\";\nimport type { GenogramInput, Union, UnionStatus } from \"./types\";\n\n/** Shared 6,4 dash for every cohabiting-flavoured union (cohabiting / dating /\n * type-not-stated), so non-marital couples read consistently. */\nconst COUPLE_DASH = [6, 4] as const;\n\n/**\n * McGoldrick notation per declared union TYPE — a per-edge VISUAL override applied at\n * emission, never a synthesized quality. `coparental` is ABSENT on purpose: it draws\n * NO couple element at all; the co-parenthood shows only on the descents converging\n * on the child(ren).\n */\nexport const UNION_NOTATION: Record<Exclude<UnionStatus, \"coparental\">, UnionEdgeStyle> = {\n married: {}, // solid bar\n cohabiting: { dash: COUPLE_DASH },\n dating: { dash: COUPLE_DASH },\n unknown: { dash: COUPLE_DASH },\n separated: { slashes: 1 }, // solid + one diagonal slash\n divorced: { slashes: 2 }, // solid + two parallel slashes\n};\n\n/**\n * Duplicate unions for the same unordered pair should not exist (callers are expected\n * to normalize), but if they do, the HIGHEST id wins — the most recent statement.\n * NEVER a status-rank heuristic: recency is a fact, ranking would be an interpretation.\n */\nexport function latestUnionPerPair(unions: Union[]): Union[] {\n const byPair = new Map<string, Union>();\n for (const u of [...unions].sort((a, b) => a.id - b.id)) {\n const key = `${Math.min(u.personAId, u.personBId)}|${Math.max(u.personAId, u.personBId)}`;\n byPair.set(key, u);\n }\n return [...byPair.values()].sort((a, b) => a.id - b.id);\n}\n\nexport interface GenogramRenderOptions extends GenogramLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: GenogramSvgLabels;\n /**\n * Verbatim legend label for caller-declared `annotated` people/unions/parentage/bonds.\n * When set AND something is annotated, a legend row with the marker glyph + this label is\n * added. compasso never supplies a default — the caller owns the wording (domain-specific).\n */\n annotationLabel?: string;\n}\n\nexport interface GenogramRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: GenogramLayout;\n}\n\n/**\n * Renders a genogram input to a self-contained SVG string. Deterministic: same data →\n * same SVG. Empty `people` yields an empty-but-valid SVG; callers decide their own\n * empty state before calling.\n */\nexport function genogramSvg(\n input: GenogramInput,\n opts: GenogramRenderOptions = {},\n): GenogramRenderResult {\n const ids = new Set(input.people.map((p) => p.id));\n const dedupedUnions = latestUnionPerPair(input.unions).filter(\n (u) => ids.has(u.personAId) && ids.has(u.personBId),\n );\n\n const layout = computeGenogramLayout(\n input.people,\n dedupedUnions,\n input.parentLinks,\n input.relationships,\n opts,\n );\n\n const unionStyleByRelId = new Map<number, UnionEdgeStyle>();\n for (const u of dedupedUnions) {\n if (u.status === \"coparental\") continue; // no element — nothing to style\n unionStyleByRelId.set(UNION_REL_ID_BASE + u.id, UNION_NOTATION[u.status]);\n }\n\n const svg = genogramLayoutSvg(layout, {\n unionStyleByRelId,\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n ...(opts.annotationLabel !== undefined ? { annotationLabel: opts.annotationLabel } : {}),\n });\n return { svg, layout };\n}\n","// Radial ecomap renderer — center node + declared external ties on 1–2 concentric\n// rings, as a SELF-CONTAINED SVG string. Pure (data in, string out), deterministic\n// (same input → same SVG), no DOM, no dependencies.\n//\n// HONESTY RULE: the diagram presents ONLY what the caller declared. A tie's line style\n// is a conservative lexical hint from the author's own quality word (ambiguous/null →\n// neutral solid line, never a synthesized value); an arrowhead appears ONLY when a\n// direction was declared (null = no arrow, never a default). The verbatim text always\n// rides the element's <title>, so a style never replaces what was said.\n//\n// Ring assignment is a deterministic PRESENTATION rule — by input order (sorted by id),\n// alternating rings when the set is large — never by any reading of the tie's content.\n//\n// Every interpolated text passes xmlEscape (labels are author-controlled; the SVG may\n// be inlined via innerHTML or embedded in a PDF). All presentation attributes are\n// literal: a standalone SVG has no stylesheet. Arrowheads are explicit polygons, NOT\n// <marker> defs — marker support is unreliable in SVG-to-PDF embedders, and inline\n// polygons also avoid def-id collisions when several SVGs share one document.\n\nimport {\n EDGE_STROKE,\n FONT_FAMILY,\n LEGEND_SWATCH_W,\n annotationDot,\n annotationSwatch,\n clampLabel,\n estimateTextWidth,\n legendBlock,\n qualityLineStyle,\n wrapLabelBalanced,\n xmlEscape,\n type EdgeLineStyle,\n type LegendEntry,\n type QualityLexicon,\n} from \"../core\";\n\n// ── Input model ───────────────────────────────────────────────────────────────\n\n/** Declared flow of the tie, relative to the CENTER: \"in\" = toward the center. */\nexport type EcomapDirection = \"in\" | \"out\" | \"both\";\n\n/**\n * One declared tie between the center (person/household) and an external system\n * (work, faith, friends, healthcare…). `label` is the author's own naming, kept\n * verbatim. `quality` is the author's verbatim wording about the tie (null = not\n * declared = neutral line). `direction` follows the same doctrine: null = no arrow.\n */\nexport interface EcomapTie {\n id: number;\n label: string;\n quality: string | null;\n direction: EcomapDirection | null;\n /** Optional verbatim <title> override (defaults to \"label · quality\"). */\n title?: string;\n /**\n * Caller-asserted flag: this tie was annotated (e.g. edited by a professional).\n * compasso never interprets this — it only draws a neutral marker and, when\n * `annotationLabel` is supplied, adds a legend row. Default undefined = not annotated.\n */\n annotated?: boolean;\n}\n\nexport interface EcomapInput {\n /** Center node label (e.g. the person or household the map is about). */\n centerLabel: string;\n ties: EcomapTie[];\n}\n\n// ── Display vocabulary ────────────────────────────────────────────────────────\n\nexport interface EcomapLabels {\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the neutral solid line (a declared tie with no styled quality). */\n neutralTie: string;\n /** Legend label for the arrowhead (declared direction of the tie). */\n direction: string;\n ariaLabel: string;\n}\n\nexport const ECOMAP_LABELS_EN: EcomapLabels = {\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n neutralTie: \"Declared tie\",\n direction: \"Declared direction of the tie\",\n ariaLabel: \"Ecomap\",\n};\n\nexport interface EcomapSvgOptions {\n /** Display clamp per tie label (verbatim text stays in the <title>). */\n maxLabelChars?: number;\n /** Node label font size (px); default 12. */\n fontSize?: number;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Quality-word lexicon — English default; see `compasso/locales/pt-br`. */\n qualityLexicon?: QualityLexicon;\n /** Display vocabulary — English default; see locale packs. */\n labels?: EcomapLabels;\n /**\n * When provided AND at least one tie has `annotated: true`, a legend row is added\n * with this label (used-keys-only pattern). compasso supplies no default — the caller\n * owns the wording (domain-agnostic).\n */\n annotationLabel?: string;\n}\n\n// ── Geometry constants ────────────────────────────────────────────────────────\n\nconst PADDING = 32;\nconst LINE_H = 14;\nconst NODE_PAD_X = 14;\nconst NODE_PAD_Y = 9;\nconst CENTER_MIN_R = 36;\nconst RING_MIN_R = 150;\n/** Min gap between two adjacent node boxes on the same ring. */\nconst NODE_GAP = 24;\n/** Radial gap between the center circle and the inner ring's nearest box edge. */\nconst RADIAL_GAP = 40;\n/** Radial gap between the two rings when the set is large enough to split. */\nconst RING_GAP = 26;\n/** Above this many ties the layout alternates between two rings. */\nconst SINGLE_RING_MAX = 8;\n\n// Ink (zinc ramp on white — matches the genogram emitter).\nconst NODE_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n// Legend row geometry + the swatch span both live in ../core (LEGEND_SWATCH_W imported\n// above for the swatch closures); the row/text/width/height bookkeeping is legendBlock.\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Internal shapes ───────────────────────────────────────────────────────────\n\ninterface SatNode {\n tie: EcomapTie;\n lines: string[];\n rx: number;\n ry: number;\n /** Filled once ring radii are known. */\n x: number;\n y: number;\n angle: number;\n style: EdgeLineStyle;\n}\n\n/** Arrowhead polygon: tip at (tipX,tipY), pointing along the unit vector (ux,uy). */\nfunction arrowHead(tipX: number, tipY: number, ux: number, uy: number, opacity: number): string {\n const LEN = 9;\n const HALF_W = 4.5;\n const bx = tipX - ux * LEN;\n const by = tipY - uy * LEN;\n const px = -uy;\n const py = ux;\n const points = [\n `${round(tipX)},${round(tipY)}`,\n `${round(bx + px * HALF_W)},${round(by + py * HALF_W)}`,\n `${round(bx - px * HALF_W)},${round(by - py * HALF_W)}`,\n ].join(\" \");\n return `<polygon points=\"${points}\" fill=\"${EDGE_INK}\" fill-opacity=\"${opacity}\"/>`;\n}\n\n/**\n * Renders a declared ecomap to a self-contained SVG string. Deterministic: same data →\n * same SVG. Zero ties yield a valid center-only SVG; callers decide their own empty\n * state before calling. The root keeps numeric width/height attributes plus a matching\n * viewBox (PDF-embedder contract).\n */\nexport function ecomapSvg(input: EcomapInput, opts: EcomapSvgOptions = {}): string {\n const fontSize = opts.fontSize ?? 12;\n const labels = opts.labels ?? ECOMAP_LABELS_EN;\n\n // ── Measure every satellite box (deterministic order: by tie id). ───────────\n const sats: SatNode[] = [...input.ties]\n .sort((a, b) => a.id - b.id)\n .map((tie) => {\n const lines = wrapLabelBalanced(clampLabel(tie.label, opts.maxLabelChars));\n const w = Math.max(...lines.map((l) => estimateTextWidth(l, fontSize))) + NODE_PAD_X * 2;\n const h = lines.length * LINE_H + NODE_PAD_Y * 2;\n return {\n tie,\n lines,\n rx: Math.max(40, w / 2),\n ry: Math.max(20, h / 2),\n x: 0,\n y: 0,\n angle: 0,\n style: qualityLineStyle(tie.quality, opts.qualityLexicon),\n };\n });\n\n const centerLines = wrapLabelBalanced(input.centerLabel);\n const centerR = Math.max(\n CENTER_MIN_R,\n Math.max(...centerLines.map((l) => estimateTextWidth(l, fontSize))) / 2 + 12,\n (centerLines.length * LINE_H) / 2 + 12,\n );\n\n // ── Ring radii: wide enough that NO two node boxes can ever touch. The safe\n // center-to-center distance is the diagonal of the worst-case box pair: if the\n // euclidean distance is ≥ hypot(width-sum, height-sum), the axis-aligned boxes\n // cannot overlap in both axes at once. Overlap-proof by construction, not by luck.\n const n = sats.length;\n const maxRx = n > 0 ? Math.max(...sats.map((s) => s.rx)) : 0;\n const maxRy = n > 0 ? Math.max(...sats.map((s) => s.ry)) : 0;\n const twoRings = n > SINGLE_RING_MAX;\n const stepAngle = n > 0 ? (Math.PI * 2) / n : Math.PI;\n const safeDist = Math.hypot(2 * maxRx + NODE_GAP, 2 * maxRy + NODE_GAP);\n /** Min radius so two nodes `steps` angular steps apart on the SAME ring clear safeDist. */\n const sameRingRadius = (steps: number): number => {\n const theta = steps * stepAngle;\n if (n <= 1 || theta >= Math.PI) return 0; // ≤2 nodes on the ring: no chord constraint\n return safeDist / (2 * Math.sin(theta / 2));\n };\n const ringStep = maxRy * 2 + RING_GAP;\n let innerR = Math.max(\n RING_MIN_R,\n centerR + RADIAL_GAP + maxRy,\n sameRingRadius(twoRings ? 2 : 1),\n );\n if (twoRings) {\n // Cross-ring neighbors sit 1 step apart at radii r and r+ringStep. Their distance\n // sqrt(r² + (r+s)² − 2r(r+s)cosΔ) grows monotonically with r — widen the inner ring\n // in fixed increments until it clears safeDist (deterministic, always terminates).\n const crossDist = (r: number): number =>\n Math.sqrt(r * r + (r + ringStep) ** 2 - 2 * r * (r + ringStep) * Math.cos(stepAngle));\n while (crossDist(innerR) < safeDist) innerR += 8;\n }\n const outerR = innerR + ringStep;\n\n for (let i = 0; i < n; i++) {\n const s = sats[i]!;\n s.angle = -Math.PI / 2 + (i * Math.PI * 2) / n;\n const r = twoRings && i % 2 === 1 ? outerR : innerR;\n s.x = r * Math.cos(s.angle);\n s.y = r * Math.sin(s.angle);\n }\n\n // ── Canvas bounds (center at origin until here), then shift positive. ───────\n let minX = -centerR;\n let minY = -centerR;\n let maxX = centerR;\n let maxY = centerR;\n for (const s of sats) {\n minX = Math.min(minX, s.x - s.rx);\n minY = Math.min(minY, s.y - s.ry);\n maxX = Math.max(maxX, s.x + s.rx);\n maxY = Math.max(maxY, s.y + s.ry);\n }\n const dx = PADDING - minX;\n const dy = PADDING - minY;\n const cx = dx;\n const cy = dy;\n for (const s of sats) {\n s.x += dx;\n s.y += dy;\n }\n let width = maxX - minX + PADDING * 2;\n let height = maxY - minY + PADDING * 2;\n\n const parts: string[] = [];\n\n // ── Tie lines first (nodes sit on top), one group per declared tie. ─────────\n for (const s of sats) {\n const ux = (cx - s.x) / Math.hypot(cx - s.x, cy - s.y);\n const uy = (cy - s.y) / Math.hypot(cx - s.x, cy - s.y);\n // Node-edge endpoint: ellipse boundary along the unit vector toward the center.\n const scale = 1 / Math.hypot(ux / s.rx, uy / s.ry);\n const x1 = s.x + ux * scale;\n const y1 = s.y + uy * scale;\n // Center-edge endpoint: circle boundary along the same direction.\n const x2 = cx - ux * centerR;\n const y2 = cy - uy * centerR;\n\n const ink = EDGE_STROKE[s.style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n const title = s.tie.title ?? (s.tie.quality !== null ? `${s.tie.label} · ${s.tie.quality}` : s.tie.label);\n const body: string[] = [\n `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n ];\n // Arrowheads ONLY for a declared direction. \"in\" points at the center, \"out\" at\n // the external system, \"both\" draws both. Tips back off the boundary so the\n // triangle never pokes into the shape.\n if (s.tie.direction === \"in\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x2, y2, ux, uy, ink.opacity)); // tip at the center edge\n }\n if (s.tie.direction === \"out\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x1, y1, -ux, -uy, ink.opacity)); // tip at the system edge\n }\n parts.push(`<g data-edge-id=\"${s.tie.id}\"><title>${xmlEscape(title)}</title>${body.join(\"\")}</g>`);\n }\n\n // ── Center node. ─────────────────────────────────────────────────────────────\n {\n const tspans = centerLines\n .map(\n (line, i) =>\n `<tspan x=\"${round(cx)}\" y=\"${round(cy - ((centerLines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n parts.push(\n `<g data-individual-id=\"center\"><title>${xmlEscape(input.centerLabel)}</title>` +\n `<circle cx=\"${round(cx)}\" cy=\"${round(cy)}\" r=\"${round(centerR)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"2\"/>` +\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text></g>`,\n );\n }\n\n // ── Satellite nodes. ─────────────────────────────────────────────────────────\n for (const s of sats) {\n const tspans = s.lines\n .map(\n (line, i) =>\n `<tspan x=\"${round(s.x)}\" y=\"${round(s.y - ((s.lines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n const pieces: string[] = [\n `<title>${xmlEscape(s.tie.label)}</title>`,\n `<ellipse cx=\"${round(s.x)}\" cy=\"${round(s.y)}\" rx=\"${round(s.rx)}\" ry=\"${round(s.ry)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"1.5\"/>`,\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text>`,\n ];\n if (s.tie.annotated) {\n pieces.push(annotationDot(s.x + 0.7 * s.rx, s.y - 0.7 * s.ry));\n }\n parts.push(`<g data-individual-id=\"e${s.tie.id}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal legend: only entries actually used. ──────────────────────────────\n if (opts.legend !== false && sats.length > 0) {\n const entries: LegendEntry[] = [];\n\n if (sats.some((s) => s.style === \"plain\")) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${EDGE_STROKE.plain.width}\" stroke-opacity=\"${EDGE_STROKE.plain.opacity}\"/>`,\n label: labels.neutralTie,\n });\n }\n const stylesUsed = new Set(sats.map((s) => s.style));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n if (sats.some((s) => s.tie.direction !== null)) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W - 8}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n arrowHead(x + LEGEND_SWATCH_W, y, 1, 0, 0.75),\n label: labels.direction,\n });\n }\n if (opts.annotationLabel !== undefined && sats.some((s) => s.tie.annotated)) {\n entries.push({\n swatch: (x, y) => annotationSwatch(x, y),\n label: opts.annotationLabel,\n });\n }\n\n if (entries.length > 0) {\n const block = legendBlock(entries, height);\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// Fault-tree input model — declared facts only. compasso draws EXACTLY what the\n// caller declares: every event carries its declared kind (the standard symbol is a\n// semantic claim only the author may make), gates are first-class rows with a declared\n// type and a declared left-to-right input order, and the top event is DECLARED, never\n// derived. Symbol lineage: NUREG-0492 (Fault Tree Handbook, US NRC 1981) distinctive\n// shapes, as permitted by IEC 61025:2006 — the rectangular IEC 60617 family is\n// rejected because its gates would be visually indistinguishable from event rectangles.\n\n/**\n * CLOSED event-kind vocabulary (NUREG-0492 Fig. IV-1):\n * - \"intermediate\": fault event from a logic combination → rectangle (incl. the top);\n * - \"basic\": basic initiating fault, no further development → circle;\n * - \"undeveloped\": not developed further (insufficient consequence/info) → diamond;\n * - \"house\": event normally expected to occur (external/boundary) → house;\n * - \"conditioning\": condition/restriction on an INHIBIT gate → oval (never a tree node);\n * - \"transfer\": transfer-in, subtree developed elsewhere → triangle (a leaf).\n */\nexport const FAULT_TREE_EVENT_KINDS = [\n \"intermediate\",\n \"basic\",\n \"undeveloped\",\n \"house\",\n \"conditioning\",\n \"transfer\",\n] as const;\nexport type FaultTreeEventKind = (typeof FAULT_TREE_EVENT_KINDS)[number];\n\n/**\n * A declared fault-tree event. `label` is verbatim (always kept in the <title>);\n * `code` is a short identifier drawn inside primary-event glyphs (null = none) —\n * matching FTA practice, where primary-event symbols carry identifiers and the\n * descriptions live beside them.\n */\nexport interface FaultTreeEvent {\n id: number;\n kind: FaultTreeEventKind;\n label: string;\n code: string | null;\n /** Optional verbatim <title> override (defaults to \"code · label\"). */\n title?: string;\n}\n\n/**\n * CLOSED gate vocabulary. NOT/NAND/NOR and PRIORITY-AND are deliberately\n * unrepresentable — an unsupported gate is a compile error, never a silent visual\n * fallback (the NOT bubble-triangle would also collide with the transfer triangle).\n */\nexport const GATE_TYPES = [\"and\", \"or\", \"xor\", \"inhibit\", \"vote\"] as const;\nexport type GateType = (typeof GATE_TYPES)[number];\n\ninterface FaultTreeGateBase {\n id: number;\n /** The intermediate event this gate resolves (drawn directly above the gate). */\n eventId: number;\n /** Declared left-to-right reading order — presentation data, honored as given. */\n inputIds: number[];\n}\n\nexport interface AndGate extends FaultTreeGateBase {\n type: \"and\";\n}\nexport interface OrGate extends FaultTreeGateBase {\n type: \"or\";\n}\nexport interface XorGate extends FaultTreeGateBase {\n type: \"xor\";\n}\nexport interface InhibitGate extends FaultTreeGateBase {\n type: \"inhibit\";\n /** Must reference a kind:\"conditioning\" event (drawn as the side oval). */\n conditionId: number;\n}\nexport interface VoteGate extends FaultTreeGateBase {\n type: \"vote\";\n /** Output occurs if ≥ k of the n inputs occur; 1 ≤ k ≤ inputIds.length. */\n k: number;\n}\nexport type FaultTreeGate = AndGate | OrGate | XorGate | InhibitGate | VoteGate;\n\n/** Input to the fault-tree render pipeline. */\nexport interface FaultTreeInput {\n /** Declared top event (must be kind \"intermediate\", never a gate input). */\n topId: number;\n events: FaultTreeEvent[];\n gates: FaultTreeGate[];\n}\n","// Display vocabularies — every human-readable string the fault tree emits, gathered\n// in overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// Gate titles carry the standard gate NAME only (a vote title appends its declared\n// \"k/n\") — the gate's semantics belong to the standard's text, not the SVG.\n\nimport type { FaultTreeEventKind, GateType } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface FaultTreeTitleLabels {\n gates: Record<GateType, string>;\n /** Title of the inhibit-gate → conditioning-oval attachment line. */\n condition: string;\n}\n\nexport const FAULT_TREE_TITLE_LABELS_EN: FaultTreeTitleLabels = {\n gates: {\n and: \"AND gate\",\n or: \"OR gate\",\n xor: \"Exclusive-OR gate\",\n inhibit: \"Inhibit gate\",\n vote: \"Voting gate\",\n },\n condition: \"condition\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface FaultTreeSvgLabels {\n events: Record<FaultTreeEventKind, string>;\n gates: Record<GateType, string>;\n ariaLabel: string;\n}\n\nexport const FAULT_TREE_SVG_LABELS_EN: FaultTreeSvgLabels = {\n events: {\n intermediate: \"Intermediate event\",\n basic: \"Basic event\",\n undeveloped: \"Undeveloped event\",\n house: \"External event (normally occurs)\",\n conditioning: \"Conditioning event\",\n transfer: \"Transfer (developed elsewhere)\",\n },\n gates: {\n and: \"AND gate (all inputs)\",\n or: \"OR gate (any input)\",\n xor: \"Exclusive-OR gate (exactly one input)\",\n inhibit: \"INHIBIT gate (input under condition)\",\n vote: \"Voting gate (k of n)\",\n },\n ariaLabel: \"Fault tree\",\n};\n","// Fault-tree validation — REJECT, never repair. The genogram silently filters\n// dangling references because a family map is elicited incrementally; a fault tree is\n// a safety artifact whose meaning lives in its logic structure, so drawing a\n// structurally invalid tree (or silently altering its logic) is worse than refusing.\n// The standard itself has a notation for \"honestly incomplete\" — the diamond\n// (undeveloped event) and the transfer triangle — and the error messages point there.\n//\n// Every problem is reported, not just the first: issues are aggregated, deduplicated\n// and sorted deterministically (by code, then message), each carrying a STABLE\n// kebab-case machine-readable `code`. Validation runs in THREE phases, each gated on\n// the previous being clean ENOUGH for the next to be meaningful — not on \"zero issues\n// so far\", so a defect in one phase never silently hides an honest issue from a later\n// one (the throw must carry ALL real issues, not just the first phase's):\n// (0) duplicate ids. The lookup maps are first-occurrence-wins, so EVERY reference\n// rule below would validate whichever duplicate row was declared first — making\n// the issue list depend on array order, violating this function's documented\n// order-invariance. When any duplicate-id issue exists we report ONLY those and\n// stop (the duplicate already forces a throw, present in every permutation).\n// (1) reference / semantic rules (R2–R7, R10–R14): top, per-gate references, arity,\n// vote threshold, gate ownership. Always evaluated once ids are unambiguous.\n// (2) graph rules (R8 reachability, R9 cycles) — gated ONLY on the reference-INTEGRITY\n// subset that genuinely makes traversal meaningless, NOT on every phase-1 issue.\n// The traversal walks `gateOf(eventId)` → gate.inputIds (+ inhibit conditionId)\n// seeded at topId, so it is corrupted by: duplicate-id (ambiguous first-wins\n// node), unknown-input (walks a phantom node), gate-on-non-intermediate /\n// transfer-with-gate (attaches a gate to a leaf, fabricating descent),\n// event-with-two-gates (gateOf's first-match silently picks one), inhibit-\n// condition (a non-conditioning conditionId is queued as a phantom node), and\n// top-not-intermediate (the BFS frontier is rooted at a non-node). Defects that\n// do NOT impair traversal — vote-threshold, gate-arity (k/arity are never read),\n// top-as-input, conditioning-as-input, event-without-gate, intermediate-reused\n// (all reference real, walkable nodes) — do NOT suppress the graph phase, so e.g.\n// a bad vote k alongside an unreachable event reports BOTH in one throw.\n//\n// Tolerated, by design (drawn as declared, never converted):\n// - repeated LEAF events (basic/undeveloped/house/transfer) in several gates' inputs\n// — that IS the standard repeated-event notation (drawn once per reference; hooks\n// are disambiguated with data-instance, see ./layout.ts);\n// - a conditioning event attached to more than one inhibit gate (one oval per gate);\n// - vote gates with k=1 or k=n (logically OR/AND — converting would be interpretation);\n// - empty labels (drawn empty; the <title> is still present).\n\nimport type { FaultTreeEvent, FaultTreeGate, FaultTreeInput } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type FaultTreeIssueCode =\n | \"duplicate-id\"\n | \"top-not-intermediate\"\n | \"top-as-input\"\n | \"gate-on-non-intermediate\"\n | \"transfer-with-gate\"\n | \"event-with-two-gates\"\n | \"event-without-gate\"\n | \"intermediate-reused\"\n | \"unknown-input\"\n | \"conditioning-as-input\"\n | \"inhibit-condition\"\n | \"gate-arity\"\n | \"vote-threshold\"\n | \"unreachable-event\"\n | \"cycle\";\n\nexport interface FaultTreeIssue {\n code: FaultTreeIssueCode;\n message: string;\n}\n\n/** Thrown by computeFaultTreeLayout / faultTreeSvg on a structurally invalid tree. */\nexport class FaultTreeValidationError extends Error {\n readonly issues: readonly FaultTreeIssue[];\n\n constructor(issues: readonly FaultTreeIssue[]) {\n super(`invalid fault tree: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"FaultTreeValidationError\";\n this.issues = issues;\n }\n}\n\n/** \"1 and 3\" / \"1, 2 and 3\" — deterministic listing for issue messages. */\nfunction listIds(ids: readonly number[]): string {\n if (ids.length === 1) return String(ids[0]);\n return `${ids.slice(0, -1).join(\", \")} and ${ids[ids.length - 1]}`;\n}\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable\n * across engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly FaultTreeIssue[]): readonly FaultTreeIssue[] {\n const unique = new Map<string, FaultTreeIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically\n * sorted (code, then message) — array order of `events`/`gates` never changes the\n * result. Empty input (no events AND no gates) is valid by definition (the renderer's\n * empty-but-valid SVG case) and reports no issues.\n */\nexport function faultTreeIssues(input: FaultTreeInput): readonly FaultTreeIssue[] {\n if (input.events.length === 0 && input.gates.length === 0) return [];\n\n const issues: FaultTreeIssue[] = [];\n const push = (code: FaultTreeIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── R1: duplicate ids (per namespace — hooks must be unique). Any duplicate makes\n // the structure ambiguous, so this is phase 0 and short-circuits the rest (below). ─\n const eventById = new Map<number, FaultTreeEvent>();\n const dupEventIds = new Set<number>();\n for (const e of input.events) {\n if (eventById.has(e.id)) dupEventIds.add(e.id);\n else eventById.set(e.id, e);\n }\n for (const id of [...dupEventIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate event id ${id}`);\n }\n const gateById = new Map<number, FaultTreeGate>();\n const dupGateIds = new Set<number>();\n for (const g of input.gates) {\n if (gateById.has(g.id)) dupGateIds.add(g.id);\n else gateById.set(g.id, g);\n }\n for (const id of [...dupGateIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate gate id ${id}`);\n }\n\n // ── Phase 0: duplicate ids short-circuit everything else. The lookup maps below are\n // first-occurrence-wins, so every downstream reference rule would validate whichever\n // duplicate row happened to be declared first — making the issue list depend on the\n // `events`/`gates` ARRAY ORDER, in direct violation of this function's documented\n // order-invariance. Rules evaluated over an ambiguous first-wins structure are as\n // meaningless as the graph rules over dangling references, so we report ONLY the\n // duplicate-id issues and stop (the structural defect already forces a throw). This\n // extends the existing phase doctrine one level up: duplicate ids → reference rules →\n // graph rules, each phase gated on the prior being clean enough to be meaningful. ──\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n const gates = [...gateById.values()].sort((a, b) => a.id - b.id);\n\n // ── R2: the declared top must be an existing intermediate event. ─────────────────\n const top = eventById.get(input.topId);\n if (top === undefined || top.kind !== \"intermediate\") {\n push(\"top-not-intermediate\", `topId ${input.topId} is not an intermediate event`);\n }\n\n // ── Per-gate reference/arity rules (R3, R4, R10–R14). ───────────────────────────\n const conditioningAsInput = new Set<number>();\n for (const g of gates) {\n const out = eventById.get(g.eventId);\n if (out !== undefined && out.kind === \"transfer\") {\n // R13 — transfer-in marks \"developed elsewhere\": a leaf by definition.\n push(\"transfer-with-gate\", `transfer event ${g.eventId} cannot have a gate`);\n } else if (out === undefined || out.kind !== \"intermediate\") {\n // R4 — only rectangles are developed through a gate.\n push(\"gate-on-non-intermediate\", `gate ${g.id} resolves non-intermediate event ${g.eventId}`);\n }\n\n // R10 — a gate IS a logic combination; INHIBIT is single-input-plus-condition.\n if (g.type === \"inhibit\") {\n if (g.inputIds.length !== 1) push(\"gate-arity\", `inhibit gate ${g.id} needs exactly 1 input`);\n } else if (g.inputIds.length < 2) {\n push(\"gate-arity\", `${g.type} gate ${g.id} needs ≥2 inputs`);\n }\n\n // R12 — a voting threshold outside the integers 1..n is meaningless. Number.isInteger\n // also rejects NaN/±Infinity and fractional k (k is a plain `number`, so JSON can\n // carry those) — drawing \"NaN/2\" or \"1.5/2\" would repair a meaningless threshold by\n // rendering it, which the reject-never-repair doctrine forbids.\n if (g.type === \"vote\" && (!Number.isInteger(g.k) || g.k < 1 || g.k > g.inputIds.length)) {\n push(\"vote-threshold\", `vote gate ${g.id}: k=${g.k} of ${g.inputIds.length}`);\n }\n\n // R11a — the oval attaches to a gate; inhibit must reference a conditioning event.\n if (g.type === \"inhibit\") {\n const cond = eventById.get(g.conditionId);\n if (cond === undefined || cond.kind !== \"conditioning\") {\n push(\"inhibit-condition\", `inhibit gate ${g.id} conditionId ${g.conditionId} is not a conditioning event`);\n }\n }\n\n for (const inputId of g.inputIds) {\n const child = eventById.get(inputId);\n if (child === undefined) {\n // Dangling input — silently dropping it would alter the declared logic.\n push(\"unknown-input\", `gate ${g.id} input ${inputId} is not a declared event`);\n continue;\n }\n // R3 — the top is the tree apex, never an input.\n if (inputId === input.topId) push(\"top-as-input\", `top event ${input.topId} is used as a gate input`);\n // R11b — a conditioning event is never a tree node (NUREG-0492: it restricts a gate).\n if (child.kind === \"conditioning\") conditioningAsInput.add(inputId);\n }\n }\n for (const id of [...conditioningAsInput].sort((a, b) => a - b)) {\n push(\"conditioning-as-input\", `conditioning event ${id} used as a gate input`);\n }\n\n // ── R5/R6: exactly one gate per intermediate event. ─────────────────────────────\n const gatesByEvent = new Map<number, number[]>();\n for (const g of gates) {\n const arr = gatesByEvent.get(g.eventId) ?? [];\n arr.push(g.id);\n gatesByEvent.set(g.eventId, arr);\n }\n for (const [eventId, gateIds] of [...gatesByEvent.entries()].sort((a, b) => a[0] - b[0])) {\n if (gateIds.length > 1) {\n push(\"event-with-two-gates\", `event ${eventId} is resolved by gates ${listIds(gateIds.sort((a, b) => a - b))}`);\n }\n }\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if (e.kind === \"intermediate\" && !gatesByEvent.has(e.id)) {\n // R6 — a rectangle without a gate falsely claims development; the diamond\n // (undeveloped) is the standard's own symbol for \"not developed further\".\n push(\"event-without-gate\", `intermediate event ${e.id} has no gate — declare it kind \"undeveloped\" instead`);\n }\n }\n\n // ── R7: an intermediate may feed only ONE gate input — duplicating whole subtrees\n // silently is synthesis; the standard's answer is the transfer triangle. ───────\n const intermediateRefs = new Map<number, number[]>(); // event id → referencing gate ids\n for (const g of gates) {\n for (const inputId of g.inputIds) {\n if (eventById.get(inputId)?.kind !== \"intermediate\") continue;\n const arr = intermediateRefs.get(inputId) ?? [];\n arr.push(g.id);\n intermediateRefs.set(inputId, arr);\n }\n }\n for (const [eventId, gateIds] of [...intermediateRefs.entries()].sort((a, b) => a[0] - b[0])) {\n if (gateIds.length > 1) {\n push(\n \"intermediate-reused\",\n `intermediate event ${eventId} feeds gates ${listIds(gateIds.sort((a, b) => a - b))} — repeat it via a \"transfer\" event`,\n );\n }\n }\n\n // ── Graph rules (R8 reachability, R9 cycles) — phase 2. Gated ONLY on the reference-\n // INTEGRITY codes that corrupt the traversal itself (see the module header for the\n // per-code justification), NOT on every phase-1 issue: a meaningless vote k or wrong\n // arity leaves the graph fully walkable, so suppressing R8/R9 for them would hide an\n // honest issue and break the \"throw with ALL issues\" doctrine. ─────────────────────\n const GRAPH_BLOCKING: ReadonlySet<FaultTreeIssueCode> = new Set([\n \"duplicate-id\",\n \"unknown-input\",\n \"gate-on-non-intermediate\",\n \"transfer-with-gate\",\n \"event-with-two-gates\",\n \"inhibit-condition\",\n \"top-not-intermediate\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n const gateOf = (eventId: number): FaultTreeGate | undefined => gates.find((g) => g.eventId === eventId);\n\n // R8 — every declared event must be reachable from the top (silently dropping\n // declared data violates honesty). Conditioning events reach through their gate.\n const reachable = new Set<number>();\n const queue: number[] = [input.topId];\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (reachable.has(id)) continue;\n reachable.add(id);\n const g = gateOf(id);\n if (g === undefined) continue;\n queue.push(...g.inputIds);\n if (g.type === \"inhibit\") queue.push(g.conditionId);\n }\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if (!reachable.has(e.id)) push(\"unreachable-event\", `event ${e.id} is declared but unreachable from the top`);\n }\n\n // R9 — cycle detection over the whole event graph (event → its gate's inputs).\n // Iterative coloring DFS, start nodes ascending, children in declared order; each\n // distinct cycle is reported once, rotated to start at its smallest event id so\n // the message is identical for any array order of the same input.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = gateOf(frame.id)?.inputIds ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n // Back edge: the cycle is the stack slice from `child` down to the current frame.\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\"cycle\", `cycle: ${[...rotated, rotated[0]!].join(\" → \")}`);\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(e.id) ?? 0) === 0) dfs(e.id);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws FaultTreeValidationError (carrying ALL issues) when the input is invalid. */\nexport function validateFaultTree(input: FaultTreeInput): void {\n const issues = faultTreeIssues(input);\n if (issues.length > 0) throw new FaultTreeValidationError(issues);\n}\n","// PURE fault-tree layout — the single source of truth for positioning and connector\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so the\n// same input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS what the caller declared. Validation\n// (./validate.ts) THROWS on a structurally invalid tree instead of repairing it —\n// a fault tree is a safety artifact and silently altering its logic is synthesis.\n// Tolerated repetition is the standard's own notation: a repeated LEAF event\n// (basic/undeveloped/house/transfer in several gates' inputs) is drawn once per\n// reference, exactly as hand-drawn FTA repeats the same circle at each site; hooks\n// are disambiguated with a 0-based `instance` index in deterministic DFS pre-order\n// (event, then inhibit condition, then inputs in declared order). This is also the\n// forward answer for DAG-shaped trees: model the shared subtree as a `transfer` leaf.\n//\n// LAYOUT — top-down levels, exactly as every NUREG-0492 / IEC 61025 figure draws it:\n// event rectangle, short stem, gate beneath, orthogonal connector rake to children.\n// Horizontal placement is NAIVE SUBTREE-SPAN PACKING (not Reingold–Tilford contours):\n// every node carries asymmetric half-extents {spanL, spanR} covering its ENTIRE\n// subtree drawing (glyphs, labels, gate, conditioning oval, its own buses); siblings\n// are placed with disjoint intervals H_GAP apart, and the recursion makes the\n// guarantee global — a 5-line inductive overlap proof, re-verified by the test\n// harness, at the cost of some width on unbalanced trees. Label widths reserve real\n// space because nodeW comes from estimateTextWidth over the wrapped lines and the\n// emitter draws with the same core metrics: what is proven is what is drawn.\n//\n// GATE-CLEARANCE INVARIANT (directly asserted in test/fault-tree/layout.test.ts):\n// every gate glyph bottom at depth d sits strictly ABOVE the child bus y, because\n// rowTop(d+1) = rowTop(d) + rowH(d) + gateZone(d) + CORRIDOR reserves the full gate\n// zone and busY = rowTop(d+1) − CORRIDOR/2 leaves CORRIDOR/2 of air below it.\n\nimport { CHAR_W, clampLabel, estimateTextWidth, wrapLabel, wrapLabelBalanced, type Point } from \"../core\";\nimport { FAULT_TREE_TITLE_LABELS_EN, type FaultTreeTitleLabels } from \"./labels\";\nimport { validateFaultTree } from \"./validate\";\nimport type { FaultTreeEvent, FaultTreeEventKind, FaultTreeGate, FaultTreeInput, GateType } from \"./types\";\n\nexport { FaultTreeValidationError, faultTreeIssues, validateFaultTree, type FaultTreeIssue, type FaultTreeIssueCode } from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render) ──────\n/** Node label font size (px). */\nexport const FT_LABEL_FONT = 12;\n/** Line height for stacked label lines (px). */\nexport const FT_LABEL_LINE_H = 14;\n/** Short-code font size (px) — drawn inside primary-event glyphs. */\nexport const CODE_FONT = 10;\n/** Gap from a leaf glyph's bottom to the top of its first label line. */\nexport const LABEL_GAP = 6;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────\nconst PADDING = 32;\n/** Min horizontal air between two sibling subtree intervals. */\nconst H_GAP = 28;\n/** Vertical band between a row's gate zone and the next row (the bus lives mid-way). */\nconst CORRIDOR = 30;\n/** Vertical stem from an event's bottom edge to its gate's top. */\nconst STEM = 10;\n/** Horizontal gap between an inhibit gate's right vertex and its conditioning node. */\nconst COND_GAP = 14;\n\n// Gate glyph boxes (NUREG-0492 distinctive shapes, drawn pointing up).\nconst GATE_W = 44;\nconst GATE_H = 36;\n/** XOR = the OR shape + a detached concave arc 5px below the base (ANSI/IEEE 91). */\nconst XOR_H = GATE_H + 5;\nconst INHIBIT_W = 36;\nconst INHIBIT_H = 46;\n/** Y of the inhibit hexagon's side-vertex midpoint (the condition line's anchor). */\nconst INHIBIT_CY = 23;\n\n// ── Namespaced element ids (one element kind per numeric block, extending the\n// genogram convention) — every data-edge-id stays traceable to its source row. ──\nexport const FT_STEM_ID_BASE = 1_000_000; // + gate id\nexport const FT_DROP_ID_BASE = 2_000_000; // + gate id\nexport const FT_BUS_ID_BASE = 3_000_000; // + gate id\nexport const FT_RISER_ID_BASE = 4_000_000; // + child event id\nexport const FT_CONDITION_ID_BASE = 5_000_000; // + gate id\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────\n\nexport interface FaultTreeNode {\n eventId: number;\n kind: FaultTreeEventKind;\n /** 0-based DFS pre-order instance index; null when the event is drawn once. */\n instance: number | null;\n /** Glyph center x. */\n cx: number;\n /** Glyph top y (leaf labels hang below the glyph; the rect IS the glyph). */\n top: number;\n /** Full node box (glyph + label block) — the packing reserved exactly this. */\n nodeW: number;\n nodeH: number;\n glyphW: number;\n glyphH: number;\n /** Wrapped display lines — inside the rect (intermediate) or below the glyph. */\n labelLines: string[];\n /** Top of the first label line's box; null when the label sits inside the rect. */\n labelTop: number | null;\n /** Clamped display code drawn inside a non-rect glyph; null = none. */\n code: string | null;\n /** Depth of the row this node lives in (a conditioning node: its gate's row). */\n depth: number;\n /** Verbatim <title> text (event.title ?? \"code · label\" ?? label). */\n title: string;\n}\n\nexport interface FaultTreeGateNode {\n gateId: number;\n type: GateType;\n cx: number;\n /** Glyph top y (all gates of a row are top-aligned at rowBottom + STEM). */\n top: number;\n glyphW: number;\n /** Full glyph height incl. the XOR's detached arc — top + glyphH = connector bottom. */\n glyphH: number;\n /** Localized gate name (vote: name + \" k/n\"). */\n title: string;\n /** \"k/n\" drawn inside a vote gate; null otherwise. */\n voteText: string | null;\n}\n\nexport type FaultTreeElementKind = \"stem\" | \"drop\" | \"bus\" | \"riser\" | \"condition\";\n\nexport interface FaultTreeElement {\n /** Namespaced id (FT_*_ID_BASE + gate id / child event id). */\n edgeId: number;\n kind: FaultTreeElementKind;\n /** Two waypoints, always axis-aligned (H or V). */\n points: Point[];\n /** Riser into a repeated-leaf instance: that instance index; else null. */\n instance: number | null;\n /** Localized gate name (condition elements: titleLabels.condition). */\n title: string;\n}\n\nexport interface FaultTreeLayout {\n width: number;\n height: number;\n /** DFS pre-order (event, condition, inputs) — repeated leaves appear per instance. */\n nodes: FaultTreeNode[];\n gates: FaultTreeGateNode[];\n elements: FaultTreeElement[];\n}\n\nexport interface FaultTreeLayoutOptions {\n /** Cap each node's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for gate/condition <title>s — English default; see locale packs. */\n titleLabels?: FaultTreeTitleLabels;\n}\n\n// ── Measurement ───────────────────────────────────────────────────────────────────\n\ninterface Measured {\n nodeW: number;\n nodeH: number;\n glyphW: number;\n glyphH: number;\n labelLines: string[];\n code: string | null;\n}\n\n/** Leaf-label wrap: tighter budget than the rect's (glyphs don't grow with text). */\nfunction wrapLeafLabel(displayLabel: string): string[] {\n const perLine = Math.min(20, Math.max(12, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n// ── Per-glyph code-char clamp — guarantees the code sits INSIDE its fixed-size\n// glyph (the design doc's \"code drawn inside the glyph\" claim), DERIVED from THIS\n// module's own metrics rather than eyeballed. Only the conditioning OVAL is\n// excluded: it GROWS to the measured code width (`rx = max(30, codeW/2 + 8)`), so\n// it never clamps — see measureEvent. The full verbatim code always survives in\n// the <title> (eventTitle), so clamping is presentation-only, never data loss.\n//\n// Geometry. The emitter (svg.ts) draws the code centered at `cx`, `text-anchor\n// \"middle\"`, its baseline (the literal `<text y>`, i.e. the code's ACTUAL drawn\n// y-position) at `top + glyphH/2 + CODE_FONT*0.32`. N chars span ±estimateTextWidth\n// (N)/2 = ±(N·CODE_FONT·CHAR_W)/2 about cx. The clamp keeps that half-span inside\n// the glyph's half-width AT THAT BASELINE Y (`codeBaselineHalfWidth` below), with a\n// couple px margin AND real-font headroom: real Helvetica caps run wider than the\n// deliberately-light CHAR_W=0.6 estimate at these small extremes (the review\n// measured ~20.3px real vs 18px estimated for a 6-char code, ≈1.13×), so we reserve\n// CODE_REAL_HEADROOM on top of the estimate. Solving for the largest integer N in\n// N·(CODE_FONT·CHAR_W·CODE_REAL_HEADROOM)/2 + CODE_MARGIN ≤ half(baseline)\n// yields (recomputed by maxCodeChars, not hand-copied): basic 5, undeveloped 5,\n// house 5, transfer 3 — the apex-up triangle is narrowest at the code's height.\nconst CODE_REAL_HEADROOM = 1.15;\nconst CODE_MARGIN = 2;\n\n/** Glyph half-width at vertical offset `y` below the glyph top, per non-rect kind. */\nfunction codeGlyphHalfAt(kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">, y: number): number {\n if (kind === \"basic\") {\n // circle r 22, center at top+22\n const dy = y - 22;\n return Math.sqrt(Math.max(0, 22 * 22 - dy * dy));\n }\n if (kind === \"undeveloped\") {\n // diamond half 24, center at top+24, linear taper to the apex/bottom\n return 24 * Math.max(0, 1 - Math.abs(y - 24) / 24);\n }\n if (kind === \"house\") {\n // walls ±22 below the eave (top+16); roof tapers linearly above it to the apex\n return y >= 16 ? 22 : (22 * y) / 16;\n }\n // transfer — apex-up triangle, base ±22 at top+35; half grows linearly from the apex\n return (22 * Math.max(0, Math.min(35, y))) / 35;\n}\n\n/** Glyph half-width at the code text's baseline (its actual drawn `<text y>`). */\nfunction codeBaselineHalfWidth(\n kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">,\n glyphH: number,\n): number {\n return codeGlyphHalfAt(kind, glyphH / 2 + CODE_FONT * 0.32);\n}\n\n/** Largest code length that, drawn, stays inside the glyph (estimator + headroom + margin). */\nexport function maxCodeChars(\n kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">,\n glyphH: number,\n): number {\n const half = codeBaselineHalfWidth(kind, glyphH);\n const perChar = (CODE_FONT * CHAR_W * CODE_REAL_HEADROOM) / 2; // half-advance with headroom\n return Math.max(1, Math.floor((half - CODE_MARGIN) / perChar));\n}\n\nfunction measureEvent(event: FaultTreeEvent, maxLabelChars: number | undefined): Measured {\n if (event.kind === \"intermediate\") {\n // The rectangle IS a text panel (the standard writes the description inside it).\n const lines = event.label === \"\" ? [] : wrapLabelBalanced(clampLabel(event.label, maxLabelChars), 3);\n const maxLineW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, FT_LABEL_FONT)), 0);\n const w = Math.max(96, maxLineW + 24);\n const h = lines.length * FT_LABEL_LINE_H + 18;\n return { nodeW: w, nodeH: h, glyphW: w, glyphH: h, labelLines: lines, code: null };\n }\n const rawCode = event.code === null || event.code === \"\" ? null : event.code;\n const lines = event.label === \"\" ? [] : wrapLeafLabel(clampLabel(event.label, maxLabelChars));\n const labelW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, FT_LABEL_FONT)), 0);\n let glyphW: number;\n let glyphH: number;\n // Fixed-size glyphs clamp the code to what their outline can hold (CODE_MAX_CHARS,\n // derived above); the conditioning OVAL instead grows to the measured code width.\n let code = rawCode;\n if (event.kind === \"basic\") {\n glyphW = 44; // circle r 22\n glyphH = 44;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"basic\", glyphH));\n } else if (event.kind === \"undeveloped\") {\n glyphW = 48; // rotated square, half 24\n glyphH = 48;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"undeveloped\", glyphH));\n } else if (event.kind === \"house\") {\n glyphW = 44; // pentagon: 24px walls + 16px roof\n glyphH = 40;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"house\", glyphH));\n } else if (event.kind === \"conditioning\") {\n // The oval reserves the FULL (only globally-capped) code width — no glyph clamp.\n code = rawCode === null ? null : clampLabel(rawCode, 6);\n const rx = Math.max(30, estimateTextWidth(code ?? \"\", CODE_FONT) / 2 + 8);\n glyphW = rx * 2;\n glyphH = 32; // ellipse ry 16\n } else {\n glyphW = 44; // transfer triangle, apex up\n glyphH = 35;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"transfer\", glyphH));\n }\n const nodeW = Math.max(glyphW, labelW);\n const nodeH = glyphH + (lines.length > 0 ? LABEL_GAP + lines.length * FT_LABEL_LINE_H : 0);\n return { nodeW, nodeH, glyphW, glyphH, labelLines: lines, code };\n}\n\nfunction eventTitle(event: FaultTreeEvent): string {\n if (event.title !== undefined) return event.title;\n return event.code !== null && event.code !== \"\" ? `${event.code} · ${event.label}` : event.label;\n}\n\n// ── Internal working tree (one node per drawn INSTANCE) ───────────────────────────\n\ninterface Inst {\n event: FaultTreeEvent;\n gate: FaultTreeGate | null;\n children: Inst[];\n /** Conditioning instance attached to an inhibit gate; positioned in the gate zone. */\n cond: Inst | null;\n depth: number;\n m: Measured;\n title: string;\n /** Per-event-id DFS pre-order sequence (becomes `instance` when the event repeats). */\n seq: number;\n // Subtree half-extents (cover the ENTIRE subtree drawing) and resolved positions.\n spanL: number;\n spanR: number;\n /** Center offset relative to the parent's center (root: unused). */\n offset: number;\n cx: number;\n}\n\n/**\n * Deterministic, overlap-proof fault-tree layout (pure function of the inputs).\n * Validates first and THROWS FaultTreeValidationError on a structurally invalid\n * tree — never sanitizes. Empty input (no events, no gates) yields an empty,\n * padded layout; `topId` is ignored in that one case.\n */\nexport function computeFaultTreeLayout(\n input: FaultTreeInput,\n opts: FaultTreeLayoutOptions = {},\n): FaultTreeLayout {\n if (input.events.length === 0 && input.gates.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], gates: [], elements: [] };\n }\n validateFaultTree(input);\n\n const titleLabels = opts.titleLabels ?? FAULT_TREE_TITLE_LABELS_EN;\n const eventById = new Map(input.events.map((e) => [e.id, e]));\n const gateByEvent = new Map(input.gates.map((g) => [g.eventId, g]));\n\n // ── Build the instance tree by DFS from the top (event → condition → inputs in\n // declared order). Validation guarantees: intermediates form a tree, leaves may\n // repeat, conditioning events never have gates or children. ───────────────────\n const allInsts: Inst[] = [];\n const seqByEvent = new Map<number, number>();\n const newInst = (event: FaultTreeEvent, gate: FaultTreeGate | null, depth: number): Inst => {\n const seq = seqByEvent.get(event.id) ?? 0;\n seqByEvent.set(event.id, seq + 1);\n const inst: Inst = {\n event,\n gate,\n children: [],\n cond: null,\n depth,\n m: measureEvent(event, opts.maxLabelChars),\n title: eventTitle(event),\n seq,\n spanL: 0,\n spanR: 0,\n offset: 0,\n cx: 0,\n };\n allInsts.push(inst);\n return inst;\n };\n const build = (eventId: number, depth: number): Inst => {\n const event = eventById.get(eventId)!;\n const gate = gateByEvent.get(eventId) ?? null;\n const inst = newInst(event, gate, depth);\n if (gate !== null) {\n if (gate.type === \"inhibit\") {\n inst.cond = newInst(eventById.get(gate.conditionId)!, null, depth);\n }\n for (const childId of gate.inputIds) inst.children.push(build(childId, depth + 1));\n }\n return inst;\n };\n const root = build(input.topId, 0);\n\n // ── Horizontal: subtree-span packing (post-order). The conditioning oval reserves\n // REAL width on the right of an inhibit-developed node — never overlaps a sibling.\n const pack = (inst: Inst): void => {\n for (const c of inst.children) pack(c);\n const condW = inst.cond !== null ? COND_GAP + inst.cond.m.nodeW : 0;\n const selfL = inst.m.nodeW / 2;\n const selfR = inst.m.nodeW / 2 + condW;\n if (inst.children.length === 0) {\n inst.spanL = selfL;\n inst.spanR = selfR;\n return;\n }\n const xs: number[] = [0];\n for (let i = 1; i < inst.children.length; i++) {\n xs.push(xs[i - 1]! + inst.children[i - 1]!.spanR + H_GAP + inst.children[i]!.spanL);\n }\n const first = inst.children[0]!;\n const last = inst.children[inst.children.length - 1]!;\n const px = (xs[0]! + xs[xs.length - 1]!) / 2;\n inst.children.forEach((c, i) => (c.offset = xs[i]! - px));\n inst.spanL = Math.max(selfL, px - (xs[0]! - first.spanL));\n inst.spanR = Math.max(selfR, xs[xs.length - 1]! + last.spanR - px);\n };\n pack(root);\n\n // Absolute centers, top-down; the root's left extent sits at PADDING.\n root.cx = PADDING + root.spanL;\n const placeX = (inst: Inst): void => {\n for (const c of inst.children) {\n c.cx = inst.cx + c.offset;\n placeX(c);\n }\n };\n placeX(root);\n\n // ── Vertical: rows by depth (per drawn instance), top-aligned; each row reserves\n // a gate zone sized to its tallest gate assembly (incl. conditioning nodes). ───\n const rowInsts: Inst[][] = [];\n const visitRows = (inst: Inst): void => {\n (rowInsts[inst.depth] ??= []).push(inst);\n for (const c of inst.children) visitRows(c);\n };\n visitRows(root);\n const depthCount = rowInsts.length;\n\n /** Vertical extent of a gate assembly below the gate's top (glyph and/or oval+label). */\n const gateExtent = (inst: Inst): number => {\n const g = inst.gate!;\n if (g.type === \"xor\") return XOR_H;\n if (g.type === \"inhibit\") {\n // Oval vertically centered on the hexagon's side vertex (INHIBIT_CY); the\n // condition node's label may extend below the hexagon bottom.\n const condBottom = INHIBIT_CY - 16 + inst.cond!.m.nodeH;\n return Math.max(INHIBIT_H, condBottom);\n }\n return GATE_H;\n };\n const rowH: number[] = [];\n const gateZone: number[] = [];\n for (let d = 0; d < depthCount; d++) {\n const insts = rowInsts[d]!;\n rowH.push(insts.reduce((m, i) => Math.max(m, i.m.nodeH), 0));\n const gated = insts.filter((i) => i.gate !== null);\n gateZone.push(gated.length === 0 ? 0 : STEM + gated.reduce((m, i) => Math.max(m, gateExtent(i)), 0));\n }\n const rowTop: number[] = [PADDING];\n for (let d = 0; d < depthCount - 1; d++) {\n rowTop.push(rowTop[d]! + rowH[d]! + gateZone[d]! + CORRIDOR);\n }\n const busY = (d: number): number => rowTop[d + 1]! - CORRIDOR / 2;\n\n const width = Math.ceil(PADDING * 2 + root.spanL + root.spanR);\n const last = depthCount - 1;\n const height = Math.ceil(rowTop[last]! + rowH[last]! + gateZone[last]! + PADDING);\n\n // ── Instance finalization: only events drawn more than once carry an index. ──────\n const instanceOf = (inst: Inst): number | null =>\n (seqByEvent.get(inst.event.id) ?? 0) > 1 ? inst.seq : null;\n\n // ── Emit nodes / gates / elements in DFS order. ───────────────────────────────────\n const nodes: FaultTreeNode[] = [];\n const gates: FaultTreeGateNode[] = [];\n const elements: FaultTreeElement[] = [];\n\n const gateTitle = (g: FaultTreeGate): string =>\n g.type === \"vote\" ? `${titleLabels.gates.vote} ${g.k}/${g.inputIds.length}` : titleLabels.gates[g.type];\n\n const pushNode = (inst: Inst, top: number): void => {\n const isRect = inst.event.kind === \"intermediate\";\n const labelTop = !isRect && inst.m.labelLines.length > 0 ? top + inst.m.glyphH + LABEL_GAP : null;\n nodes.push({\n eventId: inst.event.id,\n kind: inst.event.kind,\n instance: instanceOf(inst),\n cx: round(inst.cx),\n top: round(top),\n nodeW: round(inst.m.nodeW),\n nodeH: round(inst.m.nodeH),\n glyphW: round(inst.m.glyphW),\n glyphH: round(inst.m.glyphH),\n labelLines: inst.m.labelLines,\n labelTop: labelTop === null ? null : round(labelTop),\n code: inst.m.code,\n depth: inst.depth,\n title: inst.title,\n });\n };\n\n const emit = (inst: Inst): void => {\n const d = inst.depth;\n pushNode(inst, rowTop[d]!);\n const g = inst.gate;\n if (g === null) return;\n\n const gateTop = rowTop[d]! + rowH[d]! + STEM;\n const glyphW = g.type === \"inhibit\" ? INHIBIT_W : GATE_W;\n const glyphH = g.type === \"xor\" ? XOR_H : g.type === \"inhibit\" ? INHIBIT_H : GATE_H;\n const title = gateTitle(g);\n gates.push({\n gateId: g.id,\n type: g.type,\n cx: round(inst.cx),\n top: round(gateTop),\n glyphW,\n glyphH,\n title,\n voteText: g.type === \"vote\" ? `${g.k}/${g.inputIds.length}` : null,\n });\n\n // Conditioning node: oval centered on the hexagon's side vertex, the whole node\n // box starting COND_GAP right of the vertex so the label can never reach the gate.\n if (inst.cond !== null) {\n const cond = inst.cond;\n const nodeLeft = inst.cx + INHIBIT_W / 2 + COND_GAP;\n cond.cx = nodeLeft + cond.m.nodeW / 2;\n const condTop = gateTop + INHIBIT_CY - 16;\n pushNode(cond, condTop);\n const ovalLeft = cond.cx - cond.m.glyphW / 2;\n elements.push({\n edgeId: FT_CONDITION_ID_BASE + g.id,\n kind: \"condition\",\n points: [\n { x: round(inst.cx + INHIBIT_W / 2), y: round(gateTop + INHIBIT_CY) },\n { x: round(ovalLeft), y: round(gateTop + INHIBIT_CY) },\n ],\n instance: null,\n title: titleLabels.condition,\n });\n }\n\n // Output stem: event bottom → gate top (longer than STEM when the event is\n // shorter than its row — rows are top-aligned).\n elements.push({\n edgeId: FT_STEM_ID_BASE + g.id,\n kind: \"stem\",\n points: [\n { x: round(inst.cx), y: round(rowTop[d]! + inst.m.nodeH) },\n { x: round(inst.cx), y: round(gateTop) },\n ],\n instance: null,\n title,\n });\n // Gate drop: gate connector bottom → bus.\n const by = busY(d);\n elements.push({\n edgeId: FT_DROP_ID_BASE + g.id,\n kind: \"drop\",\n points: [\n { x: round(inst.cx), y: round(gateTop + glyphH) },\n { x: round(inst.cx), y: round(by) },\n ],\n instance: null,\n title,\n });\n // Bus: spans min→max child centers; a single-input gate degenerates to the\n // straight drop + riser (no bus element).\n if (inst.children.length > 1) {\n const xs = inst.children.map((c) => c.cx);\n elements.push({\n edgeId: FT_BUS_ID_BASE + g.id,\n kind: \"bus\",\n points: [\n { x: round(Math.min(...xs)), y: round(by) },\n { x: round(Math.max(...xs)), y: round(by) },\n ],\n instance: null,\n title,\n });\n }\n // One riser per child: bus → child glyph top (the transfer triangle's apex IS\n // its glyph top). Risers into a repeated leaf carry that instance index, since\n // their edge id (FT_RISER_ID_BASE + child event id) repeats with the leaf.\n for (const c of inst.children) {\n elements.push({\n edgeId: FT_RISER_ID_BASE + c.event.id,\n kind: \"riser\",\n points: [\n { x: round(c.cx), y: round(by) },\n { x: round(c.cx), y: round(rowTop[d + 1]!) },\n ],\n instance: instanceOf(c),\n title,\n });\n }\n for (const c of inst.children) emit(c);\n };\n emit(root);\n\n return { width, height, nodes, gates, elements };\n}\n","// Fault-tree SVG emitter — turns a computed FaultTreeLayout (./layout.ts) into a\n// SELF-CONTAINED SVG string. Pure (layout in, string out) and deterministic; it draws\n// EXACTLY what the layout computed (the overlap harness proves the layout; this\n// emitter is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — labels/codes/titles are\n// author-controlled and the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (hex colors, explicit font-family): a\n// standalone SVG has no stylesheet, no currentColor, no <defs>/<marker>;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Symbol fidelity (NUREG-0492 distinctive shapes): rectangle / circle / diamond /\n// house / oval / transfer-triangle events; AND dome, OR shield, XOR (OR + detached\n// second input curve — the ANSI/IEEE 91 distinctive shape; the legend entry\n// disambiguates), INHIBIT hexagon, VOTE (OR shield with \"k/n\" inside). Gates carry no\n// label text — the shape IS the semantics; the localized gate name rides the <title>.\n//\n// Hooks: `<g data-node-id=\"e<id>\">` per event instance and `<g data-node-id=\"g<id>\">`\n// per gate (direct-child verbatim <title>); `<g data-edge-id=\"<n>\">` per connector\n// element (namespaced ids, see ./layout.ts). Repeated-leaf instances (and their\n// risers) carry `data-instance=\"k\"` so every hook stays unambiguous.\n\nimport { FONT_FAMILY, legendBlock, xmlEscape, LEGEND_SWATCH_W, type LegendEntry } from \"../core\";\nimport { FT_LABEL_FONT, FT_LABEL_LINE_H, CODE_FONT, type FaultTreeElement, type FaultTreeGateNode, type FaultTreeLayout, type FaultTreeNode } from \"./layout\";\nimport { FAULT_TREE_SVG_LABELS_EN, type FaultTreeSvgLabels } from \"./labels\";\nimport { FAULT_TREE_EVENT_KINDS, GATE_TYPES, type FaultTreeEventKind, type GateType } from \"./types\";\n\n// Literal ink colors (zinc ramp on white — matches the genogram/ecomap emitters).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\nconst GLYPH_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport interface FaultTreeSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: FaultTreeSvgLabels;\n}\n\n// ── Event glyphs ──────────────────────────────────────────────────────────────────\n\nfunction eventGlyph(n: FaultTreeNode): string {\n const cx = n.cx;\n const top = n.top;\n if (n.kind === \"intermediate\") {\n return `<rect x=\"${round(cx - n.nodeW / 2)}\" y=\"${top}\" width=\"${n.nodeW}\" height=\"${n.nodeH}\" rx=\"2\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"basic\") {\n return `<circle cx=\"${cx}\" cy=\"${round(top + 22)}\" r=\"22\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"undeveloped\") {\n const pts = `${cx},${top} ${round(cx + 24)},${round(top + 24)} ${cx},${round(top + 48)} ${round(cx - 24)},${round(top + 24)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"house\") {\n const yB = round(top + 40);\n const eave = round(top + 16);\n const pts = `${round(cx - 22)},${yB} ${round(cx - 22)},${eave} ${cx},${top} ${round(cx + 22)},${eave} ${round(cx + 22)},${yB}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"conditioning\") {\n return `<ellipse cx=\"${cx}\" cy=\"${round(top + 16)}\" rx=\"${round(n.glyphW / 2)}\" ry=\"16\" ${GLYPH_ATTRS}/>`;\n }\n // transfer — triangle, line-to-apex (the riser ends exactly at the apex).\n const pts = `${cx},${top} ${round(cx + 22)},${round(top + 35)} ${round(cx - 22)},${round(top + 35)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n}\n\nfunction nodeSvg(n: FaultTreeNode): string {\n const pieces: string[] = [`<title>${xmlEscape(n.title)}</title>`, eventGlyph(n)];\n if (n.code !== null && n.kind !== \"intermediate\") {\n pieces.push(\n `<text x=\"${n.cx}\" y=\"${round(n.top + n.glyphH / 2 + CODE_FONT * 0.32)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${CODE_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(n.code)}</text>`,\n );\n }\n if (n.labelLines.length > 0) {\n // Inside the rect (vertically centered block) or below the glyph (labelTop).\n const firstBaseline = n.labelTop === null ? round(n.top + 19) : round(n.labelTop + 10);\n const tspans = n.labelLines\n .map((line, i) => `<tspan x=\"${n.cx}\" y=\"${round(firstBaseline + i * FT_LABEL_LINE_H)}\">${xmlEscape(line)}</tspan>`)\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${FT_LABEL_FONT}\" fill=\"${LABEL_FILL}\">${tspans}</text>`,\n );\n }\n const instance = n.instance === null ? \"\" : ` data-instance=\"${n.instance}\"`;\n return `<g data-node-id=\"e${n.eventId}\"${instance}>${pieces.join(\"\")}</g>`;\n}\n\n// ── Gate glyphs (distinctive shapes, drawn pointing up — output on top) ───────────\n\nfunction orBodyPath(cx: number, top: number, yB: number): string {\n return `M ${round(cx - 22)} ${yB} Q ${cx} ${round(yB - 14)} ${round(cx + 22)} ${yB} Q ${round(cx + 22)} ${round(top + 14)} ${cx} ${top} Q ${round(cx - 22)} ${round(top + 14)} ${round(cx - 22)} ${yB} Z`;\n}\n\nfunction gateGlyph(g: FaultTreeGateNode): string {\n const cx = g.cx;\n const top = g.top;\n const yB = round(top + 36);\n if (g.type === \"and\") {\n const d = `M ${round(cx - 22)} ${yB} L ${round(cx - 22)} ${round(yB - 14)} A 22 22 0 0 1 ${round(cx + 22)} ${round(yB - 14)} L ${round(cx + 22)} ${yB} Z`;\n return `<path d=\"${d}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"or\") {\n return `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"xor\") {\n const arc = `M ${round(cx - 22)} ${round(yB + 5)} Q ${cx} ${round(yB - 9)} ${round(cx + 22)} ${round(yB + 5)}`;\n return `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/><path d=\"${arc}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"inhibit\") {\n const pts = `${cx},${top} ${round(cx + 18)},${round(top + 12)} ${round(cx + 18)},${round(top + 34)} ${cx},${round(top + 46)} ${round(cx - 18)},${round(top + 34)} ${round(cx - 18)},${round(top + 12)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n // vote — the OR distinctive shape with the declared \"k/n\" written inside.\n return (\n `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/>` +\n `<text x=\"${cx}\" y=\"${round(yB - 10)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"9\" fill=\"${LABEL_FILL}\">${xmlEscape(g.voteText ?? \"\")}</text>`\n );\n}\n\nfunction gateSvg(g: FaultTreeGateNode): string {\n return `<g data-node-id=\"g${g.gateId}\"><title>${xmlEscape(g.title)}</title>${gateGlyph(g)}</g>`;\n}\n\n// ── Connector elements ─────────────────────────────────────────────────────────────\n\nfunction elementSvg(el: FaultTreeElement): string {\n const a = el.points[0]!;\n const b = el.points[1]!;\n const instance = el.instance === null ? \"\" : ` data-instance=\"${el.instance}\"`;\n return (\n `<g data-edge-id=\"${el.edgeId}\"${instance}><title>${xmlEscape(el.title)}</title>` +\n `<line x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/></g>`\n );\n}\n\n// ── Legend mini-glyph swatches (scaled into the 22px swatch box) ──────────────────\n\nconst MINI_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"`;\n\nfunction miniEventSwatch(kind: FaultTreeEventKind, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (kind === \"intermediate\") {\n return `<rect x=\"${round(cx - 7)}\" y=\"${round(y - 4.5)}\" width=\"14\" height=\"9\" rx=\"1\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"basic\") return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/>`;\n if (kind === \"undeveloped\") {\n return `<polygon points=\"${cx},${round(y - 7)} ${round(cx + 7)},${y} ${cx},${round(y + 7)} ${round(cx - 7)},${y}\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"house\") {\n return `<polygon points=\"${round(cx - 6)},${round(y + 5.5)} ${round(cx - 6)},${round(y - 1)} ${cx},${round(y - 5.5)} ${round(cx + 6)},${round(y - 1)} ${round(cx + 6)},${round(y + 5.5)}\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"conditioning\") return `<ellipse cx=\"${cx}\" cy=\"${y}\" rx=\"9\" ry=\"5.5\" ${MINI_ATTRS}/>`;\n return `<polygon points=\"${cx},${round(y - 5)} ${round(cx + 6)},${round(y + 5)} ${round(cx - 6)},${round(y + 5)}\" ${MINI_ATTRS}/>`;\n}\n\nfunction miniOrPath(cx: number, y: number): string {\n return `M ${round(cx - 7)} ${round(y + 5.5)} Q ${cx} ${round(y + 1)} ${round(cx + 7)} ${round(y + 5.5)} Q ${round(cx + 7)} ${round(y - 1.5)} ${cx} ${round(y - 5.5)} Q ${round(cx - 7)} ${round(y - 1.5)} ${round(cx - 7)} ${round(y + 5.5)} Z`;\n}\n\nfunction miniGateSwatch(type: GateType, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (type === \"and\") {\n const d = `M ${round(cx - 7)} ${round(y + 5.5)} L ${round(cx - 7)} ${round(y + 1.5)} A 7 7 0 0 1 ${round(cx + 7)} ${round(y + 1.5)} L ${round(cx + 7)} ${round(y + 5.5)} Z`;\n return `<path d=\"${d}\" ${MINI_ATTRS}/>`;\n }\n if (type === \"xor\") {\n return `<path d=\"${miniOrPath(cx, y)}\" ${MINI_ATTRS}/><path d=\"M ${round(cx - 7)} ${round(y + 7.5)} Q ${cx} ${round(y + 3)} ${round(cx + 7)} ${round(y + 7.5)}\" ${MINI_ATTRS}/>`;\n }\n if (type === \"inhibit\") {\n return `<polygon points=\"${cx},${round(y - 5.5)} ${round(cx + 4.5)},${round(y - 2.5)} ${round(cx + 4.5)},${round(y + 2.5)} ${cx},${round(y + 5.5)} ${round(cx - 4.5)},${round(y + 2.5)} ${round(cx - 4.5)},${round(y - 2.5)}\" ${MINI_ATTRS}/>`;\n }\n // or / vote share the OR shield mini — the legend label disambiguates the vote.\n return `<path d=\"${miniOrPath(cx, y)}\" ${MINI_ATTRS}/>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed fault-tree layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped;\n * all presentation attributes are literal. The legend lists ONLY the event kinds and\n * gate types actually present, in canonical declaration order.\n */\nexport function faultTreeLayoutSvg(layout: FaultTreeLayout, opts: FaultTreeSvgOptions = {}): string {\n const labels = opts.labels ?? FAULT_TREE_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // Connectors first, then gates, then event nodes — nodes sit on top.\n for (const el of layout.elements) parts.push(elementSvg(el));\n for (const g of layout.gates) parts.push(gateSvg(g));\n for (const n of layout.nodes) parts.push(nodeSvg(n));\n\n // ── Used-keys-only legend (core legendBlock; `legend:false` suppresses). ─────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const kindsUsed = new Set(layout.nodes.map((n) => n.kind));\n const typesUsed = new Set(layout.gates.map((g) => g.type));\n const entries: LegendEntry[] = [];\n for (const kind of FAULT_TREE_EVENT_KINDS) {\n if (!kindsUsed.has(kind)) continue;\n entries.push({ swatch: (x, y) => miniEventSwatch(kind, x, y), label: labels.events[kind] });\n }\n for (const type of GATE_TYPES) {\n if (!typesUsed.has(type)) continue;\n entries.push({ swatch: (x, y) => miniGateSwatch(type, x, y), label: labels.gates[type] });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call fault-tree render: input → { svg, layout }. Thin, honest wiring: validate\n// (throw on a structurally invalid tree — never repair), compute the pure layout,\n// emit. Callers needing finer control use computeFaultTreeLayout + faultTreeLayoutSvg\n// directly (the layout result supports hit-testing / decorating the diagram).\n\nimport { computeFaultTreeLayout, type FaultTreeLayout, type FaultTreeLayoutOptions } from \"./layout\";\nimport { faultTreeLayoutSvg } from \"./svg\";\nimport type { FaultTreeSvgLabels } from \"./labels\";\nimport type { FaultTreeInput } from \"./types\";\n\nexport interface FaultTreeRenderOptions extends FaultTreeLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: FaultTreeSvgLabels;\n}\n\nexport interface FaultTreeRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: FaultTreeLayout;\n}\n\n/**\n * Renders a fault-tree input to a self-contained SVG string. Deterministic: same\n * data → same SVG (array order never matters; a gate's `inputIds` order is honored\n * as the declared left-to-right reading order). Throws FaultTreeValidationError —\n * carrying EVERY issue, deterministically sorted — on a structurally invalid tree.\n * Empty input yields an empty-but-valid SVG; callers decide their own empty state.\n */\nexport function faultTreeSvg(input: FaultTreeInput, opts: FaultTreeRenderOptions = {}): FaultTreeRenderResult {\n const layout = computeFaultTreeLayout(input, {\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = faultTreeLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Ishikawa (fishbone / cause-and-effect) renderer — a horizontal spine running into\n// the effect head, category bones at 60°, horizontal cause twigs and ONE level of\n// diagonal sub-cause twigs — as a SELF-CONTAINED SVG string. Pure (data in, string\n// out), deterministic (same input → same SVG), no DOM, no dependencies.\n//\n// Notation (Ishikawa, *Guide to Quality Control*, JUSE 1976; ASQ template lineage):\n// the effect (\"characteristic\") is written in a box at the head of the central arrow;\n// big bones are diagonal, medium bones (causes) horizontal, small bones (sub-causes)\n// parallel to the big bone — every level drawn as an arrow converging on the effect.\n// The cartoon fish head is template folklore, not the standard, so the head is a\n// plain rectangle. Bones are at EXACTLY 60° to the spine (\"about 60°\" in the\n// literature): the angle is a constant, not an option, because every label-clearance\n// inequality below is derived from it. Beyond small bones the JUSE method itself\n// moves to why-why tables, so sub-sub-causes are typed away.\n//\n// DECLARED ORDER IS HONORED — the documented exception to the library's id-sorting\n// (ecomap) doctrine: the analyst's ordering is declared data (significant categories\n// nearest the head, alternating top/bottom; causes outward from the spine; sub-causes\n// from the bone outward). Numeric ids are still required — unique per namespace\n// (categories / causes / sub-causes), enforced by FishboneValidationError — because\n// the decoration hooks (`data-node-id`) must be unambiguous.\n//\n// HONESTY RULE: one declared category = one bone — no default 5M/6M skeleton, no\n// inferred grouping. Arrowheads are uniform notation (the diagram IS arrows\n// converging on the effect), so `arrowheads:false` toggles presentation, never data.\n//\n// Trig values are HARD-CODED literals: Math.tan/sin at runtime would make\n// byte-determinism hostage to engine-specific transcendental ulps.\n\nimport {\n FONT_FAMILY,\n LEGEND_SWATCH_W,\n clampLabel,\n estimateTextWidth,\n legendBlock,\n wrapLabel,\n wrapLabelBalanced,\n xmlEscape,\n type LegendEntry,\n} from \"../core\";\n\n// ── Input model ───────────────────────────────────────────────────────────────\n\nexport interface FishboneSubCause {\n id: number;\n /** Verbatim sub-cause text (drawn as one clamped line; full text in the <title>). */\n label: string;\n}\n\nexport interface FishboneCause {\n id: number;\n label: string;\n /** Exactly one sub-level is in scope (JUSE small bones); deeper nesting is typed away. */\n subCauses: FishboneSubCause[];\n /** Optional verbatim <title> override (defaults to the label). */\n title?: string;\n}\n\nexport interface FishboneCategory {\n id: number;\n label: string;\n causes: FishboneCause[];\n /** Optional verbatim <title> override (defaults to the label). */\n title?: string;\n}\n\nexport interface FishboneInput {\n /** The effect, written in the head box (verbatim). */\n effectLabel: string;\n /** Declared order is honored: first category nearest the head, alternating top/bottom. */\n categories: FishboneCategory[];\n}\n\n// ── Display vocabulary ────────────────────────────────────────────────────────\n\nexport interface FishboneLabels {\n /** Legend label for the cause-twig stroke (emitted only when sub-causes exist). */\n cause: string;\n /** Legend label for the sub-cause-twig stroke. */\n subCause: string;\n ariaLabel: string;\n}\n\nexport const FISHBONE_LABELS_EN: FishboneLabels = {\n cause: \"Cause\",\n subCause: \"Sub-cause\",\n ariaLabel: \"Cause-and-effect diagram (Ishikawa)\",\n};\n\n// ── Validation ────────────────────────────────────────────────────────────────\n\nexport type FishboneValidationCode = \"duplicate-id\";\n\nexport interface FishboneValidationIssue {\n /** Stable, machine-readable kebab-case code. */\n code: FishboneValidationCode;\n message: string;\n}\n\n/**\n * Thrown when ids collide within a namespace (categories / causes / sub-causes) —\n * the decoration hooks would be ambiguous. Carries ALL issues, deterministically\n * sorted (namespace order, then ascending id), never just the first. Everything\n * else (empty labels, zero causes, zero categories) is tolerated and drawn as\n * declared. The message mirrors the fault-tree shape (`invalid fishbone: …; …`)\n * so message-only logging keeps the diagram context for both modules.\n */\nexport class FishboneValidationError extends Error {\n readonly issues: readonly FishboneValidationIssue[];\n\n constructor(issues: readonly FishboneValidationIssue[]) {\n super(`invalid fishbone: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"FishboneValidationError\";\n this.issues = issues;\n }\n}\n\nfunction duplicateIds(ids: readonly number[]): number[] {\n const seen = new Set<number>();\n const dups = new Set<number>();\n for (const id of ids) {\n if (seen.has(id)) dups.add(id);\n seen.add(id);\n }\n return [...dups].sort((a, b) => a - b);\n}\n\nfunction validateIds(input: FishboneInput): void {\n const issues: FishboneValidationIssue[] = [];\n const collect = (noun: string, ids: readonly number[]): void => {\n for (const id of duplicateIds(ids)) {\n issues.push({ code: \"duplicate-id\", message: `duplicate ${noun} id ${id}` });\n }\n };\n collect(\"category\", input.categories.map((c) => c.id));\n collect(\"cause\", input.categories.flatMap((c) => c.causes.map((k) => k.id)));\n collect(\n \"sub-cause\",\n input.categories.flatMap((c) => c.causes.flatMap((k) => k.subCauses.map((s) => s.id))),\n );\n if (issues.length > 0) throw new FishboneValidationError(issues);\n}\n\n// ── Options ───────────────────────────────────────────────────────────────────\n\nexport interface FishboneSvgOptions {\n /** Display clamp per label (verbatim text stays in the <title>). */\n maxLabelChars?: number;\n /** Label font size (px); default 12. */\n fontSize?: number;\n /** Set false to suppress the legend; default true (emits only when sub-causes exist). */\n legend?: boolean;\n /** Arrowheads on spine/bones/twigs (classic Ishikawa); default true. */\n arrowheads?: boolean;\n /** Display vocabulary — English default; see `compasso/locales/pt-br`. */\n labels?: FishboneLabels;\n}\n\n// ── Geometry constants ────────────────────────────────────────────────────────\n\n// Hard-coded trig literals for the 60° bone angle (see module header).\nconst TAN60 = 1.7320508075688772;\nconst SIN60 = 0.8660254037844386;\nconst COS60 = 0.5;\n\nconst PADDING = 32;\nconst ROW_GAP = 12;\n/** Min horizontal air between adjacent same-side bone content AABBs. */\nconst BONE_GAP = 36;\nconst CAT_PAD_X = 12;\nconst CAT_PAD_Y = 8;\n/** Air between the bone's outer tip and the category box. */\nconst CAT_GAP = 12;\nconst TAIL_EXTRA = 44;\nconst HEAD_GAP = 24;\nconst HEAD_PAD_X = 14;\nconst HEAD_PAD_Y = 10;\n/** Sub-cause labels are ONE clamped line at this per-line budget (band invariant). */\nconst SUB_PER_LINE = 18;\n/** Helvetica-like glyph box at the 12px reference: ascent 11 above the baseline,\n * descent 3 below. EVERY fontSize-dependent vertical reserve is derived from these\n * (see verticalMetrics) — never used directly, so no 12px-only constant can leak\n * into the layout. */\nconst ASCENT_12 = 11;\nconst DESCENT_12 = 3;\n\n// ── fontSize-derived vertical metrics ─────────────────────────────────────────\n\ninterface VerticalMetrics {\n /** Baseline-to-glyph-top reserve (mirrors outward-stacked text on bottom bones). */\n ascent: number;\n /** Stacked-line pitch: EXACTLY ascent + descent, so consecutive baselines one\n * lineH apart give glyph bands that touch without overlapping, at any fontSize. */\n lineH: number;\n /** Innermost baseline offset from its twig: descent + 1 keeps the glyph ink 1px\n * clear of the twig stroke at any fontSize (4 at the default 12). */\n twigGap: number;\n /** Sub-twig vertical rise. blockH ≤ 2·lineH = sV − twigGap − 8 < sV, so within one\n * band the cause-label strip and the sub-label strip occupy disjoint y-slabs with\n * ≥ 8px air, and a sub-twig stays spine-ward of its label's center while crossing\n * the cause strip (both by construction, at any fontSize). */\n sV: number;\n /** First cause band starts |y| ≥ spineClear from the spine (the cross-side slab);\n * tied to the 2-line strip height so the slab tracks the type scale — anything\n * beyond the fixed ~10px bone-arrowhead reach preserves the guarantee. */\n spineClear: number;\n /** Twig length beyond its content: the bone's horizontal run across a 2-line cause\n * strip plus 25px of air — strictly above the (2·lineH + twigGap)/TAN60 + 10\n * floor the label-vs-bone clearance needs, by construction at any fontSize. */\n boneClear: number;\n /** Min horizontal air between adjacent ×1.2-padded sub-label boxes on one twig\n * (one line-height, so the air scales with the type; see the station packing). */\n subGap: number;\n}\n\n/** Derives the vertical reserves from the glyph metrics at the requested size, so\n * the slab/clearance inequalities in fishboneSvg hold BY CONSTRUCTION at any\n * fontSize. At the default 12 they reduce exactly to the original constants\n * (lineH 14, twigGap 4, sV 40, spineClear 32, boneClear 44, subGap 14), keeping\n * default output byte-stable (pinned by test/fishbone/render.test.ts). */\nfunction verticalMetrics(fontSize: number): VerticalMetrics {\n // Ceil-scaled so a reserve never rounds below the true em-scaled glyph extent.\n const ascent = Math.ceil((ASCENT_12 * fontSize) / 12);\n const descent = Math.ceil((DESCENT_12 * fontSize) / 12);\n const lineH = ascent + descent;\n const twigGap = descent + 1;\n return {\n ascent,\n lineH,\n twigGap,\n sV: 2 * lineH + twigGap + 8,\n spineClear: 2 * lineH + twigGap,\n boneClear: Math.ceil((2 * lineH + twigGap) / TAN60) + 25,\n subGap: lineH,\n };\n}\n\n// Ink (zinc ramp on white — matches the genogram/ecomap emitters). The four line\n// levels carry a decreasing stroke hierarchy (the only styled distinction a reader\n// could miss — exactly what the conditional legend names).\nconst EDGE_INK = \"#71717a\";\nconst BOX_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst SPINE_W = 2.5;\nconst SPINE_OP = 0.85;\nconst BONE_W = 2;\nconst BONE_OP = 0.8;\nconst TWIG_W = 1.5;\nconst TWIG_OP = 0.75;\nconst SUB_W = 1.2;\nconst SUB_OP = 0.7;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n/** Arrowhead polygon: tip at (tipX,tipY), pointing along the unit vector (ux,uy). */\nfunction arrowHead(tipX: number, tipY: number, ux: number, uy: number, opacity: number): string {\n const LEN = 9;\n const HALF_W = 4.5;\n const bx = tipX - ux * LEN;\n const by = tipY - uy * LEN;\n const px = -uy;\n const py = ux;\n const points = [\n `${round(tipX)},${round(tipY)}`,\n `${round(bx + px * HALF_W)},${round(by + py * HALF_W)}`,\n `${round(bx - px * HALF_W)},${round(by - py * HALF_W)}`,\n ].join(\" \");\n return `<polygon points=\"${points}\" fill=\"${EDGE_INK}\" fill-opacity=\"${opacity}\"/>`;\n}\n\nfunction lineEl(x1: number, y1: number, x2: number, y2: number, w: number, op: number): string {\n return `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${EDGE_INK}\" stroke-width=\"${w}\" stroke-opacity=\"${op}\"/>`;\n}\n\n// ── Internal measured shapes ──────────────────────────────────────────────────\n// All x positions below are relative to the bone's spine attachment; all vertical\n// positions are MAGNITUDES (distance from the spine) — the bottom side mirrors y.\n\ninterface SubBand {\n sub: FishboneSubCause;\n line: string;\n w: number;\n /** Station x on the cause twig. */\n sx: number;\n /** Outer end x of the diagonal sub-twig (= the label's center x). */\n outerX: number;\n}\n\ninterface CauseBand {\n cause: FishboneCause;\n lines: string[];\n labelW: number;\n blockH: number;\n /** Twig magnitude from the spine (the band's spine-side edge). */\n offset: number;\n bandH: number;\n /** Bone crossing at the twig's magnitude (≤ 0). */\n bx: number;\n /** Twig free end (tail-ward). */\n freeEnd: number;\n subs: SubBand[];\n}\n\ninterface Bone {\n category: FishboneCategory;\n up: boolean;\n bands: CauseBand[];\n /** Bone vertical magnitude (attach at the spine, outer end at −B / +B). */\n B: number;\n catLines: string[];\n boxW: number;\n boxH: number;\n /** Content extents relative to the attach: [ax − relL, ax + relR] contains ALL ink. */\n relL: number;\n relR: number;\n /** Absolute attach x (assigned by per-side packing). */\n ax: number;\n}\n\n/**\n * Renders a declared Ishikawa diagram to a self-contained SVG string. Deterministic:\n * same data → same SVG. Zero categories yield a valid spine+head-only SVG. Throws\n * FishboneValidationError on duplicate ids within a namespace (all issues listed).\n * The root keeps numeric width/height attributes plus a matching viewBox.\n *\n * Collision guarantee, by construction from MEASURED label widths (asserted by\n * test/fishbone/geometry.test.ts, including at non-default font sizes). Every\n * vertical reserve is derived from the glyph metrics at opts.fontSize (see\n * verticalMetrics), so the inequalities hold at ANY fontSize, not only the default:\n * 1. within a band: the cause-label strip and the sub-label strip occupy disjoint\n * y-slabs (blockH ≤ 2·lineH = sV − twigGap − 8 < sV); sub labels are x-disjoint\n * by station packing over ×1.2-padded estimates (absorbs the estimator's\n * Helvetica-caps deficit); both strips clear the slanted bone by the\n * station/boneClear inequalities;\n * 2. across bands of one bone: bands are stacked disjoint y-intervals of measured\n * heights (ROW_GAP included), and the bone crosses each slab only at its own\n * clearance-checked x;\n * 3. across bones of one side: disjoint content AABBs packed with BONE_GAP;\n * 4. across sides: open half-planes separated by the |y| < spineClear spine slab;\n * 5. head/tail: the head box sits beyond every bone's right extent + HEAD_GAP.\n * Every reserved width comes from estimateTextWidth (deliberately wide, core\n * doctrine) and the emitter draws at the same font metrics — reserved ⊇ drawn.\n */\nexport function fishboneSvg(input: FishboneInput, opts: FishboneSvgOptions = {}): string {\n validateIds(input);\n\n const fontSize = opts.fontSize ?? 12;\n const { ascent, lineH, twigGap, sV, spineClear, boneClear, subGap } = verticalMetrics(fontSize);\n const labels = opts.labels ?? FISHBONE_LABELS_EN;\n const arrows = opts.arrowheads !== false;\n\n // ── Measure every bone (declared order; even index → top, odd → bottom). ─────\n const bones: Bone[] = input.categories.map((category, idx) => {\n let cursor = spineClear;\n const bands: CauseBand[] = category.causes.map((cause) => {\n const lines = wrapLabelBalanced(clampLabel(cause.label, opts.maxLabelChars));\n const labelW = Math.max(...lines.map((l) => estimateTextWidth(l, fontSize)));\n const blockH = lines.length * lineH;\n const offset = cursor;\n const bx = -offset / TAN60;\n\n // Sub stations right→left in declared order. The first inequality keeps the\n // bone-nearest label clear of the slanted bone at the sub strip's outer edge\n // ((sV − twigGap)/TAN60 + 10 of air, which dwarfs the estimator's half-label\n // caps deficit at any fontSize). Successive stations keep the label boxes\n // disjoint with subGap air between ×1.2-PADDED estimates: CHAR_W 0.6 under-\n // reads Helvetica CAPS (≈ 0.72 em/char average), so padding each estimated\n // width by 20% restores reserved ⊇ drawn for caps-heavy labels — runs wider\n // than that (M/W walls) remain core-estimator doctrine, as everywhere else.\n const subs: SubBand[] = [];\n for (const sub of cause.subCauses) {\n const line = wrapLabel(clampLabel(sub.label, opts.maxLabelChars), SUB_PER_LINE, 1)[0]!;\n const w = estimateTextWidth(line, fontSize);\n const prev = subs.length > 0 ? subs[subs.length - 1]! : null;\n const sx =\n prev === null\n ? bx - (sV + lineH) / TAN60 - 10 - w / 2\n : prev.sx - (prev.w + w) * 0.6 - subGap;\n subs.push({ sub, line, w, sx, outerX: sx - sV / TAN60 });\n }\n\n const last = subs.length > 0 ? subs[subs.length - 1]! : null;\n const subSpan = last === null ? 0 : bx - (last.outerX - last.w / 2);\n // Twig length reserves, beyond the boneClear terms, a third term when subs\n // exist: the cause label must end BEFORE the leftmost sub-twig's outer x —\n // the diagonal sub-twigs descend through the cause-label y-slab, so a long\n // cause label hugging the free end could otherwise sit under them. (The\n // band-disjointness argument covers label strips, not the sub LINES.)\n const twigLen =\n last === null\n ? labelW + boneClear\n : Math.max(labelW + boneClear, subSpan + boneClear, labelW + (bx - last.outerX) + 10);\n\n const bandH = Math.max(blockH + twigGap, subs.length > 0 ? sV + lineH + twigGap : 0) + ROW_GAP;\n cursor += bandH;\n return { cause, lines, labelW, blockH, offset, bandH, bx, freeEnd: bx - twigLen, subs };\n });\n\n const B = cursor + 16;\n const catLines = wrapLabelBalanced(clampLabel(category.label, opts.maxLabelChars));\n const boxW = Math.max(...catLines.map((l) => estimateTextWidth(l, fontSize))) + CAT_PAD_X * 2;\n const boxH = catLines.length * lineH + CAT_PAD_Y * 2;\n const tipX = -B / TAN60;\n return {\n category,\n up: idx % 2 === 0,\n bands,\n B,\n catLines,\n boxW,\n boxH,\n // Left extent: the category box's left edge or the deepest twig free end —\n // every label sits AT or right of its twig's free end, every sub label sits\n // right of the free end too (twigLen ≥ subSpan + boneClear).\n relL: Math.max(B / TAN60 + boxW / 2, ...bands.map((b) => -b.freeEnd)),\n // Right extent: a wide category box on a short bone may overhang the attach.\n relR: Math.max(0, boxW / 2 + tipX),\n ax: 0,\n };\n });\n\n // ── Pack each side independently, right→left in declared order. ──────────────\n const cursors = { top: 0, bottom: 0 };\n for (const bone of bones) {\n const side = bone.up ? \"top\" : \"bottom\";\n bone.ax = cursors[side] - bone.relR;\n cursors[side] = bone.ax - bone.relL - BONE_GAP;\n }\n\n // ── Head box + spine extents (working coords: spine y = 0). ──────────────────\n const effLines = wrapLabelBalanced(clampLabel(input.effectLabel, opts.maxLabelChars));\n const headW = Math.max(...effLines.map((l) => estimateTextWidth(l, fontSize))) + HEAD_PAD_X * 2;\n const headH = effLines.length * lineH + HEAD_PAD_Y * 2;\n // Every bone's right extent is ≤ 0 by packing, so the head clears all of them.\n const headLeft = bones.length > 0 ? HEAD_GAP : 0;\n const tailX =\n bones.length > 0\n ? Math.min(...bones.map((b) => b.ax - b.relL)) - TAIL_EXTRA\n : headLeft - (TAIL_EXTRA + HEAD_GAP);\n\n // ── Bounds → shift positive (ecomap pattern). ────────────────────────────────\n let minY = -headH / 2;\n let maxY = headH / 2;\n for (const bone of bones) {\n const reach = bone.B + CAT_GAP + bone.boxH;\n if (bone.up) minY = Math.min(minY, -reach);\n else maxY = Math.max(maxY, reach);\n }\n const dx = PADDING - tailX;\n const dy = PADDING - minY;\n let width = headLeft + headW - tailX + PADDING * 2;\n let height = maxY - minY + PADDING * 2;\n const spineY = dy;\n\n const centeredYs = (cy: number, n: number): number[] =>\n Array.from({ length: n }, (_, i) => cy - ((n - 1) * lineH) / 2 + i * lineH + fontSize * 0.32);\n\n // Band text stacks OUTWARD from its strip's spine-side edge (magnitude e): on top\n // bones the innermost line's baseline sits twigGap beyond the edge (= descent + 1,\n // ink 1px clear of the twig at any fontSize); the bottom side mirrors with the\n // ascent so the glyphs occupy the mirrored strip.\n const bandBaselines = (e: number, n: number, up: boolean): number[] =>\n Array.from({ length: n }, (_, k) =>\n up ? spineY - (e + twigGap + (n - 1 - k) * lineH) : spineY + e + twigGap + ascent + k * lineH,\n );\n\n const textBlock = (anchor: \"start\" | \"middle\", x: number, ys: number[], lines: string[]): string =>\n `<text text-anchor=\"${anchor}\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">` +\n lines.map((line, i) => `<tspan x=\"${round(x)}\" y=\"${round(ys[i]!)}\">${xmlEscape(line)}</tspan>`).join(\"\") +\n `</text>`;\n\n const parts: string[] = [];\n\n // ── Spine (under everything), arrow into the head's left edge. ───────────────\n {\n const body = [lineEl(tailX + dx, spineY, headLeft + dx, spineY, SPINE_W, SPINE_OP)];\n if (arrows) body.push(arrowHead(headLeft + dx, spineY, 1, 0, SPINE_OP));\n parts.push(`<g data-edge-id=\"spine\"><title>${xmlEscape(labels.ariaLabel)}</title>${body.join(\"\")}</g>`);\n }\n\n // ── Bones, twigs, sub-twigs — declared order. ────────────────────────────────\n for (const bone of bones) {\n const sgn = bone.up ? -1 : 1;\n const ax = bone.ax + dx;\n const tipX = ax - bone.B / TAN60;\n\n const body = [lineEl(tipX, spineY + sgn * bone.B, ax, spineY, BONE_W, BONE_OP)];\n // The bone runs from the outer tip INTO the spine: on a top bone that direction\n // is down-right (+y), on a bottom bone up-right (−y) — opposite the side sign.\n if (arrows) body.push(arrowHead(ax, spineY, COS60, -sgn * SIN60, BONE_OP));\n const boxTop = bone.up ? spineY - bone.B - CAT_GAP - bone.boxH : spineY + bone.B + CAT_GAP;\n body.push(\n `<rect x=\"${round(tipX - bone.boxW / 2)}\" y=\"${round(boxTop)}\" width=\"${round(bone.boxW)}\" height=\"${round(bone.boxH)}\" rx=\"2\" fill=\"transparent\" stroke=\"${BOX_STROKE}\" stroke-width=\"1.5\"/>`,\n );\n body.push(textBlock(\"middle\", tipX, centeredYs(boxTop + bone.boxH / 2, bone.catLines.length), bone.catLines));\n parts.push(\n `<g data-node-id=\"b${bone.category.id}\"><title>${xmlEscape(bone.category.title ?? bone.category.label)}</title>${body.join(\"\")}</g>`,\n );\n\n for (const band of bone.bands) {\n const ty = spineY + sgn * band.offset;\n const bx = ax + band.bx;\n const freeEnd = ax + band.freeEnd;\n const cbody = [lineEl(freeEnd, ty, bx, ty, TWIG_W, TWIG_OP)];\n if (arrows) cbody.push(arrowHead(bx, ty, 1, 0, TWIG_OP));\n cbody.push(textBlock(\"start\", freeEnd + 2, bandBaselines(band.offset, band.lines.length, bone.up), band.lines));\n parts.push(\n `<g data-node-id=\"c${band.cause.id}\"><title>${xmlEscape(band.cause.title ?? band.cause.label)}</title>${cbody.join(\"\")}</g>`,\n );\n\n for (const s of band.subs) {\n const sx = ax + s.sx;\n const ox = ax + s.outerX;\n const sbody = [lineEl(ox, spineY + sgn * (band.offset + sV), sx, ty, SUB_W, SUB_OP)];\n // Parallel to the bone, pointing into the twig — same spine-ward direction.\n if (arrows) sbody.push(arrowHead(sx, ty, COS60, -sgn * SIN60, SUB_OP));\n const baseline = bone.up\n ? spineY - (band.offset + sV + twigGap)\n : spineY + band.offset + sV + twigGap + ascent;\n sbody.push(textBlock(\"middle\", ox, [baseline], [s.line]));\n parts.push(`<g data-node-id=\"s${s.sub.id}\"><title>${xmlEscape(s.sub.label)}</title>${sbody.join(\"\")}</g>`);\n }\n }\n }\n\n // ── Effect head (on top), vertically centered on the spine. ──────────────────\n {\n const x = headLeft + dx;\n parts.push(\n `<g data-node-id=\"head\"><title>${xmlEscape(input.effectLabel)}</title>` +\n `<rect x=\"${round(x)}\" y=\"${round(spineY - headH / 2)}\" width=\"${round(headW)}\" height=\"${round(headH)}\" rx=\"2\" fill=\"transparent\" stroke=\"${BOX_STROKE}\" stroke-width=\"2\"/>` +\n textBlock(\"middle\", x + headW / 2, centeredYs(spineY, effLines.length), effLines) +\n `</g>`,\n );\n }\n\n // ── Conditional legend: the fishbone is fully labeled inline — the only styled\n // distinction a reader could miss is the cause vs sub-cause stroke hierarchy,\n // so used-keys-only means: both entries when at least one sub-cause exists,\n // otherwise no legend at all. ────────────────────────────────────────────────\n const anySubs = input.categories.some((c) => c.causes.some((k) => k.subCauses.length > 0));\n if (opts.legend !== false && anySubs) {\n const entries: LegendEntry[] = [\n {\n swatch: (x, y) => lineEl(x, y, x + LEGEND_SWATCH_W, y, TWIG_W, TWIG_OP),\n label: labels.cause,\n },\n {\n swatch: (x, y) => lineEl(x, y + 5, x + LEGEND_SWATCH_W, y - 5, SUB_W, SUB_OP),\n label: labels.subCause,\n },\n ];\n const block = legendBlock(entries, height);\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// Pedigree input model — declared CLINICAL facts only. A human pedigree is a clinical\n// record: compasso draws EXACTLY what the caller declares and NEVER infers. Two declared\n// parents with no declared Mating never merge into a couple; an unaffected glyph is only\n// ever filled when the caller declares the condition; a carrier dot, a proband arrow, a\n// deceased slash all require an explicit declaration. Mode-of-inheritance is read off the\n// topology by the clinician, never asserted by the renderer.\n//\n// Notation: Bennett RL, Steinhaus French K, Resta RG, Doyle DL, \"Standardized Human\n// Pedigree Nomenclature: Update and Assessment of the Recommendations of the National\n// Society of Genetic Counselors\" (PSSC), J Genet Couns 2008; 17:424-433. Square = male,\n// circle = female, diamond = sex unknown — IDENTICAL to the genogram glyphs, so the sex\n// vocabulary (PersonSex/NodeShape) is RE-EXPORTED from ../genogram/types rather than\n// redefined (duplicating the union would be a lie). The clinical overlay (conditions,\n// carrier, proband/consultand, twins, consanguinity) is pedigree-native.\n\nimport type { PersonSex, NodeShape } from \"../genogram/types\";\nexport type { PersonSex, NodeShape };\n\n/** PSSC proband (filled arrow) / consultand (open arrow); null = neither. */\nexport type PedigreeRole = \"proband\" | \"consultand\" | null;\n\n/**\n * CLOSED life-status vocabulary. \"stillbirth\" draws an \"SB\" annotation below a full-size\n * glyph (uniform glyph metrics keep the overlap proof simple; the SB text + <title> carry\n * the fact). Pregnancy / spontaneous-loss / termination glyphs are DEFERRED (they would\n * introduce a non-square/circle/diamond glyph + gestational-age text) and are typed away\n * here — an unsupported status is a compile error, never a silent fallback.\n */\nexport const LIFE_STATUSES = [\"alive\", \"stillbirth\"] as const;\nexport type LifeStatus = (typeof LIFE_STATUSES)[number];\n\n/** PSSC twin zygosity. mz = monozygotic (tie-bar), dz = dizygotic (no bar), unknown = \"?\". */\nexport type Zygosity = \"mz\" | \"dz\" | \"unknown\";\n\n/** A condition referenced by Individual.affectedBy; drives the filled-glyph partitions. */\nexport interface Condition {\n id: number;\n /** Verbatim condition name (legend + <title>; escaped on emit). */\n label: string;\n}\n\n/**\n * A pedigree individual — declared clinical facts only; nothing inferred. Reuses the\n * genogram's exact person grammar ({ id, label, sex, deceased }) but `generation` is\n * MANDATORY and integer (a pedigree without generations is not a pedigree), and the\n * clinical overlay (affectedBy, carrier, role, lifeStatus) is pedigree-specific.\n */\nexport interface Individual {\n id: number;\n label: string;\n /** square/circle/diamond — re-exported genogram vocabulary. */\n sex: PersonSex;\n /** MANDATORY integer; smaller = older = higher row (validated, never derived here). */\n generation: number;\n /** Deceased slash (PSSC: top-left → bottom-right), reusing the genogram's exact line. */\n deceased: boolean;\n /** Asymptomatic-carrier center dot; PSSC puts it on UNAFFECTED carriers only. */\n carrier: boolean;\n /** PSSC proband (filled arrow) / consultand (open arrow); null = neither. */\n role: PedigreeRole;\n /** \"stillbirth\" → an \"SB\" annotation below the glyph. */\n lifeStatus: LifeStatus;\n /** Condition ids this individual is affected by (filled-glyph partitions, ≤4). [] = unaffected. */\n affectedBy: number[];\n /** Optional verbatim <title> override (defaults to \"<address> · label[ · affected: …]\"). */\n title?: string;\n}\n\n/**\n * A declared mating between two individuals. The pair is unordered (the layout normalizes\n * a < b). `consanguineous` draws the PSSC DOUBLE mating line — the core distinguishing\n * mark a genogram Union has no concept of (and the single biggest reason pedigree owns its\n * relational layer instead of importing the genogram's). No status vocabulary: a pedigree\n * does not draw McGoldrick divorce slashes.\n */\nexport interface Mating {\n id: number;\n partnerAId: number;\n partnerBId: number;\n /** PSSC double mating line. */\n consanguineous: boolean;\n}\n\n/** A twin group within ONE sibship: ≥2 child ids of one zygosity, all in that sibship. */\nexport interface TwinGroup {\n /** ≥2 child ids from THIS sibship that are twins of one zygosity. */\n childIds: number[];\n zygosity: Zygosity;\n}\n\n/**\n * The children of one mating, in declared left-to-right birth order (the fishbone \"declared\n * order is data\" doctrine). The sibship is a FIRST-CLASS declared object — twin zygosity\n * and birth order live here, not on the individual — so the layout draws one drop-bar per\n * DECLARED sibship and never auto-attaches a child to a mating.\n */\nexport interface Sibship {\n id: number;\n matingId: number;\n /** Child individual ids, left→right (declared order honored; PSSC birth order). */\n childIds: number[];\n /** Twin groupings among these children; [] = no twins. */\n twinGroups: TwinGroup[];\n}\n\n/** Input to the pedigree render pipeline. */\nexport interface PedigreeInput {\n conditions: Condition[];\n individuals: Individual[];\n matings: Mating[];\n sibships: Sibship[];\n}\n","// Display vocabularies — every human-readable string the pedigree emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// The split mirrors the fault-tree/genogram: TitleLabels are woven into element <title>s\n// by the LAYOUT (verbatim-preserving facts); SvgLabels are drawn by the EMITTER (legend\n// entries + accessibility text). Condition labels come from the caller's\n// `input.conditions[i].label`, not these packs (caller data, escaped on emit).\n\nimport type { NodeShape } from \"../genogram/types\";\nimport type { Zygosity } from \"./types\";\n\n/** Labels woven into element/node <title>s by the LAYOUT (verbatim-preserving). */\nexport interface PedigreeTitleLabels {\n /** Prefix → \"affected: <condition.label>, …\". */\n affected: string;\n carrier: string;\n deceased: string;\n proband: string;\n consultand: string;\n consanguineous: string;\n mating: string;\n sibship: string;\n twins: Record<Zygosity, string>;\n stillbirth: string;\n /** Used in the generation-gutter aria-style <title>, e.g. \"generation I\". */\n generation: string;\n}\n\nexport const PEDIGREE_TITLE_LABELS_EN: PedigreeTitleLabels = {\n affected: \"affected\",\n carrier: \"carrier\",\n deceased: \"deceased\",\n proband: \"proband\",\n consultand: \"consultand\",\n consanguineous: \"consanguineous mating\",\n mating: \"mating\",\n sibship: \"sibship\",\n twins: {\n mz: \"monozygotic twins\",\n dz: \"dizygotic twins\",\n unknown: \"twins, zygosity unknown\",\n },\n stillbirth: \"stillbirth\",\n generation: \"generation\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface PedigreeSvgLabels {\n shapes: Record<NodeShape, string>;\n unaffected: string;\n carrier: string;\n deceased: string;\n proband: string;\n consultand: string;\n consanguineous: string;\n twins: Record<Zygosity, string>;\n stillbirth: string;\n isolated: string;\n ariaLabel: string;\n}\n\nexport const PEDIGREE_SVG_LABELS_EN: PedigreeSvgLabels = {\n shapes: {\n square: \"Male\",\n circle: \"Female\",\n diamond: \"Sex unknown\",\n },\n unaffected: \"Unaffected\",\n carrier: \"Carrier\",\n deceased: \"Deceased\",\n proband: \"Proband\",\n consultand: \"Consultand\",\n consanguineous: \"Consanguineous mating\",\n twins: {\n mz: \"Monozygotic twins\",\n dz: \"Dizygotic twins\",\n unknown: \"Twins (zygosity unknown)\",\n },\n stillbirth: \"Stillbirth\",\n isolated: \"No recorded relatives\",\n ariaLabel: \"Pedigree chart\",\n};\n","// Pedigree validation — REJECT, never repair. A human pedigree is a CLINICAL artifact:\n// silently dropping a dangling child reference or drawing a mating to a phantom partner is\n// a medical error (mode-of-inheritance is read off the topology). This is exactly the\n// fault-tree's \"safety artifact → refuse, don't repair\" situation, and the OPPOSITE of the\n// genogram's \"elicited incrementally → filter dangling silently\". So the layout/render\n// entry points THROW PedigreeValidationError carrying EVERY issue, deduplicated and\n// deterministically sorted (by code, then message — byte comparison, no locale collation),\n// each with a STABLE kebab-case machine-readable `code`.\n//\n// THREE-PHASE gating, mirroring ./../fault-tree/validate.ts exactly — each phase gated on\n// the previous being clean ENOUGH for the next to be meaningful, NOT on \"zero issues so\n// far\" (the throw must carry ALL real issues):\n// (0) duplicate ids (per namespace: individual / mating / sibship). The lookup maps below\n// are first-occurrence-wins, so every later rule would validate whichever duplicate\n// row was declared first — making the issue list array-order-dependent. When any\n// duplicate-id exists we report ONLY those and stop.\n// (1) reference / semantic rules: partner existence + self-mating, sibship→mating\n// existence, child existence, child-of-two-sibships, twin membership, integer\n// generation, condition existence + the ≤4 quadrant cap (PSSC).\n// (2) graph rule = generation-inversion (the only rule needing the resolved parent→child\n// relation), gated ONLY on the reference-integrity subset that makes the parent→child\n// walk meaningful (unknown-partner / unknown-sibship-mating / unknown-child corrupt\n// it; a non-integer generation or a too-many-conditions defect does not).\n//\n// Tolerated, by design (drawn as declared, never repaired): empty labels (drawn empty,\n// <title> present); an individual in no mating/sibship (a founder or a loose proband —\n// drawn isolated, the genogram's isolated-group precedent); a mating with no sibship (a\n// childless declared couple — a bare mating line); `carrier` on an affected individual\n// (clinically valid — a manifesting heterozygote; the dot is just hidden under the fill).\n//\n// CROSS-GENERATION MATING is NOT rejected (avuncular unions are clinically real — §1.7);\n// only true generation-inversion (a child older than its parent row) is rejected.\n\nimport type { PedigreeInput, Individual, Mating, Sibship } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type PedigreeIssueCode =\n | \"duplicate-id\"\n | \"unknown-partner\"\n | \"self-mating\"\n | \"unknown-sibship-mating\"\n | \"unknown-child\"\n | \"child-of-two-sibships\"\n | \"twin-not-in-sibship\"\n | \"twin-group-too-small\"\n | \"twin-group-not-contiguous\"\n | \"generation-not-integer\"\n | \"unknown-condition\"\n | \"too-many-conditions\"\n | \"generation-inversion\";\n\nexport interface PedigreeIssue {\n code: PedigreeIssueCode;\n message: string;\n}\n\n/** Thrown by computePedigreeLayout / pedigreeSvg on a structurally invalid pedigree. */\nexport class PedigreeValidationError extends Error {\n readonly issues: readonly PedigreeIssue[];\n\n constructor(issues: readonly PedigreeIssue[]) {\n super(`invalid pedigree: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"PedigreeValidationError\";\n this.issues = issues;\n }\n}\n\n/** The PSSC quadrant cap: ≤4 conditions partition a glyph; beyond that needs a key/table. */\nexport const MAX_CONDITIONS_PER_INDIVIDUAL = 4;\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable across\n * engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly PedigreeIssue[]): readonly PedigreeIssue[] {\n const unique = new Map<string, PedigreeIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically sorted\n * (code, then message) — array order of individuals/matings/sibships never changes the\n * result. Empty input (no individuals AND no matings AND no sibships) is valid by\n * definition (the renderer's empty-but-valid SVG case) and reports no issues.\n */\nexport function pedigreeIssues(input: PedigreeInput): readonly PedigreeIssue[] {\n if (input.individuals.length === 0 && input.matings.length === 0 && input.sibships.length === 0) return [];\n\n const issues: PedigreeIssue[] = [];\n const push = (code: PedigreeIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── Phase 0: duplicate ids (per namespace — hooks must be unique). Any duplicate makes\n // the structure ambiguous (first-wins maps), so report ONLY these and stop. ──────────\n const individualById = new Map<number, Individual>();\n const dupIndividualIds = new Set<number>();\n for (const ind of input.individuals) {\n if (individualById.has(ind.id)) dupIndividualIds.add(ind.id);\n else individualById.set(ind.id, ind);\n }\n for (const id of [...dupIndividualIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate individual id ${id}`);\n }\n const matingById = new Map<number, Mating>();\n const dupMatingIds = new Set<number>();\n for (const m of input.matings) {\n if (matingById.has(m.id)) dupMatingIds.add(m.id);\n else matingById.set(m.id, m);\n }\n for (const id of [...dupMatingIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate mating id ${id}`);\n }\n const sibshipById = new Map<number, Sibship>();\n const dupSibshipIds = new Set<number>();\n for (const s of input.sibships) {\n if (sibshipById.has(s.id)) dupSibshipIds.add(s.id);\n else sibshipById.set(s.id, s);\n }\n for (const id of [...dupSibshipIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate sibship id ${id}`);\n }\n\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n const individuals = [...individualById.values()].sort((a, b) => a.id - b.id);\n const matings = [...matingById.values()].sort((a, b) => a.id - b.id);\n const sibships = [...sibshipById.values()].sort((a, b) => a.id - b.id);\n const conditionIds = new Set(input.conditions.map((c) => c.id));\n\n // ── Phase 1: reference / semantic rules. ──────────────────────────────────────────────\n\n // Matings reference declared individuals and are not self-matings.\n for (const m of matings) {\n if (!individualById.has(m.partnerAId)) {\n push(\"unknown-partner\", `mating ${m.id} references unknown individual ${m.partnerAId}`);\n }\n if (!individualById.has(m.partnerBId)) {\n push(\"unknown-partner\", `mating ${m.id} references unknown individual ${m.partnerBId}`);\n }\n if (m.partnerAId === m.partnerBId) {\n push(\"self-mating\", `mating ${m.id} mates individual ${m.partnerAId} with itself`);\n }\n }\n\n // Sibships reference a declared mating; child ids reference declared individuals.\n for (const s of sibships) {\n if (!matingById.has(s.matingId)) {\n push(\"unknown-sibship-mating\", `sibship ${s.id} references unknown mating ${s.matingId}`);\n }\n for (const childId of s.childIds) {\n if (!individualById.has(childId)) {\n push(\"unknown-child\", `sibship ${s.id} references unknown child ${childId}`);\n }\n }\n // Twin members must belong to THIS sibship's declared children.\n const childSet = new Set(s.childIds);\n const offending = new Set<number>();\n for (const tg of s.twinGroups) {\n for (const memberId of tg.childIds) {\n if (!childSet.has(memberId)) offending.add(memberId);\n }\n }\n for (const memberId of [...offending].sort((a, b) => a - b)) {\n push(\"twin-not-in-sibship\", `twin ${memberId} is not a child of sibship ${s.id}`);\n }\n\n // A twin group must have at least 2 members (a singleton twin is structurally incoherent).\n for (const tg of s.twinGroups) {\n if (tg.childIds.length < 2) {\n const [only] = tg.childIds;\n push(\n \"twin-group-too-small\",\n `twin group in sibship ${s.id} has only 1 member (${only ?? \"none\"}) — at least 2 required`,\n );\n }\n }\n\n // A twin group must occupy a CONTIGUOUS run within the sibship's childIds order.\n // The layout draws the MZ tie-bar assuming adjacency; a non-contiguous group would\n // cross an in-between sibling, corrupting the topology.\n for (const tg of s.twinGroups) {\n if (tg.childIds.length < 2) continue; // already caught above; skip to avoid noise\n const memberSet = new Set(tg.childIds);\n const positions = s.childIds\n .map((cid, pos) => (memberSet.has(cid) ? pos : -1))\n .filter((p) => p >= 0);\n if (positions.length === 0) continue; // all members dangling — twin-not-in-sibship covers it\n const first = positions[0]!;\n const last = positions[positions.length - 1]!;\n if (last - first !== positions.length - 1) {\n const memberList = [...tg.childIds].sort((a, b) => a - b).join(\", \");\n push(\n \"twin-group-not-contiguous\",\n `twin group [${memberList}] in sibship ${s.id} is not a contiguous run in childIds`,\n );\n }\n }\n }\n\n // An individual may belong to AT MOST one sibship (ambiguous descent otherwise).\n const sibshipsOfChild = new Map<number, number[]>();\n for (const s of sibships) {\n for (const childId of s.childIds) {\n const arr = sibshipsOfChild.get(childId) ?? [];\n arr.push(s.id);\n sibshipsOfChild.set(childId, arr);\n }\n }\n for (const [childId, sibIds] of [...sibshipsOfChild.entries()].sort((a, b) => a[0] - b[0])) {\n if (sibIds.length > 1) {\n push(\n \"child-of-two-sibships\",\n `individual ${childId} is a child of sibships ${[...sibIds].sort((a, b) => a - b).join(\", \")}`,\n );\n }\n }\n\n // Generation must be an integer (Number.isInteger also rejects NaN/±Infinity/fractions).\n for (const ind of individuals) {\n if (!Number.isInteger(ind.generation)) {\n push(\"generation-not-integer\", `individual ${ind.id} has non-integer generation ${ind.generation}`);\n }\n }\n\n // Conditions referenced by affectedBy exist; ≤4 conditions per individual (PSSC quadrant cap).\n for (const ind of individuals) {\n for (const conditionId of ind.affectedBy) {\n if (!conditionIds.has(conditionId)) {\n push(\"unknown-condition\", `individual ${ind.id} is affected by unknown condition ${conditionId}`);\n }\n }\n if (ind.affectedBy.length > MAX_CONDITIONS_PER_INDIVIDUAL) {\n push(\n \"too-many-conditions\",\n `individual ${ind.id} has ${ind.affectedBy.length} conditions — at most ${MAX_CONDITIONS_PER_INDIVIDUAL} can be drawn`,\n );\n }\n }\n\n // ── Phase 2: graph rule (generation-inversion) — gated ONLY on the reference-integrity\n // codes that corrupt the parent→child walk. A non-integer generation or a too-many-\n // conditions defect leaves the parent→child relation walkable, so it does NOT suppress\n // this phase (suppressing would hide an honest inversion, breaking the throw-with-ALL\n // doctrine). A NaN generation simply never satisfies the strict `>` comparison below. ─\n const GRAPH_BLOCKING: ReadonlySet<PedigreeIssueCode> = new Set([\n \"duplicate-id\",\n \"unknown-partner\",\n \"unknown-sibship-mating\",\n \"unknown-child\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n for (const s of sibships) {\n const mating = matingById.get(s.matingId);\n if (mating === undefined) continue;\n const a = individualById.get(mating.partnerAId);\n const b = individualById.get(mating.partnerBId);\n // A child must sit BELOW (strictly greater generation than) the LOWER of its parents\n // (the row the sibship hangs from — §1.4). Cross-generation matings are tolerated; a\n // child older than the parent row it descends from is an inversion (the tree flips).\n const parentGenerations = [a, b]\n .filter((p): p is Individual => p !== undefined && Number.isInteger(p.generation))\n .map((p) => p.generation);\n if (parentGenerations.length === 0) continue;\n const parentRow = Math.max(...parentGenerations);\n for (const childId of s.childIds) {\n const child = individualById.get(childId);\n if (child === undefined || !Number.isInteger(child.generation)) continue;\n if (child.generation <= parentRow) {\n push(\n \"generation-inversion\",\n `child ${childId} (generation ${child.generation}) is not below its parents (generation ${parentRow}) in sibship ${s.id}`,\n );\n }\n }\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws PedigreeValidationError (carrying ALL issues) when the input is invalid. */\nexport function validatePedigree(input: PedigreeInput): void {\n const issues = pedigreeIssues(input);\n if (issues.length > 0) throw new PedigreeValidationError(issues);\n}\n","// PURE pedigree layout — the single source of truth for positioning and connector\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so web/PDF/image\n// surfaces never drift. Deliberately PURE (no DOM, no clock, no randomness): the same\n// input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS what the caller declared. Validation\n// (./validate.ts) THROWS on a structurally invalid pedigree instead of repairing it — a\n// pedigree is a clinical record and silently altering its topology is a medical error.\n//\n// Notation: Bennett et al. 2008 PSSC (see ./types.ts header). Roman-numeral generations\n// (I, II, III…) in a left gutter, oldest = I on top; individuals numbered left-to-right\n// within a generation (the \"II-3\" address). Mating line (horizontal, between partners);\n// consanguineous = DOUBLE line; sibship drop-bar above sibs; one riser per child; twins\n// CONVERGE on the bar (MZ tie-bar / DZ none / unknown \"?\").\n//\n// LAYOUT — a GENERATION-ANCHORED FOREST SPAN-PACKER (the fault-tree's subtree-span packer,\n// inverted to be generation-anchored, §1.4):\n// 1. Rows by generation. Distinct generation values sorted ascending → row 0..R-1, top\n// to bottom (smaller = older = higher). Each row's y accrues prior rowHeights +\n// corridors (the fault-tree rowTop recurrence, keyed on generation not depth).\n// 2. Horizontal: a FOREST of mating subtrees. Each mating is a sub-root whose children\n// are its sibship members; we pack each subtree with asymmetric {spanL, spanR} exactly\n// like the fault-tree pack(). A child that is itself a mating partner roots its own\n// subtree below; founders/loose individuals are placed left-to-right after the forest.\n// Span intervals are disjoint by construction (the fault-tree inductive overlap proof\n// carries over — each subtree owns a disjoint x-interval), re-verified by the harness.\n// 3. Mating line at the partners' shared y (or a two-segment elbow for a cross-generation\n// mating — avuncular unions are clinically real, §1.7); consanguineous = two parallel\n// horizontals CONSANG_GAP apart.\n// 4. Twins (§1.4 / PSSC, VERIFY against Bennett et al. 2008 Fig. 2 twin panel before\n// trusting): the risers of a twin group CONVERGE to a single point on the sibship bar,\n// then split to each glyph. The route is fully ORTHOGONAL (down to a junction y,\n// HORIZONTAL to each twin's x, then DOWN to the glyph — never a diagonal fan, so the\n// overlap harness's nonOrthogonal check passes like every structural element). MZ adds\n// a short horizontal tie-bar between the convergent risers below the junction; DZ adds\n// none; unknown places a \"?\" glyph at the junction (a NODE annotation, harness-excluded\n// like the proband arrow + deceased slash).\n\nimport { clampLabel, estimateTextWidth, romanNumeral, wrapLabelBalanced, type Point } from \"../core\";\nimport { PEDIGREE_TITLE_LABELS_EN, type PedigreeTitleLabels } from \"./labels\";\nimport { validatePedigree } from \"./validate\";\nimport type { NodeShape } from \"../genogram/types\";\nimport type {\n Condition,\n Individual,\n Mating,\n PedigreeInput,\n PedigreeRole,\n Sibship,\n Zygosity,\n} from \"./types\";\n\nexport {\n PedigreeValidationError,\n pedigreeIssues,\n validatePedigree,\n type PedigreeIssue,\n type PedigreeIssueCode,\n} from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render). PREFIXED\n// (PED_*) so the root barrel's `export *` never collides with another module's value\n// constants (the v0.2 FT_LABEL_FONT rename class). ───────────────────────────────────\n/** Glyph side length / diameter (px). */\nexport const PED_GLYPH = 40;\n/** Node label font size (px). */\nexport const PED_LABEL_FONT = 12;\n/** Line height for stacked label lines (px). */\nexport const PED_LABEL_LINE_H = 14;\n/** Font size for the \"II-3\" within-generation address drawn under each glyph. */\nexport const PED_ADDRESS_FONT = 10;\n/** Gap from a glyph's bottom to the top of its first label line. */\nexport const PED_LABEL_GAP = 6;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────────\nconst PADDING = 32;\n/** Left gutter reserved for the Roman-numeral generation labels. */\nconst GUTTER = 36;\n/** Min horizontal air between two sibling/subtree intervals. */\nconst H_GAP = 28;\n/** Horizontal run of a mating line on each side of a partner glyph edge. */\nconst MATING_RUN = 22;\n/** Vertical band between a parent row's bottom and the next row (descent routes here). */\nconst CORRIDOR = 44;\n/** Drop of the twin convergence junction below the sibship bar. */\nconst TWIN_JUNCTION_DROP = 12;\n/** Gap from a hub's glyph bottom to the FIRST appended-spouse bridge dip (the genogram\n * serial-union stagger band: dips sit below the glyphs, ABOVE the labels). */\nconst BRIDGE_DIP_GAP = 10;\n/** Vertical step between successive appended-spouse bridge dips on the same row. */\nconst BRIDGE_DIP_STEP = 7;\n/** Horizontal step of each appended-spouse bridge's stub along the glyph's bottom edge, so two\n * bridges in the same row leave distinct stub columns (never a collinear shared vertical). The\n * small step keeps several distinct stubs inside the half-glyph even for a many-spouse hub. */\nconst BRIDGE_STUB_X_STEP = 3;\n\n// ── Namespaced element ids (one element kind per numeric block, extending the\n// genogram/fault-tree convention) — every data-edge-id stays traceable to its row. ──\nexport const PED_MATING_ID_BASE = 1_000_000; // + mating id (mating line; consang drawn double)\nexport const PED_DESCENT_ID_BASE = 2_000_000; // + sibship id (mating midpoint → sibship bar)\nexport const PED_SIBBAR_ID_BASE = 3_000_000; // + sibship id (the horizontal sibship bar)\nexport const PED_RISER_ID_BASE = 4_000_000; // + child individual id (bar → child)\nexport const PED_TWINBAR_ID_BASE = 5_000_000; // + (sibship id * 100 + twin ordinal) (MZ tie-bar)\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nfunction shapeForSex(sex: Individual[\"sex\"]): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────────\n\nexport interface PedigreeNode {\n individualId: number;\n shape: NodeShape;\n cx: number;\n cy: number;\n size: number;\n deceased: boolean;\n carrier: boolean;\n role: PedigreeRole;\n stillbirth: boolean;\n /** Condition ids in declared order → vertical fill partitions (≤4); [] = unaffected. */\n affectedBy: number[];\n labelLines: string[];\n /** Top of the first label line's box (below the glyph). */\n labelTop: number;\n /** \"II-3\" within-generation address. */\n addressLabel: string;\n /** Verbatim <title> text (never truncated). */\n title: string;\n}\n\nexport type PedigreeElementKind =\n | \"mating\"\n | \"mating-elbow\"\n | \"descent\"\n | \"sibship-bar\"\n | \"riser\"\n | \"twin-bar\";\n\nexport interface PedigreeElement {\n /** Namespaced id (PED_*_ID_BASE + …). */\n edgeId: number;\n kind: PedigreeElementKind;\n /** Every consecutive pair axis-aligned. */\n points: Point[];\n /** mating: draw a second parallel line (the PSSC consanguineous double line). */\n consanguineous: boolean;\n title: string;\n}\n\n/** Roman label + the y of a generation row (the left-margin gutter). */\nexport interface PedigreeGenerationLabel {\n roman: string;\n y: number;\n}\n\nexport interface PedigreeLayout {\n width: number;\n height: number;\n nodes: PedigreeNode[];\n elements: PedigreeElement[];\n generations: PedigreeGenerationLabel[];\n /** Used condition ids in declared order → assigned fill ink + verbatim label (the legend\n * keys these; label kept here so the emitter never re-derives it from a node title). */\n conditionFills: { id: number; ink: string; label: string }[];\n /** Twin zygosities actually used (drives the used-keys-only legend). */\n twinZygositiesUsed: Zygosity[];\n /** Junction points of unknown-zygosity twin groups — the emitter draws a \"?\" at each. */\n unknownTwinJunctions: Point[];\n /** Individuals in no mating and no sibship — grouped + drawn aside (genogram precedent). */\n isolatedIndividualIds: number[];\n}\n\nexport interface PedigreeLayoutOptions {\n /** Cap each node's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for <title>s — English default; see locale packs. */\n titleLabels?: PedigreeTitleLabels;\n}\n\n/**\n * Fixed condition fill ramp — the existing zinc ink array (NO new palette, §1.7). At most\n * 4 conditions are ever drawn (the PSSC quadrant cap, enforced in ./validate.ts), so 4\n * distinct, decodable solids suffice; the legend keys each one.\n */\nexport const PED_CONDITION_FILLS = [\"#52525b\", \"#a1a1aa\", \"#3f3f46\", \"#71717a\"] as const;\n\n// ── Measurement ───────────────────────────────────────────────────────────────────────\n\nfunction wrapPedigreeLabel(displayLabel: string): string[] {\n if (displayLabel === \"\") return [];\n return wrapLabelBalanced(displayLabel, 2);\n}\n\nfunction individualTitle(ind: Individual, address: string, conditionLabelById: Map<number, string>, titleLabels: PedigreeTitleLabels): string {\n if (ind.title !== undefined) return ind.title;\n const parts: string[] = [`${address} · ${ind.label}`];\n if (ind.affectedBy.length > 0) {\n const names = ind.affectedBy.map((id) => conditionLabelById.get(id) ?? String(id));\n parts.push(`${titleLabels.affected}: ${names.join(\", \")}`);\n }\n if (ind.carrier && ind.affectedBy.length === 0) parts.push(titleLabels.carrier);\n if (ind.deceased) parts.push(titleLabels.deceased);\n if (ind.role === \"proband\") parts.push(titleLabels.proband);\n else if (ind.role === \"consultand\") parts.push(titleLabels.consultand);\n if (ind.lifeStatus === \"stillbirth\") parts.push(titleLabels.stillbirth);\n return parts.join(\" · \");\n}\n\n// ── Internal working model ──────────────────────────────────────────────────────────────\n\ninterface Placed {\n ind: Individual;\n cx: number;\n /** Sub-tree half-extents (cover this individual's entire subtree drawing). */\n spanL: number;\n spanR: number;\n}\n\n/**\n * Deterministic, overlap-proof pedigree layout (pure function of the inputs). Validates\n * first and THROWS PedigreeValidationError on a structurally invalid pedigree — never\n * sanitizes. Empty input yields an empty, padded layout.\n */\nexport function computePedigreeLayout(\n input: PedigreeInput,\n opts: PedigreeLayoutOptions = {},\n): PedigreeLayout {\n if (input.individuals.length === 0 && input.matings.length === 0 && input.sibships.length === 0) {\n return {\n width: PADDING * 2,\n height: PADDING * 2,\n nodes: [],\n elements: [],\n generations: [],\n conditionFills: [],\n twinZygositiesUsed: [],\n unknownTwinJunctions: [],\n isolatedIndividualIds: [],\n };\n }\n validatePedigree(input);\n\n const titleLabels = opts.titleLabels ?? PEDIGREE_TITLE_LABELS_EN;\n const individuals = [...input.individuals].sort((a, b) => a.id - b.id);\n const individualById = new Map(individuals.map((i) => [i.id, i]));\n const matings = [...input.matings].sort((a, b) => a.id - b.id);\n const sibships = [...input.sibships].sort((a, b) => a.id - b.id);\n const conditionLabelById = new Map<number, string>(input.conditions.map((c: Condition) => [c.id, c.label]));\n\n // Normalize partner order (a < b) so the pair is unordered, deterministic geometry.\n const partnersOf = (m: Mating): [number, number] =>\n m.partnerAId <= m.partnerBId ? [m.partnerAId, m.partnerBId] : [m.partnerBId, m.partnerAId];\n\n // ── Generation rows: distinct generations ascending → row index 0..R-1. ─────────────\n const distinctGenerations = [...new Set(individuals.map((i) => i.generation))].sort((a, b) => a - b);\n const rowOfGeneration = new Map<number, number>();\n distinctGenerations.forEach((g, i) => rowOfGeneration.set(g, i));\n const rowCount = distinctGenerations.length;\n\n // ── Measure each individual's label block (used for span half-extents). ─────────────\n const labelLinesOf = new Map<number, string[]>();\n for (const ind of individuals) {\n labelLinesOf.set(ind.id, wrapPedigreeLabel(clampLabel(ind.label, opts.maxLabelChars)));\n }\n const nodeHalfWidth = (ind: Individual): number => {\n const lines = labelLinesOf.get(ind.id) ?? [];\n const labelW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, PED_LABEL_FONT)), 0);\n return Math.max(PED_GLYPH, labelW) / 2;\n };\n\n // ── Build the descent forest. A \"sibship subtree\" hangs a mating's children below it;\n // a child that is itself a mating partner roots its own mating subtree. We place by a\n // fault-tree-style post-order span pack over this forest. ──────────────────────────\n const childToSibship = new Map<number, Sibship>();\n for (const s of sibships) for (const c of s.childIds) childToSibship.set(c, s);\n const sibshipByMating = new Map<number, Sibship[]>();\n for (const s of sibships) {\n const arr = sibshipByMating.get(s.matingId) ?? [];\n arr.push(s);\n sibshipByMating.set(s.matingId, arr);\n }\n // Matings an individual partners in (declared id order for a stable tie-break).\n const matingsOfIndividual = new Map<number, Mating[]>();\n for (const m of matings) {\n for (const p of partnersOf(m)) {\n const arr = matingsOfIndividual.get(p) ?? [];\n arr.push(m);\n matingsOfIndividual.set(p, arr);\n }\n }\n\n const placedById = new Map<number, Placed>();\n // Cursor: the next free left edge for a new forest tree (kept ≥ existing extents).\n let cursorX = PADDING + GUTTER;\n\n /** Places a single individual glyph as a leaf subtree (no descent below it here). */\n const placeLeaf = (ind: Individual, leftEdge: number): Placed => {\n const half = nodeHalfWidth(ind);\n const cx = leftEdge + half;\n const placed: Placed = { ind, cx, spanL: half, spanR: half };\n placedById.set(ind.id, placed);\n return placed;\n };\n\n // To stay overlap-proof, place matings as left-to-right blocks. Each mating block =\n // [spouse glyph] over its FULL children band, with the shared (hub) partner placed once\n // and every later mating of that hub appended in a DISJOINT x-interval to the right of all\n // its earlier blocks. A child that is a partner of a LOWER mating roots that mating block\n // recursively beneath it. Founders not in any mating come last.\n const placedMatings = new Set<number>();\n const matingCount = (id: number): number => (matingsOfIndividual.get(id) ?? []).length;\n // Hub bookkeeping. A HUB is an individual in ≥2 matings (remarriage / serial union). It is\n // placed ONCE (by its first packed mating) and pinned; `hubCursor` is the next free left\n // edge to the RIGHT of every block already hung off that hub, so each subsequent spouse\n // block owns a truly disjoint interval (§1.4 invariant restored on the shared-parent path).\n // `hubSpouseSeq` counts spouses placed beside the hub so far (only the placement order).\n const hubCursor = new Map<number, number>();\n const hubSpouseSeq = new Map<number, number>();\n\n /**\n * Packs a mating subtree starting at `leftEdge`; returns the right edge consumed. The\n * sibship's children are packed FIRST into a disjoint band, the spouse is centered over\n * that band, and the partner (or the already-placed hub) sits adjacent to the spouse — so\n * the whole block (spouse + its children) owns one disjoint x-interval. A child that\n * partners a lower mating roots that mating block recursively beneath it.\n */\n const packMating = (mating: Mating, leftEdge: number): number => {\n placedMatings.add(mating.id);\n const [aId, bId] = partnersOf(mating);\n const a = individualById.get(aId)!;\n const b = individualById.get(bId)!;\n const aHalf = nodeHalfWidth(a);\n const bHalf = nodeHalfWidth(b);\n // SYMMETRIC half-separation about the pair midpoint so the descent channel (dropping\n // from the midpoint) stays clear of BOTH partner labels: each cx sits `halfSep` from the\n // midpoint, halfSep ≥ each node's half-width + MATING_RUN, so neither label box reaches\n // the midpoint (a wide label on ONE side previously crossed it — the harness caught it).\n const halfSep = Math.max(aHalf, bHalf) + MATING_RUN;\n\n const aPlaced = placedById.get(aId);\n const bPlaced = placedById.get(bId);\n // Identify the HUB partner (already placed by a prior mating, OR a fresh ≥2-mating\n // individual we now pin) and the NEW SPOUSE (the not-yet-placed partner). When neither is\n // placed and neither is a hub, it is an ordinary couple — handled in the `else` below.\n const hubId =\n aPlaced !== undefined ? aId : bPlaced !== undefined ? bId : matingCount(aId) >= 2 ? aId : matingCount(bId) >= 2 ? bId : null;\n\n // The block's children own a disjoint band starting at `blockLeft`; we recenter the\n // spouse over that band afterwards. A later mating of a hub starts at the hub's cursor.\n const blockLeft = hubId !== null && hubCursor.has(hubId) ? hubCursor.get(hubId)! : leftEdge;\n\n // ── Pack the sibship's children FIRST into [blockLeft … childrenRight], each child a leaf\n // or its own recursively-packed lower mating block — disjoint by construction. ───────\n const sibs = (sibshipByMating.get(mating.id) ?? []).sort((s1, s2) => s1.id - s2.id);\n const childIds = sibs.flatMap((s) => s.childIds);\n let childCursor = blockLeft;\n let childLeft = Number.POSITIVE_INFINITY;\n let childrenRight = blockLeft;\n let placedAnyChild = false;\n for (const childId of childIds) {\n const child = individualById.get(childId);\n if (child === undefined || placedById.has(childId)) continue;\n // The child roots a recursive mating block ONLY when it is the SENIOR (same/younger\n // generation) partner of an unplaced mating. If its only unplaced mating is to an OLDER\n // partner (an avuncular union — the child is the junior partner, e.g. uncle × niece where\n // the niece is also a sibship child here), the child is placed as a LEAF and the union is\n // drawn later as a cross-generation elbow — never fanned as a spouse block (which would\n // wrongly pin the older partner as a hub and overlap this sibship row).\n const downMating = (matingsOfIndividual.get(childId) ?? []).find((m) => {\n if (placedMatings.has(m.id)) return false;\n const [pa, pb] = partnersOf(m);\n const otherId = pa === childId ? pb : pa;\n const other = individualById.get(otherId);\n // Senior-or-equal: the child's generation is ≤ the partner's (descends or same row).\n return other === undefined || child.generation <= other.generation;\n });\n if (downMating !== undefined) {\n const right = packMating(downMating, childCursor);\n childLeft = Math.min(childLeft, placedById.get(childId)!.cx - nodeHalfWidth(child));\n childrenRight = right;\n childCursor = right + H_GAP;\n } else {\n const placed = placeLeaf(child, childCursor);\n childLeft = Math.min(childLeft, placed.cx - placed.spanL);\n childrenRight = placed.cx + placed.spanR;\n childCursor = childrenRight + H_GAP;\n }\n placedAnyChild = true;\n }\n const bandMid = placedAnyChild ? (childLeft + childrenRight) / 2 : blockLeft + halfSep;\n\n // ── Seat the partners. The SPOUSE centers over its own children band; the HUB sits one\n // halfSep to the LEFT of the spouse (so every appended spouse fans rightward and each\n // mating line is hub-edge → adjacent-spouse-edge). A pinned hub keeps its x; the spouse\n // then sits one halfSep to its RIGHT but never left of its own band. ──────────────────\n // The pair midpoint (and thus the descent origin) is recomputed from the final cx's in the\n // mating-line pass, so we only need to SEAT each partner's cx here.\n if (hubId === null) {\n // Ordinary couple: midpoint over the children band; partners ±halfSep around it.\n const pairMid = placedAnyChild ? bandMid : blockLeft + Math.max(aHalf, bHalf) + halfSep;\n placedById.set(aId, { ind: a, cx: pairMid - halfSep, spanL: aHalf, spanR: aHalf });\n placedById.set(bId, { ind: b, cx: pairMid + halfSep, spanL: bHalf, spanR: bHalf });\n } else {\n const spouseId = hubId === aId ? bId : aId;\n const spouse = individualById.get(spouseId)!;\n const spouseHalf = nodeHalfWidth(spouse);\n const hubHalf = nodeHalfWidth(individualById.get(hubId)!);\n const seq = hubSpouseSeq.get(hubId) ?? 0;\n const hubExisting = placedById.get(hubId);\n // Spouse centers over its band, but never so far left that the hub (one halfSep further\n // left, glyph half-width hubHalf) would cross blockLeft: hubCx − hubHalf ≥ blockLeft ⇒\n // spouseCx ≥ blockLeft + hubHalf + halfSep.\n const minSpouseCx = blockLeft + hubHalf + halfSep;\n let spouseCx = placedAnyChild ? Math.max(bandMid, minSpouseCx) : minSpouseCx + spouseHalf;\n if (hubExisting === undefined) {\n // First mating of this hub: pin the hub one halfSep left of the spouse.\n placedById.set(hubId, { ind: individualById.get(hubId)!, cx: spouseCx - halfSep, spanL: hubHalf, spanR: hubHalf });\n } else {\n // Later mating: the hub is pinned; the spouse fans to the right of all earlier blocks.\n spouseCx = Math.max(spouseCx, hubExisting.cx + halfSep);\n }\n placedById.set(spouseId, { ind: spouse, cx: spouseCx, spanL: spouseHalf, spanR: spouseHalf });\n hubSpouseSeq.set(hubId, seq + 1);\n }\n\n const blockRight = Math.max(\n childrenRight,\n placedById.get(aId)!.cx + nodeHalfWidth(a),\n placedById.get(bId)!.cx + nodeHalfWidth(b),\n );\n // Advance the hub's cursor past THIS block so the hub's next mating starts disjoint.\n if (hubId !== null) hubCursor.set(hubId, blockRight + H_GAP);\n return blockRight;\n };\n\n // Top matings: those whose partners are not children of any (already-traversable) sibship\n // higher up. We simply pack matings that are not yet placed, in id order, each as a new\n // forest tree; a mating reached as a descendant is consumed there (placedMatings guards\n // re-entry). Sorting by the shallower partner generation first keeps founders on top.\n const generationOfMating = (m: Mating): number => {\n const [aId, bId] = partnersOf(m);\n const a = individualById.get(aId);\n const b = individualById.get(bId);\n const gens = [a, b].filter((p): p is Individual => p !== undefined).map((p) => p.generation);\n return gens.length > 0 ? Math.min(...gens) : 0;\n };\n const rootMatings = matings\n .filter((m) => {\n // A mating is a forest ROOT when neither partner descends from a sibship (i.e. is a\n // founder pair) — those reached through a parent's sibship are packed recursively.\n const [aId, bId] = partnersOf(m);\n return !childToSibship.has(aId) && !childToSibship.has(bId);\n })\n .sort((m1, m2) => generationOfMating(m1) - generationOfMating(m2) || m1.id - m2.id);\n\n for (const m of rootMatings) {\n if (placedMatings.has(m.id)) continue;\n const right = packMating(m, cursorX);\n cursorX = right + H_GAP * 2;\n }\n // Any mating not reachable from a root (e.g. a married-in spouse whose own parents are not\n // in the pedigree but who is a descendant elsewhere) — pack remaining in id order.\n for (const m of matings) {\n if (placedMatings.has(m.id)) continue;\n const right = packMating(m, cursorX);\n cursorX = right + H_GAP * 2;\n }\n\n // Isolated individuals (no mating, no sibship membership) — drawn aside in a row group.\n const inAnyMating = new Set<number>();\n for (const m of matings) for (const p of partnersOf(m)) inAnyMating.add(p);\n const isolatedIndividualIds = individuals\n .filter((i) => !inAnyMating.has(i.id) && !childToSibship.has(i.id))\n .map((i) => i.id);\n for (const id of isolatedIndividualIds) {\n const ind = individualById.get(id)!;\n if (placedById.has(id)) continue;\n placeLeaf(ind, cursorX);\n cursorX = placedById.get(id)!.cx + nodeHalfWidth(ind) + H_GAP;\n }\n\n // Place any remaining declared individual (a child whose mating was packed already covers\n // it; this catches a stray child of an un-rooted sibship) as a trailing leaf.\n for (const ind of individuals) {\n if (placedById.has(ind.id)) continue;\n placeLeaf(ind, cursorX);\n cursorX = placedById.get(ind.id)!.cx + nodeHalfWidth(ind) + H_GAP;\n }\n\n // ── Bridge slots (post-placement, from ACTUAL adjacency). A same-generation mating whose two\n // partners have ANOTHER placed same-row individual strictly BETWEEN them needs a dipped\n // bridge line (a straight line would run through that glyph and overlap the hub's other\n // lines). Slot 0 = straight (adjacent); slot ≥ 1 = dip, staggered per ROW so co-resident\n // dips never share a depth. Driven by geometry, not placement order, so it is correct even\n // when a SPOUSE later becomes a hub for its own remarriage (both-partners-are-hubs). ──────\n const matingBridgeSlot = new Map<number, number>();\n {\n const dipSlotByRow = new Map<number, number>(); // next free dip slot per row\n // Stable order: ascending mating id, so slot assignment is deterministic.\n for (const m of [...matings].sort((m1, m2) => m1.id - m2.id)) {\n const [aId, bId] = partnersOf(m);\n const a = individualById.get(aId);\n const b = individualById.get(bId);\n if (a === undefined || b === undefined) continue;\n if (a.generation !== b.generation) continue; // cross-gen → handled as an elbow, never a dip\n const row = rowOfGeneration.get(a.generation)!;\n const loX = Math.min(placedById.get(aId)!.cx, placedById.get(bId)!.cx);\n const hiX = Math.max(placedById.get(aId)!.cx, placedById.get(bId)!.cx);\n // Any OTHER same-row placed individual whose glyph center sits strictly between them?\n const blocked = individuals.some(\n (i) =>\n i.id !== aId &&\n i.id !== bId &&\n rowOfGeneration.get(i.generation) === row &&\n placedById.has(i.id) &&\n placedById.get(i.id)!.cx > loX + 0.01 &&\n placedById.get(i.id)!.cx < hiX - 0.01,\n );\n if (!blocked) {\n matingBridgeSlot.set(m.id, 0);\n continue;\n }\n const slot = (dipSlotByRow.get(row) ?? 0) + 1;\n dipSlotByRow.set(row, slot);\n matingBridgeSlot.set(m.id, slot);\n }\n }\n\n // ── Reserve a serial-union DIP BAND per row (the genogram FIX-B precedent): an appended\n // spouse of a hub (matingBridgeSlot ≥ 1) bridges to the hub below the glyphs but ABOVE the\n // labels, so the row's labels must sit below the deepest dip. The band height is the\n // deepest slot on that row; 0 when the row has no appended-spouse bridge. ────────────────\n const rowDipBand: number[] = new Array(rowCount).fill(0);\n for (const m of matings) {\n const slot = matingBridgeSlot.get(m.id) ?? 0;\n if (slot < 1) continue;\n const [aId, bId] = partnersOf(m);\n const a = individualById.get(aId);\n const b = individualById.get(bId);\n const gens = [a, b].filter((p): p is Individual => p !== undefined).map((p) => p.generation);\n if (gens.length === 0) continue;\n const row = rowOfGeneration.get(Math.min(...gens))!; // a hub bridge is intra-row; min is safe\n rowDipBand[row] = Math.max(rowDipBand[row]!, BRIDGE_DIP_GAP + slot * BRIDGE_DIP_STEP + PED_LABEL_GAP);\n }\n\n // ── Vertical: row heights from the tallest label block in each row + the dip band; rows\n // stacked with a CORRIDOR between them (the descent routes there). ───────────────────────\n const rowHeight: number[] = new Array(rowCount).fill(0);\n for (const ind of individuals) {\n const row = rowOfGeneration.get(ind.generation)!;\n const lines = labelLinesOf.get(ind.id) ?? [];\n // glyph + dip band (label-free) + address line + label lines\n const h = PED_GLYPH + PED_LABEL_GAP + rowDipBand[row]! + (lines.length + 1) * PED_LABEL_LINE_H;\n rowHeight[row] = Math.max(rowHeight[row]!, h);\n }\n const rowTop: number[] = [PADDING];\n for (let r = 0; r < rowCount - 1; r++) {\n rowTop.push(rowTop[r]! + rowHeight[r]! + CORRIDOR);\n }\n // Glyph center y for a generation row (glyph sits at the top of its row block).\n const glyphCyOfRow = (row: number): number => rowTop[row]! + PED_GLYPH / 2;\n\n // ── Within-generation addressing: I, II, III…-<n>, numbered left-to-right by cx. ──────\n const addressByIndividual = new Map<number, string>();\n for (let row = 0; row < rowCount; row++) {\n const roman = romanNumeral(row + 1);\n const inRow = individuals\n .filter((i) => rowOfGeneration.get(i.generation) === row)\n .sort((a, b) => placedById.get(a.id)!.cx - placedById.get(b.id)!.cx || a.id - b.id);\n inRow.forEach((ind, i) => addressByIndividual.set(ind.id, `${roman}-${i + 1}`));\n }\n\n // ── Used condition fills. Keyed by condition id ASCENDING (a STABLE order independent of\n // the input.conditions array order — reordering that array must not swap inks, matching\n // the individuals/matings/sibships shuffle-invariance), the legend keys these. ─────────\n const declaredConditionIds = new Set(input.conditions.map((c) => c.id));\n const usedConditionIds = [...new Set(individuals.flatMap((i) => i.affectedBy))]\n .filter((id) => declaredConditionIds.has(id))\n .sort((x, y) => x - y);\n const conditionFills = usedConditionIds.map((id, i) => ({\n id,\n ink: PED_CONDITION_FILLS[i % PED_CONDITION_FILLS.length]!,\n label: conditionLabelById.get(id) ?? `condition ${id}`,\n }));\n\n // ── Emit nodes. ───────────────────────────────────────────────────────────────────────\n const nodes: PedigreeNode[] = [];\n for (const ind of individuals) {\n const placed = placedById.get(ind.id)!;\n const row = rowOfGeneration.get(ind.generation)!;\n const cy = glyphCyOfRow(row);\n const lines = labelLinesOf.get(ind.id) ?? [];\n const address = addressByIndividual.get(ind.id)!;\n nodes.push({\n individualId: ind.id,\n shape: shapeForSex(ind.sex),\n cx: round(placed.cx),\n cy: round(cy),\n size: PED_GLYPH,\n deceased: ind.deceased,\n carrier: ind.carrier,\n role: ind.role,\n stillbirth: ind.lifeStatus === \"stillbirth\",\n affectedBy: ind.affectedBy,\n labelLines: lines,\n // Labels sit BELOW the row's serial-union dip band (rowDipBand) so a hub's bridge dips\n // never cross a label box.\n labelTop: round(cy + PED_GLYPH / 2 + PED_LABEL_GAP + rowDipBand[row]!),\n addressLabel: address,\n title: individualTitle(ind, address, conditionLabelById, titleLabels),\n });\n }\n\n // ── Emit elements: mating lines, descents, sibship bars, risers, twin bars. ───────────\n const elements: PedigreeElement[] = [];\n const cxOf = (id: number): number => placedById.get(id)!.cx;\n const cyOf = (id: number): number => glyphCyOfRow(rowOfGeneration.get(individualById.get(id)!.generation)!);\n // Connectors attach at the GLYPH edge (uniform glyph; labels hang below, never sideways).\n const GLYPH_HALF = PED_GLYPH / 2;\n\n // Children's bar-center x per mating (min→max child cx). The descent drops from the mating\n // line at THIS x when it falls within the line span, so the straight (non-hub) descent stays\n // a single VERTICAL with no corridor bend — a bend leg would otherwise sit in the same band\n // as a hub's dipped bridge line and overlap it collinearly (the harness caught exactly that).\n const matingBarCenter = new Map<number, number>();\n for (const s of sibships) {\n const childIds = s.childIds.filter((id) => placedById.has(id));\n if (childIds.length === 0) continue;\n const xs = childIds.map(cxOf);\n const center = (Math.min(...xs) + Math.max(...xs)) / 2;\n // Several sibships of one mating share the descent origin (rare) — last write wins; the\n // descent code re-derives each sibship's own bar center, the origin only needs to be ON\n // the mating line, so any in-span value keeps the descent vertical for the common case.\n matingBarCenter.set(s.matingId, center);\n }\n\n // Mating lines (consanguineous → flagged; the emitter draws the double line).\n const matingMidpoint = new Map<number, Point>();\n // A hub's appended spouse (matingBridgeSlot ≥ 1) sits BEYOND an intermediate spouse on the\n // same row, so a straight glyph-y line would run through that spouse and overlap the hub's\n // other lines. Route it as an orthogonal elbow that DIPS into the row's reserved serial-union\n // band (rowDipBand — below the glyphs, ABOVE the labels, the genogram FIX-B precedent): a\n // stub leaves the HUB and the SPOUSE glyph BOTTOM at per-slot staggered x's (so two bridges\n // off one hub never share a vertical), drops to a per-slot dipY, and crosses below every\n // intermediate spouse glyph. The descent of a dipped mating then drops from the dip leg.\n const bridgeDipY = (slot: number): number => BRIDGE_DIP_GAP + slot * BRIDGE_DIP_STEP;\n for (const m of matings) {\n const [aId, bId] = partnersOf(m);\n const ax = cxOf(aId);\n const bx = cxOf(bId);\n const ay = cyOf(aId);\n const by = cyOf(bId);\n const leftId = ax <= bx ? aId : bId;\n const rightId = ax <= bx ? bId : aId;\n const lx = cxOf(leftId) + GLYPH_HALF;\n const rx = cxOf(rightId) - GLYPH_HALF;\n const title = m.consanguineous ? titleLabels.consanguineous : titleLabels.mating;\n const bridgeSlot = matingBridgeSlot.get(m.id) ?? 0;\n if (ay === by && bridgeSlot >= 1) {\n // Same-row mating whose spouse sits BEYOND an intermediate spouse (a hub's 2nd+ appended\n // mating) → orthogonal dip elbow in the reserved dip band. The hub is the LEFT partner by\n // construction (placed at spouse − halfSep). Stubs leave each glyph bottom at a per-slot\n // staggered x within the glyph so two bridges off one hub get distinct stub columns.\n const hubCx = cxOf(leftId);\n const spouseCx = cxOf(rightId);\n const glyphBottom = ay + GLYPH_HALF;\n const dipY = glyphBottom + bridgeDipY(bridgeSlot);\n const stubOff = Math.min(bridgeSlot * BRIDGE_STUB_X_STEP, GLYPH_HALF - 4);\n const hubStubX = hubCx + stubOff; // hub's partner is to the RIGHT → stub right-of-center\n const spouseStubX = spouseCx - stubOff; // spouse's partner is to the LEFT → left-of-center\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating-elbow\",\n points: [\n { x: round(hubStubX), y: round(glyphBottom) },\n { x: round(hubStubX), y: round(dipY) },\n { x: round(spouseStubX), y: round(dipY) },\n { x: round(spouseStubX), y: round(glyphBottom) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n // Descent hangs off the dip leg's center, already below the row's glyphs.\n matingMidpoint.set(m.id, { x: round((hubStubX + spouseStubX) / 2), y: round(dipY) });\n } else if (ay === by) {\n // Straight horizontal mating line at the shared row y.\n const y = ay;\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating\",\n points: [\n { x: round(lx), y: round(y) },\n { x: round(rx), y: round(y) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n // Drop the descent from above the children's bar center when that x stays inside the\n // LABEL-FREE channel between the partners' LABEL boxes (labels can be wider than glyphs,\n // so the channel is narrower than [lx, rx]); that keeps the descent a straight vertical\n // with no corridor bend. Otherwise drop from the pair midpoint (clear by the symmetric\n // halfSep) and let it bend in the lower corridor band. Aligning the origin matters most\n // for a hub whose appended-spouse dips occupy the upper band — a bend there would overlap\n // a dip; for plain matings the band separation keeps a bend safe either way.\n const midX = (lx + rx) / 2;\n const channelLeft = cxOf(leftId) + nodeHalfWidth(individualById.get(leftId)!);\n const channelRight = cxOf(rightId) - nodeHalfWidth(individualById.get(rightId)!);\n const barCenter = matingBarCenter.get(m.id);\n const originX =\n barCenter !== undefined && barCenter >= channelLeft && barCenter <= channelRight ? barCenter : midX;\n matingMidpoint.set(m.id, { x: round(originX), y: round(y) });\n } else {\n // Cross-generation mating → an orthogonal elbow (avuncular, §1.7). Route out of the\n // higher partner, down to the lower partner's row, then in.\n const upId = ay <= by ? aId : bId;\n const downId = ay <= by ? bId : aId;\n const upX = cxOf(upId);\n const upY = cyOf(upId);\n const downX = cxOf(downId);\n const downY = cyOf(downId);\n // When the LOWER partner is itself a placed SIBSHIP CHILD (the canonical avuncular case —\n // uncle × niece where the niece is also a sibling on her row), the up partner usually has\n // a same-row spouse between them and the niece already carries a riser into her TOP edge.\n // A naive mid-x elbow would (a) run along the up row through that spouse and (b) drop a\n // vertical collinear with the niece's riser / the sibship descent. So route the elbow\n // DOWN out of the up partner's bottom edge, across a corridor lane BELOW the up row (clear\n // of the up-row labels), and into the lower partner's nearest SIDE edge (never its top —\n // that belongs to the riser). The simple married-in-founder elbow (lower partner NOT a\n // sibship child) keeps its proven mid-x routing.\n if (childToSibship.has(downId)) {\n // Exit the up partner on the side AWAY from the lower partner (the same-row spouse, if\n // any, sits between them on the toward side), clear of the up partner's own label, drop\n // into a corridor lane BELOW the up-row labels, traverse under everything to the lower\n // partner's FAR side, then in to its side edge (its top belongs to the riser).\n const upRow = rowOfGeneration.get(individualById.get(upId)!.generation)!;\n const laneY = rowTop[upRow]! + rowHeight[upRow]! + CORRIDOR / 4 + 4;\n const downRight = downX >= upX; // lower partner is to the right\n const upExitX = upX + (downRight ? -1 : 1) * (nodeHalfWidth(individualById.get(upId)!) + 6);\n const downFarX = downX + (downRight ? 1 : -1) * (GLYPH_HALF + H_GAP / 2);\n const downSideX = downX + (downRight ? 1 : -1) * GLYPH_HALF;\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating-elbow\",\n points: [\n { x: round(upX + (downRight ? -GLYPH_HALF : GLYPH_HALF)), y: round(upY) },\n { x: round(upExitX), y: round(upY) },\n { x: round(upExitX), y: round(laneY) },\n { x: round(downFarX), y: round(laneY) },\n { x: round(downFarX), y: round(downY) },\n { x: round(downSideX), y: round(downY) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n matingMidpoint.set(m.id, { x: round(downFarX), y: round(downY) });\n } else {\n const elbowX = (upX + downX) / 2;\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating-elbow\",\n points: [\n { x: round(upX + (downX >= upX ? GLYPH_HALF : -GLYPH_HALF)), y: round(upY) },\n { x: round(elbowX), y: round(upY) },\n { x: round(elbowX), y: round(downY) },\n { x: round(downX + (upX >= downX ? GLYPH_HALF : -GLYPH_HALF)), y: round(downY) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n matingMidpoint.set(m.id, { x: round(elbowX), y: round(downY) });\n }\n }\n }\n\n // Descent + sibship bar + risers (+ twin convergence). Collect twin metadata for the\n // emitter's used-keys-only legend + the unknown-zygosity \"?\" marks.\n const twinZygositiesUsedSet = new Set<Zygosity>();\n const unknownTwinJunctions: Point[] = [];\n // Lane index per child-row so two descents' corridor HORIZONTALS bend at distinct y's\n // (collinear corridor overlap otherwise — the harness caught it on remarriage).\n const bendLaneByRow = new Map<number, number>();\n for (const s of sibships) {\n const childIds = s.childIds.filter((id) => individualById.has(id));\n if (childIds.length === 0) continue;\n const mid = matingMidpoint.get(s.matingId);\n const childRow = rowOfGeneration.get(individualById.get(childIds[0]!)!.generation)!;\n const barY = rowTop[childRow]! - CORRIDOR / 2;\n const lane = bendLaneByRow.get(childRow) ?? 0;\n bendLaneByRow.set(childRow, lane + 1);\n const childXs = childIds.map(cxOf);\n const barLeft = Math.min(...childXs);\n const barRight = Math.max(...childXs);\n\n // Descent: mating midpoint → sibship bar (vertical when aligned; a two-segment elbow\n // when the midpoint x differs from the bar center). The midpoint is the parents' line\n // center; the bar center is the children's center — usually identical by construction.\n // The elbow's HORIZONTAL leg bends inside the CORRIDOR (just above the bar), never at\n // mid-height — a mid-height bend would run through the parents' label row (the harness\n // caught exactly this). The vertical drop stays at mid.x, which is label-free between\n // the partners by the symmetric half-separation above.\n if (mid !== undefined) {\n const barCenterX = (barLeft + barRight) / 2;\n // Stagger the corridor bend per lane so co-resident descents never share a horizontal.\n // Bends live in the LOWER half of the corridor (near the bar), reserving the upper half\n // for hub bridge-line dips so the two families of horizontals never overlap collinearly.\n const bendY = barY - 2 - (lane % 3) * 3; // lower-half, label-free corridor\n const descentPoints: Point[] =\n Math.abs(mid.x - barCenterX) < 0.01\n ? [\n { x: round(mid.x), y: round(mid.y) },\n { x: round(mid.x), y: round(barY) },\n ]\n : [\n { x: round(mid.x), y: round(mid.y) },\n { x: round(mid.x), y: round(bendY) },\n { x: round(barCenterX), y: round(bendY) },\n { x: round(barCenterX), y: round(barY) },\n ];\n elements.push({\n edgeId: PED_DESCENT_ID_BASE + s.id,\n kind: \"descent\",\n points: descentPoints,\n consanguineous: false,\n title: titleLabels.sibship,\n });\n }\n\n // Sibship bar (horizontal) spanning min→max child x — only when ≥2 children.\n if (childIds.length > 1) {\n elements.push({\n edgeId: PED_SIBBAR_ID_BASE + s.id,\n kind: \"sibship-bar\",\n points: [\n { x: round(barLeft), y: round(barY) },\n { x: round(barRight), y: round(barY) },\n ],\n consanguineous: false,\n title: titleLabels.sibship,\n });\n }\n\n // Map each child to a twin group (if any) for the convergence routing.\n const twinGroupOfChild = new Map<number, { ordinal: number; zygosity: Zygosity; members: number[] }>();\n s.twinGroups.forEach((tg, ordinal) => {\n const members = tg.childIds.filter((id) => childIds.includes(id));\n for (const id of members) twinGroupOfChild.set(id, { ordinal, zygosity: tg.zygosity, members });\n });\n const emittedTwinOrdinals = new Set<number>();\n\n for (const childId of childIds) {\n const cx = cxOf(childId);\n const childTop = cyOf(childId) - PED_GLYPH / 2;\n const tg = twinGroupOfChild.get(childId);\n if (tg === undefined) {\n // Plain riser: bar → child glyph top (vertical).\n elements.push({\n edgeId: PED_RISER_ID_BASE + childId,\n kind: \"riser\",\n points: [\n { x: round(cx), y: round(barY) },\n { x: round(cx), y: round(childTop) },\n ],\n consanguineous: false,\n title: titleLabels.sibship,\n });\n continue;\n }\n // Twin: ORTHOGONAL convergence. One junction per twin group on the bar, at the group\n // members' center x; from the junction, drop a short stub, go horizontal to the child\n // x, then down to the glyph. VERIFY this geometry against Bennett et al. 2008 Fig. 2\n // (twin notation panel) before trusting — refs differ on the exact tie-bar/\"?\" spot.\n const memberXs = tg.members.map(cxOf);\n const junctionX = (Math.min(...memberXs) + Math.max(...memberXs)) / 2;\n const junctionY = barY + TWIN_JUNCTION_DROP;\n twinZygositiesUsedSet.add(tg.zygosity);\n // The shared down-stub from the bar to the junction (emitted once per group).\n if (!emittedTwinOrdinals.has(tg.ordinal)) {\n emittedTwinOrdinals.add(tg.ordinal);\n if (tg.zygosity === \"unknown\") {\n unknownTwinJunctions.push({ x: round(junctionX), y: round(junctionY) });\n }\n elements.push({\n edgeId: PED_RISER_ID_BASE + childId, // anchored on the first member for a stable id\n kind: \"riser\",\n points: [\n { x: round(junctionX), y: round(barY) },\n { x: round(junctionX), y: round(junctionY) },\n ],\n consanguineous: false,\n title: titleLabels.twins[tg.zygosity],\n });\n // MZ tie-bar: a short horizontal between the two outermost twin descents, just below\n // the junction (DZ → none; unknown → a \"?\" node annotation, emitted in svg.ts).\n if (tg.zygosity === \"mz\" && memberXs.length >= 2) {\n const tieY = junctionY + 6;\n elements.push({\n edgeId: PED_TWINBAR_ID_BASE + s.id * 100 + tg.ordinal,\n kind: \"twin-bar\",\n points: [\n { x: round(Math.min(...memberXs)), y: round(tieY) },\n { x: round(Math.max(...memberXs)), y: round(tieY) },\n ],\n consanguineous: false,\n title: titleLabels.twins.mz,\n });\n }\n }\n // From the junction: horizontal to the child x at the junction y, then down to glyph.\n const horizontalThenDown: Point[] =\n Math.abs(cx - junctionX) < 0.01\n ? [\n { x: round(cx), y: round(junctionY) },\n { x: round(cx), y: round(childTop) },\n ]\n : [\n { x: round(junctionX), y: round(junctionY) },\n { x: round(cx), y: round(junctionY) },\n { x: round(cx), y: round(childTop) },\n ];\n elements.push({\n edgeId: PED_RISER_ID_BASE + childId,\n kind: \"riser\",\n points: horizontalThenDown,\n consanguineous: false,\n title: titleLabels.twins[tg.zygosity],\n });\n }\n }\n\n // ── Canvas bounds: shift-positive is unnecessary (everything starts at PADDING+GUTTER),\n // width/height from the rightmost/bottommost drawn extent. ──────────────────────────\n let maxX = PADDING * 2;\n let maxY = PADDING * 2;\n for (const n of nodes) {\n const labelW = n.labelLines.reduce((m, l) => Math.max(m, estimateTextWidth(l, PED_LABEL_FONT)), 0);\n const half = Math.max(PED_GLYPH, labelW) / 2;\n maxX = Math.max(maxX, n.cx + half + PADDING);\n const labelBottom = n.labelTop + (n.labelLines.length + 1) * PED_LABEL_LINE_H;\n maxY = Math.max(maxY, labelBottom + PADDING);\n }\n for (const el of elements) {\n for (const p of el.points) {\n maxX = Math.max(maxX, p.x + PADDING);\n maxY = Math.max(maxY, p.y + PADDING);\n }\n }\n\n const generations: PedigreeGenerationLabel[] = [];\n for (let row = 0; row < rowCount; row++) {\n generations.push({ roman: romanNumeral(row + 1), y: round(glyphCyOfRow(row)) });\n }\n\n // Order zygosities canonically (mz, dz, unknown) for deterministic legend output.\n const ZYGOSITY_ORDER: readonly Zygosity[] = [\"mz\", \"dz\", \"unknown\"];\n const twinZygositiesUsed = ZYGOSITY_ORDER.filter((z) => twinZygositiesUsedSet.has(z));\n\n return {\n width: Math.ceil(maxX),\n height: Math.ceil(maxY),\n nodes,\n elements,\n generations,\n conditionFills,\n twinZygositiesUsed,\n unknownTwinJunctions,\n isolatedIndividualIds,\n };\n}\n","// Pedigree SVG emitter — turns a computed PedigreeLayout (./layout.ts) into a\n// SELF-CONTAINED SVG string. Pure (layout in, string out) and deterministic; it draws\n// EXACTLY what the layout computed (the overlap harness proves the layout; this emitter\n// is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — labels/conditions/titles are\n// author-controlled and the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (zinc hex colors, inline dasharray): a\n// standalone SVG has no stylesheet, no currentColor, no <defs>/<marker> — arrowheads\n// are explicit polygons; multi-condition partitions are explicit filled shapes;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Notation (Bennett et al. 2008 PSSC): square/circle/diamond sex glyphs; AFFECTED =\n// filled glyph (multi-condition = VERTICAL fill partitions ≤4, from the zinc ramp);\n// carrier = central dot (on unaffected glyphs); deceased = top-left→bottom-right slash;\n// proband = FILLED lower-left arrow, consultand = OPEN (outline) arrow; stillbirth = \"SB\"\n// text below; consanguineous mating = DOUBLE line; twins converge with an MZ tie-bar / no\n// bar (DZ) / a \"?\" (unknown). Roman-numeral generation labels sit in the left gutter.\n//\n// Hooks: `<g data-individual-id=\"p<id>\">` per individual (direct-child verbatim <title>);\n// `<g data-edge-id=\"<n>\">` per routed element (namespaced ids, see ./layout.ts).\n\nimport { FONT_FAMILY, legendBlock, xmlEscape, LEGEND_SWATCH_W, type LegendEntry } from \"../core\";\nimport {\n PED_ADDRESS_FONT,\n PED_LABEL_FONT,\n PED_LABEL_LINE_H,\n type PedigreeElement,\n type PedigreeLayout,\n type PedigreeNode,\n} from \"./layout\";\nimport { PEDIGREE_SVG_LABELS_EN, type PedigreeSvgLabels } from \"./labels\";\nimport type { NodeShape } from \"../genogram/types\";\nimport type { Zygosity } from \"./types\";\n\n// Literal ink colors (zinc ramp on white — matches the genogram/fault-tree emitters).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\nconst GLYPH_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n/** Parallel offset of the second consanguineous mating line (the PSSC double line). */\nconst CONSANG_GAP = 3;\n\nconst ZYGOSITIES: readonly Zygosity[] = [\"mz\", \"dz\", \"unknown\"];\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport interface PedigreeSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: PedigreeSvgLabels;\n}\n\n// ── Glyph outline + multi-condition vertical fill partitions ──────────────────────────\n\nfunction glyphOutline(shape: NodeShape, cx: number, cy: number, half: number): string {\n if (shape === \"square\") {\n return `<rect x=\"${round(cx - half)}\" y=\"${round(cy - half)}\" width=\"${half * 2}\" height=\"${half * 2}\" ${GLYPH_ATTRS}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${GLYPH_ATTRS}/>`;\n }\n return `<polygon points=\"${cx},${round(cy - half)} ${round(cx + half)},${cy} ${cx},${round(cy + half)} ${round(cx - half)},${cy}\" ${GLYPH_ATTRS}/>`;\n}\n\n/**\n * The glyph's vertical extent (top, bottom) at a horizontal offset from center, so a fill\n * partition slice is CLIPPED to the glyph outline (no <clipPath> — pure geometry). Square\n * is full-height everywhere; circle/diamond taper. Returns [yTop, yBottom] at |dx|.\n */\nfunction glyphVerticalExtentAt(shape: NodeShape, cy: number, half: number, dx: number): [number, number] {\n const ax = Math.min(Math.abs(dx), half);\n if (shape === \"square\") return [cy - half, cy + half];\n if (shape === \"circle\") {\n const h = Math.sqrt(Math.max(0, half * half - ax * ax));\n return [cy - h, cy + h];\n }\n // diamond: linear taper to 0 at |dx| = half.\n const h = half - ax;\n return [cy - h, cy + h];\n}\n\n/** Vertical fill partitions (≤4) for an affected glyph, each clipped to the outline. */\nfunction fillPartitions(n: PedigreeNode, half: number, inkByCondition: Map<number, string>): string {\n const ids = n.affectedBy;\n if (ids.length === 0) return \"\";\n const cx = n.cx;\n const cy = n.cy;\n const sliceW = (half * 2) / ids.length;\n return ids\n .map((id, i) => {\n const left = cx - half + i * sliceW;\n // Sample the outline extent at a handful of x's across the slice and build a polygon\n // hugging the glyph border (top edge L→R, bottom edge R→L). Dense enough for a\n // circle/diamond to read as a clean partition.\n const SAMPLES = 8;\n const top: string[] = [];\n const bottom: string[] = [];\n for (let s = 0; s <= SAMPLES; s++) {\n const x = left + (sliceW * s) / SAMPLES;\n const [yt, yb] = glyphVerticalExtentAt(n.shape, cy, half, x - cx);\n top.push(`${round(x)},${round(yt)}`);\n bottom.push(`${round(x)},${round(yb)}`);\n }\n const pts = [...top, ...bottom.reverse()].join(\" \");\n const ink = inkByCondition.get(id) ?? GLYPH_STROKE;\n return `<polygon points=\"${pts}\" fill=\"${ink}\" stroke=\"none\"/>`;\n })\n .join(\"\");\n}\n\n// ── Node annotations (carrier dot, deceased slash, proband/consultand arrow, SB). These\n// are NODE decorations (NOT routed elements) — the deceased slash + arrows are the only\n// diagonals, harness-excluded exactly like the genogram's deceased slash. ────────────\n\nfunction carrierDot(n: PedigreeNode): string {\n // PSSC: the dot marks an UNAFFECTED carrier; a filled glyph would hide it.\n if (!n.carrier || n.affectedBy.length > 0) return \"\";\n return `<circle cx=\"${n.cx}\" cy=\"${n.cy}\" r=\"4\" fill=\"${GLYPH_STROKE}\" stroke=\"none\"/>`;\n}\n\nfunction deceasedSlash(n: PedigreeNode, half: number): string {\n if (!n.deceased) return \"\";\n // Top-left → bottom-right, reusing the genogram's exact deceased line, slightly extended\n // past the glyph so it reads over a filled glyph.\n const ext = half + 4;\n return `<line x1=\"${round(n.cx - ext)}\" y1=\"${round(n.cy - ext)}\" x2=\"${round(n.cx + ext)}\" y2=\"${round(n.cy + ext)}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`;\n}\n\nfunction probandArrow(n: PedigreeNode, half: number): string {\n if (n.role === null) return \"\";\n // An arrow at the glyph's lower-left, pointing up-right toward the glyph (PSSC). Filled\n // for the proband, open (outline only) for the consultand — one shape, two fills.\n const tipX = round(n.cx - half);\n const tipY = round(n.cy + half);\n const tailX = round(tipX - 16);\n const tailY = round(tipY + 16);\n const filled = n.role === \"proband\";\n const fill = filled ? GLYPH_STROKE : \"transparent\";\n // Shaft + a small arrowhead polygon at the tip (explicit polygon — no marker).\n const shaft = `<line x1=\"${tailX}\" y1=\"${tailY}\" x2=\"${tipX}\" y2=\"${tipY}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`;\n // Arrowhead pointing up-right (toward the glyph), two barbs off the tip.\n const head = `<polygon points=\"${tipX},${tipY} ${round(tipX - 8)},${round(tipY + 2)} ${round(tipX - 2)},${round(tipY + 8)}\" fill=\"${fill}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n return shaft + head;\n}\n\nfunction stillbirthMark(n: PedigreeNode, half: number): string {\n if (!n.stillbirth) return \"\";\n // PSSC: a stillbirth is annotated with the literal \"SB\" below the glyph (the legend uses\n // the descriptive wording). Placed just below the glyph, left of the address line.\n const y = round(n.cy + half + PED_ADDRESS_FONT);\n return `<text x=\"${round(n.cx - half - 2)}\" y=\"${y}\" text-anchor=\"end\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_ADDRESS_FONT}\" font-weight=\"bold\" fill=\"${LABEL_FILL}\">SB</text>`;\n}\n\nfunction nodeSvg(n: PedigreeNode, inkByCondition: Map<number, string>): string {\n const half = n.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(n.title)}</title>`,\n // Fill partitions sit UNDER the outline so the border stays crisp.\n fillPartitions(n, half, inkByCondition),\n glyphOutline(n.shape, n.cx, n.cy, half),\n carrierDot(n),\n deceasedSlash(n, half),\n probandArrow(n, half),\n stillbirthMark(n, half),\n ];\n // Within-generation address (\"II-3\") just below the glyph.\n const addressY = round(n.labelTop + PED_ADDRESS_FONT);\n pieces.push(\n `<text x=\"${n.cx}\" y=\"${addressY}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_ADDRESS_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(n.addressLabel)}</text>`,\n );\n if (n.labelLines.length > 0) {\n const firstBaseline = round(n.labelTop + PED_LABEL_LINE_H + 10);\n const tspans = n.labelLines\n .map((line, i) => `<tspan x=\"${n.cx}\" y=\"${round(firstBaseline + i * PED_LABEL_LINE_H)}\">${xmlEscape(line)}</tspan>`)\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_LABEL_FONT}\" fill=\"${LABEL_FILL}\">${tspans}</text>`,\n );\n }\n return `<g data-individual-id=\"p${n.individualId}\">${pieces.join(\"\")}</g>`;\n}\n\n// ── Routed elements ────────────────────────────────────────────────────────────────────\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: readonly { x: number; y: number }[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\nfunction elementSvg(el: PedigreeElement): string {\n const pts = el.points;\n const title = `<title>${xmlEscape(el.title)}</title>`;\n const stroke = `stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"`;\n const draw = (offsetY: number): string => {\n const shifted = pts.map((p) => ({ x: p.x, y: round(p.y + offsetY) }));\n if (shifted.length === 2) {\n return `<line x1=\"${shifted[0]!.x}\" y1=\"${shifted[0]!.y}\" x2=\"${shifted[1]!.x}\" y2=\"${shifted[1]!.y}\" ${stroke}/>`;\n }\n return `<path d=\"${pathData(shifted)}\" fill=\"none\" ${stroke}/>`;\n };\n const body =\n el.consanguineous && (el.kind === \"mating\" || el.kind === \"mating-elbow\")\n ? draw(-CONSANG_GAP / 2) + draw(CONSANG_GAP / 2)\n : draw(0);\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body}</g>`;\n}\n\n/** The \"?\" glyphs at unknown-zygosity twin junctions (node-style annotations from layout). */\nfunction unknownTwinMarks(layout: PedigreeLayout): string {\n return layout.unknownTwinJunctions\n .map(\n (p) =>\n `<text x=\"${round(p.x + 6)}\" y=\"${round(p.y + 4)}\" font-family=\"${FONT_FAMILY}\" font-size=\"12\" font-weight=\"bold\" fill=\"${LABEL_FILL}\">?</text>`,\n )\n .join(\"\");\n}\n\n// ── Legend mini-glyph swatches (scaled into the 22px swatch box) ──────────────────────\n\nconst MINI_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"`;\n\nfunction miniShapeSwatch(shape: NodeShape, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (shape === \"square\") return `<rect x=\"${round(cx - 6)}\" y=\"${round(y - 6)}\" width=\"12\" height=\"12\" ${MINI_ATTRS}/>`;\n if (shape === \"circle\") return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/>`;\n return `<polygon points=\"${cx},${round(y - 7)} ${round(cx + 7)},${y} ${cx},${round(y + 7)} ${round(cx - 7)},${y}\" ${MINI_ATTRS}/>`;\n}\n\nfunction miniSwatchCircle(filled: boolean, ink: string, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" fill=\"${filled ? ink : \"transparent\"}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n}\n\nfunction miniCarrierSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/><circle cx=\"${cx}\" cy=\"${y}\" r=\"2\" fill=\"${GLYPH_STROKE}\" stroke=\"none\"/>`;\n}\n\nfunction miniDeceasedSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/><line x1=\"${round(cx - 7)}\" y1=\"${round(y - 7)}\" x2=\"${round(cx + 7)}\" y2=\"${round(y + 7)}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n}\n\nfunction miniArrowSwatch(filled: boolean, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n const tipX = round(cx - 2);\n const tipY = round(y + 2);\n return (\n `<line x1=\"${round(tipX - 8)}\" y1=\"${round(tipY + 8)}\" x2=\"${tipX}\" y2=\"${tipY}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>` +\n `<polygon points=\"${tipX},${tipY} ${round(tipX - 5)},${round(tipY + 1)} ${round(tipX - 1)},${round(tipY + 5)}\" fill=\"${filled ? GLYPH_STROKE : \"transparent\"}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1\"/>`\n );\n}\n\nfunction miniConsanguineousSwatch(x: number, y: number): string {\n const x1 = round(x + 2);\n const x2 = round(x + LEGEND_SWATCH_W - 2);\n return (\n `<line x1=\"${x1}\" y1=\"${round(y - 1.5)}\" x2=\"${x2}\" y2=\"${round(y - 1.5)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${x1}\" y1=\"${round(y + 1.5)}\" x2=\"${x2}\" y2=\"${round(y + 1.5)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>`\n );\n}\n\nfunction miniTwinSwatch(zygosity: Zygosity, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n const apexY = round(y - 6);\n const baseY = round(y + 6);\n const left = round(cx - 6);\n const right = round(cx + 6);\n // Orthogonal convergence mini: an inverted Y of axis-aligned stubs.\n const stub =\n `<line x1=\"${cx}\" y1=\"${apexY}\" x2=\"${cx}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${left}\" y1=\"${y}\" x2=\"${right}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${left}\" y1=\"${y}\" x2=\"${left}\" y2=\"${baseY}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${right}\" y1=\"${y}\" x2=\"${right}\" y2=\"${baseY}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>`;\n if (zygosity === \"mz\") {\n return stub + `<line x1=\"${left}\" y1=\"${round(y + 3)}\" x2=\"${right}\" y2=\"${round(y + 3)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>`;\n }\n if (zygosity === \"unknown\") {\n return stub + `<text x=\"${round(cx + 8)}\" y=\"${round(y + 3)}\" font-family=\"${FONT_FAMILY}\" font-size=\"9\" fill=\"${LABEL_FILL}\">?</text>`;\n }\n return stub;\n}\n\n/**\n * Emits a self-contained SVG for a computed pedigree layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal. The legend lists ONLY the features actually used.\n */\nexport function pedigreeLayoutSvg(layout: PedigreeLayout, opts: PedigreeSvgOptions = {}): string {\n const labels = opts.labels ?? PEDIGREE_SVG_LABELS_EN;\n const inkByCondition = new Map(layout.conditionFills.map((c) => [c.id, c.ink]));\n const parts: string[] = [];\n\n // Routed elements first, then unknown-twin \"?\" marks, then nodes on top.\n for (const el of layout.elements) parts.push(elementSvg(el));\n parts.push(unknownTwinMarks(layout));\n for (const n of layout.nodes) parts.push(nodeSvg(n, inkByCondition));\n\n // Roman-numeral generation gutter (left margin).\n for (const g of layout.generations) {\n parts.push(\n `<text x=\"${round(16)}\" y=\"${round(g.y + PED_LABEL_FONT * 0.32)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_LABEL_FONT}\" font-weight=\"bold\" fill=\"${LABEL_FILL}\">${xmlEscape(g.roman)}</text>`,\n );\n }\n\n // ── Used-keys-only legend (core legendBlock; `legend:false` suppresses). ─────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: LegendEntry[] = [];\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({ swatch: (x, y) => miniShapeSwatch(shape, x, y), label: labels.shapes[shape] });\n }\n // One row per USED condition (sex-neutral circle filled with that condition's ink).\n for (const c of layout.conditionFills) {\n entries.push({ swatch: (x, y) => miniSwatchCircle(true, c.ink, x, y), label: c.label });\n }\n if (layout.nodes.some((n) => n.affectedBy.length === 0)) {\n entries.push({ swatch: (x, y) => miniSwatchCircle(false, GLYPH_STROKE, x, y), label: labels.unaffected });\n }\n if (layout.nodes.some((n) => n.carrier && n.affectedBy.length === 0)) {\n entries.push({ swatch: miniCarrierSwatch, label: labels.carrier });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({ swatch: miniDeceasedSwatch, label: labels.deceased });\n }\n if (layout.nodes.some((n) => n.role === \"proband\")) {\n entries.push({ swatch: (x, y) => miniArrowSwatch(true, x, y), label: labels.proband });\n }\n if (layout.nodes.some((n) => n.role === \"consultand\")) {\n entries.push({ swatch: (x, y) => miniArrowSwatch(false, x, y), label: labels.consultand });\n }\n if (layout.nodes.some((n) => n.stillbirth)) {\n entries.push({ swatch: () => \"\", label: labels.stillbirth });\n }\n if (layout.elements.some((el) => el.consanguineous)) {\n entries.push({ swatch: miniConsanguineousSwatch, label: labels.consanguineous });\n }\n const twinsUsed = new Set(layout.twinZygositiesUsed);\n for (const z of ZYGOSITIES) {\n if (!twinsUsed.has(z)) continue;\n entries.push({ swatch: (x, y) => miniTwinSwatch(z, x, y), label: labels.twins[z] });\n }\n if (layout.isolatedIndividualIds.length > 0) {\n entries.push({ swatch: () => \"\", label: labels.isolated });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call pedigree render: input → { svg, layout }. Thin, honest wiring: validate (throw\n// on a structurally invalid pedigree — never repair), compute the pure layout, emit.\n// Callers needing finer control use computePedigreeLayout + pedigreeLayoutSvg directly (the\n// layout result supports hit-testing / decorating the diagram).\n\nimport { computePedigreeLayout, type PedigreeLayout, type PedigreeLayoutOptions } from \"./layout\";\nimport { pedigreeLayoutSvg } from \"./svg\";\nimport type { PedigreeSvgLabels } from \"./labels\";\nimport type { PedigreeInput } from \"./types\";\n\nexport interface PedigreeRenderOptions extends PedigreeLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: PedigreeSvgLabels;\n}\n\nexport interface PedigreeRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: PedigreeLayout;\n}\n\n/**\n * Renders a pedigree input to a self-contained SVG string. Deterministic: same data → same\n * SVG (array order never matters; a sibship's `childIds` order is honored as the declared\n * left-to-right birth order). Throws PedigreeValidationError — carrying EVERY issue,\n * deterministically sorted — on a structurally invalid pedigree. Empty input yields an\n * empty-but-valid SVG; callers decide their own empty state.\n */\nexport function pedigreeSvg(input: PedigreeInput, opts: PedigreeRenderOptions = {}): PedigreeRenderResult {\n const layout = computePedigreeLayout(input, {\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = pedigreeLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Display vocabularies — every human-readable string the phylo tree emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// Title labels are woven into element/node <title>s by the LAYOUT (verbatim-preserving:\n// a branch's actual length / a clade's actual support always rides the title, even when\n// the drawn diagram omits them). Svg labels are drawn by the EMITTER (legend, aria).\n\nimport type { PhyloMode } from \"./types\";\n\n/** Labels woven into <title>s by the LAYOUT (verbatim-preserving). */\nexport interface PhyloTitleLabels {\n /** \"branch length\" → \"branch length: 0.123\" when a length is present. */\n branchLength: string;\n /** \"support\" → \"support: 95\" when a support value is present. */\n support: string;\n clade: string;\n tip: string;\n root: string;\n}\n\nexport const PHYLO_TITLE_LABELS_EN: PhyloTitleLabels = {\n branchLength: \"branch length\",\n support: \"support\",\n clade: \"clade\",\n tip: \"tip\",\n root: \"root\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface PhyloSvgLabels {\n support: string;\n scaleBar: string;\n alignedTip: string;\n /** Aria label switches on the layout's render mode. */\n ariaLabel: Record<PhyloMode, string>;\n}\n\nexport const PHYLO_SVG_LABELS_EN: PhyloSvgLabels = {\n support: \"Support value (bootstrap/posterior)\",\n scaleBar: \"Scale: substitutions per site\",\n alignedTip: \"Aligned tip (true position dotted)\",\n ariaLabel: {\n cladogram: \"Phylogenetic tree (cladogram)\",\n phylogram: \"Phylogenetic tree (phylogram)\",\n },\n};\n","// Phylo validation — the MIDDLE doctrine. A phylogenetic tree is not a safety artifact\n// like a fault tree (an incomplete/exploratory tree is a legitimate thing to draw), but\n// unlike a genogram a tree MUST be a tree to lay out (a cycle or a forest has no\n// root-anchored x). So we throw PhyloValidationError carrying a MINIMAL closed code set\n// that rejects only what makes layout impossible or ambiguous — never what is merely\n// incomplete. The shape (sorted kebab-case { code, message } issues, three-phase gating)\n// is the fault-tree's, verbatim.\n//\n// Every problem is reported, not just the first: issues are aggregated, deduplicated and\n// sorted deterministically (by code, then message — byte comparison, no locale collation),\n// each carrying a STABLE kebab-case `code`. Validation runs in THREE phases, each gated on\n// the prior being clean ENOUGH for the next to be meaningful (NOT on \"zero issues so far\",\n// so a defect in one phase never hides an honest issue from a later one):\n// (0) duplicate ids (per namespace). The lookup maps below are first-occurrence-wins, so\n// every reference rule would otherwise depend on array order — violating this\n// function's documented order-invariance. Any duplicate-id issue → report ONLY those\n// and stop (the duplicate already forces a throw, present in every permutation).\n// (1) reference + structural-tree rules: unknown-endpoint (an edge to a phantom node),\n// unknown-root, multiple-parents (a node with ≥2 incoming edges — a DAG, not a tree),\n// negative-length (a meaningless distance — reject, never clamp), tip-with-children\n// (a declared isTip flag contradicting topology). All evaluated once ids are\n// unambiguous; none requires a clean graph walk.\n// (2) graph rules: cycle (a back-edge in the parent→child walk) and disconnected-node\n// (a node unreachable from root). Gated ONLY on the reference-INTEGRITY subset that\n// corrupts the traversal itself — duplicate-id (ambiguous first-wins node),\n// unknown-endpoint (walks a phantom node), unknown-root (the BFS frontier roots at a\n// non-node), multiple-parents (the child-set is ambiguous). negative-length and\n// tip-with-children leave the graph fully walkable, so they do NOT suppress the graph\n// phase: a negative length alongside an unreachable node reports BOTH in one throw.\n//\n// Tolerated, by design (drawn as declared, never converted):\n// - empty labels (drawn empty; the <title> is still present);\n// - missing support (null/absent — drawn unlabeled);\n// - a single-node tree (root only, no edges — a valid degenerate tree, one tip);\n// - null lengths (phylogram → 0) and zero-length branches (a node directly above its\n// parent's x — a real polytomy/zero-support resolution, NOT an error);\n// - unbalanced / ladderized topology (declared child order honored, never auto-sorted).\n\nimport type { PhyloInput, PhyloNode } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type PhyloIssueCode =\n | \"duplicate-id\"\n | \"unknown-endpoint\"\n | \"unknown-root\"\n | \"multiple-parents\"\n | \"cycle\"\n | \"disconnected-node\"\n | \"tip-with-children\"\n | \"negative-length\";\n\nexport interface PhyloIssue {\n code: PhyloIssueCode;\n message: string;\n}\n\n/** Thrown by computePhyloLayout / phyloSvg on a structurally un-layout-able tree. */\nexport class PhyloValidationError extends Error {\n readonly issues: readonly PhyloIssue[];\n\n constructor(issues: readonly PhyloIssue[]) {\n super(`invalid phylo tree: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"PhyloValidationError\";\n this.issues = issues;\n }\n}\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable\n * across engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly PhyloIssue[]): readonly PhyloIssue[] {\n const unique = new Map<string, PhyloIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically\n * sorted (code, then message) — array order of `nodes`/`edges` never changes the result.\n * Empty input (no nodes AND no edges) is valid by definition (the renderer's\n * empty-but-valid SVG case) and reports no issues.\n */\nexport function phyloIssues(input: PhyloInput): readonly PhyloIssue[] {\n if (input.nodes.length === 0 && input.edges.length === 0) return [];\n\n const issues: PhyloIssue[] = [];\n const push = (code: PhyloIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── R1: duplicate ids (per namespace — hooks must be unique). Any duplicate makes the\n // structure ambiguous, so this is phase 0 and short-circuits the rest (below). ─────\n const nodeById = new Map<number, PhyloNode>();\n const dupNodeIds = new Set<number>();\n for (const n of input.nodes) {\n if (nodeById.has(n.id)) dupNodeIds.add(n.id);\n else nodeById.set(n.id, n);\n }\n for (const id of [...dupNodeIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate node id ${id}`);\n }\n const dupEdgeIds = new Set<number>();\n const seenEdgeIds = new Set<number>();\n for (const e of input.edges) {\n if (seenEdgeIds.has(e.id)) dupEdgeIds.add(e.id);\n else seenEdgeIds.add(e.id);\n }\n for (const id of [...dupEdgeIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate edge id ${id}`);\n }\n\n // ── Phase 0: duplicate ids short-circuit everything else (see module header). ────────\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n // ── R2: the declared root must be an existing node. ──────────────────────────────────\n if (!nodeById.has(input.rootId)) {\n push(\"unknown-root\", `rootId ${input.rootId} is not a declared node`);\n }\n\n // ── Per-edge reference / structural rules. The child→parent map drives the graph\n // phase: built only from edges with BOTH endpoints declared (a phantom endpoint\n // would seed a non-existent node). ────────────────────────────────────────────────\n const incomingByChild = new Map<number, number[]>(); // child id → parent ids (declared edges only)\n for (const e of [...input.edges].sort((a, b) => a.id - b.id)) {\n const knownParent = nodeById.has(e.parentId);\n const knownChild = nodeById.has(e.childId);\n if (!knownParent) push(\"unknown-endpoint\", `edge ${e.id} parentId ${e.parentId} is not a declared node`);\n if (!knownChild) push(\"unknown-endpoint\", `edge ${e.id} childId ${e.childId} is not a declared node`);\n // R4 — a non-finite or negative distance is meaningless. Reject (never clamp): drawing\n // it would silently reinterpret the data AND a non-finite length poisons the phylogram\n // scale (cumulative dist → Infinity, scale → 0, x → padLeft + Infinity·0 = NaN, and the\n // whole SVG emits viewBox=\"0 0 NaN …\"). `Number.isFinite` is false for NaN/+Inf/-Inf,\n // so the one guard covers every corrupt SPECIFIED value; null stays valid (→ 0 in the\n // phylogram, the legitimate \"unspecified\" branch).\n if (e.length !== null && (!Number.isFinite(e.length) || e.length < 0)) {\n push(\"negative-length\", `edge ${e.id} has non-finite or negative length ${e.length}`);\n }\n if (knownParent && knownChild) {\n const arr = incomingByChild.get(e.childId) ?? [];\n arr.push(e.parentId);\n incomingByChild.set(e.childId, arr);\n }\n }\n\n // R3 — a tree node has at most ONE parent; ≥2 incoming edges is a DAG (un-layout-able\n // with a single root-anchored x). Reported per child, ascending.\n const childIdsWithEdges = new Set<number>();\n for (const e of input.edges) childIdsWithEdges.add(e.childId);\n for (const [childId, parents] of [...incomingByChild.entries()].sort((a, b) => a[0] - b[0])) {\n if (parents.length > 1) {\n push(\"multiple-parents\", `node ${childId} has ${parents.length} parents`);\n }\n }\n\n // R5 — isTip is DERIVED: a node with an outgoing edge is internal, a node with none is a\n // tip. A declared isTip flag that contradicts the topology is reported (honesty rule —\n // we draw the declared topology, we never invent or suppress a leaf because of a flag).\n const hasChildren = new Set<number>();\n for (const e of input.edges) {\n if (nodeById.has(e.parentId)) hasChildren.add(e.parentId);\n }\n for (const n of [...nodeById.values()].sort((a, b) => a.id - b.id)) {\n if (n.isTip === true && hasChildren.has(n.id)) {\n push(\"tip-with-children\", `node ${n.id} is declared a tip but has children`);\n } else if (n.isTip === false && !hasChildren.has(n.id)) {\n push(\"tip-with-children\", `node ${n.id} is declared internal but has no children`);\n }\n }\n\n // ── Graph rules (cycle, disconnected-node) — phase 2. Gated ONLY on the reference-\n // INTEGRITY codes that corrupt the traversal (see the module header), NOT on every\n // phase-1 issue: a negative length or a contradicted tip flag leaves the graph fully\n // walkable, so suppressing the graph phase for them would hide an honest issue. ─────\n const GRAPH_BLOCKING: ReadonlySet<PhyloIssueCode> = new Set<PhyloIssueCode>([\n \"duplicate-id\",\n \"unknown-endpoint\",\n \"unknown-root\",\n \"multiple-parents\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n // Children of a node in declared edge order (stable-sorted by edge id), declared edges\n // only — every endpoint is known here (no unknown-endpoint survived the gate).\n const childrenOf = new Map<number, number[]>();\n for (const e of [...input.edges].sort((a, b) => a.id - b.id)) {\n const arr = childrenOf.get(e.parentId) ?? [];\n arr.push(e.childId);\n childrenOf.set(e.parentId, arr);\n }\n\n // R6 — cycle detection over the parent→child graph (coloring DFS, start nodes\n // ascending, children in declared order). Each distinct cycle is reported once,\n // rotated to start at its smallest node id so the message is array-order-independent.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = childrenOf.get(frame.id) ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\"cycle\", `cycle: ${[...rotated, rotated[0]!].join(\" → \")}`);\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n for (const n of [...nodeById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(n.id) ?? 0) === 0) dfs(n.id);\n }\n\n // R7 — every declared node must be reachable from the root (a forest has no single\n // root-anchored x). Silently dropping a declared component violates honesty.\n const reachable = new Set<number>();\n const queue: number[] = [input.rootId];\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (reachable.has(id)) continue;\n reachable.add(id);\n for (const childId of childrenOf.get(id) ?? []) queue.push(childId);\n }\n for (const n of [...nodeById.values()].sort((a, b) => a.id - b.id)) {\n if (!reachable.has(n.id)) push(\"disconnected-node\", `node ${n.id} is unreachable from the root`);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws PhyloValidationError (carrying ALL issues) when the input is un-layout-able. */\nexport function validatePhylo(input: PhyloInput): void {\n const issues = phyloIssues(input);\n if (issues.length > 0) throw new PhyloValidationError(issues);\n}\n","// PURE phylo layout — the single source of truth for positioning and connector routing.\n// The emitter (./svg.ts) draws EXACTLY what this computes, so web / PDF / image pipelines\n// can never drift. Deliberately PURE — no DOM, no Node APIs, no clock, no randomness —\n// so the same input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS the declared topology. Validation\n// (./validate.ts) THROWS on an un-layout-able tree (cycle, forest, DAG) rather than\n// repairing it. A branch length absent from the cladogram x is NEVER lost: it always\n// rides the branch element's <title>. A tip is DERIVED (no outgoing edge); we never\n// invent or suppress a leaf.\n//\n// LAYOUT — the classic tidy-tree (the textbook phylogeny algorithm):\n// * Tip ordering: one DFS from rootId, children in DECLARED edge order (stable-sorted\n// by edge id for determinism — the cladistics \"declared order is the analyst's\n// ladderization choice, never auto-sorted\"). Tips numbered 0..L-1 in DFS-visit order.\n// * Leaf y: tip i → y = top + i·ROW_SLOT + ROW_SLOT/2. Equal disjoint slots ⇒ no\n// vertical overlap by construction (the genogram's column bands, transposed 90°).\n// * Internal y = midpoint of its children's y ((min+max)/2), computed post-order.\n// Horizontal:\n// * cladogram: x = padLeft + depth·LEVEL_W; tips right-aligned to maxDepth's x; a dotted\n// EXTENSION segment fills from a tip's true depth-x to the alignment line (FigTree).\n// * phylogram: x = padLeft + cumulativeLength(root→node)·SCALE, SCALE = drawW/maxRootTip\n// (fit-to-width). null/0 lengths contribute 0 ⇒ a node sits directly above its parent\n// (a zero-length branch — valid, NOT an error). Tips not right-aligned unless alignTips.\n// Edges = rectangular elbows (orthogonal, harness-clean): one shared VERTICAL \"clade bar\"\n// per parent spanning min→max child y at the parent's x, plus one HORIZONTAL \"branch\" per\n// child from parentX to childX at childY. Overlap proof: tips own disjoint y-bands; an\n// internal node's y is strictly between its children's bands ⇒ clade bars nest without\n// overlap; branches live at distinct child-y's. Same inductive structure as the fault\n// tree, transposed.\n\nimport { clampLabel, estimateTextWidth, type Point } from \"../core\";\nimport { PHYLO_TITLE_LABELS_EN, type PhyloTitleLabels } from \"./labels\";\nimport { validatePhylo } from \"./validate\";\nimport type { PhyloInput, PhyloMode, PhyloNode } from \"./types\";\n\nexport { PhyloValidationError, phyloIssues, validatePhylo, type PhyloIssue, type PhyloIssueCode } from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render) ───────────\n/** Tip-label font size (px). */\nexport const PHYLO_LABEL_FONT = 12;\n/** Vertical slot per tip (px) — equal slots guarantee vertical disjointness. */\nexport const PHYLO_ROW_SLOT = 22;\n/** Support-value font size (px) — drawn just left of an internal node. */\nexport const PHYLO_SUPPORT_FONT = 10;\n/** Gap from a tip point to the start of its label text. */\nexport const PHYLO_LABEL_GAP = 8;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────────\nconst PADDING = 32;\n/** Horizontal level width per topological depth (cladogram x; phylogram fallback). */\nconst PHYLO_LEVEL_W = 72;\n/** Tip dot radius (a small filled marker at each node point). */\nconst PHYLO_TIP_R = 2.5;\n/** Reserved gap to the left of an internal node for its support text (when showSupport). */\nconst SUPPORT_GAP = 4;\n/** Vertical gap reserved below the tree for the scale bar assembly. */\nconst SCALEBAR_ZONE = 34;\n/** Drawn length cap (in px) of the available width for the tree body. */\nconst MIN_DRAW_W = PHYLO_LEVEL_W; // a degenerate single-depth tree still gets one level\n/** Phylogram-only x nudge (px) for an INTERNAL child whose zero/null branch lands it at\n * exactly its parent's x. Without it, the child's clade bar and the parent's clade bar are\n * two collinear verticals (double-drawn line, ambiguous polytomy). One pixel right gives\n * the child's bar its own vertical while preserving the \"directly above the parent\" read; a\n * TIP at the parent's x needs no nudge (a tip has no clade bar). PRESENTATION-only — the\n * verbatim 0/null length still rides the branch element's <title>. */\nconst PHYLO_ZERO_NUDGE = 1;\n\n// ── Namespaced element-id blocks (one element kind per numeric block; every\n// data-edge-id stays traceable to its source node) ─────────────────────────────────\nexport const PHYLO_CLADEBAR_ID_BASE = 1_000_000; // + parent node id (the vertical bar)\nexport const PHYLO_BRANCH_ID_BASE = 2_000_000; // + child node id (the horizontal branch)\nexport const PHYLO_EXTENSION_ID_BASE = 3_000_000; // + tip node id (dotted right-align extension)\nexport const PHYLO_ROOTSTUB_ID_BASE = 4_000_000; // + root id (the short left stub into the root)\nexport const PHYLO_SCALEBAR_ID = 5_000_000; // the labelled scale-bar segment\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────────\n\nexport interface PhyloLayoutNode {\n nodeId: number;\n isTip: boolean;\n /** Node point center. */\n cx: number;\n cy: number;\n /** Bootstrap/posterior; null when absent (always in the <title> regardless). */\n support: number | null;\n /** Tip label as a single clamped line, drawn right of the tip point; [] for internals. */\n labelLines: string[];\n /** x where the tip label text starts (after PHYLO_LABEL_GAP); the tip's drawn-x for an\n * aligned tip is the alignment line, so the label always clears the tip point. */\n labelLeft: number;\n /** Edges from the root (a tip in cladogram mode keeps its TRUE depth here). */\n depth: number;\n /** Verbatim <title> text (node.title ?? label + branch-length/support). */\n title: string;\n}\n\nexport type PhyloElementKind = \"clade-bar\" | \"branch\" | \"extension\" | \"root-stub\" | \"scale-bar\";\n\nexport interface PhyloElement {\n /** Namespaced id (PHYLO_*_ID_BASE + parent/child/tip/root id, or PHYLO_SCALEBAR_ID). */\n edgeId: number;\n kind: PhyloElementKind;\n /** Consecutive pairs axis-aligned (clade-bar = V, branch/extension/scale-bar = H). */\n points: Point[];\n /** Drawn dotted (extension + scale-bar ticks are NOT here — only the extension leader). */\n dotted: boolean;\n /** Branch: the verbatim length for the <title>; null otherwise / unspecified. */\n length: number | null;\n title: string;\n}\n\nexport interface PhyloScaleBar {\n /** Branch-length value the bar represents (a nice round step). */\n length: number;\n /** Bar's left x and baseline y. */\n x: number;\n y: number;\n /** Drawn pixel length of the bar (length·SCALE). */\n pxLength: number;\n /** Displayed numeric label (the value, trimmed of trailing zeros). */\n valueLabel: string;\n}\n\nexport interface PhyloLayout {\n width: number;\n height: number;\n mode: PhyloMode;\n /** DFS pre-order (root first, then children in declared edge order). */\n nodes: PhyloLayoutNode[];\n elements: PhyloElement[];\n /** Present only in phylogram mode with scaleBar !== false and a non-degenerate scale. */\n scaleBar: PhyloScaleBar | null;\n /** True when the layout reserved left-margin space for support text AND any internal\n * node carries a support value — the emitter draws support text iff this is set. */\n showSupport: boolean;\n}\n\nexport interface PhyloLayoutOptions {\n /** \"cladogram\" (default) | \"phylogram\". */\n mode?: PhyloMode;\n /** Dotted tip-alignment extensions. cladogram default true; phylogram default false. */\n alignTips?: boolean;\n /** Reserve left margin + draw support text at internal nodes. Default false. */\n showSupport?: boolean;\n /** Draw the phylogram scale bar (ignored in cladogram). Default true. */\n scaleBar?: boolean;\n /** Cap each tip's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for node/branch <title>s — English default. */\n titleLabels?: PhyloTitleLabels;\n}\n\n// ── niceScaleStep — the largest power-of-ten × {1, 2, 5} that is ≤ maxLen/4. A pure\n// function so the scale bar is a stable, \"nice\" round number regardless of the data's\n// exact range (the standard FigTree/ggtree scale-bar value). maxLen ≤ 0 → 0. ─────────\nexport function niceScaleStep(maxLen: number): number {\n if (!(maxLen > 0)) return 0;\n const target = maxLen / 4;\n const exp = Math.floor(Math.log10(target));\n const pow = Math.pow(10, exp);\n // A small relative tolerance so a value imperceptibly below a boundary (e.g. 0.2/4 =\n // 0.04999999999999999 from float rounding) still selects the intended \"nice\" step —\n // the scale value is presentation-only and snapping to the boundary is the honest read.\n const tol = target * 1e-9;\n for (const mult of [5, 2, 1]) {\n const step = mult * pow;\n if (step <= target + tol) return step;\n }\n // target < pow (only when log10 rounding leaves a gap) → the next decade down's 5×.\n return 5 * Math.pow(10, exp - 1);\n}\n\n/** Trims a numeric scale value to a short label (\"0.50\" → \"0.5\", \"1.0\" → \"1\"). */\nfunction trimNumber(n: number): string {\n if (Number.isInteger(n)) return String(n);\n return String(Number(n.toPrecision(6))).replace(/0+$/, \"\").replace(/\\.$/, \"\");\n}\n\n// ── Internal working node ──────────────────────────────────────────────────────────────\n\ninterface Work {\n node: PhyloNode;\n children: Work[];\n depth: number;\n /** Cumulative root→node branch length (phylogram); 0 for null/zero lengths. */\n dist: number;\n /** Length of the edge INTO this node (the root's is null). */\n inLength: number | null;\n cx: number;\n cy: number;\n}\n\nfunction nodeTitle(\n node: PhyloNode,\n isTip: boolean,\n isRoot: boolean,\n inLength: number | null,\n labels: PhyloTitleLabels,\n): string {\n if (node.title !== undefined) return node.title;\n const role = isRoot ? labels.root : isTip ? labels.tip : labels.clade;\n const head = node.label === \"\" ? role : node.label;\n const parts: string[] = [head];\n if (inLength !== null) parts.push(`${labels.branchLength}: ${trimNumber(inLength)}`);\n if (!isTip && node.support !== undefined && node.support !== null) {\n parts.push(`${labels.support}: ${trimNumber(node.support)}`);\n }\n return parts.join(\" · \");\n}\n\n/**\n * Deterministic, overlap-proof phylo layout (pure function of the inputs). Validates\n * first and THROWS PhyloValidationError on an un-layout-able tree — never sanitizes.\n * Empty input (no nodes, no edges) yields an empty, padded layout; `rootId` is ignored\n * in that one case.\n */\nexport function computePhyloLayout(input: PhyloInput, opts: PhyloLayoutOptions = {}): PhyloLayout {\n const mode: PhyloMode = opts.mode ?? \"cladogram\";\n if (input.nodes.length === 0 && input.edges.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, mode, nodes: [], elements: [], scaleBar: null, showSupport: false };\n }\n validatePhylo(input);\n\n const titleLabels = opts.titleLabels ?? PHYLO_TITLE_LABELS_EN;\n const alignTips = opts.alignTips ?? (mode === \"cladogram\");\n const showSupport = opts.showSupport ?? false;\n const wantScaleBar = (opts.scaleBar ?? true) && mode === \"phylogram\";\n\n const nodeById = new Map(input.nodes.map((n) => [n.id, n]));\n // Children of a node in declared edge order (stable by edge id) — the validated tree\n // guarantees every endpoint exists and each node has ≤1 parent.\n const childrenOf = new Map<number, number[]>();\n const inLengthByChild = new Map<number, number | null>();\n for (const e of [...input.edges].sort((a, b) => a.id - b.id)) {\n (childrenOf.get(e.parentId) ?? childrenOf.set(e.parentId, []).get(e.parentId)!).push(e.childId);\n inLengthByChild.set(e.childId, e.length);\n }\n\n // ── Build the working tree by DFS from the root (children in declared order). ─────────\n const allWork: Work[] = [];\n const build = (nodeId: number, depth: number, dist: number): Work => {\n const node = nodeById.get(nodeId)!;\n const inLength = inLengthByChild.get(nodeId) ?? null;\n const work: Work = { node, children: [], depth, dist, inLength, cx: 0, cy: 0 };\n allWork.push(work);\n for (const childId of childrenOf.get(nodeId) ?? []) {\n const childLen = inLengthByChild.get(childId);\n const add = childLen === null || childLen === undefined ? 0 : Math.max(0, childLen);\n work.children.push(build(childId, depth + 1, dist + add));\n }\n return work;\n };\n const root = build(input.rootId, 0, 0);\n\n const isTip = (w: Work): boolean => w.children.length === 0;\n\n // ── Vertical: equal leaf slots in DFS order; internal y = midpoint of children. ───────\n const top = PADDING;\n let tipIndex = 0;\n const assignY = (w: Work): void => {\n if (isTip(w)) {\n w.cy = top + tipIndex * PHYLO_ROW_SLOT + PHYLO_ROW_SLOT / 2;\n tipIndex += 1;\n return;\n }\n for (const c of w.children) assignY(c);\n const ys = w.children.map((c) => c.cy);\n w.cy = (Math.min(...ys) + Math.max(...ys)) / 2;\n };\n assignY(root);\n const tipCount = tipIndex;\n\n // ── Horizontal: depth-x (cladogram) or cumulative-length-x (phylogram, fit-to-width). ─\n const maxDepth = allWork.reduce((m, w) => Math.max(m, w.depth), 0);\n const maxDist = allWork.reduce((m, w) => Math.max(m, w.dist), 0);\n\n // Left margin: PADDING + reserved support-text width (only when showSupport AND any\n // internal node actually carries a support value — measured space, the house rule).\n const supportNodes = allWork.filter(\n (w) => !isTip(w) && w.node.support !== undefined && w.node.support !== null,\n );\n // Effective flag: support text is drawn ONLY when requested AND at least one internal\n // node actually carries a value (the layout reserves the margin for exactly that text).\n const effectiveShowSupport = showSupport && supportNodes.length > 0;\n const supportMargin = effectiveShowSupport\n ? supportNodes.reduce(\n (m, w) => Math.max(m, estimateTextWidth(trimNumber(w.node.support as number), PHYLO_SUPPORT_FONT)),\n 0,\n ) + SUPPORT_GAP\n : 0;\n const padLeft = PADDING + supportMargin;\n\n // Tip-label widths reserve real space on the right so the canvas always contains them.\n const tipLabelW = allWork\n .filter(isTip)\n .reduce((m, w) => Math.max(m, estimateTextWidth(clampLabel(w.node.label, opts.maxLabelChars), PHYLO_LABEL_FONT)), 0);\n const labelReserve = (tipCount > 0 ? PHYLO_LABEL_GAP + tipLabelW : 0) + PADDING;\n\n // Phylogram scale: fit the deepest root-to-tip distance to the available draw width\n // (the genogram's fit-to-container ethos). The width tracks topological depth so a deep\n // tree gets room; MIN_DRAW_W keeps a shallow tree (e.g. a single split) drawable.\n const phylogramScaled = mode === \"phylogram\" && maxDist > 0;\n const drawW = Math.max(MIN_DRAW_W, maxDepth * PHYLO_LEVEL_W);\n const scale = phylogramScaled ? drawW / maxDist : 0;\n\n const xOf = (w: Work): number => {\n if (phylogramScaled) return padLeft + w.dist * scale;\n return padLeft + w.depth * PHYLO_LEVEL_W; // cladogram (or degenerate phylogram)\n };\n for (const w of allWork) w.cx = xOf(w);\n\n // Phylogram-only de-collinearity nudge. A zero/null-length branch lands an INTERNAL child\n // at exactly its parent's x, so the child's clade bar and the parent's clade bar become\n // two collinear verticals (a double-drawn line that reads as an ambiguous polytomy). We\n // push such a child PHYLO_ZERO_NUDGE px right of the parent's FINAL x so its bar lives on\n // its own vertical — preserving the \"directly above the parent\" read (one pixel). A TIP at\n // the parent's x is fine (no clade bar), so it is never nudged. Pre-order so a chain of\n // zero-length internals each clears its own (already-nudged) parent — the monotone\n // cx(child) ≥ cx(parent) invariant is preserved, strictly. Purely positional: the verbatim\n // 0/null length is untouched (it still rides the branch element's <title>).\n if (phylogramScaled) {\n const nudge = (w: Work): void => {\n for (const c of w.children) {\n if (!isTip(c) && c.cx <= w.cx + 1e-6) c.cx = w.cx + PHYLO_ZERO_NUDGE;\n nudge(c);\n }\n };\n nudge(root);\n }\n\n // The alignment line for right-aligned tips. `alignTips` defaults true in cladogram\n // (the defining right-aligned look) and false in phylogram (the x IS the data); setting\n // it false in cladogram drops both the alignment AND the dotted extensions. Internals\n // keep their computed x; only TIPS are pushed to the line. In cladogram the line is the\n // deepest depth-x; in phylogram (alignTips:true) it is the rightmost tip's own x.\n const tipsAligned = alignTips;\n const maxTipX = allWork.filter(isTip).reduce((m, w) => Math.max(m, w.cx), padLeft);\n const alignX = phylogramScaled ? maxTipX : padLeft + maxDepth * PHYLO_LEVEL_W;\n const tipDrawX = (w: Work): number => (tipsAligned ? alignX : w.cx);\n\n // ── Canvas size. ──────────────────────────────────────────────────────────────────────\n const rightmost = tipsAligned ? alignX : allWork.reduce((m, w) => Math.max(m, w.cx), padLeft);\n const treeBottom = top + (tipCount > 0 ? tipCount * PHYLO_ROW_SLOT : PHYLO_ROW_SLOT);\n const scaleBarPx = wantScaleBar && maxDist > 0 ? niceScaleStep(maxDist) * scale : 0;\n const hasScaleBar = wantScaleBar && maxDist > 0 && scaleBarPx > 0;\n const width = Math.ceil(rightmost + labelReserve);\n const height = Math.ceil(treeBottom + (hasScaleBar ? SCALEBAR_ZONE : 0) + PADDING / 2);\n\n // ── Emit nodes (DFS pre-order) + elements. ────────────────────────────────────────────\n const nodes: PhyloLayoutNode[] = [];\n const elements: PhyloElement[] = [];\n\n const branchTitle = (w: Work): string => {\n if (w.inLength !== null) return `${titleLabels.branchLength}: ${trimNumber(w.inLength)}`;\n return titleLabels.branchLength;\n };\n\n // Root stub: a short horizontal lead-in to the root point (left of it), so a root with\n // a single child still reads as a tree origin. Drawn from padLeft − stub to the root x.\n const ROOT_STUB = 14;\n const rootDrawX = isTip(root) ? tipDrawX(root) : root.cx;\n elements.push({\n edgeId: PHYLO_ROOTSTUB_ID_BASE + root.node.id,\n kind: \"root-stub\",\n points: [\n { x: round(Math.max(PADDING / 2, rootDrawX - ROOT_STUB)), y: round(root.cy) },\n { x: round(rootDrawX), y: round(root.cy) },\n ],\n dotted: false,\n length: null,\n title: titleLabels.root,\n });\n\n const emit = (w: Work): void => {\n const tip = isTip(w);\n const isRoot = w === root;\n const drawX = tip ? tipDrawX(w) : w.cx;\n const support = w.node.support === undefined ? null : w.node.support;\n const labelLine = tip && w.node.label !== \"\" ? [clampLabel(w.node.label, opts.maxLabelChars)] : [];\n nodes.push({\n nodeId: w.node.id,\n isTip: tip,\n cx: round(drawX),\n cy: round(w.cy),\n support,\n labelLines: labelLine,\n labelLeft: round(drawX + PHYLO_TIP_R + PHYLO_LABEL_GAP),\n depth: w.depth,\n title: nodeTitle(w.node, tip, isRoot, w.inLength, titleLabels),\n });\n\n // Aligned tip → a dotted EXTENSION from its true branch-end x to the alignment line.\n if (tip && tipsAligned && w.cx < alignX - 1e-6) {\n elements.push({\n edgeId: PHYLO_EXTENSION_ID_BASE + w.node.id,\n kind: \"extension\",\n points: [\n { x: round(w.cx), y: round(w.cy) },\n { x: round(alignX), y: round(w.cy) },\n ],\n dotted: true,\n length: null,\n title: titleLabels.tip,\n });\n }\n\n if (w.children.length === 0) return;\n\n // One shared VERTICAL clade bar at the parent's x, spanning min→max child y.\n const childYs = w.children.map((c) => c.cy);\n const barTop = Math.min(...childYs);\n const barBottom = Math.max(...childYs);\n if (barBottom - barTop > 1e-6) {\n elements.push({\n edgeId: PHYLO_CLADEBAR_ID_BASE + w.node.id,\n kind: \"clade-bar\",\n points: [\n { x: round(w.cx), y: round(barTop) },\n { x: round(w.cx), y: round(barBottom) },\n ],\n dotted: false,\n length: null,\n title: isRoot ? titleLabels.root : titleLabels.clade,\n });\n }\n\n // One HORIZONTAL branch per child: parentX → childX at childY (the rectangular elbow).\n for (const c of w.children) {\n elements.push({\n edgeId: PHYLO_BRANCH_ID_BASE + c.node.id,\n kind: \"branch\",\n points: [\n { x: round(w.cx), y: round(c.cy) },\n { x: round(c.cx), y: round(c.cy) },\n ],\n dotted: false,\n length: c.inLength,\n title: branchTitle(c),\n });\n }\n for (const c of w.children) emit(c);\n };\n emit(root);\n\n // ── Scale bar (phylogram only): a labelled horizontal segment in the dead space below\n // the tree. Its value is a niceScaleStep of the deepest distance. ───────────────────\n let scaleBar: PhyloScaleBar | null = null;\n if (hasScaleBar) {\n const stepLen = niceScaleStep(maxDist);\n const barX = padLeft;\n const barY = treeBottom + SCALEBAR_ZONE / 2;\n scaleBar = {\n length: stepLen,\n x: round(barX),\n y: round(barY),\n pxLength: round(scaleBarPx),\n valueLabel: trimNumber(stepLen),\n };\n elements.push({\n edgeId: PHYLO_SCALEBAR_ID,\n kind: \"scale-bar\",\n points: [\n { x: round(barX), y: round(barY) },\n { x: round(barX + scaleBarPx), y: round(barY) },\n ],\n dotted: false,\n length: stepLen,\n title: `${titleLabels.branchLength}: ${trimNumber(stepLen)}`,\n });\n }\n\n return { width, height, mode, nodes, elements, scaleBar, showSupport: effectiveShowSupport };\n}\n","// Phylo SVG emitter — turns a computed PhyloLayout (./layout.ts) into a SELF-CONTAINED\n// SVG string. Pure (layout in, string out) and deterministic; it draws EXACTLY what the\n// layout computed (the overlap harness proves the layout; this emitter is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — labels/titles are author-controlled and\n// the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (hex colors, explicit font-family, inline\n// dasharray): a standalone SVG has no stylesheet, no currentColor, no <defs>/<marker>;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Drawing: rectangular (\"square elbow\") tree — a vertical clade bar per internal node + a\n// horizontal branch per child; aligned tips get a dotted extension leader; a small filled\n// dot marks each node point; tip labels sit left-anchored to the right of the tip; support\n// values (when showSupport baked the margin in) draw text-anchor:end just left of the\n// internal node. The phylogram scale bar is a first-class drawn element below the tree.\n//\n// Hooks: `<g data-node-id=\"n<id>\">` per node (direct-child verbatim <title>);\n// `<g data-edge-id=\"<n>\">` per element (namespaced ids, see ./layout.ts).\n\nimport { FONT_FAMILY, legendBlock, xmlEscape, LEGEND_SWATCH_W, type LegendEntry } from \"../core\";\nimport {\n PHYLO_LABEL_FONT,\n PHYLO_SUPPORT_FONT,\n type PhyloElement,\n type PhyloLayout,\n type PhyloLayoutNode,\n} from \"./layout\";\nimport { PHYLO_SVG_LABELS_EN, type PhyloSvgLabels } from \"./labels\";\n\n// Literal ink colors (zinc ramp on white — matches every other compasso emitter).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport interface PhyloSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: PhyloSvgLabels;\n}\n\n// ── Node points + tip labels + support text ───────────────────────────────────────────\n\nfunction nodeSvg(n: PhyloLayoutNode, showSupport: boolean): string {\n const pieces: string[] = [`<title>${xmlEscape(n.title)}</title>`];\n // A small filled dot marks every node point (tip and internal).\n pieces.push(`<circle cx=\"${n.cx}\" cy=\"${n.cy}\" r=\"2.5\" fill=\"${GLYPH_STROKE}\"/>`);\n // Tip label: single clamped line, left-anchored right of the tip point.\n if (n.labelLines.length > 0) {\n pieces.push(\n `<text x=\"${n.labelLeft}\" y=\"${round(n.cy + PHYLO_LABEL_FONT * 0.32)}\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_LABEL_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(n.labelLines[0]!)}</text>`,\n );\n }\n // Internal support value: text-anchor:end just left of the node (margin reserved in\n // the layout). Drawn only when requested AND the value is present.\n if (showSupport && !n.isTip && n.support !== null) {\n pieces.push(\n `<text x=\"${round(n.cx - 4)}\" y=\"${round(n.cy - 3)}\" text-anchor=\"end\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_SUPPORT_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(String(n.support))}</text>`,\n );\n }\n return `<g data-node-id=\"n${n.nodeId}\">${pieces.join(\"\")}</g>`;\n}\n\n// ── Connector elements (clade bars, branches, dotted extensions, root stub, scale bar) ──\n\nfunction elementSvg(el: PhyloElement): string {\n const a = el.points[0]!;\n const b = el.points[1]!;\n const dash = el.dotted ? ` stroke-dasharray=\"2,3\"` : \"\";\n const opacity = el.kind === \"extension\" ? \"0.5\" : \"0.75\";\n return (\n `<g data-edge-id=\"${el.edgeId}\"><title>${xmlEscape(el.title)}</title>` +\n `<line x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"${opacity}\"${dash}/></g>`\n );\n}\n\n// ── Scale-bar value label (drawn separately from its segment element) ──────────────────\n\nfunction scaleBarLabelSvg(layout: PhyloLayout): string {\n const bar = layout.scaleBar;\n if (bar === null) return \"\";\n // Small end ticks frame the bar; the value sits centered above it.\n const tick = (x: number): string =>\n `<line x1=\"${x}\" y1=\"${round(bar.y - 3)}\" x2=\"${x}\" y2=\"${round(bar.y + 3)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>`;\n return (\n tick(bar.x) +\n tick(round(bar.x + bar.pxLength)) +\n `<text x=\"${round(bar.x + bar.pxLength / 2)}\" y=\"${round(bar.y - 6)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_SUPPORT_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(bar.valueLabel)}</text>`\n );\n}\n\n// ── Legend mini-swatches ───────────────────────────────────────────────────────────────\n\nfunction supportSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return (\n `<circle cx=\"${cx}\" cy=\"${y}\" r=\"2.5\" fill=\"${GLYPH_STROKE}\"/>` +\n `<text x=\"${round(cx + 5)}\" y=\"${round(y + PHYLO_SUPPORT_FONT * 0.32)}\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_SUPPORT_FONT}\" fill=\"${LABEL_FILL}\">95</text>`\n );\n}\n\nfunction scaleSwatch(x: number, y: number): string {\n return `<line x1=\"${round(x)}\" y1=\"${y}\" x2=\"${round(x + LEGEND_SWATCH_W)}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>`;\n}\n\nfunction alignedTipSwatch(x: number, y: number): string {\n return `<line x1=\"${round(x)}\" y1=\"${y}\" x2=\"${round(x + LEGEND_SWATCH_W)}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.5\" stroke-dasharray=\"2,3\"/>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed phylo layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal. The legend is minimal and used-keys-only: a phylo\n * tree is self-labelling (tips carry names), so often it has zero entries.\n *\n * `showSupport` is read off the layout's reserved margin: the emitter draws the support\n * text only when a support value was reserved (any internal node has a non-null support\n * AND the support margin > PADDING). This keeps the emitter pinned to the layout — it\n * never reserves what the layout didn't, nor draws what it can't fit.\n */\nexport function phyloLayoutSvg(layout: PhyloLayout, opts: PhyloSvgOptions = {}): string {\n const labels = opts.labels ?? PHYLO_SVG_LABELS_EN;\n // showSupport is a layout-affecting option (it reserves left margin), so the layout\n // bakes the resolved flag in — the emitter reads it off the layout and never re-decides.\n const showSupport = layout.showSupport;\n\n const parts: string[] = [];\n\n // Connectors first, then node points/labels — points sit on top.\n for (const el of layout.elements) parts.push(elementSvg(el));\n parts.push(scaleBarLabelSvg(layout));\n for (const n of layout.nodes) parts.push(nodeSvg(n, showSupport));\n\n // ── Used-keys-only legend (core legendBlock; `legend:false` suppresses). ──────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: LegendEntry[] = [];\n if (showSupport) entries.push({ swatch: supportSwatch, label: labels.support });\n if (layout.scaleBar !== null) entries.push({ swatch: scaleSwatch, label: labels.scaleBar });\n if (layout.elements.some((e) => e.kind === \"extension\")) {\n entries.push({ swatch: alignedTipSwatch, label: labels.alignedTip });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel[layout.mode])}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call phylo render: input → { svg, layout }. Thin, honest wiring: validate (throw on\n// an un-layout-able tree — never repair), compute the pure layout, emit. Callers needing\n// finer control use computePhyloLayout + phyloLayoutSvg directly (the layout result\n// supports hit-testing / decorating the diagram).\n\nimport { computePhyloLayout, type PhyloLayout, type PhyloLayoutOptions } from \"./layout\";\nimport { phyloLayoutSvg } from \"./svg\";\nimport type { PhyloSvgLabels } from \"./labels\";\nimport type { PhyloInput } from \"./types\";\n\nexport interface PhyloRenderOptions extends PhyloLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: PhyloSvgLabels;\n}\n\nexport interface PhyloRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: PhyloLayout;\n}\n\n/**\n * Renders a phylo input to a self-contained SVG string. Deterministic: same data → same\n * SVG (array order never matters; a node's children are drawn in declared edge order, the\n * analyst's ladderization choice, never auto-sorted). Throws PhyloValidationError —\n * carrying EVERY issue, deterministically sorted — on an un-layout-able tree (cycle,\n * forest, DAG, dangling reference). Empty input yields an empty-but-valid SVG.\n */\nexport function phyloSvg(input: PhyloInput, opts: PhyloRenderOptions = {}): PhyloRenderResult {\n const layout = computePhyloLayout(input, {\n ...(opts.mode !== undefined ? { mode: opts.mode } : {}),\n ...(opts.alignTips !== undefined ? { alignTips: opts.alignTips } : {}),\n ...(opts.showSupport !== undefined ? { showSupport: opts.showSupport } : {}),\n ...(opts.scaleBar !== undefined ? { scaleBar: opts.scaleBar } : {}),\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = phyloLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Org-chart input model — declared facts only. compasso draws EXACTLY who the caller\n// declares reports to whom: every reporting line carries its declared `kind` (the line\n// STYLE is a semantic claim only the author may make), every box is a declared position,\n// and the ROOT is never declared — it is READ from topology (a position that is no solid\n// edge's report). There is deliberately NO `level`/`depth`/`isManager`/`order` field on\n// the input: depth is derived from the declared solid edges, not trusted from a flag (the\n// honesty rule). Multi-root forests (holding cos, co-CEOs, pre-merger) are real and\n// tolerated, never an error.\n\n/**\n * CLOSED reporting vocabulary — a line is drawn ONLY for a declared relationship, styled\n * ONLY by a declared kind. No inference, no synthesis.\n * - \"line\" — solid PRIMARY reporting line; defines the tree spine (a node's row & parent).\n * - \"assistant\" — solid SIDE-STEM staff/EA role; STILL a structural child of exactly one\n * manager (it sets the report's row = manager.depth + 1 band), but drawn\n * beside the manager's stem above the line-report bus rather than packed\n * into the sibling rake.\n * - \"dotted\" — dashed secondary/matrix line. NON-STRUCTURAL: never defines a row or a\n * parent; an OVERLAY between two already-placed boxes (dotted-line-manager\n * convention).\n */\nexport const ORG_REPORT_KINDS = [\"line\", \"assistant\", \"dotted\"] as const;\nexport type OrgReportKind = (typeof ORG_REPORT_KINDS)[number];\n\n/**\n * CLOSED vacancy vocabulary. A box is vacant ONLY when DECLARED so — never inferred from\n * an empty name. A vacant box may legitimately carry a name (a departed incumbent or a\n * target hire); both are drawn.\n */\nexport const ORG_VACANCIES = [\"filled\", \"vacant\"] as const;\nexport type OrgVacancy = (typeof ORG_VACANCIES)[number];\n\n/**\n * A declared organizational position (one box). `name`/`title`/`subtitle` are verbatim\n * (always kept in the <title>); empty strings / nulls are drawn as declared.\n */\nexport interface OrgPosition {\n id: number;\n /** Verbatim person/role name — line 1 of the box. \"\" allowed (drawn empty; <title> intact). */\n name: string;\n /** Verbatim job title — line 2 (smaller). null = name-only box. */\n title: string | null;\n /**\n * OPTIONAL third line (department/unit), verbatim, measured into boxW like the others.\n * null = none. NOT a metrics/compensation field — that interpretive cut stands.\n */\n subtitle: string | null;\n /**\n * \"vacant\" → dashed box + inset open-seat frame + localized \"(vago)\" marker line.\n * A box is vacant ONLY when DECLARED so — never inferred from an empty name.\n * (validation defaults an absent value → \"filled\").\n */\n vacancy: OrgVacancy;\n /** Verbatim <title> override; defaults below (see svg.ts). */\n hover?: string;\n /**\n * Caller-asserted annotation flag. compasso never decides what \"annotated\" MEANS —\n * it only draws a discreet dot at the box's upper-right when true. Default undefined\n * === not annotated (backward-compatible).\n */\n annotated?: boolean;\n}\n\n/**\n * One row per DECLARED relationship, manager → report. There is no `order` column in\n * v0.4.0 — sibling order among reports is by ascending `reportId`.\n */\nexport interface OrgReport {\n id: number;\n /** Manager — drawn ABOVE. */\n managerId: number;\n /** Report — drawn BELOW (line) or side-stemmed (assistant). */\n reportId: number;\n /** Reporting-line kind (validation defaults an absent value → \"line\"). */\n kind: OrgReportKind;\n /** Verbatim relationship label (e.g. \"interim\", \"matrix\") for the <title>; null = none. */\n label?: string | null;\n /**\n * Caller-asserted annotation flag. compasso never decides what \"annotated\" MEANS —\n * it only draws a discreet tick at the edge's midpoint when true. Default undefined\n * === not annotated (backward-compatible).\n */\n annotated?: boolean;\n}\n\n/** Input to the org-chart render pipeline — flat, id-referenced rows, never nested. */\nexport interface OrgChartInput {\n positions: OrgPosition[];\n reports: OrgReport[];\n}\n\n/**\n * Presentation-only derived box style (solid = filled, dashed = vacant). Computed in\n * render.ts / svg.ts from `vacancy` — NOT an input field.\n */\nexport type OrgBoxStyle = \"solid\" | \"dashed\";\n","// Display vocabularies — every human-readable string the org chart emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// Split, mirroring fault-tree/genogram: `OrgChartTitleLabels` is woven into element/box\n// <title>s by the LAYOUT (verbatim-preserving — the localized kind word rides each line's\n// <title>, never the map); `OrgChartSvgLabels` is drawn by the EMITTER (legend, aria).\n// `reportKinds` is a `Record<OrgReportKind, string>` so a missing kind is a compile error\n// (`pnpm typecheck` is the completeness guard).\n\nimport type { OrgReportKind } from \"./types\";\n\n/** Labels woven into element/box <title>s by the LAYOUT (verbatim-preserving). */\nexport interface OrgChartTitleLabels {\n reportKinds: Record<OrgReportKind, string>;\n /** The \"(vacant)\" box marker line, drawn inside a vacant box. */\n vacant: string;\n}\n\nexport const ORG_CHART_TITLE_LABELS_EN: OrgChartTitleLabels = {\n reportKinds: { line: \"Reports to\", assistant: \"Assistant to\", dotted: \"Dotted-line report to\" },\n vacant: \"(vacant)\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface OrgChartSvgLabels {\n legend: { line: string; assistant: string; dotted: string; vacant: string };\n ariaLabel: string;\n}\n\nexport const ORG_CHART_SVG_LABELS_EN: OrgChartSvgLabels = {\n legend: { line: \"Reports to\", assistant: \"Assistant\", dotted: \"Dotted-line / matrix\", vacant: \"Vacant position\" },\n ariaLabel: \"Organizational chart\",\n};\n","// Org-chart validation — REJECT, never repair. The genogram silently filters dangling\n// references because a family map is elicited incrementally; an org chart is an\n// AUTHORITATIVE artifact whose meaning is \"who answers to whom\", so drawing a structurally\n// invalid chart (a dropped line, a synthesized parent) misstates the hierarchy and is\n// worse than refusing. The honest escape hatch for a node with two real bosses is the\n// dotted line — keep ONE solid reporting line, make the rest kind:\"dotted\".\n//\n// Every problem is reported, not just the first: issues are aggregated, deduplicated and\n// sorted deterministically (by code, then message), each carrying a STABLE kebab-case\n// `code`. Validation runs in THREE phases, each gated on the previous being clean ENOUGH\n// for the next to be meaningful — not on \"zero issues so far\", so a defect in one phase\n// never silently hides an honest issue from a later one (the throw carries ALL real\n// issues, not just the first phase's):\n// (0) duplicate ids (per namespace — positions AND reports). The lookup maps are\n// first-occurrence-wins, so EVERY reference rule below would validate whichever\n// duplicate row was declared first — making the issue list depend on array order,\n// violating this function's documented order-invariance. When any duplicate-id issue\n// exists we report ONLY those and stop (the duplicate already forces a throw).\n// (1) reference / semantic rules: unknown manager/report endpoints, self-loops, a node\n// with ≥2 SOLID structural parents, and an assistant that itself manages a solid edge\n// (v0.4.0 scopes assistants as side-stem LEAVES — a non-leaf assistant would silently\n// drop its subtree, so we REJECT rather than repair). Evaluated once ids are unambiguous.\n// (2) graph rule (cycle over the SOLID-edge graph) — gated ONLY on the reference-\n// INTEGRITY subset that genuinely corrupts traversal: duplicate-id (ambiguous\n// first-wins node), unknown-manager / unknown-report (walks a phantom node), and\n// multiple-managers (the instance-tree build picks one of two solid parents and\n// would walk an ambiguous structure). `self-report` does NOT block: it references a\n// real, walkable node, and the DFS defensively skips `from === to` solid edges.\n//\n// Tolerated, by design (drawn as declared, never an error):\n// - FOREST — zero/one/many roots (no invented super-root, no inter-tree connector);\n// - dotted edges crossing between forest trees, dotted-only cycles, a dotted edge sharing\n// a solid pair's direction (dotted is NON-structural — never triggers cycle or\n// multiple-managers); a dotted edge into an already-solid-parented box is FINE;\n// - empty name/title/subtitle (drawn empty; the <title> is still present);\n// - a vacant box with a name (departed incumbent / target hire).\n\nimport type { OrgChartInput, OrgPosition, OrgReport } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type OrgChartIssueCode =\n | \"duplicate-id\"\n | \"unknown-manager\"\n | \"unknown-report\"\n | \"self-report\"\n | \"multiple-managers\"\n | \"assistant-has-reports\"\n | \"too-many-matrix-edges\"\n | \"cycle\";\n\n/**\n * Routing capacity: the max number of dotted (matrix) connections one position can be an\n * endpoint of (as manager OR report). Each such edge must escape that box's edge to a\n * box-free column at a distinct (column, exit-y) slot; a finite box edge holds only finitely\n * many clean orthogonal exits, so beyond this the escape columns/exit-rows would collide.\n * 5 is the conservative bound proven collision-free even for the shortest single-line box —\n * a position with more matrix lines than this is rejected rather than misdrawn (the\n * reject-don't-repair doctrine). Realistic matrix orgs sit far below it.\n */\nexport const ORG_MAX_MATRIX_EDGES_PER_NODE = 5;\n\nexport interface OrgChartIssue {\n code: OrgChartIssueCode;\n message: string;\n}\n\n/** Thrown by computeOrgChartLayout / orgChartSvg on a structurally invalid chart. */\nexport class OrgChartValidationError extends Error {\n readonly issues: readonly OrgChartIssue[];\n\n constructor(issues: readonly OrgChartIssue[]) {\n super(`invalid org chart: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"OrgChartValidationError\";\n this.issues = issues;\n }\n}\n\n/** \"1 and 3\" / \"1, 2 and 3\" — deterministic listing for issue messages. */\nfunction listIds(ids: readonly number[]): string {\n if (ids.length === 1) return String(ids[0]);\n return `${ids.slice(0, -1).join(\", \")} and ${ids[ids.length - 1]}`;\n}\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable\n * across engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly OrgChartIssue[]): readonly OrgChartIssue[] {\n const unique = new Map<string, OrgChartIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Graph-phase gating set: the cycle DFS runs only when no reference-INTEGRITY issue\n * corrupts the traversal. duplicate-id / unknown-manager / unknown-report make a walked\n * node ambiguous or phantom; multiple-managers makes the instance-tree's \"pick one solid\n * parent\" build ambiguous. self-report does NOT block (real walkable node; the DFS skips\n * the self-loop defensively).\n */\nconst GRAPH_BLOCKING: ReadonlySet<OrgChartIssueCode> = new Set<OrgChartIssueCode>([\n \"duplicate-id\",\n \"unknown-manager\",\n \"unknown-report\",\n \"multiple-managers\",\n]);\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically sorted\n * (code, then message) — array order of `positions`/`reports` never changes the result.\n * Empty input (no positions AND no reports) is valid by definition (the renderer's\n * empty-but-valid SVG case) and reports no issues. A forest (zero/one/many roots) is\n * valid and never reported.\n */\nexport function orgChartIssues(input: OrgChartInput): readonly OrgChartIssue[] {\n if (input.positions.length === 0 && input.reports.length === 0) return [];\n\n const issues: OrgChartIssue[] = [];\n const push = (code: OrgChartIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── Phase 0: duplicate ids (per namespace — positions and reports are two namespaces;\n // hooks must be unique). Any duplicate makes the structure ambiguous, so this\n // short-circuits the rest (below). ─────────────────────────────────────────────────\n const positionById = new Map<number, OrgPosition>();\n const dupPositionIds = new Set<number>();\n for (const p of input.positions) {\n if (positionById.has(p.id)) dupPositionIds.add(p.id);\n else positionById.set(p.id, p);\n }\n for (const id of [...dupPositionIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate position id ${id}`);\n }\n const reportById = new Map<number, OrgReport>();\n const dupReportIds = new Set<number>();\n for (const r of input.reports) {\n if (reportById.has(r.id)) dupReportIds.add(r.id);\n else reportById.set(r.id, r);\n }\n for (const id of [...dupReportIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate report id ${id}`);\n }\n\n // Duplicate ids short-circuit everything else: the lookup maps above are\n // first-occurrence-wins, so every downstream reference rule would validate whichever\n // duplicate row happened to be declared first — making the issue list depend on the\n // ARRAY ORDER, in direct violation of this function's documented order-invariance. We\n // report ONLY the duplicate-id issues and stop (the structural defect already forces a\n // throw, and is present in every permutation).\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n const reports = [...reportById.values()].sort((a, b) => a.id - b.id);\n\n // ── Phase 1: reference / semantic rules. ─────────────────────────────────────────────\n // Endpoints must reference declared positions; a box may not report to itself; a node\n // has exactly ONE structural parent. `solidParents` accumulates the SOLID (line|assistant)\n // parent edge ids per report position to fire multiple-managers regardless of kind mix.\n const solidParents = new Map<number, number[]>(); // reportId → solid edge ids\n const assistantReportEdge = new Map<number, number>(); // position → first assistant edge it is the report of\n const solidManagedEdges = new Map<number, number[]>(); // managerId → solid edge ids it manages\n const dottedDegree = new Map<number, number>(); // position → # dotted edges it is an endpoint of (mgr or rep)\n for (const r of reports) {\n const hasManager = positionById.has(r.managerId);\n const hasReport = positionById.has(r.reportId);\n if (!hasManager) {\n push(\"unknown-manager\", `report ${r.id} managerId ${r.managerId} is not a declared position`);\n }\n if (!hasReport) {\n push(\"unknown-report\", `report ${r.id} reportId ${r.reportId} is not a declared position`);\n }\n // R: a box reporting to itself is meaningless and self-loops layout — on ANY kind.\n if (r.managerId === r.reportId) {\n push(\"self-report\", `report ${r.id} has managerId === reportId (${r.managerId})`);\n }\n // A SOLID edge (line | assistant) is a structural parent — accumulate even when an\n // endpoint is unknown, so a node with two solid parents is still flagged (the codes\n // are independent facts). dotted is NON-structural and excluded here.\n if (r.kind !== \"dotted\") {\n const arr = solidParents.get(r.reportId) ?? [];\n arr.push(r.id);\n solidParents.set(r.reportId, arr);\n // Track each position's SOLID down-edges (it is the manager of) so a non-leaf\n // assistant — a position that is an assistant-report yet manages a solid edge — is\n // caught below. `reports` is id-sorted, so the lowest edge id lands first.\n const managed = solidManagedEdges.get(r.managerId) ?? [];\n managed.push(r.id);\n solidManagedEdges.set(r.managerId, managed);\n }\n // First (lowest-id) assistant edge that makes this position an assistant-report. A\n // self-loop assistant is excluded — `self-report` already carries that fact and the\n // position never legitimately becomes a side-stem leaf.\n if (r.kind === \"assistant\" && r.managerId !== r.reportId && !assistantReportEdge.has(r.reportId)) {\n assistantReportEdge.set(r.reportId, r.id);\n }\n // Per-position dotted (matrix) degree, for the routing-capacity cap below. A dotted edge\n // makes BOTH endpoints escape their box edge, so each declared endpoint counts once;\n // self-loops (already `self-report`) and phantom endpoints (already `unknown-*`) are\n // excluded — they never reach the router.\n if (r.kind === \"dotted\" && r.managerId !== r.reportId) {\n if (positionById.has(r.managerId)) dottedDegree.set(r.managerId, (dottedDegree.get(r.managerId) ?? 0) + 1);\n if (positionById.has(r.reportId)) dottedDegree.set(r.reportId, (dottedDegree.get(r.reportId) ?? 0) + 1);\n }\n }\n // multiple-managers fires whenever a position is the report of ≥2 SOLID edges, regardless\n // of kind — including one `line` parent AND one `assistant` parent (still two structural\n // parents; the instance-tree DFS would be ambiguous about which owns the row). There is\n // no \"which kind wins\" tiebreak — it is rejected. Escape hatch: keep one solid line, make\n // the rest kind:\"dotted\".\n for (const [reportId, edgeIds] of [...solidParents.entries()].sort((a, b) => a[0] - b[0])) {\n if (edgeIds.length > 1) {\n push(\n \"multiple-managers\",\n `position ${reportId} is the report of solid edges ${listIds(edgeIds.sort((a, b) => a - b))} — keep one solid line, make the rest kind \"dotted\"`,\n );\n }\n }\n\n // assistant-has-reports: v0.4.0 draws an assistant as a side-stem LEAF, so a position\n // that is an assistant-report AND manages a solid (line|assistant) edge would have its\n // entire subtree silently dropped. REJECT it (reject-don't-repair) — keep the lowest\n // managed solid edge id in the message so the author knows which line to recut. Ascending\n // position id for a deterministic, array-order-invariant list.\n for (const [positionId, assistEdgeId] of [...assistantReportEdge.entries()].sort((a, b) => a[0] - b[0])) {\n const managed = solidManagedEdges.get(positionId);\n if (managed !== undefined && managed.length > 0) {\n const firstManaged = Math.min(...managed);\n push(\n \"assistant-has-reports\",\n `position ${positionId} is an assistant (report of edge ${assistEdgeId}) but manages solid edge ${firstManaged} — assistants are leaves`,\n );\n }\n }\n\n // too-many-matrix-edges: a position that is an endpoint of more dotted (matrix) edges than\n // the router can place distinct box-free escape slots for (see ORG_MAX_MATRIX_EDGES_PER_NODE).\n // Reject rather than misdraw (overlapping/colliding lines). Ascending position id for a\n // deterministic, array-order-invariant list.\n for (const [positionId, count] of [...dottedDegree.entries()].sort((a, b) => a[0] - b[0])) {\n if (count > ORG_MAX_MATRIX_EDGES_PER_NODE) {\n push(\n \"too-many-matrix-edges\",\n `position ${positionId} has ${count} dotted (matrix) connections — at most ${ORG_MAX_MATRIX_EDGES_PER_NODE} are supported per position`,\n );\n }\n }\n\n // ── Phase 2: graph rule (cycle over the SOLID-edge graph). Gated ONLY on the reference-\n // INTEGRITY codes that corrupt the traversal itself (see GRAPH_BLOCKING). dotted edges\n // are EXCLUDED — a matrix back-link is legal and never a cycle. ─────────────────────\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n // Adjacency manager → reports over SOLID edges only, in ascending reportId so the DFS\n // walks children deterministically (array-order-invariant). `from === to` self-loops\n // are skipped defensively (self-report carries that fact as its own code).\n const solidChildren = new Map<number, number[]>();\n for (const r of reports) {\n if (r.kind === \"dotted\") continue;\n if (r.managerId === r.reportId) continue;\n const arr = solidChildren.get(r.managerId) ?? [];\n arr.push(r.reportId);\n solidChildren.set(r.managerId, arr);\n }\n for (const arr of solidChildren.values()) arr.sort((a, b) => a - b);\n\n // Iterative coloring DFS, start nodes ascending; each distinct cycle is reported once,\n // rotated to start at its smallest position id so the message is identical for any\n // array order of the same input.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = solidChildren.get(frame.id) ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n // Back edge: the cycle is the stack slice from `child` down to the current frame.\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\"cycle\", `cycle: ${[...rotated, rotated[0]!].join(\" → \")}`);\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n for (const p of [...positionById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(p.id) ?? 0) === 0) dfs(p.id);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws OrgChartValidationError (carrying ALL issues) when the input is invalid. */\nexport function validateOrgChart(input: OrgChartInput): void {\n const issues = orgChartIssues(input);\n if (issues.length > 0) throw new OrgChartValidationError(issues);\n}\n","// PURE org-chart layout — the single source of truth for box positioning and connector\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so every surface\n// (web, PDF, image pipelines) stays pinned together and can never drift.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so the same\n// input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS what the caller declared. There is NO\n// `level`/`depth`/`order` field on the input — depth is READ from the declared solid\n// edges (line|assistant) and the root is READ from topology (a position that is no solid\n// edge's report). Validation (./validate.ts) THROWS on a structurally invalid chart\n// instead of repairing it — an org chart is an authoritative artifact and silently\n// altering who-answers-to-whom is synthesis. Forests (zero/one/many roots) are tolerated.\n//\n// LAYOUT — top-down rows, exactly as every org chart draws it: manager box, short stem\n// down to a sibling bus, drops to each line-report box. Horizontal placement is NAIVE\n// SUBTREE-SPAN PACKING (the fault-tree `pack` transposed top-down, NOT Reingold–Tilford\n// contours): every subtree carries asymmetric half-extents {halfL, halfR}; siblings are\n// placed with disjoint intervals ORG_SIBLING_GAP apart, the recursion makes the guarantee\n// global (a 5-line inductive overlap proof, re-verified by the test harness), at the cost\n// of some width on unbalanced trees. Label widths reserve REAL space because boxW comes\n// from estimateTextWidth over the wrapped lines and the emitter draws with the same core\n// metrics — what is proven is what is drawn.\n//\n// CORRIDOR-GROW INVARIANT (asserted in test/org-chart/layout.test.ts): a manager's\n// assistant stack hangs in the corridor between its row and the next; the corridor grows\n// to clear the tallest stack, so every manager box bottom AND every assistant box bottom\n// sits strictly ABOVE the child bus y (the fault-tree gate-clearance analog).\n//\n// DOTTED/MATRIX overlay → a reserved RIGHT-MARGIN GUTTER (the decisive graft): after the\n// solid tree is placed, each dotted edge routes as a 3-segment orthogonal elbow into a\n// per-edge lane at x > every box's right edge — box-free by construction.\n\nimport { clampLabel, estimateTextWidth, wrapLabelBalanced, type Point } from \"../core\";\nimport { ORG_CHART_TITLE_LABELS_EN, type OrgChartTitleLabels } from \"./labels\";\nimport { validateOrgChart } from \"./validate\";\nimport type { OrgBoxStyle, OrgChartInput, OrgPosition, OrgReport } from \"./types\";\n\nexport {\n OrgChartValidationError,\n orgChartIssues,\n validateOrgChart,\n type OrgChartIssue,\n type OrgChartIssueCode,\n} from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render) ──────\n/** Name line font size (px). */\nexport const ORG_LABEL_FONT = 12;\n/** Title + subtitle + vacant marker font size (px). */\nexport const ORG_TITLE_FONT = 10;\n/** Line height for stacked label lines inside a box (px). */\nexport const ORG_LABEL_LINE_H = 14;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────\n/** Canvas padding on every side. */\nconst PADDING = 32;\n/** Min horizontal air between two sibling subtree intervals. */\nconst ORG_SIBLING_GAP = 28;\n/** Min horizontal air between two forest trees. */\nconst ORG_TREE_GAP = 56;\n/** Base vertical band between a row and the next (the bus lives mid-way). */\nconst ORG_CORRIDOR = 30;\n/** Minimum box width (boxes never shrink below this even with tiny labels). */\nconst ORG_MIN_BOX_W = 120;\n/** Horizontal padding inside a box (each side). */\nconst ORG_BOX_PAD_X = 12;\n/** Vertical padding inside a box (each side). */\nconst ORG_BOX_PAD_Y = 9;\n/** Horizontal gap from a manager's stem to an assistant box (reserved into ownHalfL). */\nconst ORG_ASSIST_GAP = 24;\n/** Vertical gap between stacked assistant bands (and below the last one). */\nconst ORG_ASSIST_BAND_DROP = 14;\n/** Horizontal gap from the tree's right edge to the first dotted gutter lane. */\nconst ORG_MATRIX_GUTTER_GAP = 28;\n/** Horizontal pitch between adjacent dotted gutter lanes. */\nconst ORG_MATRIX_LANE_PITCH = 14;\n/** Horizontal step between adjacent escape-vertical lanes that share a column. The GLOBAL\n * greedy first-fit (STEP 6 / FIX 2) nudges any y-overlapping coincident vertical by\n * lane*ORG_MATRIX_ESCAPE_STEP in the endpoint's escape direction until its column is clear of\n * every already-placed vertical; box-freeness holds while lane*STEP stays inside the MEASURED\n * box-free band to that side (distance to the nearest real box edge overlapping the vertical's\n * y-span). The router asserts (escape-column-overflow) rather than misdraw if a nudge exceeds\n * the band. */\nconst ORG_MATRIX_ESCAPE_STEP = 2;\n\n// ── Namespaced element ids (one element kind per numeric block, fault-tree convention)\n// — every data-edge-id stays traceable to its source row. ───────────────────────\nexport const ORG_STEM_ID_BASE = 1_000_000; // + managerId (manager box bottom → bus level)\nexport const ORG_BUS_ID_BASE = 2_000_000; // + managerId (horizontal sibling bus)\nexport const ORG_DROP_ID_BASE = 3_000_000; // + reportId (bus → line-report box top)\nexport const ORG_ASSIST_ID_BASE = 4_000_000; // + reportId (side-stem elbow to assistant)\nexport const ORG_DOTTED_ID_BASE = 5_000_000; // + report.id (matrix gutter route)\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// A box's LEFT/RIGHT edge AS DRAWN. svg.ts draws the rect at left = round(node.cx −\n// node.boxW/2) from the EMITTED (rounded) node geometry (node.cx === round(cx), node.boxW\n// === round(boxW)); width is node.boxW. Any segment that attaches to a box edge (the assist\n// elbow, the dotted matrix stub) MUST target these exact values — deriving the edge from raw\n// cx/boxW (or from a sibling expression like managerCx − gap) rounds DIFFERENTLY and lands\n// the endpoint a sub-cent INSIDE the box (a real off-by-0.01 in the emitted SVG, flagged by\n// the overlap harness). boxW is an exact multiple of 0.01, so drawnLeft + boxW === the box's\n// own right edge. Box CENTERS (stem/drop x) already use round(cx) === node.cx and are fine.\nconst drawnLeftEdge = (cx: number, boxW: number): number => round(round(cx) - round(boxW) / 2);\nconst drawnRightEdge = (cx: number, boxW: number): number => drawnLeftEdge(cx, boxW) + round(boxW);\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────\n\nexport type OrgElementKind = \"stem\" | \"bus\" | \"drop\" | \"assist\" | \"dotted\";\n\nexport interface OrgNode {\n positionId: number;\n /** Box center x. */\n cx: number;\n /** Box top y. */\n top: number;\n boxW: number;\n boxH: number;\n /** \"solid\" = filled, \"dashed\" = vacant (presentation-only derived value). */\n style: OrgBoxStyle;\n /** Wrapped display lines per family (drawn centered, stacked, by font size). */\n nameLines: string[];\n titleLines: string[];\n subtitleLines: string[];\n /** Localized \"(vago)\" marker line; null on filled boxes. */\n vacantMarker: string | null;\n /** True for side-branched assistant nodes (legend + harness use it). */\n isAssistant: boolean;\n /** Depth of the row this node lives in (assistant: its manager's row + 1 band). */\n depth: number;\n /** Verbatim <title> text. */\n title: string;\n /** True when the caller declared this position annotated. Drives the dot marker in svg.ts. */\n annotated: boolean;\n}\n\nexport interface OrgElement {\n /** Namespaced id (ORG_*_ID_BASE + managerId / reportId / report.id). */\n edgeId: number;\n kind: OrgElementKind;\n /** ≥2 waypoints, every consecutive pair axis-aligned (H or V). */\n points: Point[];\n /** True only on \"dotted\" elements. */\n dashed: boolean;\n /** Verbatim <title> text (woven from the title-label pack). */\n title: string;\n /** True when the source OrgReport was declared annotated. Drives the tick marker in svg.ts.\n * stem/bus: not 1:1 with a report — annotated:false by design (documented choice). */\n annotated: boolean;\n}\n\nexport interface OrgChartLayout {\n width: number;\n height: number;\n nodes: OrgNode[];\n elements: OrgElement[];\n /** Forest order, ascending id. */\n rootPositionIds: number[];\n}\n\nexport interface OrgChartLayoutOptions {\n /** Cap each box's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for box/element <title>s — English default; see locale packs. */\n titleLabels?: OrgChartTitleLabels;\n}\n\n// ── PURE span-packer (Judge-1 seam) ────────────────────────────────────────────────\n// Consumes ONLY half-extents + gap constants; returns the per-child offsets and the\n// subtree's own half-extents. ZERO references to OrgNode, assistant, vacancy, depth,\n// style or the rake — so a later lift to a shared core/tree.ts is a provably-zero-change\n// refactor (do NOT extract core/tree.ts in v0.4.0 — module-local per shipped precedent).\n// Unit-tested directly in test/org-chart/pack-subtree.test.ts.\n\n/** A node's own symmetric-or-asymmetric half-extents plus its children's half-extents. */\nexport interface PackNode {\n ownHalfL: number;\n ownHalfR: number;\n /** One entry per child, in placement order; empty = leaf. */\n children: { halfL: number; halfR: number }[];\n}\n\nexport interface PackGaps {\n siblingGap: number;\n}\n\nexport interface PackResult {\n /** Subtree half-extents (cover the ENTIRE subtree). */\n halfL: number;\n halfR: number;\n /** Center offset of each child relative to this node's center (parallel to children). */\n offsets: number[];\n}\n\n/**\n * Span-packs a node's children into disjoint horizontal intervals (the fault-tree `pack`\n * transposed top-down). Children c1..cn: x1 = 0; x_{i+1} = x_i + halfR_i + siblingGap +\n * halfL_{i+1}. Parent axis a = (x1 + xn)/2 — centered over its line-report block. The\n * returned offsets are each child's center MINUS the parent axis. Subtree halfL/halfR\n * extend ownHalf* to cover the children block. Pure + deterministic.\n */\nexport function packSubtree(node: PackNode, gaps: PackGaps): PackResult {\n const { ownHalfL, ownHalfR, children } = node;\n if (children.length === 0) {\n return { halfL: ownHalfL, halfR: ownHalfR, offsets: [] };\n }\n const xs: number[] = [0];\n for (let i = 1; i < children.length; i++) {\n xs.push(xs[i - 1]! + children[i - 1]!.halfR + gaps.siblingGap + children[i]!.halfL);\n }\n const first = children[0]!;\n const last = children[children.length - 1]!;\n const axis = (xs[0]! + xs[xs.length - 1]!) / 2;\n const offsets = xs.map((x) => x - axis);\n const halfL = Math.max(ownHalfL, axis - (xs[0]! - first.halfL));\n const halfR = Math.max(ownHalfR, xs[xs.length - 1]! + last.halfR - axis);\n return { halfL, halfR, offsets };\n}\n\n// ── Box measurement (via core text metrics; what is reserved is what is drawn) ──────\n\ninterface Measured {\n boxW: number;\n boxH: number;\n nameLines: string[];\n titleLines: string[];\n subtitleLines: string[];\n vacantMarker: string | null;\n}\n\nfunction measurePosition(\n position: OrgPosition,\n maxLabelChars: number | undefined,\n vacantWord: string,\n): Measured {\n const nameLines =\n position.name === \"\" ? [] : wrapLabelBalanced(clampLabel(position.name, maxLabelChars), 2);\n const titleLines =\n position.title === null ? [] : wrapLabelBalanced(clampLabel(position.title, maxLabelChars), 2);\n const subtitleLines =\n position.subtitle === null ? [] : wrapLabelBalanced(clampLabel(position.subtitle, maxLabelChars), 1);\n const vacantMarker = position.vacancy === \"vacant\" ? vacantWord : null;\n\n let innerW = 0;\n for (const l of nameLines) innerW = Math.max(innerW, estimateTextWidth(l, ORG_LABEL_FONT));\n for (const l of titleLines) innerW = Math.max(innerW, estimateTextWidth(l, ORG_TITLE_FONT));\n for (const l of subtitleLines) innerW = Math.max(innerW, estimateTextWidth(l, ORG_TITLE_FONT));\n if (vacantMarker !== null) innerW = Math.max(innerW, estimateTextWidth(vacantMarker, ORG_TITLE_FONT));\n\n const boxW = Math.max(ORG_MIN_BOX_W, innerW + ORG_BOX_PAD_X * 2);\n const lineCount =\n nameLines.length + titleLines.length + subtitleLines.length + (vacantMarker !== null ? 1 : 0);\n const boxH = ORG_BOX_PAD_Y * 2 + lineCount * ORG_LABEL_LINE_H;\n return { boxW, boxH, nameLines, titleLines, subtitleLines, vacantMarker };\n}\n\nfunction positionTitle(position: OrgPosition, vacantWord: string): string {\n if (position.hover !== undefined) return position.hover;\n if (position.title !== null) {\n return position.name === \"\" ? position.title : `${position.name} — ${position.title}`;\n }\n if (position.name !== \"\") return position.name;\n return vacantWord; // vacant box with no name & no title — append the vacant word\n}\n\n// ── Internal working node (one per declared position; org positions never repeat) ──\n\ninterface Inst {\n position: OrgPosition;\n m: Measured;\n style: OrgBoxStyle;\n title: string;\n depth: number;\n /** Line-report children (ascending reportId), placed into the sibling rake. */\n lineChildren: Inst[];\n /** Assistant children (ascending reportId), side-stemmed left of the stem. */\n assistants: { inst: Inst; report: OrgReport }[];\n /** Reserved left/right half-extents of THIS node's own box (+ assistant reservation). */\n ownHalfL: number;\n ownHalfR: number;\n /** Subtree half-extents after packing. */\n spanL: number;\n spanR: number;\n /** Offset of each line-child center relative to this node's center. */\n offsets: number[];\n /** Absolute box center x (resolved top-down). */\n cx: number;\n /** Report row that made this an assistant (for the assist element's title/id). */\n assistReport: OrgReport | null;\n /** Absolute box top y for an assistant (set during emit; line nodes use rowTop[depth]). */\n assistTop: number;\n}\n\n/**\n * Deterministic, overlap-proof org-chart layout (pure function of the inputs). Validates\n * first and THROWS OrgChartValidationError on a structurally invalid chart — never\n * sanitizes. Empty input (no positions AND no reports) yields an empty, padded layout.\n */\nexport function computeOrgChartLayout(\n input: OrgChartInput,\n opts: OrgChartLayoutOptions = {},\n): OrgChartLayout {\n if (input.positions.length === 0 && input.reports.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], rootPositionIds: [] };\n }\n validateOrgChart(input);\n\n const titleLabels = opts.titleLabels ?? ORG_CHART_TITLE_LABELS_EN;\n const vacantWord = titleLabels.vacant;\n const positionById = new Map(input.positions.map((p) => [p.id, p]));\n\n // Solid (line|assistant) edges only define the tree. id-sort for order-independence;\n // sibling order among reports is by ascending reportId.\n const reports = [...input.reports].sort((a, b) => a.id - b.id);\n const solidReports = reports.filter((r) => r.kind !== \"dotted\");\n\n // Build per-manager child buckets (line-reports + assistants), each ascending reportId.\n const lineChildIds = new Map<number, OrgReport[]>();\n const assistChildIds = new Map<number, OrgReport[]>();\n const solidParentReportId = new Set<number>(); // positions that have a solid parent\n for (const r of solidReports) {\n solidParentReportId.add(r.reportId);\n const bucket = r.kind === \"assistant\" ? assistChildIds : lineChildIds;\n const arr = bucket.get(r.managerId) ?? [];\n arr.push(r);\n bucket.set(r.managerId, arr);\n }\n for (const arr of lineChildIds.values()) arr.sort((a, b) => a.reportId - b.reportId);\n for (const arr of assistChildIds.values()) arr.sort((a, b) => a.reportId - b.reportId);\n\n // Roots: positions that are no solid edge's reportId, ascending id (forest order).\n const rootPositionIds = input.positions\n .map((p) => p.id)\n .filter((id) => !solidParentReportId.has(id))\n .sort((a, b) => a - b);\n\n // ── Build the instance tree per root over solid edges (each position once). ────────\n const newInst = (position: OrgPosition, depth: number, assistReport: OrgReport | null): Inst => {\n const m = measurePosition(position, opts.maxLabelChars, vacantWord);\n return {\n position,\n m,\n style: position.vacancy === \"vacant\" ? \"dashed\" : \"solid\",\n title: positionTitle(position, vacantWord),\n depth,\n lineChildren: [],\n assistants: [],\n ownHalfL: m.boxW / 2,\n ownHalfR: m.boxW / 2,\n spanL: 0,\n spanR: 0,\n offsets: [],\n cx: 0,\n assistReport,\n assistTop: 0,\n };\n };\n\n const allInsts: Inst[] = [];\n const build = (positionId: number, depth: number, assistReport: OrgReport | null): Inst => {\n const position = positionById.get(positionId)!;\n const inst = newInst(position, depth, assistReport);\n allInsts.push(inst);\n // Assistants live in the manager's corridor band: same row index as a line-report\n // (depth+1) for measurement, but they do NOT advance the row — STEP 4 handles that.\n for (const r of assistChildIds.get(positionId) ?? []) {\n const a = build(r.reportId, depth + 1, r);\n inst.assistants.push({ inst: a, report: r });\n }\n for (const r of lineChildIds.get(positionId) ?? []) {\n inst.lineChildren.push(build(r.reportId, depth + 1, null));\n }\n return inst;\n };\n const roots = rootPositionIds.map((id) => build(id, 0, null));\n\n // ── STEP 3 — assistant side-stem reservation (per-side LEFT, before packing). An\n // assistant adds ORG_ASSIST_GAP + max(assistantBoxW) to the manager's ownHalfL.\n // Vertical stacking never widens further. ─────────────────────────────────────────\n for (const inst of allInsts) {\n if (inst.assistants.length > 0) {\n const widest = inst.assistants.reduce((m, a) => Math.max(m, a.inst.m.boxW), 0);\n inst.ownHalfL = inst.m.boxW / 2 + ORG_ASSIST_GAP + widest;\n }\n }\n\n // ── STEP 2 — horizontal span-pack (post-order) via the PURE packSubtree. ───────────\n const gaps: PackGaps = { siblingGap: ORG_SIBLING_GAP };\n const pack = (inst: Inst): void => {\n for (const c of inst.lineChildren) pack(c);\n const result = packSubtree(\n {\n ownHalfL: inst.ownHalfL,\n ownHalfR: inst.ownHalfR,\n children: inst.lineChildren.map((c) => ({ halfL: c.spanL, halfR: c.spanR })),\n },\n gaps,\n );\n inst.spanL = result.halfL;\n inst.spanR = result.halfR;\n inst.offsets = result.offsets;\n };\n for (const root of roots) pack(root);\n\n // Absolute centers, top-down; forest trees laid left→right ORG_TREE_GAP apart.\n let cursor = PADDING;\n for (const root of roots) {\n root.cx = cursor + root.spanL;\n const placeX = (inst: Inst): void => {\n inst.lineChildren.forEach((c, i) => {\n c.cx = inst.cx + inst.offsets[i]!;\n placeX(c);\n });\n };\n placeX(root);\n cursor = root.cx + root.spanR + ORG_TREE_GAP;\n }\n const canvasRight = roots.length === 0 ? PADDING : cursor - ORG_TREE_GAP; // last root's right edge\n\n // ── STEP 4 — vertical rows by declared depth, with the corridor grown for assistants.\n const rowInsts: Inst[][] = [];\n for (const inst of allInsts) (rowInsts[inst.depth] ??= []).push(inst);\n const depthCount = rowInsts.length;\n\n // Assistant stack height hanging below a manager (sum of assistant boxH + band drops).\n const assistStackH = (inst: Inst): number => {\n if (inst.assistants.length === 0) return 0;\n return (\n inst.assistants.reduce((s, a) => s + a.inst.m.boxH + ORG_ASSIST_BAND_DROP, 0) + ORG_ASSIST_BAND_DROP\n );\n };\n\n const rowH: number[] = [];\n for (let d = 0; d < depthCount; d++) {\n // Row height = tallest LINE-REPORT box in the row (assistants excluded — they hang\n // in the corridor band, not the row). Assistants share a depth index but are not\n // line-children of anyone, so filter them out here.\n const lineBoxes = (rowInsts[d] ?? []).filter((i) => i.assistReport === null);\n rowH.push(lineBoxes.reduce((m, i) => Math.max(m, i.m.boxH), 0));\n }\n\n // Assistant zone below row d: the tallest assistant stack hanging off any manager in\n // row d. Reserved ABOVE the corridor (the fault-tree gateZone analog) so the bus sits\n // CORRIDOR/2 below the BOTTOM of every assistant stack — every assistant box (and its\n // elbow) is strictly above the bus, and every drop (busY → next row) is below it.\n const assistZone: number[] = [];\n for (let d = 0; d < depthCount; d++) {\n let tallest = 0;\n for (const inst of rowInsts[d] ?? []) tallest = Math.max(tallest, assistStackH(inst));\n assistZone.push(tallest);\n }\n\n const rowTop: number[] = [PADDING];\n for (let d = 0; d < depthCount - 1; d++) {\n rowTop.push(rowTop[d]! + rowH[d]! + assistZone[d]! + ORG_CORRIDOR);\n }\n const busY = (d: number): number => rowTop[d + 1]! - ORG_CORRIDOR / 2;\n\n const last = depthCount - 1;\n // The last row's managers cannot have line-reports below them, but a leaf manager in\n // the last row carries no assistants of its own row index either (assistants share the\n // child's depth) — assistZone[last] folds any trailing assistant stack into the height.\n const height = Math.ceil(rowTop[last]! + rowH[last]! + assistZone[last]! + PADDING);\n\n // ── Emit nodes + solid rake elements (DFS order per root). ─────────────────────────\n const nodes: OrgNode[] = [];\n const elements: OrgElement[] = [];\n\n const reportTitle = (kind: OrgReport[\"kind\"], label: string | null | undefined): string => {\n const word = titleLabels.reportKinds[kind];\n return label !== null && label !== undefined ? `${word} · ${label}` : word;\n };\n\n const pushNode = (inst: Inst): void => {\n nodes.push({\n positionId: inst.position.id,\n cx: round(inst.cx),\n top: round(rowTop[inst.depth]!),\n boxW: round(inst.m.boxW),\n boxH: round(inst.m.boxH),\n style: inst.style,\n nameLines: inst.m.nameLines,\n titleLines: inst.m.titleLines,\n subtitleLines: inst.m.subtitleLines,\n vacantMarker: inst.m.vacantMarker,\n isAssistant: inst.assistReport !== null,\n depth: inst.depth,\n title: inst.title,\n annotated: inst.position.annotated ?? false,\n });\n };\n\n const emit = (inst: Inst): void => {\n const d = inst.depth;\n\n // Assistants: top-aligned bands hanging in this manager's corridor (below its row),\n // each its own band-y, the box LEFT of the stem (right edge faces the stem), the\n // elbow a 2-segment orthogonal polyline staying in the reserved left gutter.\n let bandY = rowTop[d]! + rowH[d]! + ORG_ASSIST_BAND_DROP;\n for (const { inst: a, report } of inst.assistants) {\n // Reserved left gutter: stem at inst.cx; assistant box right edge ORG_ASSIST_GAP left.\n const assistRight = inst.cx - ORG_ASSIST_GAP;\n a.cx = assistRight - a.m.boxW / 2;\n // Position the assistant box top at the band-y; its row index (depth) is the same\n // band as a line-report but rowTop[depth] is the line-report row — override per box.\n const assistTop = bandY;\n a.assistTop = assistTop;\n const assistMidY = assistTop + a.m.boxH / 2;\n nodes.push({\n positionId: a.position.id,\n cx: round(a.cx),\n top: round(assistTop),\n boxW: round(a.m.boxW),\n boxH: round(a.m.boxH),\n style: a.style,\n nameLines: a.m.nameLines,\n titleLines: a.m.titleLines,\n subtitleLines: a.m.subtitleLines,\n vacantMarker: a.m.vacantMarker,\n isAssistant: true,\n depth: a.depth,\n title: a.title,\n annotated: a.position.annotated ?? false,\n });\n // Elbow: from the stem at the assistant's mid-y, horizontally LEFT to the box's\n // right edge (2 axis-aligned segments via 3 waypoints; first segment degenerate is\n // avoided because the stem x ≠ box-right x by ORG_ASSIST_GAP). The endpoint must land\n // on the assistant's DRAWN right edge — round(assistRight) (= managerCx − gap) rounds\n // a sub-cent off the box's own round(node.cx − node.boxW/2) edge (seed-103792 sliver).\n elements.push({\n edgeId: ORG_ASSIST_ID_BASE + report.reportId,\n kind: \"assist\",\n points: [\n { x: round(inst.cx), y: round(assistMidY) },\n { x: drawnRightEdge(a.cx, a.m.boxW), y: round(assistMidY) },\n ],\n dashed: false,\n title: reportTitle(\"assistant\", report.label),\n annotated: report.annotated ?? false,\n });\n bandY += a.m.boxH + ORG_ASSIST_BAND_DROP;\n }\n\n pushNode(inst);\n\n // Solid rake to line-reports (none → no stem/bus/drop).\n if (inst.lineChildren.length === 0) return;\n const by = busY(d);\n const boxBottom = rowTop[d]! + inst.m.boxH;\n\n // stem: manager box bottom-center → bus level. Vertical. (Lengthens to busY when the\n // box is shorter than its row's tallest — the row is top-aligned.)\n // stem/bus are not 1:1 with a single OrgReport — annotated:false by design (documented\n // in OrgElement.annotated). The drop IS 1:1 with the child's incoming line report.\n elements.push({\n edgeId: ORG_STEM_ID_BASE + inst.position.id,\n kind: \"stem\",\n points: [\n { x: round(inst.cx), y: round(boxBottom) },\n { x: round(inst.cx), y: round(by) },\n ],\n dashed: false,\n title: reportTitle(\"line\", null),\n annotated: false,\n });\n\n const childCxs = inst.lineChildren.map((c) => c.cx);\n // bus: only for ≥2 line-reports (a single report degenerates to stem + drop on one x).\n // bus is not 1:1 with a single OrgReport — annotated:false by design.\n if (inst.lineChildren.length > 1) {\n elements.push({\n edgeId: ORG_BUS_ID_BASE + inst.position.id,\n kind: \"bus\",\n points: [\n { x: round(Math.min(...childCxs)), y: round(by) },\n { x: round(Math.max(...childCxs)), y: round(by) },\n ],\n dashed: false,\n title: reportTitle(\"line\", null),\n annotated: false,\n });\n }\n\n // drop: bus → each line-report box top-center. Vertical.\n // drops are 1:1 with each child's incoming line report — propagate annotated.\n const lineReports = lineChildIds.get(inst.position.id) ?? [];\n const lineReportByChildId = new Map(lineReports.map((r) => [r.reportId, r]));\n for (const c of inst.lineChildren) {\n const lineReport = lineReportByChildId.get(c.position.id);\n elements.push({\n edgeId: ORG_DROP_ID_BASE + c.position.id,\n kind: \"drop\",\n points: [\n { x: round(c.cx), y: round(by) },\n { x: round(c.cx), y: round(rowTop[c.depth]!) },\n ],\n dashed: false,\n title: reportTitle(\"line\", null),\n annotated: lineReport?.annotated ?? false,\n });\n }\n\n for (const c of inst.lineChildren) emit(c);\n };\n for (const root of roots) emit(root);\n\n // ── STEP 6 — dotted/matrix overlay → reserved RIGHT-MARGIN GUTTER (vertical lane) +\n // a bottom traverse channel (horizontal runs). The decisive graft is the gutter at\n // x > every box's right edge — box-free by construction for the vertical lane. The\n // horizontal runs that REACH the gutter cannot sit at a box's mid-y (they would\n // cross intervening same-row boxes — the \"distant columns of same row\" adversarial\n // case), so each endpoint ESCAPES its box to a box-free column, drops into a bottom\n // channel below every box, and traverses horizontally there. A box-free escape\n // column exists at the SUBTREE right edge (cx + spanR): descendants live inside\n // [cx−spanL, cx+spanR] so their interiors never cross that boundary x, and the next\n // sibling subtree starts ORG_SIBLING_GAP further right. A GLOBAL escape-vertical lane\n // allocation (below) keeps every coincident drop (a shared endpoint's fan, a same-column\n // rep/mgr pair, OR two distinct nodes whose subtree-right boundary equals the same x)\n // from double-drawing. Result is fully orthogonal AND box-free; the harness proves it.\n //\n // Escape geometry per node: the box edge a dotted stub exits and the box-free column it\n // escapes to, SIDE-AWARE. A packed LINE node escapes RIGHT: stub exits its right edge\n // (cx + boxW/2) to the subtree-boundary column (cx + spanR), box-free because descendants\n // live inside [cx−spanL, cx+spanR] and the next sibling starts ORG_SIBLING_GAP further\n // right. An ASSISTANT is NOT packed and sits LEFT of its manager's stem — its right edge\n // is INSIDE the main line-report column, so escaping right would pierce those boxes\n // (defect B). It escapes LEFT instead: stub exits its left edge (cx − boxW/2) into its\n // RESERVED left gutter (cleared in STEP 3 via ORG_ASSIST_GAP), a small box-free band.\n // `side` (+1 right / −1 left) makes the per-endpoint slot offset push AWAY from the box,\n // staying box-free in either gutter.\n interface Escape {\n side: 1 | -1;\n /** Box edge the stub exits (right edge when side=+1, left edge when side=−1). */\n boxEdge: number;\n /** Box-free escape column the stub reaches (with slot 0). */\n escCol: number;\n midY: number;\n boxH: number;\n }\n // FIX 1 — an assistant escapes at its MANAGER's subtree-LEFT boundary, not at its own\n // leftEdge−gap. The own-leftEdge column is box-free only inside the assistant's OWN\n // corridor band; descending to the bottom channel it crosses line-report/assistant boxes\n // in LOWER rows that sit at that x (root cause 1). The manager's WHOLE subtree lives\n // inside [managerCx−spanL, managerCx+spanR], so managerCx−spanL is to the LEFT of every\n // box in the manager's subtree — the strip there is the manager's reserved left gutter,\n // clear down the entire canvas (the next left sibling is ORG_SIBLING_GAP further left).\n // The box-exit stub still leaves the assistant's LEFT edge and runs left to that column\n // at the assistant's band-y (box-free: that row strip is the manager's left gutter).\n const instByPos = new Map(allInsts.map((i) => [i.position.id, i]));\n const escapeByPos = new Map<number, Escape>();\n for (const inst of allInsts) {\n const isAssist = inst.assistReport !== null;\n const boxTop = isAssist ? inst.assistTop : rowTop[inst.depth]!;\n // Attach the matrix stub at the box edges AS DRAWN (seed-7763 dotted#0 × box#p1 sliver).\n const leftEdge = drawnLeftEdge(inst.cx, inst.m.boxW);\n const rightEdge = drawnRightEdge(inst.cx, inst.m.boxW);\n if (isAssist) {\n const managerInst = instByPos.get(inst.assistReport!.managerId)!;\n escapeByPos.set(inst.position.id, {\n side: -1,\n boxEdge: leftEdge,\n escCol: managerInst.cx - managerInst.spanL,\n midY: boxTop + inst.m.boxH / 2,\n boxH: inst.m.boxH,\n });\n } else {\n escapeByPos.set(inst.position.id, {\n side: 1,\n boxEdge: rightEdge,\n escCol: inst.cx + inst.spanR,\n midY: boxTop + inst.m.boxH / 2,\n boxH: inst.m.boxH,\n });\n }\n }\n\n const nodeById = new Map(nodes.map((n) => [n.positionId, n]));\n const dottedReports = reports.filter(\n (r) => r.kind === \"dotted\" && nodeById.has(r.managerId) && nodeById.has(r.reportId) && r.managerId !== r.reportId,\n );\n // Bottom channel sits below the tallest box bottom in the whole canvas.\n let maxBoxBottom = PADDING;\n for (const n of nodes) maxBoxBottom = Math.max(maxBoxBottom, n.top + n.boxH);\n\n let laneCount = 0;\n let channelLanes = 0;\n if (dottedReports.length > 0) {\n // Right-gutter vertical lanes packed by the two endpoints' y-interval (ascending\n // report.id — dottedReports is already id-sorted). Non-overlapping edges share a lane.\n const laneOf = new Map<number, number>();\n laneCount = allocateLanes(\n dottedReports.map((r) => {\n const rep = escapeByPos.get(r.reportId)!;\n const mgr = escapeByPos.get(r.managerId)!;\n return {\n lo: Math.min(rep.midY, mgr.midY),\n hi: Math.max(rep.midY, mgr.midY),\n set: (lane: number) => laneOf.set(r.id, lane),\n };\n }),\n );\n // Each edge gets TWO bottom-channel y-lanes (report-side + manager-side traverse) so\n // the two horizontals never collinear-overlap each other; indexed by edge order.\n channelLanes = dottedReports.length * 2;\n const channelTop = maxBoxBottom + ORG_MATRIX_GUTTER_GAP;\n // Per-endpoint exit-Y slots: when ONE box is the endpoint of several dotted edges (a\n // node that is the dotted target of N managers — the matrix fan), each edge must exit\n // that box's edge at a DISTINCT y, else their horizontal stubs collinear-overlap.\n // Spread the exit y's around the box mid-y, bounded inside the box's edge.\n const exitSlot = new Map<number, number>(); // positionId → next slot index\n const nextExitY = (posId: number, mid: number, boxH: number): number => {\n const slot = exitSlot.get(posId) ?? 0;\n exitSlot.set(posId, slot + 1);\n if (slot === 0) return mid;\n // Alternate above/below the mid-y; stay within ±(boxH/2 − 6) of the box center.\n const step = Math.min(6, Math.max(2, (boxH / 2 - 6) / Math.max(1, Math.ceil(slot / 2))));\n const sign = slot % 2 === 1 ? -1 : 1;\n return mid + sign * Math.ceil(slot / 2) * step;\n };\n\n // ── Per-edge x-INDEPENDENT geometry, computed FIRST (the escape-column x is decided\n // globally afterwards). exitY spreads same-node rows; chY is unique per edge. ──────\n interface EdgeGeom {\n r: (typeof dottedReports)[number];\n i: number;\n repMidY: number;\n mgrMidY: number;\n repBoxEdge: number;\n mgrBoxEdge: number;\n repChY: number;\n mgrChY: number;\n laneX: number;\n repEscX: number; // filled by the global escape-vertical lane allocation\n mgrEscX: number;\n }\n const geoms: EdgeGeom[] = dottedReports.map((r, i) => {\n const rep = escapeByPos.get(r.reportId)!;\n const mgr = escapeByPos.get(r.managerId)!;\n return {\n r,\n i,\n repMidY: round(nextExitY(r.reportId, rep.midY, rep.boxH)),\n mgrMidY: round(nextExitY(r.managerId, mgr.midY, mgr.boxH)),\n repBoxEdge: round(rep.boxEdge),\n mgrBoxEdge: round(mgr.boxEdge),\n repChY: round(channelTop + (2 * i) * ORG_MATRIX_LANE_PITCH),\n mgrChY: round(channelTop + (2 * i + 1) * ORG_MATRIX_LANE_PITCH),\n laneX: round(canvasRight + ORG_MATRIX_GUTTER_GAP + laneOf.get(r.id)! * ORG_MATRIX_LANE_PITCH),\n repEscX: 0,\n mgrEscX: 0,\n };\n });\n\n // ── GLOBAL escape-vertical LANE ALLOCATION (replaces the per-position slot nudge and the\n // rep===mgr special-case — both subsumed). Every dotted edge owns TWO escape verticals\n // (report side, manager side); each draws over the y-interval [min(exitY,chY),\n // max(exitY,chY)]. We GROUP verticals by `${round(escCol)}:${side}` — same base column\n // AND same escape direction — then run allocateLanes over the group's y-intervals: a\n // vertical's column x = round(escCol + side*lane*STEP). Disjoint-y verticals share a lane\n // (same x, never a double-draw because they don't overlap); OVERLAPPING-y verticals get\n // distinct lanes (distinct x). This is overlap-proof for the escape-column class BY\n // CONSTRUCTION and uniformly subsumes the three observed failure modes: same-node fan\n // (same column, overlapping y → distinct lanes), same-column rep/mgr pair in a single-\n // child chain (the old fix-C special case), AND the cross-node coincidence (two distinct\n // nodes whose subtree-right boundary equals the same x — Root vs Boss C: base 448,\n // overlapping y → lanes 0 and 1).\n //\n // BOX-FREE BOUND (geometry-exact, MEASURED — not a fixed gap): a right-escaping (line) node's\n // base escCol = cx + spanR is the subtree's right boundary; all its descendant boxes live\n // inside [cx−spanL, cx+spanR], so the base column AND the band immediately to its right are\n // box-free until the NEXT box (an immediate right sibling subtree starts ORG_SIBLING_GAP away;\n // a pure right-leaning chain with no right sibling has the whole right margin clear). A left-\n // escaping assistant's base is leftEdge−ORG_ASSIST_ESCAPE_GAP, box-free leftward through its\n // reserved ORG_ASSIST_GAP gutter. Nudged columns march in `side` by lane*STEP, deeper into that\n // band. Rather than assume a fixed gutter width, we MEASURE the actual band per group: the\n // distance from escCol to the nearest real box edge on the escape side that vertically overlaps\n // the group's combined y-span (canvasRight/left-margin when none blocks). A coincident base\n // column is only produced by a right-leaning spine (each ancestor's cx+spanR equals the spine-\n // tip's right edge — many verticals, but their tip subtree is the RIGHTMOST so the margin to\n // their right is wide) or a fan into one node (per-node dotted degree capped at 5 in\n // validate.ts, ORG_MAX_MATRIX_EDGES_PER_NODE). The GUARANTEE: the deepest lane (lanes−1)*STEP\n // stays strictly inside the measured band, or we ASSERT (escape-column-overflow) rather than\n // misdraw. This is overlap-proof for the escape-column class BY CONSTRUCTION against the real\n // geometry; the harness is the oracle on every corpus case (incl. a depth-5 spine with 10\n // coincident verticals on one base column, which the wide margin absorbs).\n interface EscVert {\n escCol: number;\n side: 1 | -1;\n lo: number;\n hi: number;\n assign: (x: number) => void;\n }\n const verts: EscVert[] = [];\n for (const g of geoms) {\n const rep = escapeByPos.get(g.r.reportId)!;\n const mgr = escapeByPos.get(g.r.managerId)!;\n verts.push({\n escCol: rep.escCol,\n side: rep.side,\n lo: Math.min(g.repMidY, g.repChY),\n hi: Math.max(g.repMidY, g.repChY),\n assign: (x) => (g.repEscX = x),\n });\n verts.push({\n escCol: mgr.escCol,\n side: mgr.side,\n lo: Math.min(g.mgrMidY, g.mgrChY),\n hi: Math.max(g.mgrMidY, g.mgrChY),\n assign: (x) => (g.mgrEscX = x),\n });\n }\n // FIX 2 — GLOBAL greedy first-fit (replaces the per-group allocateLanes, which de-conflicted\n // only WITHIN one base-column group → a nudged column from group X could land on group Y's\n // column with overlapping y, double-drawing — root cause 2). Here NO two y-overlapping escape\n // verticals ever share a final x, across ALL groups. Each vertical starts at its base column and\n // steps in its escape `side` by ORG_MATRIX_ESCAPE_STEP until its x is clear of every already-placed\n // vertical it shares y with. Collinear-overlap = 0 BY CONSTRUCTION, globally (subsumes both the\n // per-group fan de-confliction AND the cross-group coincidence). Deterministic processing order\n // (edge id, then side) → byte-stable output. Box-free BAND is still measured per vertical and the\n // existing escape-column-overflow assertion fires rather than misdraw; with FIX 1 + the per-node\n // cap of 5 it should never fire on realistic input (the fuzzer confirms).\n //\n // The de-confliction nudge marches in the SAME direction the stub exits (`side`) — AWAY from the\n // node's box, into its box-free band. A LINE node's base column is its subtree-RIGHT boundary\n // (cx+spanR); everything to its right is clear out to canvasRight, so it nudges RIGHT. An ASSISTANT\n // escapes at its manager's subtree-LEFT boundary (managerCx−spanL, FIX 1); EVERY box in that\n // subtree lives to its right (a descendant box's left edge may sit EXACTLY on the boundary), so the\n // box-free room is to the LEFT — toward the canvas edge / the previous tree's gutter — and it nudges\n // LEFT. Nudging the assistant right would step straight into the leftmost descendant box, nudging\n // left stays in the clear margin. The box-exit stub runs from the assistant's left edge to the\n // (nudged) column at the assistant's band-y, box-free either way.\n const VERT_EPS = 0.01;\n // Stable processing order = edge id, then side (report-side before manager-side). `verts` is\n // built [rep0, mgr0, rep1, mgr1, …] over the id-sorted geoms, so the natural index ALREADY\n // encodes (edgeId asc, rep<mgr); make it explicit so a refactor of `verts` can't perturb it.\n const ordered = verts\n .map((v, idx) => ({ v, key: geoms[Math.floor(idx / 2)]!.r.id * 2 + (idx % 2) }))\n .sort((a, b) => a.key - b.key)\n .map((e) => e.v);\n const placed: { x: number; lo: number; hi: number }[] = [];\n const yOverlap = (aLo: number, aHi: number, bLo: number, bHi: number): boolean =>\n Math.min(aHi, bHi) - Math.max(aLo, bLo) > VERT_EPS;\n for (const v of ordered) {\n // Box-free band on the escape side, MEASURED from the real boxes that vertically overlap THIS\n // vertical's y-span: the candidate may march up to (but not into) the nearest box edge on that\n // side. The base column itself is box-free by construction (subtree-right boundary on the right;\n // manager's subtree-left boundary on the left). With no box in the way the band runs to the tree's\n // right edge (canvasRight) on the right, or to the CANVAS edge (x=0) on the left — NOT to PADDING,\n // because the leftmost tree's left boundary sits at PADDING yet the margin down to x=0 is clear.\n let band = v.side === 1 ? Math.max(canvasRight - v.escCol, ORG_MATRIX_GUTTER_GAP) : v.escCol;\n for (const n of nodes) {\n const bLeft = n.cx - n.boxW / 2;\n const bRight = n.cx + n.boxW / 2;\n if (n.top + n.boxH <= v.lo + VERT_EPS || n.top >= v.hi - VERT_EPS) continue; // no y-overlap\n if (v.side === 1 && bLeft > v.escCol + VERT_EPS) band = Math.min(band, bLeft - v.escCol);\n else if (v.side === -1 && bRight < v.escCol - VERT_EPS) band = Math.min(band, v.escCol - bRight);\n }\n let lane = 0;\n let candidate = round(v.escCol);\n // Step away from the box (in `side`) until the candidate column is clear of every placed vertical\n // that shares y with this one.\n while (placed.some((p) => Math.abs(p.x - candidate) < VERT_EPS && yOverlap(p.lo, p.hi, v.lo, v.hi))) {\n lane += 1;\n candidate = round(v.escCol + v.side * lane * ORG_MATRIX_ESCAPE_STEP);\n }\n // A lane-0 vertical sits on its base column — box-free BY CONSTRUCTION, so it needs no band\n // check. A NUDGED vertical must stay strictly inside the measured box-free band, else we assert\n // rather than misdraw.\n if (lane > 0 && lane * ORG_MATRIX_ESCAPE_STEP >= band - VERT_EPS) {\n throw new Error(\n `org-chart: escape-column-overflow — escape vertical nudged ${lane * ORG_MATRIX_ESCAPE_STEP}px from its base column exceeds the ${round(band)}px box-free band`,\n );\n }\n placed.push({ x: candidate, lo: v.lo, hi: v.hi });\n v.assign(candidate);\n }\n\n for (const g of geoms) {\n // 8 waypoints (box edge → escape column → channel → lane → channel → escape column →\n // box edge). Collapse a DEGENERATE first/last stub: a leaf line node's box edge IS its\n // escape column (boxW/2 === spanR with lane 0), so the box-exit and the down-escape\n // share an x → drop the duplicate point so \"every consecutive pair axis-aligned\" holds\n // by construction (no zero-length segment).\n elements.push({\n edgeId: ORG_DOTTED_ID_BASE + g.r.id,\n kind: \"dotted\",\n points: collapseDegenerate([\n { x: g.repBoxEdge, y: g.repMidY }, // out the report box's edge\n { x: g.repEscX, y: g.repMidY }, // → box-free escape column (in own gutter lane)\n { x: g.repEscX, y: g.repChY }, // → down into the bottom traverse channel\n { x: g.laneX, y: g.repChY }, // → across (below all boxes) to the right gutter lane\n { x: g.laneX, y: g.mgrChY }, // → down the right gutter (right of every box)\n { x: g.mgrEscX, y: g.mgrChY }, // → back across (below all boxes) to the manager column\n { x: g.mgrEscX, y: g.mgrMidY }, // → up the box-free escape column\n { x: g.mgrBoxEdge, y: g.mgrMidY }, // → into the manager box's edge\n ]),\n dashed: true,\n title: reportTitle(\"dotted\", g.r.label),\n annotated: g.r.annotated ?? false,\n });\n }\n }\n\n const width =\n dottedReports.length > 0\n ? Math.ceil(canvasRight + ORG_MATRIX_GUTTER_GAP + (laneCount - 1) * ORG_MATRIX_LANE_PITCH + ORG_MATRIX_GUTTER_GAP + PADDING)\n : Math.ceil(canvasRight + PADDING);\n\n // When dotted edges exist the bottom traverse channel hangs below every box; grow the\n // height to cover the deepest channel lane + padding (else solid-tree height stands).\n const finalHeight =\n channelLanes > 0\n ? Math.ceil(maxBoxBottom + ORG_MATRIX_GUTTER_GAP + (channelLanes - 1) * ORG_MATRIX_LANE_PITCH + PADDING)\n : height;\n\n return { width, height: finalHeight, nodes, elements, rootPositionIds };\n}\n\n/** Drop consecutive duplicate waypoints (a zero-length segment) so the routed polyline\n * keeps the \"≥2 waypoints, every consecutive pair axis-aligned over a positive length\"\n * contract by construction — e.g. a leaf line node whose box edge IS its escape column.\n * A two-point result is preserved even if degenerate (cannot happen here: the channel\n * detour guarantees ≥4 distinct points), so the OrgElement.points ≥2 invariant holds. */\nfunction collapseDegenerate(points: Point[]): Point[] {\n const out: Point[] = [];\n for (const p of points) {\n const prev = out[out.length - 1];\n if (prev === undefined || prev.x !== p.x || prev.y !== p.y) out.push(p);\n }\n return out;\n}\n\n/** Allocate lanes for a set of y-intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so abutting edges may share). Mirror\n * of the genogram allocateLanes (src/genogram/layout.ts) — keeps the gutter narrow. */\nfunction allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n","// Org-chart SVG emitter — turns a computed OrgChartLayout (./layout.ts) into a\n// SELF-CONTAINED SVG string. Pure (layout in, string out) and deterministic; it draws\n// EXACTLY what the layout computed (the overlap harness proves the layout; this emitter\n// is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — names/titles/subtitles/titles are\n// author-controlled and the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (hex colors, explicit font-family): a\n// standalone SVG has no stylesheet, no currentColor, no <defs>/<marker>;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Notation (zinc ramp on white): box rect rx=2 (filled → solid stroke; vacant → dashed\n// stroke + a 3px-inset open-seat frame); centered stacked tspans differentiated by font\n// SIZE (name 12, title/subtitle/vacant 10), never weight; solid stem/bus/drop/assist\n// edges as #71717a w1.5 op .75; dotted via EDGE_STROKE.distant (dasharray 4,4 op .55).\n// NO markers/arrowheads — direction is encoded by manager-above/report-below.\n//\n// Hooks: `<g data-node-id=\"p<id>\">` per box (direct-child verbatim <title>);\n// `<g data-edge-id=\"<n>\">` per element (<title> first), namespaced ids from ./layout.ts.\n\nimport {\n annotationDot,\n annotationSwatch,\n annotationTick,\n EDGE_STROKE,\n FONT_FAMILY,\n legendBlock,\n pathData,\n xmlEscape,\n LEGEND_SWATCH_W,\n type LegendEntry,\n} from \"../core\";\nimport {\n ORG_LABEL_FONT,\n ORG_LABEL_LINE_H,\n ORG_TITLE_FONT,\n type OrgChartLayout,\n type OrgElement,\n type OrgNode,\n} from \"./layout\";\nimport { ORG_CHART_SVG_LABELS_EN, type OrgChartSvgLabels } from \"./labels\";\n\n// Literal ink colors (zinc ramp on white — matches the genogram/ecomap/fault-tree emitters).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\nconst GLYPH_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\nconst VACANT_DASH = `stroke-dasharray=\"6,4\"`;\n/** The dotted/matrix line presentation, reused from the core style table (NOT a judgment). */\nconst DOTTED = EDGE_STROKE.distant; // { width: 1.5, dash: [4, 4], opacity: 0.55 }\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// Box vertical padding (mirrors layout ORG_BOX_PAD_Y; the text baseline math needs it).\nconst ORG_BOX_PAD_Y = 9;\n\nexport interface OrgChartSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: OrgChartSvgLabels;\n /**\n * Legend label for the annotation row. When provided AND at least one node or element\n * is annotated, one legend row is appended (used-keys-only pattern). The library\n * supplies no default — the caller owns the wording (domain-agnostic).\n */\n annotationLabel?: string;\n}\n\n// ── Box ─────────────────────────────────────────────────────────────────────────────\n\nfunction boxSvg(n: OrgNode): string {\n const left = round(n.cx - n.boxW / 2);\n const pieces: string[] = [`<title>${xmlEscape(n.title)}</title>`];\n\n // Rect: filled → solid stroke; vacant → dashed stroke + a 3px-inset open-seat frame.\n if (n.style === \"dashed\") {\n pieces.push(\n `<rect x=\"${left}\" y=\"${n.top}\" width=\"${n.boxW}\" height=\"${n.boxH}\" rx=\"2\" ${GLYPH_ATTRS} ${VACANT_DASH}/>`,\n );\n const ix = round(left + 3);\n const iy = round(n.top + 3);\n const iw = round(n.boxW - 6);\n const ih = round(n.boxH - 6);\n pieces.push(`<rect x=\"${ix}\" y=\"${iy}\" width=\"${iw}\" height=\"${ih}\" rx=\"2\" ${GLYPH_ATTRS} ${VACANT_DASH}/>`);\n } else {\n pieces.push(`<rect x=\"${left}\" y=\"${n.top}\" width=\"${n.boxW}\" height=\"${n.boxH}\" rx=\"2\" ${GLYPH_ATTRS}/>`);\n }\n\n // Centered stacked tspans: name (12) → title (10) → subtitle (10) → vacant marker (10).\n // Differentiated by font SIZE, not weight. Each text element groups one font size so\n // a single <text font-size> covers its tspans (baseline stepping by ORG_LABEL_LINE_H).\n let lineIndex = 0;\n const firstBaseline = (i: number): number =>\n round(n.top + ORG_BOX_PAD_Y + ORG_LABEL_LINE_H / 2 + i * ORG_LABEL_LINE_H + ORG_LABEL_FONT * 0.32);\n\n const textBlock = (lines: string[], font: number): string => {\n if (lines.length === 0) return \"\";\n const tspans = lines\n .map((line, i) => `<tspan x=\"${n.cx}\" y=\"${firstBaseline(lineIndex + i)}\">${xmlEscape(line)}</tspan>`)\n .join(\"\");\n lineIndex += lines.length;\n return `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${font}\" fill=\"${LABEL_FILL}\">${tspans}</text>`;\n };\n\n pieces.push(textBlock(n.nameLines, ORG_LABEL_FONT));\n pieces.push(textBlock(n.titleLines, ORG_TITLE_FONT));\n pieces.push(textBlock(n.subtitleLines, ORG_TITLE_FONT));\n if (n.vacantMarker !== null) pieces.push(textBlock([n.vacantMarker], ORG_TITLE_FONT));\n\n // Annotation dot: upper-right corner of the glyph, inset 4px so it sits on/near the box.\n if (n.annotated) pieces.push(annotationDot(round(n.cx + n.boxW / 2) - 4, n.top + 4));\n\n return `<g data-node-id=\"p${n.positionId}\">${pieces.filter((p) => p !== \"\").join(\"\")}</g>`;\n}\n\n// ── Connector elements ───────────────────────────────────────────────────────────────\n\nfunction elementSvg(el: OrgElement): string {\n const head = `<g data-edge-id=\"${el.edgeId}\"><title>${xmlEscape(el.title)}</title>`;\n const tick = el.annotated ? annotationTick(el.points) : \"\";\n if (el.dashed) {\n const dash = DOTTED.dash === null ? \"\" : ` stroke-dasharray=\"${DOTTED.dash[0]},${DOTTED.dash[1]}\"`;\n return (\n head +\n `<path d=\"${pathData(el.points)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${DOTTED.width}\" stroke-opacity=\"${DOTTED.opacity}\"${dash}/>${tick}</g>`\n );\n }\n // Solid stem/bus/drop = single segment <line>; assist = 2-segment <path>.\n if (el.points.length === 2) {\n const a = el.points[0]!;\n const b = el.points[1]!;\n return (\n head +\n `<line x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>${tick}</g>`\n );\n }\n return head + `<path d=\"${pathData(el.points)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>${tick}</g>`;\n}\n\n// ── Legend mini-swatches (scaled into the 22px swatch box) ─────────────────────────\n\nconst MINI_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"`;\n\nfunction lineSwatch(x: number, y: number): string {\n const x1 = round(x + 2);\n const x2 = round(x + LEGEND_SWATCH_W - 2);\n return `<line x1=\"${x1}\" y1=\"${y}\" x2=\"${x2}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>`;\n}\n\nfunction assistantSwatch(x: number, y: number): string {\n // A short stem + side-elbow into a small box (the side-stem convention in miniature).\n const stemX = round(x + LEGEND_SWATCH_W - 4);\n const boxX = round(x + 1);\n return (\n `<line x1=\"${stemX}\" y1=\"${round(y - 4)}\" x2=\"${stemX}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n `<line x1=\"${stemX}\" y1=\"${y}\" x2=\"${round(boxX + 8)}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n `<rect x=\"${boxX}\" y=\"${round(y - 3.5)}\" width=\"8\" height=\"7\" rx=\"1\" ${MINI_ATTRS}/>`\n );\n}\n\nfunction dottedSwatch(x: number, y: number): string {\n const x1 = round(x + 2);\n const x2 = round(x + LEGEND_SWATCH_W - 2);\n const dash = DOTTED.dash === null ? \"\" : ` stroke-dasharray=\"${DOTTED.dash[0]},${DOTTED.dash[1]}\"`;\n return `<line x1=\"${x1}\" y1=\"${y}\" x2=\"${x2}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${DOTTED.width}\" stroke-opacity=\"${DOTTED.opacity}\"${dash}/>`;\n}\n\nfunction vacantSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n const bx = round(cx - 8);\n const by = round(y - 5);\n return (\n `<rect x=\"${bx}\" y=\"${by}\" width=\"16\" height=\"10\" rx=\"1\" ${MINI_ATTRS} stroke-dasharray=\"3,2\"/>` +\n `<rect x=\"${round(bx + 2)}\" y=\"${round(by + 2)}\" width=\"12\" height=\"6\" rx=\"1\" ${MINI_ATTRS} stroke-dasharray=\"3,2\"/>`\n );\n}\n\n/**\n * Emits a self-contained SVG for a computed org-chart layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal. The legend lists ONLY the features actually\n * present (a solid line, an assistant, a dotted edge, a vacant box), in canonical order.\n */\nexport function orgChartLayoutSvg(layout: OrgChartLayout, opts: OrgChartSvgOptions = {}): string {\n const labels = opts.labels ?? ORG_CHART_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // Elements first, then boxes (boxes sit on top), then legend.\n for (const el of layout.elements) parts.push(elementSvg(el));\n for (const n of layout.nodes) parts.push(boxSvg(n));\n\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const hasSolid = layout.elements.some((e) => e.kind === \"stem\" || e.kind === \"bus\" || e.kind === \"drop\");\n const hasAssistant = layout.nodes.some((n) => n.isAssistant);\n const hasDotted = layout.elements.some((e) => e.kind === \"dotted\");\n const hasVacant = layout.nodes.some((n) => n.style === \"dashed\");\n const entries: LegendEntry[] = [];\n if (hasSolid) entries.push({ swatch: lineSwatch, label: labels.legend.line });\n if (hasAssistant) entries.push({ swatch: assistantSwatch, label: labels.legend.assistant });\n if (hasDotted) entries.push({ swatch: dottedSwatch, label: labels.legend.dotted });\n if (hasVacant) entries.push({ swatch: vacantSwatch, label: labels.legend.vacant });\n // Annotation row: only when label is provided AND at least one node or element is\n // annotated (used-keys-only pattern, consistent with the other legend rows).\n if (\n opts.annotationLabel !== undefined &&\n (layout.nodes.some((n) => n.annotated) || layout.elements.some((e) => e.annotated))\n ) {\n entries.push({ swatch: annotationSwatch, label: opts.annotationLabel });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call org-chart render: input → { svg, layout }. Thin, honest wiring: validate\n// (throw on a structurally invalid chart — never repair), compute the pure layout, emit.\n// Callers needing finer control use computeOrgChartLayout + orgChartLayoutSvg directly\n// (the layout result supports hit-testing / decorating the diagram).\n\nimport { computeOrgChartLayout, type OrgChartLayout, type OrgChartLayoutOptions } from \"./layout\";\nimport { orgChartLayoutSvg } from \"./svg\";\nimport type { OrgChartSvgLabels } from \"./labels\";\nimport type { OrgChartInput } from \"./types\";\n\nexport interface OrgChartRenderOptions extends OrgChartLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: OrgChartSvgLabels;\n /**\n * Legend label for the annotation row. Forwarded to orgChartLayoutSvg. When provided\n * AND at least one node or element is annotated, a legend row is appended.\n * The library supplies no default — the caller owns the wording.\n */\n annotationLabel?: string;\n}\n\nexport interface OrgChartRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: OrgChartLayout;\n}\n\n/**\n * Renders an org-chart input to a self-contained SVG string. Deterministic: same data →\n * same SVG (array order never matters; sibling order among reports is the ascending\n * reportId). Throws OrgChartValidationError — carrying EVERY issue, deterministically\n * sorted — on a structurally invalid chart. Empty input yields an empty-but-valid SVG;\n * callers decide their own empty state.\n */\nexport function orgChartSvg(input: OrgChartInput, opts: OrgChartRenderOptions = {}): OrgChartRenderResult {\n const layout = computeOrgChartLayout(input, {\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = orgChartLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n ...(opts.annotationLabel !== undefined ? { annotationLabel: opts.annotationLabel } : {}),\n });\n return { svg, layout };\n}\n"]}
1
+ {"version":3,"sources":["../src/core/xml.ts","../src/core/roman.ts","../src/core/geometry.ts","../src/core/text.ts","../src/core/legend.ts","../src/core/stroke.ts","../src/core/annotation.ts","../src/core/layered.ts","../src/core/glyph.ts","../src/core/compartment.ts","../src/core/grid.ts","../src/genogram/types.ts","../src/genogram/labels.ts","../src/genogram/kinship.ts","../src/genogram/layout.ts","../src/genogram/svg.ts","../src/genogram/render.ts","../src/ecomap/render.ts","../src/fault-tree/types.ts","../src/fault-tree/labels.ts","../src/fault-tree/validate.ts","../src/fault-tree/layout.ts","../src/fault-tree/svg.ts","../src/fault-tree/render.ts","../src/fishbone/render.ts","../src/pedigree/types.ts","../src/pedigree/labels.ts","../src/pedigree/validate.ts","../src/pedigree/layout.ts","../src/pedigree/svg.ts","../src/pedigree/render.ts","../src/phylo/labels.ts","../src/phylo/validate.ts","../src/phylo/layout.ts","../src/phylo/svg.ts","../src/phylo/render.ts","../src/org-chart/types.ts","../src/org-chart/labels.ts","../src/org-chart/validate.ts","../src/org-chart/layout.ts","../src/org-chart/svg.ts","../src/org-chart/render.ts","../src/prisma/types.ts","../src/prisma/validate.ts","../src/prisma/labels.ts","../src/prisma/layout.ts","../src/prisma/svg.ts","../src/prisma/render.ts","../src/uml/types.ts","../src/uml/validate.ts","../src/uml/labels.ts","../src/uml/layout.ts","../src/uml/svg.ts","../src/uml/render.ts"],"names":["round","r","allocateLanes","pathData","PADDING","EDGE_INK","w","h","GRAPH_BLOCKING","lines","last","GLYPH_STROKE","LABEL_FILL","pts","elementSvg","arrowHead","sortIssues","H_GAP","CORRIDOR","shapeForSex","GLYPH_ATTRS","nodeSvg","MINI_ATTRS","listIds","ORG_BOX_PAD_Y","BOX_STROKE","boxSvg","raw","portPts","edgeId","pt"],"mappings":"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","file":"index.cjs","sourcesContent":["// XML/SVG escaping — every interpolated text in an emitted SVG MUST pass through\n// this. Diagram labels are typically user/author-controlled, and the SVG string may\n// be injected via innerHTML in a browser or embedded as vectors in a PDF — an\n// unescaped label is an XSS / `</svg>`-breakout vector on every surface at once.\n\n/** Escapes a string for use in SVG/XML text content AND attribute values. */\nexport function xmlEscape(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n}\n","// Roman numeral formatting for level/generation labels (pedigree generation rows\n// I, II, III…; any leveled diagram). Standard subtractive notation, valid for\n// integers 1..3999. A renderer must NEVER crash on a weird generation index, so\n// out-of-range / non-integer inputs fall back to the Arabic number as a string\n// rather than throwing or emitting nonsense like \"MMMM…\". Pure + deterministic.\n\nconst ROMAN_TABLE: ReadonlyArray<readonly [number, string]> = [\n [1000, \"M\"],\n [900, \"CM\"],\n [500, \"D\"],\n [400, \"CD\"],\n [100, \"C\"],\n [90, \"XC\"],\n [50, \"L\"],\n [40, \"XL\"],\n [10, \"X\"],\n [9, \"IX\"],\n [5, \"V\"],\n [4, \"IV\"],\n [1, \"I\"],\n];\n\n/** Uppercase Roman numeral for an integer in 1..3999 (1→\"I\", 4→\"IV\", 1990→\"MCMXC\").\n * Out of range or non-integer → the Arabic number as a string (graceful fallback). */\nexport function romanNumeral(n: number): string {\n if (!Number.isInteger(n) || n < 1 || n > 3999) return String(n);\n let remaining = n;\n let out = \"\";\n for (const [value, symbol] of ROMAN_TABLE) {\n while (remaining >= value) {\n out += symbol;\n remaining -= value;\n }\n }\n return out;\n}\n","// Shared geometry primitives.\n\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** \"M x y L x y …\" path data from a polyline. */\nexport function pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n","// Pure, deterministic text metrics — no DOM, no canvas, no font files. Every layout\n// in this library reserves space from these estimates and every emitter draws with\n// the same constants, so what is proven collision-free is what is drawn.\n\n/**\n * Conservative per-character advance, as a fraction of the font size. The pure module\n * can't measure real glyphs (no DOM/canvas), so it estimates width = chars * font *\n * CHAR_W. It is deliberately a touch WIDER than Helvetica's ~0.5 average advance: a\n * layout reserves slightly more room than the text needs, so the real render always\n * fits inside its reserved box.\n */\nexport const CHAR_W = 0.6;\n\n/** Pure, deterministic width estimate for a single line of text at `fontPx`. */\nexport function estimateTextWidth(text: string, fontPx: number): number {\n return text.length * fontPx * CHAR_W;\n}\n\n/**\n * Wraps a label onto up to `maxLines` lines (default 2) so long labels don't sprawl.\n * Greedy word fill; each line capped at `perLine` chars (…-truncated only if a line\n * still overflows). The LAST allowed line absorbs every remaining word before the cap\n * applies — words are never dropped mid-label, only visibly elided. Pure + shared so\n * every renderer wraps identically. The full text is always kept elsewhere (the\n * node's `label`, an SVG <title>, or a side list), so nothing is silently lost.\n *\n * INVARIANT: with the default `maxLines` the output is byte-identical to the\n * historical two-line implementation (pinned by test/core/text.test.ts) — both\n * shipped renderers wrap through here.\n */\nexport function wrapLabel(label: string, perLine: number, maxLines = 2): string[] {\n if (label.length <= perLine) return [label];\n const cap = (s: string): string =>\n s.length > perLine ? s.slice(0, Math.max(1, perLine - 1)) + \"…\" : s;\n const lines: string[] = [\"\"];\n for (const word of label.split(/\\s+/)) {\n const last = lines.length - 1;\n const current = lines[last]!;\n if (current === \"\" || (current + \" \" + word).length <= perLine) {\n lines[last] = current === \"\" ? word : `${current} ${word}`;\n } else if (lines.length < maxLines) {\n lines.push(word);\n } else {\n lines[last] = `${current} ${word}`;\n }\n }\n // A trailing-whitespace \"word\" (\"a b \".split(/\\s+/) → [\"a\",\"b\",\"\"]) may open a line\n // it never fills; the historical code dropped that empty line, so this does too.\n if (lines.length > 1 && lines[lines.length - 1] === \"\") lines.pop();\n return lines.map(cap);\n}\n\n/**\n * House \"balanced\" wrap policy (extracted verbatim from the ecomap's tie-label wrap,\n * itself mirroring the genogram's): per-line budget `min(26, max(14, ceil(len/2)+2))`\n * splits a medium label into two roughly even lines instead of one long + one short,\n * then the greedy `wrapLabel` fill (and its `maxLines` semantics) applies. The shipped\n * renderers keep their local copies for now — new modules consume this one; migrating\n * them is a separate provably-zero-change refactor.\n */\nexport function wrapLabelBalanced(label: string, maxLines?: number): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(label.length / 2) + 2));\n return wrapLabel(label, perLine, maxLines);\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept by the caller. */\nexport function clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n/** Font stack shared by every emitter; PDF embedders typically map it onto Helvetica. */\nexport const FONT_FAMILY = \"Helvetica, Arial, sans-serif\";\n","// Shared legend machinery — the exact row format the genogram and ecomap emitters\n// currently duplicate character-for-character (`<g data-compasso-legend=\"true\">` with\n// swatch-closure rows). Extracted so new diagram modules don't add a third copy;\n// the two shipped emitters keep their local blocks for now (migrating them is a\n// separate, provably-zero-change refactor — pinned byte-for-byte against the ecomap's\n// emitted legend in test/core/legend.test.ts).\n//\n// The caller stays in charge of the HONESTY RULE half: it decides WHICH entries exist\n// (used-keys-only) and what each swatch draws; this module only owns the row geometry,\n// the text emission (xmlEscape — labels may come from caller-supplied packs), and the\n// width/height bookkeeping both renderers compute identically.\n\nimport { FONT_FAMILY, estimateTextWidth } from \"./text\";\nimport { xmlEscape } from \"./xml\";\n\n// Row metrics shared by every legend in the library. Exported because swatch builders\n// need them (a line swatch spans LEGEND_SWATCH_W; a glyph swatch centers on it).\nexport const LEGEND_ROW_H = 18;\nexport const LEGEND_PAD = 16;\nexport const LEGEND_SWATCH_W = 22;\nexport const LEGEND_GAP = 14;\nexport const LEGEND_FONT = 11;\n\n// Legend text ink — the zinc glyph stroke both shipped emitters use for legend labels.\nconst LEGEND_TEXT_FILL = \"#52525b\";\n\nexport interface LegendEntry {\n /**\n * Swatch markup builder, called with the swatch's left x and the row's center y.\n * The builder owns its own escaping/rounding (it typically reuses the module's\n * glyph/line emitters); it should draw within LEGEND_SWATCH_W of x.\n */\n swatch: (x: number, yCenter: number) => string;\n /** Display label (escaped here; verbatim pack text in, escaped SVG out). */\n label: string;\n}\n\nexport interface LegendBlock {\n /** `<g data-compasso-legend=\"true\">…</g>` — empty string when there are no entries. */\n svg: string;\n /** Minimum canvas width the legend needs; callers take `max(width, block.width)`. */\n width: number;\n /** New total canvas height including the legend; callers assign it directly. */\n height: number;\n}\n\n/**\n * Emits the legend group for the given entries below `startY` (the diagram's current\n * height). Pure + deterministic; coordinates are interpolated exactly as the shipped\n * emitters do. Zero entries (used-keys-only found nothing) → no markup, zero width\n * contribution, height unchanged — safe to call unconditionally.\n */\nexport function legendBlock(entries: readonly LegendEntry[], startY: number): LegendBlock {\n if (entries.length === 0) return { svg: \"\", width: 0, height: startY };\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${LEGEND_TEXT_FILL}\">${xmlEscape(entry.label)}</text>`\n );\n });\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n return {\n svg: `<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`,\n width: LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD,\n height: startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2,\n };\n}\n","// Edge line styles — a neutral, presentation-only style for a relationship line.\n// NOT a judgment: a deterministic, lexical hint derived from the author's own quality\n// word. The literal word always rides the element's <title>, so a style never replaces\n// what was said. Unknown/ambiguous quality → \"plain\".\n\nexport type EdgeLineStyle = \"plain\" | \"close\" | \"distant\" | \"conflict\" | \"cutoff\";\n\n/** Stroke attributes per style — shared by every renderer so SVG and PDF match. */\nexport interface EdgeStroke {\n width: number;\n /** SVG dash array / PDF dash pattern as [dash, gap]; null = solid. */\n dash: [number, number] | null;\n opacity: number;\n}\n\nexport const EDGE_STROKE: Record<EdgeLineStyle, EdgeStroke> = {\n plain: { width: 1.5, dash: null, opacity: 0.6 },\n close: { width: 3, dash: null, opacity: 0.85 },\n distant: { width: 1.5, dash: [4, 4], opacity: 0.55 },\n conflict: { width: 2, dash: [2, 2], opacity: 0.75 },\n cutoff: { width: 1.5, dash: [6, 5], opacity: 0.4 },\n};\n\n/**\n * A pluggable lexicon mapping free-text quality words onto line styles. Needles are\n * diacritic-free, lowercase substrings of the author's own words; `negations` are\n * whole words that flip the meaning of the very word a needle would match (\"not\n * close\"), so their presence makes the matcher abstain to \"plain\" rather than risk\n * an inverted visual. Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface QualityLexicon {\n buckets: readonly { style: Exclude<EdgeLineStyle, \"plain\">; needles: readonly string[] }[];\n negations: readonly string[];\n}\n\n// English default. Conservative stems: each needle is a substring match on the\n// normalized text, and the SINGLE-BUCKET rule below keeps competing signals honest.\n// \"no\" alone is deliberately NOT a negation: \"no contact\" is a genuine cutoff signal.\nexport const QUALITY_LEXICON_EN: QualityLexicon = {\n buckets: [\n {\n style: \"close\",\n needles: [\"close\", \"warm\", \"support\", \"lov\", \"affection\", \"caring\", \"tight\", \"harmon\", \"healthy\"],\n },\n {\n style: \"distant\",\n needles: [\"distant\", \"detach\", \"absent\", \"cold\", \"drift\"],\n },\n {\n style: \"conflict\",\n needles: [\"conflict\", \"fight\", \"tens\", \"difficult\", \"hostil\", \"violen\", \"abus\", \"aggress\", \"complicat\", \"toxic\", \"argu\"],\n },\n {\n style: \"cutoff\",\n needles: [\"estrang\", \"cut off\", \"cutoff\", \"no contact\", \"broken off\", \"sever\"],\n },\n ],\n negations: [\"not\", \"never\", \"no longer\", \"hardly\"],\n};\n\n/** Lowercase + strip diacritics so matching ignores accents. */\nexport function normalizeText(text: string): string {\n return text.normalize(\"NFD\").replace(/[̀-ͯ]/g, \"\").toLowerCase();\n}\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Maps a free-text relationship quality to a neutral line style. Deterministic and\n * conservative: returns a specific style ONLY when exactly one lexical bucket matches;\n * null/empty/ambiguous/negated/unknown all fall back to \"plain\". The caller still\n * keeps the verbatim quality word, so nothing the author said is ever lost.\n */\nexport function qualityLineStyle(\n quality: string | null,\n lexicon: QualityLexicon = QUALITY_LEXICON_EN,\n): EdgeLineStyle {\n if (quality === null) return \"plain\";\n const haystack = normalizeText(quality);\n if (haystack.trim() === \"\") return \"plain\";\n\n if (lexicon.negations.length > 0) {\n const negation = new RegExp(`\\\\b(${lexicon.negations.map(escapeRegExp).join(\"|\")})\\\\b`);\n if (negation.test(haystack)) return \"plain\";\n }\n\n const matched: EdgeLineStyle[] = [];\n for (const { style, needles } of lexicon.buckets) {\n if (needles.some((n) => haystack.includes(n))) matched.push(style);\n }\n return matched.length === 1 ? matched[0]! : \"plain\";\n}\n","// A discreet, NEUTRAL \"this element was annotated by the caller\" marker, shared by every\n// diagram family. compasso never decides what an annotation MEANS — the caller asserts the\n// `annotated` flag from its own domain knowledge and supplies the legend label; the library\n// only draws a standardised mark. Pure presentation: literal SVG primitives, no <defs>, no\n// <marker>, no CSS. The mark is a DECORATION drawn inside an element's existing <g> (like a\n// genogram deceased slash) — never a layout box or routed segment, so it cannot create or\n// hide an overlap. Ink is the shared zinc-600 glyph stroke (#52525b) for cross-family unity.\nimport { LEGEND_SWATCH_W } from \"./legend\";\nimport type { Point } from \"./geometry\";\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport const ANNOTATION_INK = \"#52525b\";\nconst DOT_R = 3;\nconst TICK_HALF = 3;\n\n/**\n * A small filled dot marking an annotated NODE. Pass the point where it should sit — callers\n * place it at the node's upper-right (inset), the conventional \"has a note\" corner.\n */\nexport function annotationDot(cx: number, cy: number): string {\n return `<circle cx=\"${round(cx)}\" cy=\"${round(cy)}\" r=\"${DOT_R}\" fill=\"${ANNOTATION_INK}\" fill-opacity=\"0.6\"/>`;\n}\n\n/**\n * A short tick perpendicular to an annotated EDGE at the midpoint of its middle segment.\n * Org-chart / genogram polylines are axis-aligned, so the perpendicular is trivial; a tick on\n * a near-diagonal falls back to a vertical mark. Returns \"\" for a degenerate (<2-point) path.\n */\nexport function annotationTick(points: readonly Point[]): string {\n if (points.length < 2) return \"\";\n const i = Math.floor((points.length - 1) / 2);\n const a = points[i]!;\n const b = points[i + 1] ?? points[i]!;\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const horizontal = Math.abs(a.y - b.y) <= Math.abs(a.x - b.x);\n const x1 = horizontal ? mx : mx - TICK_HALF;\n const x2 = horizontal ? mx : mx + TICK_HALF;\n const y1 = horizontal ? my - TICK_HALF : my;\n const y2 = horizontal ? my + TICK_HALF : my;\n return `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${ANNOTATION_INK}\" stroke-width=\"1.5\"/>`;\n}\n\n/** Legend swatch for the annotation row: the same dot, centred in the swatch column. */\nexport function annotationSwatch(x: number, yCenter: number): string {\n return annotationDot(x + LEGEND_SWATCH_W / 2, yCenter);\n}\n","// Pure layout primitives shared across diagram families. Every function here is\n// deterministic and has zero references to any diagram-specific type (OrgNode,\n// GenogramPerson, etc.). Each was verified to have ≥2 real consumers before being\n// lifted; none is speculative.\n\n// ── packSubtree ────────────────────────────────────────────────────────────────\n// Moved VERBATIM from src/org-chart/layout.ts (was lines 180-223 before this lift).\n// See that file's \"PURE span-packer (Judge-1 seam)\" comment for the overlap-proof\n// and consumer notes.\n\n/** A node's own symmetric-or-asymmetric half-extents plus its children's half-extents. */\nexport interface PackNode {\n ownHalfL: number;\n ownHalfR: number;\n /** One entry per child, in placement order; empty = leaf. */\n children: { halfL: number; halfR: number }[];\n}\n\nexport interface PackGaps {\n siblingGap: number;\n}\n\nexport interface PackResult {\n /** Subtree half-extents (cover the ENTIRE subtree). */\n halfL: number;\n halfR: number;\n /** Center offset of each child relative to this node's center (parallel to children). */\n offsets: number[];\n}\n\n/**\n * Span-packs a node's children into disjoint horizontal intervals (the fault-tree `pack`\n * transposed top-down). Children c1..cn: x1 = 0; x_{i+1} = x_i + halfR_i + siblingGap +\n * halfL_{i+1}. Parent axis a = (x1 + xn)/2 — centered over its line-report block. The\n * returned offsets are each child's center MINUS the parent axis. Subtree halfL/halfR\n * extend ownHalf* to cover the children block. Pure + deterministic.\n */\nexport function packSubtree(node: PackNode, gaps: PackGaps): PackResult {\n const { ownHalfL, ownHalfR, children } = node;\n if (children.length === 0) {\n return { halfL: ownHalfL, halfR: ownHalfR, offsets: [] };\n }\n const xs: number[] = [0];\n for (let i = 1; i < children.length; i++) {\n xs.push(xs[i - 1]! + children[i - 1]!.halfR + gaps.siblingGap + children[i]!.halfL);\n }\n const first = children[0]!;\n const last = children[children.length - 1]!;\n const axis = (xs[0]! + xs[xs.length - 1]!) / 2;\n const offsets = xs.map((x) => x - axis);\n const halfL = Math.max(ownHalfL, axis - (xs[0]! - first.halfL));\n const halfR = Math.max(ownHalfR, xs[xs.length - 1]! + last.halfR - axis);\n return { halfL, halfR, offsets };\n}\n\n// ── allocateLanes ──────────────────────────────────────────────────────────────\n// Moved VERBATIM from src/org-chart/layout.ts (was lines 939-959 before this lift).\n// A byte-identical copy exists in src/genogram/layout.ts — that copy is NOT removed\n// this release (separate zero-change follow-up per the shipped migration discipline).\n\n/** Allocate lanes for a set of y-intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so abutting edges may share). Mirror\n * of the genogram allocateLanes (src/genogram/layout.ts) — keeps the gutter narrow. */\nexport function allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n\n// ── bandStack ──────────────────────────────────────────────────────────────────\n// NEW — captures the row-stacking recurrence verified duplicated in\n// org-chart/layout.ts (rowTop/busY) and fault-tree/layout.ts (gateZone).\n// `zoneH` generalises assistZone / gateZone (pass 0 when no side-zone exists).\n\nexport interface BandRow {\n /** Height of the content row itself (tallest box, etc.). */\n rowH: number;\n /** Height of the side-zone hanging BELOW the row and ABOVE the corridor\n * (assistant stack, gate zone, …). Pass 0 when there is no zone. */\n zoneH: number;\n}\n\nexport interface BandStackOpts {\n /** Canvas padding placed above row 0 and below the last row. */\n padding: number;\n /** Vertical gap between rows (the bus lives at busY = next rowTop − corridor/2). */\n corridor: number;\n}\n\nexport interface BandStackResult {\n /** rowTop[d] = y of the top edge of row d. rowTop[0] = padding. */\n rowTop: number[];\n /** y of the bus (connector horizontal bar) between row d and row d+1. */\n busY: (d: number) => number;\n /** Total canvas height (last row bottom + last zoneH + padding). */\n height: number;\n}\n\n/**\n * Stacks rows top-down with a corridor between them.\n *\n * Recurrence:\n * rowTop[0] = padding\n * rowTop[d+1] = rowTop[d] + rows[d].rowH + rows[d].zoneH + corridor\n * busY(d) = rowTop[d+1] − corridor / 2\n * height = rowTop[last] + rows[last].rowH + rows[last].zoneH + padding\n *\n * An empty `rows` array returns `{ rowTop: [], busY: () => 0, height: padding * 2 }`.\n * Pure + deterministic.\n */\nexport function bandStack(rows: BandRow[], opts: BandStackOpts): BandStackResult {\n const { padding, corridor } = opts;\n if (rows.length === 0) {\n return { rowTop: [], busY: () => 0, height: padding * 2 };\n }\n const rowTop: number[] = [padding];\n for (let d = 0; d < rows.length - 1; d++) {\n rowTop.push(rowTop[d]! + rows[d]!.rowH + rows[d]!.zoneH + corridor);\n }\n const last = rows.length - 1;\n const busY = (d: number): number => rowTop[d + 1]! - corridor / 2;\n const height = rowTop[last]! + rows[last]!.rowH + rows[last]!.zoneH + padding;\n return { rowTop, busY, height };\n}\n","// Explicit-polygon glyph kit — cardinal arrowheads, triangles, diamonds.\n//\n// Rules (AGENTS.md):\n// - All functions PURE; return a `points` string only.\n// - Caller owns fill/stroke — this kit NEVER bakes presentation.\n// - Cardinal Dir only: rotation = sign-flips on size, NO trig.\n// - round() every coordinate to 2 decimals.\n// - No <defs>, no <marker>, no CSS.\n\nimport type { Point } from \"./geometry\";\n\n// ── Direction ─────────────────────────────────────────────────────────────────\n\n/** Cardinal direction; tip of the glyph points in this direction. */\nexport type Dir = \"up\" | \"down\" | \"left\" | \"right\";\n\n/** Unit vector components for each cardinal direction. */\nfunction dirVec(dir: Dir): readonly [ux: number, uy: number] {\n switch (dir) {\n case \"right\": return [1, 0];\n case \"left\": return [-1, 0];\n case \"down\": return [0, 1];\n case \"up\": return [0, -1];\n }\n}\n\n/** Format a single point pair to 2-decimal strings. */\nfunction r(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction pt(x: number, y: number): string {\n return `${r(x)},${r(y)}`;\n}\n\n// ── Size consts ───────────────────────────────────────────────────────────────\n\n/** Open/filled arrowhead length (from tip to base). */\nexport const GLYPH_ARROW_LEN = 10;\n/** Open/filled arrowhead half-width at the base. */\nexport const GLYPH_ARROW_HALF = 5;\n\n/** Generalization/realization triangle length (from tip to base). */\nexport const GLYPH_TRI_LEN = 14;\n/** Generalization/realization triangle half-width at the base. */\nexport const GLYPH_TRI_HALF = 8;\n\n/** Aggregation/composition diamond length (tip to base, full axis). */\nexport const GLYPH_DIAMOND_LEN = 16;\n/** Aggregation/composition diamond half-width at mid-point. */\nexport const GLYPH_DIAMOND_HALF = 6;\n\n// ── Arrowheads ────────────────────────────────────────────────────────────────\n\n/**\n * Three-point open arrowhead (\"<\" shape, 2-stroke polyline).\n * Caller should set fill=\"none\".\n *\n * @param tip - apex of the arrowhead (where the line ends)\n * @param dir - direction the tip points\n * @param len - depth of the arrowhead (default GLYPH_ARROW_LEN)\n * @param half - half-width at the base (default GLYPH_ARROW_HALF)\n */\nexport function arrowOpenPoints(\n tip: Point,\n dir: Dir,\n len: number = GLYPH_ARROW_LEN,\n half: number = GLYPH_ARROW_HALF,\n): string {\n return _arrowPoints(tip, dir, len, half);\n}\n\n/**\n * Three-point solid (filled) arrowhead.\n * Caller should set fill to the desired ink color.\n *\n * @param tip - apex of the arrowhead (where the line ends)\n * @param dir - direction the tip points\n * @param len - depth of the arrowhead (default GLYPH_ARROW_LEN)\n * @param half - half-width at the base (default GLYPH_ARROW_HALF)\n */\nexport function arrowFilledPoints(\n tip: Point,\n dir: Dir,\n len: number = GLYPH_ARROW_LEN,\n half: number = GLYPH_ARROW_HALF,\n): string {\n return _arrowPoints(tip, dir, len, half);\n}\n\n/**\n * Shared arrow geometry: 3 points — tip, base+perp, base-perp.\n * Identical for open and filled (caller controls fill/stroke).\n *\n * Formula matches the fishbone arrowHead function:\n * base = tip - (ux*len, uy*len)\n * perpendicular = (-uy, ux)\n * pt1 = tip\n * pt2 = base + perp * half\n * pt3 = base - perp * half\n */\nfunction _arrowPoints(tip: Point, dir: Dir, len: number, half: number): string {\n const [ux, uy] = dirVec(dir);\n const tx = tip.x;\n const ty = tip.y;\n // base center (back from tip along the direction)\n const bx = tx - ux * len;\n const by = ty - uy * len;\n // perpendicular unit vector\n const px = -uy;\n const py = ux;\n return [\n pt(tx, ty),\n pt(bx + px * half, by + py * half),\n pt(bx - px * half, by - py * half),\n ].join(\" \");\n}\n\n// ── Triangle ──────────────────────────────────────────────────────────────────\n\n/**\n * Three-point isoceles triangle (generalization/realization head).\n * Same geometry as the arrowhead; caller fills white (open triangle) or ink (realization).\n *\n * @param tip - apex of the triangle (where the line ends)\n * @param dir - direction the tip points\n * @param len - depth tip→base (default GLYPH_TRI_LEN)\n * @param half - half-width at the base (default GLYPH_TRI_HALF)\n */\nexport function trianglePoints(\n tip: Point,\n dir: Dir,\n len: number = GLYPH_TRI_LEN,\n half: number = GLYPH_TRI_HALF,\n): string {\n return _arrowPoints(tip, dir, len, half);\n}\n\n// ── Diamond ───────────────────────────────────────────────────────────────────\n\n/**\n * Four-point rhombus (aggregation / composition diamond).\n * Points in order: tip → left-side → base → right-side.\n *\n * The `tip` is the outer apex (the one on the LINE, away from the source box).\n * The diamond extends `len` in the `dir` direction (toward the source box).\n * Left/right side-points are `half` perpendicular units off the mid-axis.\n *\n * @param tip - outer apex (where the line ends, nearest the target)\n * @param dir - direction from tip toward the source box\n * @param len - length of the full diamond axis (default GLYPH_DIAMOND_LEN)\n * @param half - half-width at the widest point (default GLYPH_DIAMOND_HALF)\n */\nexport function diamondPoints(\n tip: Point,\n dir: Dir,\n len: number = GLYPH_DIAMOND_LEN,\n half: number = GLYPH_DIAMOND_HALF,\n): string {\n const [ux, uy] = dirVec(dir);\n const tx = tip.x;\n const ty = tip.y;\n // mid-point (halfway along the axis)\n const mx = tx + ux * (len / 2);\n const my = ty + uy * (len / 2);\n // base (far end, at the source box edge)\n const basex = tx + ux * len;\n const basey = ty + uy * len;\n // perpendicular unit vector (-uy, ux)\n const px = -uy;\n const py = ux;\n return [\n pt(tx, ty),\n pt(mx - px * half, my - py * half),\n pt(basex, basey),\n pt(mx + px * half, my + py * half),\n ].join(\" \");\n}\n\n// ── Inset metric ──────────────────────────────────────────────────────────────\n\n/**\n * How far the LINE must stop short of the box edge so it meets the glyph BASE\n * (not the box face). Layout reserves this space; svg draws the line to this\n * point and the polygon from it.\n *\n * For arrows and triangles: the line ends at the glyph base, which is `len`\n * from the tip (the tip sits at the box edge). Inset = len.\n *\n * For diamonds: the diamond BASE is at the box edge; the tip is `len` outward.\n * The line ends at the diamond tip = `len` from the box edge. Inset = len.\n *\n * Direction does not affect the scalar inset value (rotation is sign-flip only).\n */\nexport function glyphInset(_dir: Dir, kind: \"arrow\" | \"triangle\" | \"diamond\"): number {\n switch (kind) {\n case \"arrow\": return GLYPH_ARROW_LEN;\n case \"triangle\": return GLYPH_TRI_LEN;\n case \"diamond\": return GLYPH_DIAMOND_LEN;\n }\n}\n","// Pure, deterministic multi-compartment box measurer. Guarantees that what\n// layout reserves is exactly what svg draws: every caller reads geometry from\n// CompartmentMetrics and never re-derives it independently.\n\nimport { estimateTextWidth } from \"./text\";\n\nexport interface CompartmentMetrics {\n /** Shared box width (all compartments share straight vertical sides). */\n boxW: number;\n /** Total box height (sum of all compartment heights). */\n boxH: number;\n /** Per-compartment row info: the line strings, the y of the compartment's\n * first-line baseline region (top of the padY region above the first line),\n * and the font size carried through. */\n rows: { lines: string[]; top: number; font: number }[];\n /** Y-coordinates of internal horizontal dividers (one between each pair of\n * consecutive compartments). Length = compartments.length - 1. */\n dividerYs: number[];\n}\n\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\n/**\n * Measures a multi-compartment UML-style box.\n *\n * @param compartments Ordered list of compartments (top→bottom). Each carries\n * its pre-wrapped `lines` and the `font` size for those lines.\n * An EMPTY compartment (`lines.length === 0`) still reserves one blank row of\n * `lineH` height so the abstract-class empty-operations divider is always drawn.\n * @param opts\n * - padX Horizontal padding inside the box (applied left + right).\n * - padY Vertical padding above the first line and below the last line of\n * each compartment.\n * - lineH Height of a single line (applies to every compartment uniformly).\n * - minW Minimum box width (shared across all compartments).\n * - sepPad Reserved for future per-separator padding; currently unused in\n * geometry (dividers are flush horizontal rules) but accepted in the\n * signature per the brief contract.\n */\nexport function measureCompartmentBox(\n compartments: { lines: string[]; font: number }[],\n opts: { padX: number; padY: number; lineH: number; minW: number; sepPad: number },\n): CompartmentMetrics {\n const { padX, padY, lineH, minW } = opts;\n\n // --- boxW: shared width, max over ALL lines in ALL compartments ---\n let maxLineW = 0;\n for (const c of compartments) {\n for (const line of c.lines) {\n const w = estimateTextWidth(line, c.font);\n if (w > maxLineW) maxLineW = w;\n }\n }\n const boxW = round(Math.max(minW, maxLineW + 2 * padX));\n\n // --- Per-compartment heights and divider positions ---\n const rows: CompartmentMetrics[\"rows\"] = [];\n const dividerYs: number[] = [];\n let y = 0;\n\n for (let i = 0; i < compartments.length; i++) {\n const c = compartments[i]!;\n // An empty compartment reserves one blank row.\n const lineCount = c.lines.length > 0 ? c.lines.length : 1;\n const compartmentH = padY + lineCount * lineH + padY;\n\n rows.push({\n lines: c.lines,\n top: round(y + padY),\n font: c.font,\n });\n\n y += compartmentH;\n\n if (i < compartments.length - 1) {\n dividerYs.push(round(y));\n }\n }\n\n const boxH = round(y);\n\n return { boxW, boxH, rows, dividerYs };\n}\n","// Pure 2-D grid packer. Guarantees disjoint cell AABBs by construction —\n// the UML box-overlap proof (2-D analog of packSubtree's disjoint-interval\n// induction). Every cell occupies exactly one (col, row) slot; colW[c] is\n// the widest cell in column c; rowH[r] is the tallest cell in row r. Column\n// x-origins accumulate left-to-right with colGap between columns; row\n// y-origins accumulate top-to-bottom with rowGap between rows. cellX/cellY\n// are the CENTER coordinates of each cell — callers subtract w/2 or h/2 to\n// get the top-left corner for drawing.\n\nexport interface GridCell {\n col: number;\n row: number;\n w: number;\n h: number;\n}\n\nexport interface GridResult {\n /** Center x of each cell (parallel to the input cells array). */\n cellX: number[];\n /** Center y of each cell (parallel to the input cells array). */\n cellY: number[];\n /** Width of each column (index = column index, 0 … maxCol). */\n colW: number[];\n /** Height of each row (index = row index, 0 … maxRow). */\n rowH: number[];\n}\n\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\n/**\n * Packs a set of cells into a declared 2-D grid.\n *\n * @param cells Each cell declares its (col, row) position and its own (w, h).\n * Multiple cells may share a column or row; no two cells may share BOTH\n * col and row (undefined behaviour — first-write wins for column/row maxima).\n * Columns and rows are identified by non-negative integer indices. Sparse\n * grids (gaps in column or row numbering) are legal; the skipped indices\n * get width/height 0 and contribute zero extent.\n * @param gaps colGap: horizontal gutter between adjacent columns;\n * rowGap: vertical gutter between adjacent rows.\n */\nexport function packGrid(\n cells: GridCell[],\n gaps: { colGap: number; rowGap: number },\n): GridResult {\n if (cells.length === 0) {\n return { cellX: [], cellY: [], colW: [], rowH: [] };\n }\n\n const { colGap, rowGap } = gaps;\n\n // ── 1. Find grid extents ───────────────────────────────────────────────────\n let maxCol = 0;\n let maxRow = 0;\n for (const c of cells) {\n if (c.col > maxCol) maxCol = c.col;\n if (c.row > maxRow) maxRow = c.row;\n }\n\n // ── 2. Compute per-column widths and per-row heights ──────────────────────\n // Initialise to 0 so sparse slots remain 0.\n const colW: number[] = Array.from({ length: maxCol + 1 }, () => 0);\n const rowH: number[] = Array.from({ length: maxRow + 1 }, () => 0);\n\n for (const c of cells) {\n if (c.w > colW[c.col]!) colW[c.col] = c.w;\n if (c.h > rowH[c.row]!) rowH[c.row] = c.h;\n }\n\n // ── 3. Accumulate column x-origins (left edge of each column) ────────────\n const colX: number[] = Array.from({ length: maxCol + 1 }, () => 0);\n for (let c = 1; c <= maxCol; c++) {\n colX[c] = round(colX[c - 1]! + colW[c - 1]! + colGap);\n }\n\n // ── 4. Accumulate row y-origins (top edge of each row) ────────────────────\n const rowY: number[] = Array.from({ length: maxRow + 1 }, () => 0);\n for (let r = 1; r <= maxRow; r++) {\n rowY[r] = round(rowY[r - 1]! + rowH[r - 1]! + rowGap);\n }\n\n // ── 5. Compute cell centers ────────────────────────────────────────────────\n // cellX[i] = left edge of column + half column width (CENTER x)\n // cellY[i] = top edge of row + half row height (CENTER y)\n const cellX: number[] = cells.map((c) =>\n round(colX[c.col]! + colW[c.col]! / 2),\n );\n const cellY: number[] = cells.map((c) =>\n round(rowY[c.row]! + rowH[c.row]! / 2),\n );\n\n return { cellX, cellY, colW, rowH };\n}\n","// Genogram input model — declared facts only. compasso draws EXACTLY what the caller\n// declares and NEVER synthesizes structure: two declared parents without a declared\n// union never merge into a couple; a \"coparental\" union draws no couple element; a\n// free-text relationship never silently becomes kinship. Collection doctrine (who may\n// assert a fact, how it was captured) is the caller's concern — this is a renderer.\n\n/** Sex marker for a genogram node (standard notation: square/circle/diamond). */\nexport type PersonSex = \"male\" | \"female\" | \"unknown\";\n\n/** A genogram node. `generation` is relative (0 = index person; negative = older). */\nexport interface Person {\n id: number;\n label: string;\n sex: PersonSex;\n deceased: boolean;\n generation: number | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/**\n * CLOSED status vocabulary for a declared union. Notable semantics:\n * - \"coparental\": the two were NEVER a couple and have child(ren) together;\n * - \"unknown\": a union was declared, but its type was not;\n * - widowhood is NOT a status — death lives on Person.deceased and never\n * alters the declared status;\n * - no value for \"not stated\": the union simply is not passed in.\n */\nexport const UNION_STATUSES = [\n \"married\",\n \"cohabiting\",\n \"dating\",\n \"separated\",\n \"divorced\",\n \"coparental\",\n \"unknown\",\n] as const;\n\nexport type UnionStatus = (typeof UNION_STATUSES)[number];\n\n/**\n * A declared couple bond between two people. The pair is unordered and expected\n * normalized to personAId < personBId with ONE union per pair (duplicates are the\n * caller's to resolve). `quality` is the author's verbatim wording about the bond.\n */\nexport interface Union {\n id: number;\n /** Always the smaller person id (normalized pair). */\n personAId: number;\n personBId: number;\n status: UnionStatus;\n quality: string | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/**\n * A declared parentage link: parent → child, one row PER DECLARED genitor (two\n * genitors = two links, each individually stated — never promoted from a union).\n */\nexport interface ParentLink {\n id: number;\n parentId: number;\n childId: number;\n quality: string | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/**\n * A typed free-text edge between two people. `type` and `quality` are verbatim\n * labels. This carries NON-STRUCTURAL ties only (closeness, conflict…) — unions\n * and parentage are first-class above.\n */\nexport interface Relationship {\n id: number;\n fromPersonId: number;\n toPersonId: number;\n type: string;\n quality: string | null;\n /** Caller-declared: this element was annotated (e.g. edited). compasso never interprets it. */\n annotated?: boolean;\n}\n\n/** Input to the genogram render pipeline. */\nexport interface GenogramInput {\n people: Person[];\n unions: Union[];\n parentLinks: ParentLink[];\n relationships: Relationship[];\n}\n\n/** Node glyph shapes (standard notation: square = male, circle = female, diamond = unknown). */\nexport type NodeShape = \"square\" | \"circle\" | \"diamond\";\n","// Display vocabularies — every human-readable string the genogram emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n\nimport type { EdgeLineStyle } from \"../core\";\nimport type { NodeShape, UnionStatus } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface GenogramTitleLabels {\n unionStatus: Record<UnionStatus, string>;\n /** Title prefix for a parent→child descent (\"parent of\"). */\n parentage: string;\n}\n\nexport const GENOGRAM_TITLE_LABELS_EN: GenogramTitleLabels = {\n unionStatus: {\n married: \"married\",\n cohabiting: \"cohabiting\",\n dating: \"dating\",\n separated: \"separated\",\n divorced: \"divorced\",\n coparental: \"co-parents (never a couple)\",\n unknown: \"union (type not stated)\",\n },\n parentage: \"parent of\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface GenogramSvgLabels {\n shapes: Record<NodeShape, string>;\n deceased: string;\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the group of people with no drawn connection. */\n isolated: string;\n ariaLabel: string;\n}\n\nexport const GENOGRAM_SVG_LABELS_EN: GenogramSvgLabels = {\n shapes: {\n square: \"Man\",\n circle: \"Woman\",\n diamond: \"Sex not stated\",\n },\n deceased: \"Deceased\",\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n isolated: \"No recorded ancestry\",\n ariaLabel: \"Family map (genogram)\",\n};\n","// Relationship → MAP class (presentation only). A genogram draws only the structural\n// SKELETON: declared unions + parent links. A free-text `relationship` becomes a map\n// LINE only when it is NON-parentage. Kinship that is READ FROM THE TREE (grandparent/\n// sibling/uncle/cousin/nephew…) draws NOTHING — it is already implied by the descent/\n// union structure, so a dedicated line would only duplicate and clutter. A DIRECT\n// parentage word (mother/father/child) with no declared parent link is PROMOTED to a\n// descent (oriented by declared generation) so the person is not orphaned. NOTHING here\n// synthesizes undeclared structure: derived kinship draws nothing at all, and promotion\n// only ORIENTS an already-declared parent-child word. The verbatim \"type · quality\" of\n// EVERY relationship is the caller's to keep showing in its own lists.\n\nimport { normalizeText } from \"../core\";\n\nexport type RelationshipMapClass = \"derived\" | \"parentage\" | \"bond\";\n\n/**\n * A pluggable kinship vocabulary. Tokens are diacritic-free, lowercase, matched WHOLE\n * (so a token never matches inside another word) after splitting the type on\n * non-alphanumerics (\"half-brother\" → [\"half\",\"brother\"]). Checked DERIVED-first, so\n * \"brother on my father's side\" reads as a sibling, never as a parent. These lists are\n * closed and conservative — an unrecognized word stays a non-structural bond (the\n * honest default). Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface KinshipLexicon {\n /** Kinship read from the tree (sibling/grandparent/uncle/cousin…): never a line. */\n derived: ReadonlySet<string>;\n /** Direct parentage words (mother/father/son…): promotable to a descent. */\n parentage: ReadonlySet<string>;\n /** Parentage words whose FROM endpoint is the CHILD — used only to orient a\n * promotion when declared generations do not decide it. */\n childWords: ReadonlySet<string>;\n}\n\nexport const KINSHIP_EN: KinshipLexicon = {\n derived: new Set([\n \"brother\", \"brothers\", \"sister\", \"sisters\", \"sibling\", \"siblings\",\n \"grandmother\", \"grandfather\", \"grandma\", \"grandpa\", \"granny\", \"grandad\",\n \"granddad\", \"grandparent\", \"grandparents\",\n \"grandson\", \"granddaughter\", \"grandchild\", \"grandchildren\",\n \"uncle\", \"uncles\", \"aunt\", \"aunts\", \"auntie\",\n \"cousin\", \"cousins\",\n \"nephew\", \"nephews\", \"niece\", \"nieces\",\n ]),\n parentage: new Set([\n \"mother\", \"mothers\", \"mom\", \"mum\", \"father\", \"fathers\", \"dad\",\n \"parent\", \"parents\",\n \"son\", \"sons\", \"daughter\", \"daughters\",\n ]),\n childWords: new Set([\"son\", \"sons\", \"daughter\", \"daughters\"]),\n};\n\n/** Lowercase + accent-stripped tokens of a free-text relationship type. */\nexport function relationshipTypeTokens(type: string): string[] {\n return normalizeText(type).split(/[^a-z0-9]+/).filter((t) => t !== \"\");\n}\n\n/**\n * Classifies a free-text relationship `type` for the MAP. Pure + deterministic.\n * Derived kinship is checked first so a compound like \"brother on my father's side\"\n * is read as a sibling (derived), never promoted as a parent. The verbatim word is\n * unaffected — this decides only whether the tie becomes a line, and which kind.\n */\nexport function classifyRelationshipType(\n type: string,\n kinship: KinshipLexicon = KINSHIP_EN,\n): RelationshipMapClass {\n const toks = relationshipTypeTokens(type);\n if (toks.some((t) => kinship.derived.has(t))) return \"derived\";\n if (toks.some((t) => kinship.parentage.has(t))) return \"parentage\";\n return \"bond\";\n}\n","// PURE genogram layout — the single source of truth for positioning and glyph/edge\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so it loads\n// identically in browsers, server runtimes and test environments, and the same input\n// always yields the same layout. Anything with a side effect belongs elsewhere.\n//\n// HONESTY RULE: this module only POSITIONS and ROUTES the facts the caller declared. It\n// computes NO score, interpretation, prognosis or diagnosis, and it NEVER synthesizes\n// undeclared structure: a `coparental` union draws no couple element; two declared\n// parents WITHOUT a declared union never merge into a couple-bar descent (each gets its\n// own descent); free-text `relationships` stay non-structural bonds. Shapes follow the\n// standard genogram convention (square = male, circle = female, diamond = unknown; a\n// diagonal stroke marks deceased). The verbatim \"type · quality\" / status label is\n// ALWAYS kept on every routed element's <title>, so a style never replaces what was said.\n//\n// LAYOUT — orthogonal (McGoldrick) and overlap-proof BY CONSTRUCTION (not by luck). The\n// diagram is a grid: people sit in COLUMNS inside generation ROWS; the empty bands\n// BETWEEN columns (GUTTERS) and BETWEEN rows (CORRIDORS) are the only places routing\n// segments live, each in a numbered LANE allocated by interval-overlap so two segments\n// in the same lane can never overlap. Every consecutive pair of waypoints is axis-aligned\n// (horizontal or vertical) — there are NO diagonals and NO text on map edges (the\n// verbatim text rides the <title> and the caller's side lists). Glyphs and their labels\n// live entirely inside their columns; gutters and corridors are content-free by\n// construction, so a routed segment can never cross a glyph or a label box.\n//\n// PROVENANCE: descends from the production genogram renderer the author wrote for the\n// Ventory project (same copyright holder); developed independently of any third-party\n// diagram engine.\nimport {\n CHAR_W,\n clampLabel,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n wrapLabelBalanced,\n EDGE_STROKE,\n type EdgeLineStyle,\n type EdgeStroke,\n type Point,\n type QualityLexicon,\n} from \"../core\";\nimport { GENOGRAM_TITLE_LABELS_EN, type GenogramTitleLabels } from \"./labels\";\nimport {\n classifyRelationshipType,\n relationshipTypeTokens,\n KINSHIP_EN,\n type KinshipLexicon,\n type RelationshipMapClass,\n} from \"./kinship\";\nimport type {\n NodeShape,\n ParentLink,\n Person,\n PersonSex,\n Relationship,\n Union,\n} from \"./types\";\n\n// Re-exports so callers (and the emitter) can reach the full vocabulary through this\n// module, mirroring the original single-file layout.\nexport { CHAR_W, estimateTextWidth, qualityLineStyle, wrapLabel, EDGE_STROKE };\nexport type { EdgeLineStyle, EdgeStroke, Point, QualityLexicon };\nexport { classifyRelationshipType, relationshipTypeTokens, KINSHIP_EN };\nexport type { KinshipLexicon, RelationshipMapClass };\nexport type { NodeShape };\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\nexport const NODE_SIZE = 56;\nconst PADDING = 32;\n/** Min horizontal gap between two adjacent columns' content boxes (a gutter's base). */\nconst COL_PAD = 30;\n/** Gap from a glyph's bottom to the top of its first label line. */\nconst LABEL_GAP_TOP = 8;\n/** Base height of a routing corridor (before lanes widen it). */\nconst CORRIDOR_BASE = 24;\n/** Vertical/horizontal spacing between two routing lanes in a corridor/gutter. */\nconst LANE_H = 8;\n/** Vertical drop between successive serial-union (remarriage) bars below the glyph row,\n * so 2+ unions on one person never read as one continuous rail (McGoldrick, FIX B). */\nconst UNION_STAGGER = 12;\n/** Horizontal offset (from glyph center, toward the partner) of a dipped union-bar's stub,\n * so a person in two serial unions gets two distinct stub columns (FIX B). < NODE_SIZE/2. */\nconst STUB_X_OFF = 14;\n/** Extra horizontal separation placed before an isolated-people group (SPEC). */\nconst ISOLATED_GUTTER_EXTRA = 2 * COL_PAD;\n\n// ── Type metrics (shared by layout AND both renderers, so geometry == render) ──\n/** Node label font size (px). The live SVG renders at this size; the PDF scales it. */\nexport const LABEL_FONT = 12;\n/** Line height for stacked node-label lines (px). */\nexport const LABEL_LINE_H = 14;\n/** Edge label font size (px) — kept for the shared metrics contract (invariant #9). */\nexport const EDGE_FONT = 11;\n// CHAR_W / estimateTextWidth live in ../core (re-exported above): the overlap-proof\n// guarantee depends on layout and emitters sharing these exact metrics.\n\n// ── Namespaced element ids (kept stable so data-edge-id stays traceable, §7.2) ──\n// relationships keep their own id; unions live at 1_000_000+id; parent links at\n// 2_000_000+id; PROMOTED descents (a direct-parentage free-text relationship drawn as a\n// descent — see classifyRelationshipType) at 3_000_000+rel id. Four disjoint blocks, so a\n// promoted descent never collides with a real parent link and every edge stays traceable\n// to its source. Deterministic, and visible in the overlap harness / data-edge-id.\nexport const UNION_REL_ID_BASE = 1_000_000;\nexport const PARENT_REL_ID_BASE = 2_000_000;\nexport const PROMOTED_REL_ID_BASE = 3_000_000;\n\n// ── Node glyphs ──────────────────────────────────────────────────────────────\nfunction shapeForSex(sex: PersonSex): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Edge line styles ─────────────────────────────────────────────────────────\n// EdgeLineStyle / EDGE_STROKE / qualityLineStyle live in ../core (re-exported above):\n// a neutral, presentation-only style for a NON-STRUCTURAL bond line, lexically hinted\n// from the author's own quality word — never a judgment, verbatim word always kept.\n\n/**\n * Per-edge VISUAL union style applied at emission (§7.2 / FIX 3) — the McGoldrick\n * notation for a declared union TYPE, WITHOUT touching the layout or the patient's\n * words. `coparental` never gets one (it draws no edge). Defined here (not in\n * fallback-svg) so a routed element can carry it and the emitter stays free of layout\n * cycles; fallback-svg re-exports it for the existing call sites.\n */\nexport interface UnionEdgeStyle {\n /** Inline stroke-dasharray [dash, gap] on the bar; absent = solid (e.g. casado). */\n dash?: readonly [number, number];\n /** Diagonal status slashes at the midpoint: 1 = separação, 2 = divórcio. */\n slashes?: 0 | 1 | 2;\n}\n\n// ── Relationship → MAP class ───────────────────────────────────────────────────\n// classifyRelationshipType / relationshipTypeTokens / KinshipLexicon live in ./kinship\n// (re-exported above): derived kinship draws NOTHING, direct parentage may be PROMOTED\n// to a descent, everything else stays a non-structural bond. Node labels wrap through\n// core's `wrapLabelBalanced` (the house balanced policy) and clamp through core's\n// `clampLabel` — both shared with every other emitter, so what is reserved is what is\n// drawn. wrapLabel/wrapLabelBalanced/clampLabel all live in ../core.\n\n// ── Positioned layout ────────────────────────────────────────────────────────\n\nexport interface GenogramNode {\n personId: number;\n /** Full, verbatim label (used for tooltips/aria — never truncated). */\n label: string;\n shape: NodeShape;\n deceased: boolean;\n /** Caller-declared: this node was annotated. Mirrors Person.annotated — never interpreted. */\n annotated: boolean;\n /** Center of the node. */\n cx: number;\n cy: number;\n /** Side length (square) / diameter (circle) / width (diamond). */\n size: number;\n /** Pre-wrapped display lines (already capped for the requested density). */\n labelLines: string[];\n /** Y of the TOP of the first label line's box (each next line is +LABEL_LINE_H). */\n labelTop: number;\n}\n\n/** A routed map element — the orthogonal replacement for the old straight `GenogramEdge`. */\nexport type GenogramElementKind =\n | \"union-bar\" // adjacent same-row partners: straight H bar, glyph-edge to glyph-edge\n | \"union-elbow\" // non-adjacent / cross-row partners: orthogonal route\n | \"descent\" // parent(s) → child plumbing segment(s)\n | \"sibling-bar\" // one shared H bar per union child-group (≥1 children)\n | \"bond\"; // non-structural relationship, orthogonal route\n\nexport interface GenogramElement {\n kind: GenogramElementKind;\n /** Source row ids for traceability; merged bonds carry every merged rel id. */\n relIds: number[];\n /** data-edge-id value: highest relId (matches latestUnionPerPair's highest-wins). */\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n /** Polyline; EVERY consecutive pair is axis-aligned (H or V). */\n points: Point[];\n /** Verbatim titles (one per source row), joined for the <title>. */\n titles: string[];\n lineStyle: EdgeLineStyle; // bonds only; structural elements are \"plain\"\n unionStyle?: UnionEdgeStyle; // union-bar / union-elbow: dash + slashes\n dotted?: boolean; // lone-parent / coparental descents\n /** Caller-declared: this edge was annotated. Propagated from the source input row(s). */\n annotated: boolean;\n}\n\nexport interface GenogramLayout {\n width: number;\n height: number;\n nodes: GenogramNode[];\n elements: GenogramElement[];\n /** People with NO drawn structural/bond connection — grouped to the side and labeled\n * \"Sem ascendência registrada\" so a loose glyph is never left unexplained. */\n isolatedPersonIds: number[];\n}\n\n// ── Internal working types ─────────────────────────────────────────────────────\n\n/**\n * A parent→child descent to draw — either a DECLARED parent_link (real) or a PROMOTED\n * direct-parentage relationship (no declared link existed for the pair). `edgeId` is\n * pre-namespaced (real: PARENT_REL_ID_BASE+link id; promoted: PROMOTED_REL_ID_BASE+rel id),\n * so both flow through the same descent machinery and stay traceable in data-edge-id.\n */\ninterface LayoutLink {\n parentId: number;\n childId: number;\n quality: string | null;\n edgeId: number;\n annotated: boolean;\n}\n\ninterface Measured {\n person: Person;\n lines: string[];\n /** max(NODE_SIZE, widest wrapped line) — the horizontal footprint. */\n contentW: number;\n}\n\n/** A vertical segment living in a gutter, awaiting a lane. */\ninterface GutterReq {\n gutter: number; // gutter index g in [-1, colCount-1]\n side: -1 | 0 | 1; // -1 hug left column, +1 hug right column, 0 center (union spine)\n rowLo: number; // continuous row coordinate (row r → r; corridor k → k+0.5)\n rowHi: number;\n lane: number; // filled by the allocator\n}\n\n/** A horizontal segment living in a corridor, awaiting a lane. Its pixel x-interval is\n * resolved AFTER the column/gutter geometry is fixed, so the lane allocator can use the\n * EXACT extent (a u-index proxy collapses for within-one-gutter spans). */\ninterface CorridorReq {\n corridor: number; // corridor index k in [0, rowCount-1] (k = below row k)\n xRange: () => [number, number]; // pixel [xMin, xMax], resolved post-column-geometry\n lane: number;\n}\n\n/** A sideways glyph departure stub, awaiting a height slot. */\ninterface StubReq {\n personId: number;\n side: -1 | 1;\n slot: number; // height slot index, filled below\n}\n\n/** An arrival into a glyph TOP, awaiting an x-offset slot. */\ninterface ArrivalReq {\n personId: number;\n slot: number;\n}\n\n/** A planned element: its kind/metadata + a builder that resolves to pixel points. */\ninterface PlannedElement {\n kind: GenogramElementKind;\n relIds: number[];\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n titles: string[];\n lineStyle: EdgeLineStyle;\n unionStyle?: UnionEdgeStyle;\n dotted?: boolean;\n annotated: boolean;\n build: () => Point[];\n}\n\n// Height slots for stacked departures from one glyph side (avoid y=cy so a union bar at\n// cy is never crossed). Within ±(NODE_SIZE/2 − 4) so the stub stays on the glyph edge.\nconst STUB_OFFSETS = [9, -9, 18, -18, 26, -26] as const;\n/** Max |x-offset| for an arrival into a glyph TOP (kept inside the top edge half-width). */\nconst ARRIVAL_HALF = NODE_SIZE / 2 - 8;\n\nfunction stubOffset(slot: number): number {\n return STUB_OFFSETS[Math.min(slot, STUB_OFFSETS.length - 1)]!;\n}\n/** Spread arrivals across a glyph TOP so each lands on a distinct x — slot 0 stays\n * CENTERED (the primary descent), later arrivals alternate to either side. For any\n * fan-in count, no two verticals share a column (overlap-proof). */\nfunction arrivalOffset(slot: number, total: number): number {\n if (slot === 0 || total <= 1) return 0;\n const step = Math.min(12, ARRIVAL_HALF / Math.max(1, Math.ceil((total - 1) / 2)));\n const sign = slot % 2 === 1 ? -1 : 1;\n return sign * Math.ceil(slot / 2) * step;\n}\n\n/** Allocate lanes for a set of intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so collinear segments may abut). */\nfunction allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n\n/**\n * Deterministic, overlap-proof ORTHOGONAL layout (pure function of the inputs — same\n * data always yields the same geometry). People are grouped by `generation` (null trails\n * as a bottom row), rows ordered oldest-on-top. Declared structure is drawn as McGoldrick\n * elements: same-row adjacent unions as straight bars, couples-with-children as a shared\n * sibling bar, lone/co-parental genitors as dotted descents, and free-text relationships\n * as orthogonally-routed bonds — NEVER promoting a bond into structure.\n *\n * @param unions caller-deduped (one per pair) declared couple bonds.\n * @param parentLinks declared parent→child links (one row per declared genitor).\n * @param relationships non-structural ties (drawn as bonds).\n * @param opts.maxLabelChars cap each node's DISPLAY label to this many chars (compact\n * preview); the full verbatim text is still exposed on `node.label`.\n * @param opts.kinship / opts.qualityLexicon / opts.titleLabels — locale packs (English\n * defaults; see `compasso/locales/pt-br`).\n */\nexport interface GenogramLayoutOptions {\n maxLabelChars?: number;\n kinship?: KinshipLexicon;\n qualityLexicon?: QualityLexicon;\n titleLabels?: GenogramTitleLabels;\n}\n\nexport function computeGenogramLayout(\n people: Person[],\n unions: Union[],\n parentLinks: ParentLink[],\n relationships: Relationship[],\n opts: GenogramLayoutOptions = {},\n): GenogramLayout {\n const kinship = opts.kinship ?? KINSHIP_EN;\n const titleLabels = opts.titleLabels ?? GENOGRAM_TITLE_LABELS_EN;\n if (people.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], isolatedPersonIds: [] };\n }\n\n const ids = new Set(people.map((p) => p.id));\n const pairKey = (a: number, b: number): string => `${Math.min(a, b)}|${Math.max(a, b)}`;\n const genById = new Map<number, number | null>(people.map((p) => [p.id, p.generation]));\n\n // Sanitize structural inputs (drop self/missing endpoints — keep declared facts only).\n const validUnions = unions\n .filter((u) => ids.has(u.personAId) && ids.has(u.personBId) && u.personAId !== u.personBId)\n .sort((a, b) => a.id - b.id);\n const coupleUnions = validUnions.filter((u) => u.status !== \"coparental\");\n const validLinks = parentLinks\n .filter((l) => ids.has(l.parentId) && ids.has(l.childId) && l.parentId !== l.childId)\n .sort((a, b) => a.id - b.id);\n const validRels = relationships\n .filter((r) => ids.has(r.fromPersonId) && ids.has(r.toPersonId) && r.fromPersonId !== r.toPersonId)\n .sort((a, b) => a.id - b.id);\n\n // ── SKELETON-ONLY (presentation): classify each free-text relationship for the MAP ─────\n // - \"derived\" (avó/irmão/tio/…): READ from the tree → draws NOTHING here.\n // - \"parentage\" (mãe/pai/filho/…): a declared parent-child word → PROMOTED to a descent\n // when no parent_link already declares the pair (else a duplicate, dropped\n // from the map); never a bond.\n // - \"bond\" (everything else): a non-structural tie → drawn as a bond, as before.\n // The verbatim \"type · quality\" of EVERY relationship still rides the dossier side lists.\n const relClass = new Map<number, RelationshipMapClass>(\n validRels.map((r) => [r.id, classifyRelationshipType(r.type, kinship)]),\n );\n const bondRels = validRels.filter((r) => relClass.get(r.id) === \"bond\");\n const parentageRels = validRels.filter((r) => relClass.get(r.id) === \"parentage\");\n\n // Effective descents = declared parent_links (real) + promoted parentage relationships.\n const realLinks: LayoutLink[] = validLinks.map((l) => ({\n parentId: l.parentId,\n childId: l.childId,\n quality: l.quality,\n edgeId: PARENT_REL_ID_BASE + l.id,\n annotated: l.annotated ?? false,\n }));\n const declaredPairs = new Set(validLinks.map((l) => pairKey(l.parentId, l.childId)));\n const promotedByPair = new Map<string, LayoutLink>();\n for (const r of parentageRels) {\n const key = pairKey(r.fromPersonId, r.toPersonId);\n if (declaredPairs.has(key)) continue; // already a declared parent_link → no double-draw\n if (promotedByPair.has(key)) continue; // same pair stated twice → one descent (id-order)\n // Orient parent→child by DECLARED generation (older = parent). When generations do not\n // decide (equal or null), fall back to the parentage WORD + the declared from/to:\n // mãe/pai → from is the parent; filho/filha → from is the child. Either way nothing is\n // invented — both endpoints and the parent-child nature were declared; only the arrow.\n const ga = genById.get(r.fromPersonId) ?? null;\n const gb = genById.get(r.toPersonId) ?? null;\n let parentId: number;\n let childId: number;\n if (ga !== null && gb !== null && ga !== gb) {\n [parentId, childId] = ga < gb ? [r.fromPersonId, r.toPersonId] : [r.toPersonId, r.fromPersonId];\n } else {\n const fromIsChild = relationshipTypeTokens(r.type).some((t) => kinship.childWords.has(t));\n [parentId, childId] = fromIsChild ? [r.toPersonId, r.fromPersonId] : [r.fromPersonId, r.toPersonId];\n }\n if (parentId === childId) continue;\n promotedByPair.set(key, { parentId, childId, quality: r.quality, edgeId: PROMOTED_REL_ID_BASE + r.id, annotated: r.annotated ?? false });\n }\n const allLinks: LayoutLink[] = [...realLinks, ...promotedByPair.values()].sort((a, b) => a.edgeId - b.edgeId);\n\n // Declared (non-coparental) union lookup by unordered pair → union.\n const coupleByPair = new Map<string, Union>();\n for (const u of coupleUnions) coupleByPair.set(pairKey(u.personAId, u.personBId), u);\n\n // Parents per child and links per (parent,child) — real links + promoted descents.\n const parentsOf = new Map<number, number[]>();\n const linkOf = new Map<string, LayoutLink>();\n for (const l of allLinks) {\n const arr = parentsOf.get(l.childId) ?? [];\n if (!arr.includes(l.parentId)) arr.push(l.parentId);\n parentsOf.set(l.childId, arr);\n linkOf.set(`${l.parentId}>${l.childId}`, l);\n }\n\n // A person is ISOLATED when they have NO drawn connection: no union, no descent (real or\n // promoted), and no bond. A relationship suppressed from the map (derived kinship like\n // \"minha tia\", read from the tree) does NOT count as a tie — so such a person is grouped\n // to the side and labeled \"Sem ascendência registrada\", never left as a loose glyph.\n const hasTie = new Set<number>();\n for (const u of validUnions) {\n hasTie.add(u.personAId);\n hasTie.add(u.personBId);\n }\n for (const l of allLinks) {\n hasTie.add(l.parentId);\n hasTie.add(l.childId);\n }\n for (const r of bondRels) {\n hasTie.add(r.fromPersonId);\n hasTie.add(r.toPersonId);\n }\n const isIsolated = (id: number): boolean => !hasTie.has(id);\n\n // ── Pass 1a: rows by declared generation (null last), oldest on top ──────────────\n const byGen = new Map<number | null, Person[]>();\n for (const p of people) {\n const bucket = byGen.get(p.generation);\n if (bucket === undefined) byGen.set(p.generation, [p]);\n else bucket.push(p);\n }\n const genKeys = [...byGen.keys()].sort((a, b) => {\n if (a === null) return 1;\n if (b === null) return -1;\n return a - b;\n });\n const rowCount = genKeys.length;\n const rowOfPerson = new Map<number, number>();\n genKeys.forEach((g, r) => byGen.get(g)!.forEach((p) => rowOfPerson.set(p.id, r)));\n\n // ── Pass 1b: couple BLOCKS per row (connected components of same-row couple unions),\n // linearized so partners land adjacent; then barycenter ordering; isolated rightmost.\n type Block = number[]; // person ids, left-to-right\n const rowBlocks: Block[][] = genKeys.map((g, r) => {\n const members = byGen.get(g)!.map((p) => p.id);\n // adjacency from same-row couple unions\n const adj = new Map<number, number[]>();\n for (const id of members) adj.set(id, []);\n for (const u of coupleUnions) {\n if (rowOfPerson.get(u.personAId) === r && rowOfPerson.get(u.personBId) === r) {\n adj.get(u.personAId)!.push(u.personBId);\n adj.get(u.personBId)!.push(u.personAId);\n }\n }\n for (const id of members) adj.get(id)!.sort((a, b) => a - b);\n // connected components\n const seen = new Set<number>();\n const blocks: Block[] = [];\n for (const start of [...members].sort((a, b) => a - b)) {\n if (seen.has(start)) continue;\n const comp: number[] = [];\n const stack = [start];\n seen.add(start);\n while (stack.length > 0) {\n const n = stack.pop()!;\n comp.push(n);\n for (const m of adj.get(n)!) if (!seen.has(m)) { seen.add(m); stack.push(m); }\n }\n blocks.push(linearizeBlock(comp, adj));\n }\n return blocks;\n });\n\n // Barycenter sweeps (downward then upward), gated on rowCount ≥ 2. Aesthetic only —\n // it reorders blocks to align children under parents; it never moves anyone off a row.\n const flattened = (): Map<number, number> => {\n const pos = new Map<number, number>();\n for (const blocks of rowBlocks) {\n let c = 0;\n for (const b of blocks) for (const id of b) pos.set(id, c++);\n }\n return pos;\n };\n const structuralNeighbors = (id: number): number[] => {\n const out: { id: number; w: number }[] = [];\n // Barycenter ordering uses NON-coparental unions only (SPEC Pass 1 / FIX E): a\n // coparental pair draws no couple bar, so it must exert no ordering attraction either.\n for (const u of coupleUnions) {\n if (u.personAId === id) out.push({ id: u.personBId, w: 1 });\n else if (u.personBId === id) out.push({ id: u.personAId, w: 1 });\n }\n for (const l of allLinks) {\n if (l.childId === id) out.push({ id: l.parentId, w: 1 });\n else if (l.parentId === id) out.push({ id: l.childId, w: 1 });\n }\n for (const rl of bondRels) {\n if (rl.fromPersonId === id) out.push({ id: rl.toPersonId, w: 0.5 });\n else if (rl.toPersonId === id) out.push({ id: rl.fromPersonId, w: 0.5 });\n }\n return out.map((o) => o.id);\n };\n const neighborWeight = (id: number, other: number): number => {\n let w = 0;\n // NON-coparental unions only — same FIX E rationale as structuralNeighbors.\n for (const u of coupleUnions) if ((u.personAId === id && u.personBId === other) || (u.personBId === id && u.personAId === other)) w = Math.max(w, 1);\n for (const l of allLinks) if ((l.childId === id && l.parentId === other) || (l.parentId === id && l.childId === other)) w = Math.max(w, 1);\n for (const rl of bondRels) if ((rl.fromPersonId === id && rl.toPersonId === other) || (rl.toPersonId === id && rl.fromPersonId === other)) w = Math.max(w, 0.5);\n return w;\n };\n const sweep = (r: number, ref: number): void => {\n const pos = flattened();\n const blocks = rowBlocks[r]!;\n const bcOf = (b: Block): number => {\n let sum = 0;\n let wsum = 0;\n for (const id of b) {\n for (const nb of structuralNeighbors(id)) {\n if (rowOfPerson.get(nb) !== ref) continue;\n const w = neighborWeight(id, nb);\n sum += (pos.get(nb) ?? 0) * w;\n wsum += w;\n }\n }\n return wsum === 0 ? Number.POSITIVE_INFINITY : sum / wsum;\n };\n const keyed = blocks.map((b) => ({ b, bc: bcOf(b), minId: Math.min(...b) }));\n keyed.sort((x, y) => (x.bc !== y.bc ? x.bc - y.bc : x.minId - y.minId));\n rowBlocks[r] = keyed.map((k) => k.b);\n };\n if (rowCount >= 2) {\n for (let r = 1; r < rowCount; r++) sweep(r, r - 1);\n for (let r = rowCount - 2; r >= 0; r--) sweep(r, r + 1);\n }\n\n // Isolated people drift fully right: stable-partition each row so isolated singleton\n // blocks trail the connected ones (ordered by id). No connector is ever drawn for them.\n for (let r = 0; r < rowCount; r++) {\n const blocks = rowBlocks[r]!;\n const connected = blocks.filter((b) => !(b.length === 1 && isIsolated(b[0]!)));\n const isolated = blocks.filter((b) => b.length === 1 && isIsolated(b[0]!)).sort((a, b) => a[0]! - b[0]!);\n rowBlocks[r] = [...connected, ...isolated];\n }\n\n // ── Pass 1c: assign (row, col) to every person via the global column grid ─────────\n const colOf = new Map<number, number>();\n let colCount = 0;\n for (let r = 0; r < rowCount; r++) {\n let c = 0;\n for (const b of rowBlocks[r]!) for (const id of b) colOf.set(id, c++);\n colCount = Math.max(colCount, c);\n }\n const colOrThrow = (id: number): number => colOf.get(id)!;\n\n // Column where the isolated-only tail begins (extra gutter sits just before it).\n let isolatedTailCol = colCount; // none by default\n {\n const peopleAtCol: number[][] = Array.from({ length: colCount }, () => []);\n for (const p of people) peopleAtCol[colOrThrow(p.id)]!.push(p.id);\n for (let c = colCount - 1; c >= 1; c--) {\n const all = peopleAtCol[c]!;\n if (all.length > 0 && all.every((id) => isIsolated(id))) isolatedTailCol = c;\n else break;\n }\n }\n\n // ── Pass 2 prep: measure labels; column widths; per-row label heights ─────────────\n const measured = new Map<number, Measured>();\n for (const p of people) {\n const lines = wrapLabelBalanced(clampLabel(p.label, opts.maxLabelChars));\n const contentW = Math.max(NODE_SIZE, lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, LABEL_FONT)), 0));\n measured.set(p.id, { person: p, lines, contentW });\n }\n const colWidth: number[] = Array.from({ length: colCount }, () => NODE_SIZE);\n for (const p of people) {\n const c = colOrThrow(p.id);\n colWidth[c] = Math.max(colWidth[c]!, measured.get(p.id)!.contentW);\n }\n const rowMaxLines: number[] = Array.from({ length: rowCount }, () => 1);\n for (const p of people) {\n const r = rowOfPerson.get(p.id)!;\n rowMaxLines[r] = Math.max(rowMaxLines[r]!, measured.get(p.id)!.lines.length);\n }\n\n // ── Pass 2: route every element symbolically and register lane/slot requests ──────\n const planned: PlannedElement[] = [];\n const gutterReqs: GutterReq[] = [];\n const corridorReqs: CorridorReq[] = [];\n const stubCount = new Map<string, number>(); // `${id}:${side}` → slots used\n const arrivalCount = new Map<number, number>(); // id → arrival slots used\n\n const newStub = (personId: number, side: -1 | 1): StubReq => {\n const key = `${personId}:${side}`;\n const slot = stubCount.get(key) ?? 0;\n stubCount.set(key, slot + 1);\n return { personId, side, slot };\n };\n const newArrival = (personId: number): ArrivalReq => {\n const slot = arrivalCount.get(personId) ?? 0;\n arrivalCount.set(personId, slot + 1);\n return { personId, slot };\n };\n const departSide = (srcId: number, dstId: number): -1 | 1 => {\n const sc = colOrThrow(srcId);\n const dc = colOrThrow(dstId);\n if (dc > sc) return 1;\n if (dc < sc) return -1;\n return sc < colCount - 1 ? 1 : -1;\n };\n // The gutter a connector departs INTO, and which side of it the departing column is on.\n const gutterFor = (srcCol: number, side: -1 | 1): { gutter: number; gSide: -1 | 1 } =>\n side === 1\n ? { gutter: srcCol, gSide: -1 } // depart right → gutter to the right; src is its LEFT column\n : { gutter: srcCol - 1, gSide: 1 }; // depart left → gutter to the left; src is its RIGHT column\n\n // A cross-row connector: sideways stub from the UPPER node, gutter drop, corridor cross,\n // arrival into the LOWER glyph TOP. Returns a builder closure over the resolved geo.\n // Robust to either argument order: it routes from whichever node is in the SHALLOWER\n // (upper) declared generation, so a parent declared in a YOUNGER generation than the\n // child (srcRow > dstRow) still gets a valid, non-negative, in-range corridor and an\n // ordered gutter span instead of a negative index (FIX D-1). Normal upper→lower calls\n // are unchanged: the upper node is the source and corridor = lowerRow − 1 as before.\n const planConnector = (\n srcId: number,\n dstId: number,\n arrivalAtCenter: boolean,\n ): (() => Point[]) => {\n const srcRow = rowOfPerson.get(srcId)!;\n const dstRow = rowOfPerson.get(dstId)!;\n // Departure is always from the upper node; arrival into the lower node's TOP edge.\n const [upperId, lowerId] = srcRow <= dstRow ? [srcId, dstId] : [dstId, srcId];\n const upperRow = rowOfPerson.get(upperId)!;\n const lowerRow = rowOfPerson.get(lowerId)!;\n const side = departSide(upperId, lowerId);\n const { gutter, gSide } = gutterFor(colOrThrow(upperId), side);\n const stub = newStub(upperId, side);\n // Corridor just above the lower row, clamped in-range (degenerate same-row → band 0).\n const corridor = Math.max(0, Math.min(rowCount - 1, lowerRow - 1));\n const gReq: GutterReq = {\n gutter,\n side: gSide,\n rowLo: Math.min(upperRow, corridor + 0.5),\n rowHi: Math.max(upperRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(gReq);\n const arrival = arrivalAtCenter ? null : newArrival(lowerId);\n const arrivalX = (): number =>\n geo.cx(colOrThrow(lowerId)) + (arrival ? arrivalOffset(arrival.slot, arrivalCount.get(lowerId) ?? 1) : 0);\n const cReq: CorridorReq = {\n corridor,\n xRange: () => {\n const gx = geo.gutterLaneX(gReq);\n const ax = arrivalX();\n return [Math.min(gx, ax), Math.max(gx, ax)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const sy = geo.cy(upperRow) + stubOffset(stub.slot);\n const sEdge = side === 1 ? geo.glyphRight(upperId) : geo.glyphLeft(upperId);\n const gx = geo.gutterLaneX(gReq);\n const cyCorr = geo.corridorLaneY(cReq);\n const ax = arrivalX();\n const topY = geo.cy(lowerRow) - NODE_SIZE / 2;\n return [\n { x: sEdge, y: sy },\n { x: gx, y: sy },\n { x: gx, y: cyCorr },\n { x: ax, y: cyCorr },\n { x: ax, y: topY },\n ];\n };\n };\n\n // A same-row connector (U under the row): both endpoints leave sideways toward each\n // other, drop into the corridor below the row, and cross there.\n const planUConnector = (aId: number, bId: number): (() => Point[]) => {\n const row = rowOfPerson.get(aId)!;\n const [leftId, rightId] = colOrThrow(aId) <= colOrThrow(bId) ? [aId, bId] : [bId, aId];\n const stubL = newStub(leftId, 1);\n const stubR = newStub(rightId, -1);\n const gL = gutterFor(colOrThrow(leftId), 1);\n const gR = gutterFor(colOrThrow(rightId), -1);\n const gReqL: GutterReq = { gutter: gL.gutter, side: gL.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n const gReqR: GutterReq = { gutter: gR.gutter, side: gR.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n gutterReqs.push(gReqL, gReqR);\n const cReq: CorridorReq = {\n corridor: row,\n xRange: () => {\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n return [Math.min(xL, xR), Math.max(xL, xR)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const yL = geo.cy(row) + stubOffset(stubL.slot);\n const yR = geo.cy(row) + stubOffset(stubR.slot);\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n const cyCorr = geo.corridorLaneY(cReq);\n return [\n { x: geo.glyphRight(leftId), y: yL },\n { x: xL, y: yL },\n { x: xL, y: cyCorr },\n { x: xR, y: cyCorr },\n { x: xR, y: yR },\n { x: geo.glyphLeft(rightId), y: yR },\n ];\n };\n };\n\n const unionTitle = (u: Union): string =>\n u.quality !== null\n ? `${titleLabels.unionStatus[u.status]} · ${u.quality}`\n : titleLabels.unionStatus[u.status];\n const linkTitle = (l: { quality: string | null }): string =>\n l.quality !== null ? `${titleLabels.parentage} · ${l.quality}` : titleLabels.parentage;\n\n // 2a. Unions: same-row adjacent → bar; otherwise → elbow. (coparental drew nothing.)\n // McGoldrick SERIAL-UNION staggering (FIX B): when a person is in 2+ same-row union-bars\n // (remarriage), the bars would all sit at glyph-center cy and read as ONE continuous\n // rail. So within each connected chain of adjacent bars (components sharing a person),\n // the LOWEST union id stays at cy (level 0) and every other bar DIPS to a distinct depth\n // below the row's glyphs (level k → glyph bottom + k·UNION_STAGGER), drawn as a 3-seg\n // elbow (stub-down from each partner's glyph bottom → across → stub-up). The dip depth\n // is reserved in the row band (`rowDipDepth`) so labels never collide.\n const unionIsBar = new Map<number, boolean>();\n const barUnions = coupleUnions.filter(\n (u) =>\n rowOfPerson.get(u.personAId) === rowOfPerson.get(u.personBId) &&\n Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1,\n );\n // Per row, connected components of adjacent bar-unions (sharing a person), each ordered\n // by union id; index 0 → level 0 (cy), index k → dip level k. Deterministic.\n const unionDipLevel = new Map<number, number>(); // union id → dip level (0 = at cy)\n const rowDipLevels: number[] = Array.from({ length: rowCount }, () => 0);\n {\n const byRow = new Map<number, Union[]>();\n for (const u of barUnions) {\n const r = rowOfPerson.get(u.personAId)!;\n (byRow.get(r) ?? byRow.set(r, []).get(r)!).push(u);\n }\n for (const [r, rowUnions] of byRow) {\n // person → adjacent bar-unions on this row\n const unionsOfPerson = new Map<number, Union[]>();\n for (const u of rowUnions) {\n (unionsOfPerson.get(u.personAId) ?? unionsOfPerson.set(u.personAId, []).get(u.personAId)!).push(u);\n (unionsOfPerson.get(u.personBId) ?? unionsOfPerson.set(u.personBId, []).get(u.personBId)!).push(u);\n }\n const seen = new Set<number>();\n // Stable component discovery: walk unions in ascending id; BFS the shared-person graph.\n for (const start of [...rowUnions].sort((a, b) => a.id - b.id)) {\n if (seen.has(start.id)) continue;\n const comp: Union[] = [];\n const stack = [start];\n seen.add(start.id);\n while (stack.length > 0) {\n const u = stack.pop()!;\n comp.push(u);\n for (const pid of [u.personAId, u.personBId]) {\n for (const nb of unionsOfPerson.get(pid) ?? []) {\n if (!seen.has(nb.id)) {\n seen.add(nb.id);\n stack.push(nb);\n }\n }\n }\n }\n comp.sort((a, b) => a.id - b.id);\n comp.forEach((u, i) => unionDipLevel.set(u.id, i));\n rowDipLevels[r] = Math.max(rowDipLevels[r]!, comp.length - 1);\n }\n }\n }\n\n for (const u of coupleUnions) {\n const aRow = rowOfPerson.get(u.personAId)!;\n const bRow = rowOfPerson.get(u.personBId)!;\n const adjacent =\n aRow === bRow && Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1;\n unionIsBar.set(u.id, adjacent);\n const edgeId = UNION_REL_ID_BASE + u.id;\n if (adjacent) {\n const [leftId, rightId] = colOrThrow(u.personAId) < colOrThrow(u.personBId)\n ? [u.personAId, u.personBId]\n : [u.personBId, u.personAId];\n const dipLevel = unionDipLevel.get(u.id) ?? 0;\n planned.push({\n kind: \"union-bar\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n annotated: u.annotated ?? false,\n build: () => {\n const cy = geo.cy(rowOfPerson.get(leftId)!);\n if (dipLevel === 0) {\n // First bar of the chain: the classic straight bar at glyph-center cy.\n return [\n { x: geo.glyphRight(leftId), y: cy },\n { x: geo.glyphLeft(rightId), y: cy },\n ];\n }\n // Dipped bar: stub-down from each partner's glyph BOTTOM to the dipped Y, across.\n // The stubs leave the glyph bottom OFFSET toward the partner (left partner →\n // right-of-center, right partner → left-of-center), so a person in two serial\n // unions (one on each side) gets two distinct stub columns that never overlap.\n const y = geo.unionDipY(rowOfPerson.get(leftId)!, dipLevel);\n const bottom = cy + NODE_SIZE / 2;\n const lx = geo.cx(colOrThrow(leftId)) + STUB_X_OFF; // partner is to the right\n const rx = geo.cx(colOrThrow(rightId)) - STUB_X_OFF; // partner is to the left\n return [\n { x: lx, y: bottom },\n { x: lx, y },\n { x: rx, y },\n { x: rx, y: bottom },\n ];\n },\n });\n } else {\n const sameRow = aRow === bRow;\n const build = sameRow\n ? planUConnector(u.personAId, u.personBId)\n : (() => {\n const [up, lo] = aRow < bRow ? [u.personAId, u.personBId] : [u.personBId, u.personAId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"union-elbow\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n annotated: u.annotated ?? false,\n build,\n });\n }\n }\n\n // 2b. Descents. Decide, per child, the single declared COUPLE pair (if any) whose\n // union is an adjacent bar; that pair gets the shared sibling-bar descent, every\n // other declared genitor gets a dotted lone descent. No declared couple → all\n // dotted (Caso B / co-parental): each genitor its own descent, never a bar.\n const coupleChildrenByUnion = new Map<number, number[]>(); // union id → children\n const loneLinks: LayoutLink[] = [];\n for (const childId of [...parentsOf.keys()].sort((a, b) => a - b)) {\n const parents = [...parentsOf.get(childId)!].sort((a, b) => a - b);\n const couplePairUnions = parents\n .flatMap((p, i) => parents.slice(i + 1).map((q) => coupleByPair.get(pairKey(p, q))))\n .filter((u): u is Union => u !== undefined && unionIsBar.get(u.id) === true);\n if (couplePairUnions.length === 1) {\n const u = couplePairUnions[0]!;\n const arr = coupleChildrenByUnion.get(u.id) ?? [];\n arr.push(childId);\n coupleChildrenByUnion.set(u.id, arr);\n const couplePeople = new Set([u.personAId, u.personBId]);\n for (const p of parents) if (!couplePeople.has(p)) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n } else {\n for (const p of parents) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n }\n }\n\n // Couple descents (processed first, by union id): one shared sibling-bar per child-row\n // group, a center spine from the bar, and a vertical drop to each child's glyph TOP.\n for (const u of coupleUnions) {\n const children = coupleChildrenByUnion.get(u.id);\n if (children === undefined || children.length === 0) continue;\n const leftId = colOrThrow(u.personAId) < colOrThrow(u.personBId) ? u.personAId : u.personBId;\n const interGutter = colOrThrow(leftId); // gutter between the two adjacent partners\n const parentRow = rowOfPerson.get(u.personAId)!;\n // A couple descent must leave the union BAR, so on a dipped (serial-union) bar the\n // spine starts at the dipped bar's Y, not the glyph-center cy (FIX B).\n const uDipLevel = unionDipLevel.get(u.id) ?? 0;\n const spineStartY = (): number =>\n uDipLevel === 0 ? geo.cy(parentRow) : geo.unionDipY(parentRow, uDipLevel);\n // Group children by their row (almost always one row).\n const byChildRow = new Map<number, number[]>();\n for (const c of children) {\n const cr = rowOfPerson.get(c)!;\n (byChildRow.get(cr) ?? byChildRow.set(cr, []).get(cr)!).push(c);\n }\n for (const childRow of [...byChildRow.keys()].sort((a, b) => a - b)) {\n const groupKids = byChildRow.get(childRow)!.sort((a, b) => colOrThrow(a) - colOrThrow(b));\n // Corridor just above the child row; clamped in-range so a degenerate \"couple + child\n // all on generation 0\" (childRow === 0) routes in band 0 instead of corridor[-1]\n // (undefined) — defensive, no fixture triggers it (FIX D-2).\n const corridor = Math.max(0, Math.min(rowCount - 1, childRow - 1));\n // The descent lives in ONE corridor lane shared by the spine, sibling bar and the\n // child drops, spanning the spine column and every child column.\n const sibSpan = (): number[] => [geo.gutterCenterX(interGutter), ...groupKids.map((c) => geo.cx(colOrThrow(c)))];\n const sibReq: CorridorReq = {\n corridor,\n xRange: () => {\n const xs = sibSpan();\n return [Math.min(...xs), Math.max(...xs)];\n },\n lane: 0,\n };\n corridorReqs.push(sibReq);\n const spineReq: GutterReq = {\n gutter: interGutter,\n side: 0,\n rowLo: Math.min(parentRow, corridor + 0.5), // ordered (FIX D-2): never inverted\n rowHi: Math.max(parentRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(spineReq);\n const aId = (c: number): number => linkOf.get(`${u.personAId}>${c}`)!.edgeId;\n // The A-side element (spine / sibling-bar / single-child elbow) carries the SAME\n // A-side link(s) its relIds/titles track, so its annotation must come from THAT link —\n // hardcoding false silently drops the marker for a child of a couple (B-side drop\n // propagates; A-side did not). Mirrors childDrop's `annotated: link.annotated`.\n const aLinkAnnotated = (c: number): boolean => linkOf.get(`${u.personAId}>${c}`)!.annotated ?? false;\n // A child drop represents ONE declared parentage link (the given parent → c). Its\n // data-edge-id AND its <title> both come from THAT link, so the verbatim parentage\n // (incl. any quality word) matches what the drop's id declares (FIX C-1) — never a\n // hardcoded B-side title under an A-side id.\n const childDrop = (c: number, parentId: number): void => {\n const link = linkOf.get(`${parentId}>${c}`)!;\n const edgeId = link.edgeId;\n const arr = newArrival(c); // couples are processed first → claims the CENTER slot\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: null,\n toPersonId: c,\n titles: [linkTitle(link)],\n lineStyle: \"plain\",\n annotated: link.annotated,\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const x = geo.cx(colOrThrow(c)) + arrivalOffset(arr.slot, arrivalCount.get(c) ?? 1);\n return [\n { x, y },\n { x, y: geo.cy(rowOfPerson.get(c)!) - NODE_SIZE / 2 },\n ];\n },\n });\n };\n\n if (groupKids.length === 1) {\n // Single child: spine + bar-to-child is ONE elbow (parent A's link), the drop is\n // the other (parent B's link) — exactly two data-edge-id groups, one per declared\n // parentage (the verify-sweep 1:1 traceability contract), same pixels as a bar.\n const c = groupKids[0]!;\n planned.push({\n kind: \"descent\",\n relIds: [aId(c)],\n edgeId: aId(c),\n fromPersonId: null,\n toPersonId: null,\n titles: [linkTitle(linkOf.get(`${u.personAId}>${c}`)!)],\n lineStyle: \"plain\",\n annotated: aLinkAnnotated(c),\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const sx = geo.gutterCenterX(interGutter);\n const cx = geo.cx(colOrThrow(c));\n return [\n { x: sx, y: spineStartY() },\n { x: sx, y: sy },\n { x: cx, y: sy },\n ];\n },\n });\n childDrop(c, u.personBId);\n } else {\n // ≥2 children: one shared sibling bar + one spine + a drop per child. Each child's\n // drop carries its B-side parentage id; the sibling bar carries A[0] (and traces\n // every remaining A-side link in relIds), the spine carries A[1] — distinct\n // data-edge-id per group, every declared link present in relIds.\n const aLinks = groupKids.map((c) => aId(c));\n // The verbatim A-side parentage title for child c (incl. any quality word).\n const aLinkTitle = (c: number): string => linkTitle(linkOf.get(`${u.personAId}>${c}`)!);\n planned.push({\n kind: \"sibling-bar\",\n relIds: [aLinks[0]!, ...aLinks.slice(2)],\n edgeId: aLinks[0]!,\n fromPersonId: null,\n toPersonId: null,\n // Carry the verbatim title of EVERY A-side link this bar represents, so no\n // declared quality word is dropped from the drawn element (FIX C-2 / SPEC inv #4).\n titles: [aLinkTitle(groupKids[0]!), ...groupKids.slice(2).map(aLinkTitle)],\n lineStyle: \"plain\",\n annotated: [groupKids[0]!, ...groupKids.slice(2)].some(aLinkAnnotated),\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const xs = sibSpan();\n return [\n { x: Math.min(...xs), y },\n { x: Math.max(...xs), y },\n ];\n },\n });\n planned.push({\n kind: \"descent\",\n relIds: [aLinks[1]!],\n edgeId: aLinks[1]!,\n fromPersonId: null,\n toPersonId: null,\n titles: [aLinkTitle(groupKids[1]!)], // the A-side link this spine carries, verbatim\n lineStyle: \"plain\",\n annotated: aLinkAnnotated(groupKids[1]!),\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const x = geo.gutterCenterX(interGutter);\n return [\n { x, y: spineStartY() },\n { x, y: sy },\n ];\n },\n });\n for (const c of groupKids) childDrop(c, u.personBId);\n }\n }\n }\n\n // Lone / co-parental descents (dotted), by edge id (real before promoted, deterministic).\n for (const l of [...loneLinks].sort((a, b) => a.edgeId - b.edgeId)) {\n const edgeId = l.edgeId;\n const pRow = rowOfPerson.get(l.parentId)!;\n const cRow = rowOfPerson.get(l.childId)!;\n const build = pRow === cRow\n ? planUConnector(l.parentId, l.childId)\n : planConnector(l.parentId, l.childId, false);\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: l.parentId,\n toPersonId: l.childId,\n titles: [linkTitle(l)],\n lineStyle: \"plain\",\n dotted: true,\n annotated: l.annotated,\n build,\n });\n }\n\n // 2c. Bonds (free-text relationships), with the honesty-safe merge: same unordered\n // pair AND same computed lineStyle merge into one drawn element; different styles\n // draw separately (merging would have to pick one side's style).\n const bondGroups = new Map<string, { relIds: number[]; titles: string[]; style: EdgeLineStyle; aId: number; bId: number; annotated: boolean }>();\n for (const r of bondRels) {\n const style = qualityLineStyle(r.quality, opts.qualityLexicon);\n const lo = Math.min(r.fromPersonId, r.toPersonId);\n const hi = Math.max(r.fromPersonId, r.toPersonId);\n const key = `${lo}|${hi}|${style}`;\n const title = r.quality !== null ? `${r.type} · ${r.quality}` : r.type;\n const g = bondGroups.get(key);\n if (g === undefined) {\n bondGroups.set(key, { relIds: [r.id], titles: [title], style, aId: r.fromPersonId, bId: r.toPersonId, annotated: r.annotated ?? false });\n } else {\n g.relIds.push(r.id);\n g.titles.push(title);\n if (r.annotated) g.annotated = true; // any annotated member → whole group annotated\n }\n }\n const bondList = [...bondGroups.values()].sort((a, b) => Math.max(...a.relIds) - Math.max(...b.relIds));\n for (const g of bondList) {\n const aRow = rowOfPerson.get(g.aId)!;\n const bRow = rowOfPerson.get(g.bId)!;\n const build = aRow === bRow\n ? planUConnector(g.aId, g.bId)\n : (() => {\n const [up, lo] = aRow < bRow ? [g.aId, g.bId] : [g.bId, g.aId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"bond\",\n relIds: g.relIds,\n edgeId: Math.max(...g.relIds),\n fromPersonId: g.aId,\n toPersonId: g.bId,\n titles: g.titles,\n lineStyle: g.style,\n annotated: g.annotated,\n build,\n });\n }\n\n // ── Pass 3: staged geometry so corridor lanes are allocated on EXACT pixel x ───────\n // Mutable geometry state, filled stage by stage; the build/xRange closures (created in\n // Pass 2) read it through `geo` at call time only — never before its stage fills it.\n const colCenterX: number[] = [];\n const colLeftX: number[] = [];\n const colRightX: number[] = [];\n const rowCenterY: number[] = [];\n const rowLabelTopY: number[] = [];\n const corridorTopY: number[] = [];\n const dims = { width: 0 };\n const gutterLaneCount = new Map<string, number>(); // `${gutter}:${side}` → count\n const corridorLaneCount: number[] = Array.from({ length: rowCount }, () => 0);\n const laneCount = (gutter: number, side: -1 | 0 | 1): number => gutterLaneCount.get(`${gutter}:${side}`) ?? 0;\n\n const geo = {\n cx: (c: number): number => colCenterX[c]!,\n cy: (r: number): number => rowCenterY[r]!,\n glyphRight: (id: number): number => colCenterX[colOrThrow(id)]! + NODE_SIZE / 2,\n glyphLeft: (id: number): number => colCenterX[colOrThrow(id)]! - NODE_SIZE / 2,\n gutterCenterX: (g: number): number => {\n const left = g < 0 ? PADDING : colRightX[g]!;\n const right = g >= colCount - 1 ? dims.width - PADDING : colLeftX[g + 1]!;\n return (left + right) / 2;\n },\n gutterLaneX: (req: GutterReq): number => {\n const left = req.gutter < 0 ? PADDING : colRightX[req.gutter]!;\n const right = req.gutter >= colCount - 1 ? dims.width - PADDING : colLeftX[req.gutter + 1]!;\n const lCount = laneCount(req.gutter, -1);\n if (req.side === -1) return left + (req.lane + 1) * LANE_H; // hug left, stack rightward\n if (req.side === 0) return left + (lCount + req.lane + 1) * LANE_H; // center group (spine)\n return right - (req.lane + 1) * LANE_H; // hug right, stack leftward\n },\n corridorLaneY: (req: CorridorReq): number =>\n corridorTopY[req.corridor]! + CORRIDOR_BASE / 2 + req.lane * LANE_H,\n /** Y of a dipped serial-union bar (level ≥ 1): below the row's glyph bottom edge. */\n unionDipY: (r: number, level: number): number =>\n rowCenterY[r]! + NODE_SIZE / 2 + level * UNION_STAGGER,\n };\n\n // Stage 1 — gutter lanes: per (gutter, side), by row-span interval. Left-hug and\n // right-hug stacks sit on opposite sides; the center group is the union spine.\n const gutterGroups = new Map<string, GutterReq[]>();\n for (const req of gutterReqs) {\n const k = `${req.gutter}:${req.side}`;\n (gutterGroups.get(k) ?? gutterGroups.set(k, []).get(k)!).push(req);\n }\n for (const [k, reqs] of gutterGroups) {\n gutterLaneCount.set(\n k,\n allocateLanes(reqs.map((req) => ({ lo: req.rowLo, hi: req.rowHi, set: (lane: number) => (req.lane = lane) }))),\n );\n }\n\n // Stage 2 — column geometry from gutter lane counts (+ the isolated extra gutter).\n const gutterWidth = (g: number): number => {\n const lanes = laneCount(g, -1) + laneCount(g, 0) + laneCount(g, 1);\n const extra = g === isolatedTailCol - 1 ? ISOLATED_GUTTER_EXTRA : 0;\n if (g === -1 || g === colCount - 1) return lanes > 0 ? COL_PAD + lanes * LANE_H + extra : extra;\n return COL_PAD + lanes * LANE_H + extra;\n };\n let cursorX = PADDING + gutterWidth(-1);\n for (let c = 0; c < colCount; c++) {\n colLeftX[c] = cursorX;\n colCenterX[c] = cursorX + colWidth[c]! / 2;\n cursorX += colWidth[c]!;\n colRightX[c] = cursorX;\n cursorX += gutterWidth(c);\n }\n dims.width = cursorX + PADDING;\n\n // Stage 3 — corridor lanes on EXACT pixel x-ranges (columns are now placed, so a\n // within-one-gutter span is measured precisely — no collapsing u-index proxy).\n const corridorGroups = new Map<number, CorridorReq[]>();\n for (const req of corridorReqs) (corridorGroups.get(req.corridor) ?? corridorGroups.set(req.corridor, []).get(req.corridor)!).push(req);\n for (const [k, reqs] of corridorGroups) {\n corridorLaneCount[k] = allocateLanes(\n reqs.map((req) => {\n const [lo, hi] = req.xRange();\n return { lo, hi, set: (lane: number) => (req.lane = lane) };\n }),\n );\n }\n\n // Stage 4 — row geometry from corridor lane counts.\n const corridorHeight = (k: number): number => {\n const lanes = corridorLaneCount[k] ?? 0;\n if (lanes > 0) return CORRIDOR_BASE + lanes * LANE_H;\n return k < rowCount - 1 ? CORRIDOR_BASE : 0; // interior rows always keep a gap\n };\n // Reserve a band BELOW each row's glyphs for its dipped serial-union bars (FIX B), so\n // labels sit below the deepest dip and never collide. 0 when the row has no remarriage.\n const rowDipReserve = (r: number): number =>\n rowDipLevels[r]! > 0 ? rowDipLevels[r]! * UNION_STAGGER + 6 : 0;\n let cursorY = PADDING;\n for (let r = 0; r < rowCount; r++) {\n rowCenterY[r] = cursorY + NODE_SIZE / 2;\n rowLabelTopY[r] = cursorY + NODE_SIZE + rowDipReserve(r) + LABEL_GAP_TOP;\n cursorY = rowLabelTopY[r]! + rowMaxLines[r]! * LABEL_LINE_H;\n corridorTopY[r] = cursorY;\n cursorY += corridorHeight(r);\n }\n const width = dims.width;\n const height = cursorY + PADDING;\n\n // ── Build nodes + finalize elements ──────────────────────────────────────────────\n const nodes: GenogramNode[] = [...people]\n .sort((a, b) => a.id - b.id)\n .map((p) => {\n const m = measured.get(p.id)!;\n const r = rowOfPerson.get(p.id)!;\n const c = colOrThrow(p.id);\n return {\n personId: p.id,\n label: p.label,\n shape: shapeForSex(p.sex),\n deceased: p.deceased,\n annotated: p.annotated ?? false,\n cx: colCenterX[c]!,\n cy: rowCenterY[r]!,\n size: NODE_SIZE,\n labelLines: m.lines,\n labelTop: rowLabelTopY[r]!,\n };\n });\n\n const elements: GenogramElement[] = planned.map((pl) => ({\n kind: pl.kind,\n relIds: pl.relIds,\n edgeId: pl.edgeId,\n fromPersonId: pl.fromPersonId,\n toPersonId: pl.toPersonId,\n points: pl.build(),\n titles: pl.titles,\n lineStyle: pl.lineStyle,\n annotated: pl.annotated,\n ...(pl.unionStyle !== undefined ? { unionStyle: pl.unionStyle } : {}),\n ...(pl.dotted ? { dotted: true } : {}),\n }));\n\n // People with no drawn connection (only-suppressed/derived ties, or none at all).\n const isolatedPersonIds = people\n .filter((p) => isIsolated(p.id))\n .map((p) => p.id)\n .sort((a, b) => a - b);\n\n return { width, height, nodes, elements, isolatedPersonIds };\n}\n\n/** Linearize a connected couple-component so partners land adjacent. A simple path is\n * walked from its lowest-id endpoint (→ a clean chain); anything else is DFS-ordered\n * from the lowest id (hub gets two adjacent partners; the rest become union-elbows). */\nfunction linearizeBlock(comp: number[], adj: Map<number, number[]>): number[] {\n if (comp.length <= 1) return [...comp];\n const inComp = new Set(comp);\n const degree = (id: number): number => adj.get(id)!.filter((n) => inComp.has(n)).length;\n const endpoints = comp.filter((id) => degree(id) === 1).sort((a, b) => a - b);\n const edgeCount = comp.reduce((s, id) => s + degree(id), 0) / 2;\n const isPath = edgeCount === comp.length - 1 && endpoints.length === 2;\n const order: number[] = [];\n const seen = new Set<number>();\n if (isPath) {\n let cur: number | undefined = endpoints[0]!;\n while (cur !== undefined) {\n order.push(cur);\n seen.add(cur);\n cur = adj.get(cur)!.filter((n) => inComp.has(n)).sort((a, b) => a - b).find((n) => !seen.has(n));\n }\n return order;\n }\n const stack = [Math.min(...comp)];\n while (stack.length > 0) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n order.push(n);\n for (const m of adj.get(n)!.filter((x) => inComp.has(x)).sort((a, b) => b - a)) {\n if (!seen.has(m)) stack.push(m);\n }\n }\n return order;\n}\n","// Genogram SVG emitter — turns a computed GenogramLayout (./layout.ts, the pure\n// orthogonal declared-generation layout) into a SELF-CONTAINED SVG string.\n//\n// Two hard requirements:\n// - XML-ESCAPING of EVERY interpolated text. Labels are author-controlled and the\n// SVG string may be injected via innerHTML in a browser or embedded as vectors in\n// a PDF — an unescaped label is an XSS/`</svg>`-breakout vector on every surface.\n// - LITERAL presentation attributes (hex colors, inline stroke-dasharray, an explicit\n// font-family). A standalone SVG inside a PDF has no stylesheet, no `currentColor`.\n//\n// It is deliberately PURE (string in, string out) and DETERMINISTIC (same layout → same\n// SVG), and it draws EXACTLY what the layout computed: node centers and the routed\n// orthogonal polylines are consumed verbatim, never recomputed (the overlap harness\n// proves the layout; this emitter is pinned to it). Decoration hooks for callers: one\n// `<g data-individual-id=\"p<id>\">` per person with a direct-child `<title>` and bare\n// rect/circle/polygon glyph; `data-edge-id` on every routed group.\n//\n// HONESTY RULE: presentation only. There is ZERO text on map edges — the verbatim\n// \"type · quality\" / status label lives in each routed group's <title> (and the\n// caller's side lists). The one styling decision the CALLER may make is\n// `unionStyleByRelId`: a per-edge VISUAL override applied at emission — a\n// stroke-dasharray and/or McGoldrick status slashes — giving each declared union TYPE\n// the full notation (married solid, cohabiting/dating dashed, separated one slash,\n// divorced two) without the layout fabricating any quality text.\nimport { FONT_FAMILY, LEGEND_SWATCH_W, annotationDot, annotationSwatch, annotationTick, legendBlock, xmlEscape, type LegendEntry } from \"../core\";\nimport {\n EDGE_STROKE,\n LABEL_FONT,\n LABEL_LINE_H,\n type GenogramElement,\n type GenogramLayout,\n type NodeShape,\n type Point,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { GENOGRAM_SVG_LABELS_EN, type GenogramSvgLabels } from \"./labels\";\n\n// Re-export so callers can reach the union-notation type through the emitter module.\nexport type { UnionEdgeStyle } from \"./layout\";\nexport { xmlEscape };\n\n// Literal ink colors (zinc ramp, matching the app shell on white — the PDF page).\nconst GLYPH_STROKE = \"#52525b\";\nconst NODE_LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Structural (union / descent / sibling-bar) stroke — neutral, solid.\nconst STRUCT_WIDTH = 1.5;\nconst STRUCT_OPACITY = 0.75;\n// Dotted descent (lone-parent / co-parental): the visual kin of schematex's secondary.\nconst DOTTED_DASH: readonly [number, number] = [2, 3];\nconst DOTTED_OPACITY = 0.55;\n\n// Legend row geometry + the used-keys-only block now come from core (`legendBlock`);\n// only the glyph/line swatch closures below stay module-specific (LEGEND_SWATCH_W from\n// core sizes them). The legend ink (#52525b) is the core LEGEND_TEXT_FILL, identical to\n// this emitter's GLYPH_STROKE — so migrating onto core changes zero bytes.\n\nexport interface GenogramSvgOptions {\n /**\n * Per-edge VISUAL union style (edgeId → {dash?, slashes?}), applied at emission.\n * Gives each declared union TYPE its own McGoldrick notation. Overrides any\n * `unionStyle` already on the element.\n */\n unionStyleByRelId?: ReadonlyMap<number, UnionEdgeStyle>;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: GenogramSvgLabels;\n /**\n * Legend label for annotated elements. When provided AND at least one element or node is\n * annotated, a legend row is added (used-keys-only). The library supplies no default —\n * the caller owns the wording (domain-agnostic).\n */\n annotationLabel?: string;\n}\n\n/** Glyph markup for one shape centered at (cx, cy) with the given half-size. */\nfunction glyphSvg(shape: NodeShape, cx: number, cy: number, half: number): string {\n const stroke = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n if (shape === \"square\") {\n return `<rect x=\"${cx - half}\" y=\"${cy - half}\" width=\"${half * 2}\" height=\"${half * 2}\" rx=\"4\" ${stroke}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${stroke}/>`;\n }\n return `<polygon points=\"${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}\" ${stroke}/>`;\n}\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\n/** The longest horizontal segment of a polyline (for placing union-elbow slashes). */\nfunction longestHSegment(points: Point[]): [Point, Point] {\n let best: [Point, Point] = [points[0]!, points[points.length - 1]!];\n let bestLen = -1;\n for (let i = 0; i + 1 < points.length; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n if (a.y === b.y) {\n const len = Math.abs(b.x - a.x);\n if (len > bestLen) {\n bestLen = len;\n best = [a, b];\n }\n }\n }\n return best;\n}\n\n/**\n * McGoldrick status slashes at the midpoint of a segment (1 = separação, 2 = divórcio),\n * drawn in screen-space \"/\" orientation and offset along the segment for the two divorce\n * strokes. Same ink/width as the bar so the mark reads as part of it.\n */\nfunction slashMarks(a: Point, b: Point, count: 1 | 2, width: number): string {\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n const HALF = 7; // slash half-length\n const STEP = 4; // along-segment offset between the two divorce slashes\n const offsets = count === 1 ? [0] : [-STEP, STEP];\n return offsets\n .map((o) => {\n const px = mx + ux * o;\n const py = my + uy * o;\n return `<line x1=\"${px - HALF}\" y1=\"${py + HALF}\" x2=\"${px + HALF}\" y2=\"${py - HALF}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\"/>`;\n })\n .join(\"\");\n}\n\n/** Resolve a union element's effective McGoldrick style (override wins over element). */\nfunction resolveUnionStyle(\n el: GenogramElement,\n override: ReadonlyMap<number, UnionEdgeStyle>,\n): UnionEdgeStyle {\n return override.get(el.edgeId) ?? el.unionStyle ?? {};\n}\n\n/** Emits one routed element as a `<g data-edge-id>` group (≥3 points → path, else line),\n * with the verbatim titles in a <title> and ZERO text. */\nfunction elementSvg(el: GenogramElement, override: ReadonlyMap<number, UnionEdgeStyle>): string {\n const title = `<title>${xmlEscape(el.titles.join(\"\\n\"))}</title>`;\n const pts = el.points;\n const drawLine = (dash: readonly [number, number] | null, width: number, opacity: number): string => {\n const dashAttr = dash === null ? \"\" : ` stroke-dasharray=\"${dash[0]} ${dash[1]}\"`;\n if (pts.length === 2) {\n return `<line x1=\"${pts[0]!.x}\" y1=\"${pts[0]!.y}\" x2=\"${pts[1]!.x}\" y2=\"${pts[1]!.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n }\n return `<path d=\"${pathData(pts)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n };\n\n const tick = el.annotated ? annotationTick(el.points) : \"\";\n\n if (el.kind === \"union-bar\" || el.kind === \"union-elbow\") {\n const style = resolveUnionStyle(el, override);\n const body: string[] = [drawLine(style.dash ?? null, STRUCT_WIDTH, STRUCT_OPACITY)];\n const slashes = style.slashes ?? 0;\n if (slashes === 1 || slashes === 2) {\n // A straight 2-point bar uses its own segment; a dipped serial-union bar (3-seg\n // elbow, FIX B) and any union-elbow ride the LONGEST horizontal segment so the\n // separado/divorciado slashes land on the across part, never on a vertical stub.\n const [a, b] = pts.length === 2 ? [pts[0]!, pts[1]!] : longestHSegment(pts);\n body.push(slashMarks(a, b, slashes, STRUCT_WIDTH));\n }\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body.join(\"\")}${tick}</g>`;\n }\n\n if (el.kind === \"descent\" || el.kind === \"sibling-bar\") {\n const dash = el.dotted ? DOTTED_DASH : null;\n const opacity = el.dotted ? DOTTED_OPACITY : STRUCT_OPACITY;\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(dash, STRUCT_WIDTH, opacity)}${tick}</g>`;\n }\n\n // bond\n const ink = EDGE_STROKE[el.lineStyle];\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(ink.dash, ink.width, ink.opacity)}${tick}</g>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed genogram layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal; there is NO text on map edges.\n */\nexport function genogramLayoutSvg(layout: GenogramLayout, opts: GenogramSvgOptions = {}): string {\n const override = opts.unionStyleByRelId ?? new Map<number, UnionEdgeStyle>();\n const labels = opts.labels ?? GENOGRAM_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // ── Routed elements first so nodes sit on top (same stacking as the JSX render). ───\n for (const el of layout.elements) parts.push(elementSvg(el, override));\n\n // ── Nodes: glyph + deceased mark + wrapped label, hook-compatible with schematex. ─\n for (const node of layout.nodes) {\n const half = node.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(node.label)}</title>`,\n glyphSvg(node.shape, node.cx, node.cy, half),\n ];\n if (node.deceased) {\n pieces.push(\n `<line x1=\"${node.cx - half}\" y1=\"${node.cy - half}\" x2=\"${node.cx + half}\" y2=\"${node.cy + half}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n );\n }\n if (node.annotated) {\n pieces.push(annotationDot(node.cx + 0.7 * half, node.cy - 0.7 * half));\n }\n const tspans = node.labelLines\n .map(\n (line, i) =>\n `<tspan x=\"${node.cx}\" y=\"${node.labelTop + 10 + i * LABEL_LINE_H}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${LABEL_FONT}\" fill=\"${NODE_LABEL_FILL}\">${tspans}</text>`,\n );\n parts.push(`<g data-individual-id=\"p${node.personId}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal pt-BR legend: only entries actually used. ──────────────────────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: LegendEntry[] = [];\n\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({\n swatch: (x, y) => glyphSvg(shape, x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.shapes[shape],\n });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({\n swatch: (x, y) =>\n glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6) +\n `<line x1=\"${x + LEGEND_SWATCH_W / 2 - 6}\" y1=\"${y - 6}\" x2=\"${x + LEGEND_SWATCH_W / 2 + 6}\" y2=\"${y + 6}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n label: labels.deceased,\n });\n }\n\n // NOTE (deliberate, gate-tested): the fallback legend carries NO union-TYPE or\n // dotted-descent entry. Each declared union's type and each co-parenthood fact lives\n // VERBATIM in the element's <title> and in the dossier's structured side lists (the\n // psychologist's authoritative reading) — duplicating it as a legend key is the\n // \"known, documented gap\" pinned by test/verify-pdf.test.ts §(e). The dash/slash\n // notation itself stays on the drawn bars; only the legend stays minimal.\n\n // Bond styles actually used.\n const stylesUsed = new Set(layout.elements.filter((e) => e.kind === \"bond\").map((e) => e.lineStyle));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n\n // Unconnected glyphs (a person whose only declared tie is derived kinship like \"minha\n // tia\" — read from the tree, never a line — or who was mentioned with no tie at all)\n // sit grouped to the side with NO connector. This entry labels that group so a loose\n // glyph is never left unexplained; the verbatim tie still lives in the dossier list.\n if (layout.isolatedPersonIds.length > 0) {\n entries.push({\n swatch: (x, y) => glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.isolated,\n });\n }\n\n // Annotation marker — only when the caller supplied a label AND at least one element/node is annotated.\n if (\n opts.annotationLabel !== undefined &&\n (layout.nodes.some((n) => n.annotated) || layout.elements.some((e) => e.annotated))\n ) {\n entries.push({\n swatch: (x, y) => annotationSwatch(x, y),\n label: opts.annotationLabel,\n });\n }\n\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call genogram render: input → self-contained SVG string. Thin, honest wiring:\n// dedupe unions per pair, compute the pure layout, give each declared union TYPE its\n// McGoldrick notation as a per-edge visual override, emit. Callers needing finer\n// control use computeGenogramLayout + genogramLayoutSvg directly.\n\nimport {\n UNION_REL_ID_BASE,\n computeGenogramLayout,\n type GenogramLayout,\n type GenogramLayoutOptions,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { genogramLayoutSvg } from \"./svg\";\nimport type { GenogramSvgLabels } from \"./labels\";\nimport type { GenogramInput, Union, UnionStatus } from \"./types\";\n\n/** Shared 6,4 dash for every cohabiting-flavoured union (cohabiting / dating /\n * type-not-stated), so non-marital couples read consistently. */\nconst COUPLE_DASH = [6, 4] as const;\n\n/**\n * McGoldrick notation per declared union TYPE — a per-edge VISUAL override applied at\n * emission, never a synthesized quality. `coparental` is ABSENT on purpose: it draws\n * NO couple element at all; the co-parenthood shows only on the descents converging\n * on the child(ren).\n */\nexport const UNION_NOTATION: Record<Exclude<UnionStatus, \"coparental\">, UnionEdgeStyle> = {\n married: {}, // solid bar\n cohabiting: { dash: COUPLE_DASH },\n dating: { dash: COUPLE_DASH },\n unknown: { dash: COUPLE_DASH },\n separated: { slashes: 1 }, // solid + one diagonal slash\n divorced: { slashes: 2 }, // solid + two parallel slashes\n};\n\n/**\n * Duplicate unions for the same unordered pair should not exist (callers are expected\n * to normalize), but if they do, the HIGHEST id wins — the most recent statement.\n * NEVER a status-rank heuristic: recency is a fact, ranking would be an interpretation.\n */\nexport function latestUnionPerPair(unions: Union[]): Union[] {\n const byPair = new Map<string, Union>();\n for (const u of [...unions].sort((a, b) => a.id - b.id)) {\n const key = `${Math.min(u.personAId, u.personBId)}|${Math.max(u.personAId, u.personBId)}`;\n byPair.set(key, u);\n }\n return [...byPair.values()].sort((a, b) => a.id - b.id);\n}\n\nexport interface GenogramRenderOptions extends GenogramLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: GenogramSvgLabels;\n /**\n * Verbatim legend label for caller-declared `annotated` people/unions/parentage/bonds.\n * When set AND something is annotated, a legend row with the marker glyph + this label is\n * added. compasso never supplies a default — the caller owns the wording (domain-specific).\n */\n annotationLabel?: string;\n}\n\nexport interface GenogramRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: GenogramLayout;\n}\n\n/**\n * Renders a genogram input to a self-contained SVG string. Deterministic: same data →\n * same SVG. Empty `people` yields an empty-but-valid SVG; callers decide their own\n * empty state before calling.\n */\nexport function genogramSvg(\n input: GenogramInput,\n opts: GenogramRenderOptions = {},\n): GenogramRenderResult {\n const ids = new Set(input.people.map((p) => p.id));\n const dedupedUnions = latestUnionPerPair(input.unions).filter(\n (u) => ids.has(u.personAId) && ids.has(u.personBId),\n );\n\n const layout = computeGenogramLayout(\n input.people,\n dedupedUnions,\n input.parentLinks,\n input.relationships,\n opts,\n );\n\n const unionStyleByRelId = new Map<number, UnionEdgeStyle>();\n for (const u of dedupedUnions) {\n if (u.status === \"coparental\") continue; // no element — nothing to style\n unionStyleByRelId.set(UNION_REL_ID_BASE + u.id, UNION_NOTATION[u.status]);\n }\n\n const svg = genogramLayoutSvg(layout, {\n unionStyleByRelId,\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n ...(opts.annotationLabel !== undefined ? { annotationLabel: opts.annotationLabel } : {}),\n });\n return { svg, layout };\n}\n","// Radial ecomap renderer — center node + declared external ties on 1–2 concentric\n// rings, as a SELF-CONTAINED SVG string. Pure (data in, string out), deterministic\n// (same input → same SVG), no DOM, no dependencies.\n//\n// HONESTY RULE: the diagram presents ONLY what the caller declared. A tie's line style\n// is a conservative lexical hint from the author's own quality word (ambiguous/null →\n// neutral solid line, never a synthesized value); an arrowhead appears ONLY when a\n// direction was declared (null = no arrow, never a default). The verbatim text always\n// rides the element's <title>, so a style never replaces what was said.\n//\n// Ring assignment is a deterministic PRESENTATION rule — by input order (sorted by id),\n// alternating rings when the set is large — never by any reading of the tie's content.\n//\n// Every interpolated text passes xmlEscape (labels are author-controlled; the SVG may\n// be inlined via innerHTML or embedded in a PDF). All presentation attributes are\n// literal: a standalone SVG has no stylesheet. Arrowheads are explicit polygons, NOT\n// <marker> defs — marker support is unreliable in SVG-to-PDF embedders, and inline\n// polygons also avoid def-id collisions when several SVGs share one document.\n\nimport {\n EDGE_STROKE,\n FONT_FAMILY,\n LEGEND_SWATCH_W,\n annotationDot,\n annotationSwatch,\n clampLabel,\n estimateTextWidth,\n legendBlock,\n qualityLineStyle,\n wrapLabelBalanced,\n xmlEscape,\n type EdgeLineStyle,\n type LegendEntry,\n type QualityLexicon,\n} from \"../core\";\n\n// ── Input model ───────────────────────────────────────────────────────────────\n\n/** Declared flow of the tie, relative to the CENTER: \"in\" = toward the center. */\nexport type EcomapDirection = \"in\" | \"out\" | \"both\";\n\n/**\n * One declared tie between the center (person/household) and an external system\n * (work, faith, friends, healthcare…). `label` is the author's own naming, kept\n * verbatim. `quality` is the author's verbatim wording about the tie (null = not\n * declared = neutral line). `direction` follows the same doctrine: null = no arrow.\n */\nexport interface EcomapTie {\n id: number;\n label: string;\n quality: string | null;\n direction: EcomapDirection | null;\n /** Optional verbatim <title> override (defaults to \"label · quality\"). */\n title?: string;\n /**\n * Caller-asserted flag: this tie was annotated (e.g. edited by a professional).\n * compasso never interprets this — it only draws a neutral marker and, when\n * `annotationLabel` is supplied, adds a legend row. Default undefined = not annotated.\n */\n annotated?: boolean;\n}\n\nexport interface EcomapInput {\n /** Center node label (e.g. the person or household the map is about). */\n centerLabel: string;\n ties: EcomapTie[];\n}\n\n// ── Display vocabulary ────────────────────────────────────────────────────────\n\nexport interface EcomapLabels {\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the neutral solid line (a declared tie with no styled quality). */\n neutralTie: string;\n /** Legend label for the arrowhead (declared direction of the tie). */\n direction: string;\n ariaLabel: string;\n}\n\nexport const ECOMAP_LABELS_EN: EcomapLabels = {\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n neutralTie: \"Declared tie\",\n direction: \"Declared direction of the tie\",\n ariaLabel: \"Ecomap\",\n};\n\nexport interface EcomapSvgOptions {\n /** Display clamp per tie label (verbatim text stays in the <title>). */\n maxLabelChars?: number;\n /** Node label font size (px); default 12. */\n fontSize?: number;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Quality-word lexicon — English default; see `compasso/locales/pt-br`. */\n qualityLexicon?: QualityLexicon;\n /** Display vocabulary — English default; see locale packs. */\n labels?: EcomapLabels;\n /**\n * When provided AND at least one tie has `annotated: true`, a legend row is added\n * with this label (used-keys-only pattern). compasso supplies no default — the caller\n * owns the wording (domain-agnostic).\n */\n annotationLabel?: string;\n}\n\n// ── Geometry constants ────────────────────────────────────────────────────────\n\nconst PADDING = 32;\nconst LINE_H = 14;\nconst NODE_PAD_X = 14;\nconst NODE_PAD_Y = 9;\nconst CENTER_MIN_R = 36;\nconst RING_MIN_R = 150;\n/** Min gap between two adjacent node boxes on the same ring. */\nconst NODE_GAP = 24;\n/** Radial gap between the center circle and the inner ring's nearest box edge. */\nconst RADIAL_GAP = 40;\n/** Radial gap between the two rings when the set is large enough to split. */\nconst RING_GAP = 26;\n/** Above this many ties the layout alternates between two rings. */\nconst SINGLE_RING_MAX = 8;\n\n// Ink (zinc ramp on white — matches the genogram emitter).\nconst NODE_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n// Legend row geometry + the swatch span both live in ../core (LEGEND_SWATCH_W imported\n// above for the swatch closures); the row/text/width/height bookkeeping is legendBlock.\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Internal shapes ───────────────────────────────────────────────────────────\n\ninterface SatNode {\n tie: EcomapTie;\n lines: string[];\n rx: number;\n ry: number;\n /** Filled once ring radii are known. */\n x: number;\n y: number;\n angle: number;\n style: EdgeLineStyle;\n}\n\n/** Arrowhead polygon: tip at (tipX,tipY), pointing along the unit vector (ux,uy). */\nfunction arrowHead(tipX: number, tipY: number, ux: number, uy: number, opacity: number): string {\n const LEN = 9;\n const HALF_W = 4.5;\n const bx = tipX - ux * LEN;\n const by = tipY - uy * LEN;\n const px = -uy;\n const py = ux;\n const points = [\n `${round(tipX)},${round(tipY)}`,\n `${round(bx + px * HALF_W)},${round(by + py * HALF_W)}`,\n `${round(bx - px * HALF_W)},${round(by - py * HALF_W)}`,\n ].join(\" \");\n return `<polygon points=\"${points}\" fill=\"${EDGE_INK}\" fill-opacity=\"${opacity}\"/>`;\n}\n\n/**\n * Renders a declared ecomap to a self-contained SVG string. Deterministic: same data →\n * same SVG. Zero ties yield a valid center-only SVG; callers decide their own empty\n * state before calling. The root keeps numeric width/height attributes plus a matching\n * viewBox (PDF-embedder contract).\n */\nexport function ecomapSvg(input: EcomapInput, opts: EcomapSvgOptions = {}): string {\n const fontSize = opts.fontSize ?? 12;\n const labels = opts.labels ?? ECOMAP_LABELS_EN;\n\n // ── Measure every satellite box (deterministic order: by tie id). ───────────\n const sats: SatNode[] = [...input.ties]\n .sort((a, b) => a.id - b.id)\n .map((tie) => {\n const lines = wrapLabelBalanced(clampLabel(tie.label, opts.maxLabelChars));\n const w = Math.max(...lines.map((l) => estimateTextWidth(l, fontSize))) + NODE_PAD_X * 2;\n const h = lines.length * LINE_H + NODE_PAD_Y * 2;\n return {\n tie,\n lines,\n rx: Math.max(40, w / 2),\n ry: Math.max(20, h / 2),\n x: 0,\n y: 0,\n angle: 0,\n style: qualityLineStyle(tie.quality, opts.qualityLexicon),\n };\n });\n\n const centerLines = wrapLabelBalanced(input.centerLabel);\n const centerR = Math.max(\n CENTER_MIN_R,\n Math.max(...centerLines.map((l) => estimateTextWidth(l, fontSize))) / 2 + 12,\n (centerLines.length * LINE_H) / 2 + 12,\n );\n\n // ── Ring radii: wide enough that NO two node boxes can ever touch. The safe\n // center-to-center distance is the diagonal of the worst-case box pair: if the\n // euclidean distance is ≥ hypot(width-sum, height-sum), the axis-aligned boxes\n // cannot overlap in both axes at once. Overlap-proof by construction, not by luck.\n const n = sats.length;\n const maxRx = n > 0 ? Math.max(...sats.map((s) => s.rx)) : 0;\n const maxRy = n > 0 ? Math.max(...sats.map((s) => s.ry)) : 0;\n const twoRings = n > SINGLE_RING_MAX;\n const stepAngle = n > 0 ? (Math.PI * 2) / n : Math.PI;\n const safeDist = Math.hypot(2 * maxRx + NODE_GAP, 2 * maxRy + NODE_GAP);\n /** Min radius so two nodes `steps` angular steps apart on the SAME ring clear safeDist. */\n const sameRingRadius = (steps: number): number => {\n const theta = steps * stepAngle;\n if (n <= 1 || theta >= Math.PI) return 0; // ≤2 nodes on the ring: no chord constraint\n return safeDist / (2 * Math.sin(theta / 2));\n };\n const ringStep = maxRy * 2 + RING_GAP;\n let innerR = Math.max(\n RING_MIN_R,\n centerR + RADIAL_GAP + maxRy,\n sameRingRadius(twoRings ? 2 : 1),\n );\n if (twoRings) {\n // Cross-ring neighbors sit 1 step apart at radii r and r+ringStep. Their distance\n // sqrt(r² + (r+s)² − 2r(r+s)cosΔ) grows monotonically with r — widen the inner ring\n // in fixed increments until it clears safeDist (deterministic, always terminates).\n const crossDist = (r: number): number =>\n Math.sqrt(r * r + (r + ringStep) ** 2 - 2 * r * (r + ringStep) * Math.cos(stepAngle));\n while (crossDist(innerR) < safeDist) innerR += 8;\n }\n const outerR = innerR + ringStep;\n\n for (let i = 0; i < n; i++) {\n const s = sats[i]!;\n s.angle = -Math.PI / 2 + (i * Math.PI * 2) / n;\n const r = twoRings && i % 2 === 1 ? outerR : innerR;\n s.x = r * Math.cos(s.angle);\n s.y = r * Math.sin(s.angle);\n }\n\n // ── Canvas bounds (center at origin until here), then shift positive. ───────\n let minX = -centerR;\n let minY = -centerR;\n let maxX = centerR;\n let maxY = centerR;\n for (const s of sats) {\n minX = Math.min(minX, s.x - s.rx);\n minY = Math.min(minY, s.y - s.ry);\n maxX = Math.max(maxX, s.x + s.rx);\n maxY = Math.max(maxY, s.y + s.ry);\n }\n const dx = PADDING - minX;\n const dy = PADDING - minY;\n const cx = dx;\n const cy = dy;\n for (const s of sats) {\n s.x += dx;\n s.y += dy;\n }\n let width = maxX - minX + PADDING * 2;\n let height = maxY - minY + PADDING * 2;\n\n const parts: string[] = [];\n\n // ── Tie lines first (nodes sit on top), one group per declared tie. ─────────\n for (const s of sats) {\n const ux = (cx - s.x) / Math.hypot(cx - s.x, cy - s.y);\n const uy = (cy - s.y) / Math.hypot(cx - s.x, cy - s.y);\n // Node-edge endpoint: ellipse boundary along the unit vector toward the center.\n const scale = 1 / Math.hypot(ux / s.rx, uy / s.ry);\n const x1 = s.x + ux * scale;\n const y1 = s.y + uy * scale;\n // Center-edge endpoint: circle boundary along the same direction.\n const x2 = cx - ux * centerR;\n const y2 = cy - uy * centerR;\n\n const ink = EDGE_STROKE[s.style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n const title = s.tie.title ?? (s.tie.quality !== null ? `${s.tie.label} · ${s.tie.quality}` : s.tie.label);\n const body: string[] = [\n `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n ];\n // Arrowheads ONLY for a declared direction. \"in\" points at the center, \"out\" at\n // the external system, \"both\" draws both. Tips back off the boundary so the\n // triangle never pokes into the shape.\n if (s.tie.direction === \"in\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x2, y2, ux, uy, ink.opacity)); // tip at the center edge\n }\n if (s.tie.direction === \"out\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x1, y1, -ux, -uy, ink.opacity)); // tip at the system edge\n }\n parts.push(`<g data-edge-id=\"${s.tie.id}\"><title>${xmlEscape(title)}</title>${body.join(\"\")}</g>`);\n }\n\n // ── Center node. ─────────────────────────────────────────────────────────────\n {\n const tspans = centerLines\n .map(\n (line, i) =>\n `<tspan x=\"${round(cx)}\" y=\"${round(cy - ((centerLines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n parts.push(\n `<g data-individual-id=\"center\"><title>${xmlEscape(input.centerLabel)}</title>` +\n `<circle cx=\"${round(cx)}\" cy=\"${round(cy)}\" r=\"${round(centerR)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"2\"/>` +\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text></g>`,\n );\n }\n\n // ── Satellite nodes. ─────────────────────────────────────────────────────────\n for (const s of sats) {\n const tspans = s.lines\n .map(\n (line, i) =>\n `<tspan x=\"${round(s.x)}\" y=\"${round(s.y - ((s.lines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n const pieces: string[] = [\n `<title>${xmlEscape(s.tie.label)}</title>`,\n `<ellipse cx=\"${round(s.x)}\" cy=\"${round(s.y)}\" rx=\"${round(s.rx)}\" ry=\"${round(s.ry)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"1.5\"/>`,\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text>`,\n ];\n if (s.tie.annotated) {\n pieces.push(annotationDot(s.x + 0.7 * s.rx, s.y - 0.7 * s.ry));\n }\n parts.push(`<g data-individual-id=\"e${s.tie.id}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal legend: only entries actually used. ──────────────────────────────\n if (opts.legend !== false && sats.length > 0) {\n const entries: LegendEntry[] = [];\n\n if (sats.some((s) => s.style === \"plain\")) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${EDGE_STROKE.plain.width}\" stroke-opacity=\"${EDGE_STROKE.plain.opacity}\"/>`,\n label: labels.neutralTie,\n });\n }\n const stylesUsed = new Set(sats.map((s) => s.style));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n if (sats.some((s) => s.tie.direction !== null)) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W - 8}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n arrowHead(x + LEGEND_SWATCH_W, y, 1, 0, 0.75),\n label: labels.direction,\n });\n }\n if (opts.annotationLabel !== undefined && sats.some((s) => s.tie.annotated)) {\n entries.push({\n swatch: (x, y) => annotationSwatch(x, y),\n label: opts.annotationLabel,\n });\n }\n\n if (entries.length > 0) {\n const block = legendBlock(entries, height);\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// Fault-tree input model — declared facts only. compasso draws EXACTLY what the\n// caller declares: every event carries its declared kind (the standard symbol is a\n// semantic claim only the author may make), gates are first-class rows with a declared\n// type and a declared left-to-right input order, and the top event is DECLARED, never\n// derived. Symbol lineage: NUREG-0492 (Fault Tree Handbook, US NRC 1981) distinctive\n// shapes, as permitted by IEC 61025:2006 — the rectangular IEC 60617 family is\n// rejected because its gates would be visually indistinguishable from event rectangles.\n\n/**\n * CLOSED event-kind vocabulary (NUREG-0492 Fig. IV-1):\n * - \"intermediate\": fault event from a logic combination → rectangle (incl. the top);\n * - \"basic\": basic initiating fault, no further development → circle;\n * - \"undeveloped\": not developed further (insufficient consequence/info) → diamond;\n * - \"house\": event normally expected to occur (external/boundary) → house;\n * - \"conditioning\": condition/restriction on an INHIBIT gate → oval (never a tree node);\n * - \"transfer\": transfer-in, subtree developed elsewhere → triangle (a leaf).\n */\nexport const FAULT_TREE_EVENT_KINDS = [\n \"intermediate\",\n \"basic\",\n \"undeveloped\",\n \"house\",\n \"conditioning\",\n \"transfer\",\n] as const;\nexport type FaultTreeEventKind = (typeof FAULT_TREE_EVENT_KINDS)[number];\n\n/**\n * A declared fault-tree event. `label` is verbatim (always kept in the <title>);\n * `code` is a short identifier drawn inside primary-event glyphs (null = none) —\n * matching FTA practice, where primary-event symbols carry identifiers and the\n * descriptions live beside them.\n */\nexport interface FaultTreeEvent {\n id: number;\n kind: FaultTreeEventKind;\n label: string;\n code: string | null;\n /** Optional verbatim <title> override (defaults to \"code · label\"). */\n title?: string;\n}\n\n/**\n * CLOSED gate vocabulary. NOT/NAND/NOR and PRIORITY-AND are deliberately\n * unrepresentable — an unsupported gate is a compile error, never a silent visual\n * fallback (the NOT bubble-triangle would also collide with the transfer triangle).\n */\nexport const GATE_TYPES = [\"and\", \"or\", \"xor\", \"inhibit\", \"vote\"] as const;\nexport type GateType = (typeof GATE_TYPES)[number];\n\ninterface FaultTreeGateBase {\n id: number;\n /** The intermediate event this gate resolves (drawn directly above the gate). */\n eventId: number;\n /** Declared left-to-right reading order — presentation data, honored as given. */\n inputIds: number[];\n}\n\nexport interface AndGate extends FaultTreeGateBase {\n type: \"and\";\n}\nexport interface OrGate extends FaultTreeGateBase {\n type: \"or\";\n}\nexport interface XorGate extends FaultTreeGateBase {\n type: \"xor\";\n}\nexport interface InhibitGate extends FaultTreeGateBase {\n type: \"inhibit\";\n /** Must reference a kind:\"conditioning\" event (drawn as the side oval). */\n conditionId: number;\n}\nexport interface VoteGate extends FaultTreeGateBase {\n type: \"vote\";\n /** Output occurs if ≥ k of the n inputs occur; 1 ≤ k ≤ inputIds.length. */\n k: number;\n}\nexport type FaultTreeGate = AndGate | OrGate | XorGate | InhibitGate | VoteGate;\n\n/** Input to the fault-tree render pipeline. */\nexport interface FaultTreeInput {\n /** Declared top event (must be kind \"intermediate\", never a gate input). */\n topId: number;\n events: FaultTreeEvent[];\n gates: FaultTreeGate[];\n}\n","// Display vocabularies — every human-readable string the fault tree emits, gathered\n// in overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// Gate titles carry the standard gate NAME only (a vote title appends its declared\n// \"k/n\") — the gate's semantics belong to the standard's text, not the SVG.\n\nimport type { FaultTreeEventKind, GateType } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface FaultTreeTitleLabels {\n gates: Record<GateType, string>;\n /** Title of the inhibit-gate → conditioning-oval attachment line. */\n condition: string;\n}\n\nexport const FAULT_TREE_TITLE_LABELS_EN: FaultTreeTitleLabels = {\n gates: {\n and: \"AND gate\",\n or: \"OR gate\",\n xor: \"Exclusive-OR gate\",\n inhibit: \"Inhibit gate\",\n vote: \"Voting gate\",\n },\n condition: \"condition\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface FaultTreeSvgLabels {\n events: Record<FaultTreeEventKind, string>;\n gates: Record<GateType, string>;\n ariaLabel: string;\n}\n\nexport const FAULT_TREE_SVG_LABELS_EN: FaultTreeSvgLabels = {\n events: {\n intermediate: \"Intermediate event\",\n basic: \"Basic event\",\n undeveloped: \"Undeveloped event\",\n house: \"External event (normally occurs)\",\n conditioning: \"Conditioning event\",\n transfer: \"Transfer (developed elsewhere)\",\n },\n gates: {\n and: \"AND gate (all inputs)\",\n or: \"OR gate (any input)\",\n xor: \"Exclusive-OR gate (exactly one input)\",\n inhibit: \"INHIBIT gate (input under condition)\",\n vote: \"Voting gate (k of n)\",\n },\n ariaLabel: \"Fault tree\",\n};\n","// Fault-tree validation — REJECT, never repair. The genogram silently filters\n// dangling references because a family map is elicited incrementally; a fault tree is\n// a safety artifact whose meaning lives in its logic structure, so drawing a\n// structurally invalid tree (or silently altering its logic) is worse than refusing.\n// The standard itself has a notation for \"honestly incomplete\" — the diamond\n// (undeveloped event) and the transfer triangle — and the error messages point there.\n//\n// Every problem is reported, not just the first: issues are aggregated, deduplicated\n// and sorted deterministically (by code, then message), each carrying a STABLE\n// kebab-case machine-readable `code`. Validation runs in THREE phases, each gated on\n// the previous being clean ENOUGH for the next to be meaningful — not on \"zero issues\n// so far\", so a defect in one phase never silently hides an honest issue from a later\n// one (the throw must carry ALL real issues, not just the first phase's):\n// (0) duplicate ids. The lookup maps are first-occurrence-wins, so EVERY reference\n// rule below would validate whichever duplicate row was declared first — making\n// the issue list depend on array order, violating this function's documented\n// order-invariance. When any duplicate-id issue exists we report ONLY those and\n// stop (the duplicate already forces a throw, present in every permutation).\n// (1) reference / semantic rules (R2–R7, R10–R14): top, per-gate references, arity,\n// vote threshold, gate ownership. Always evaluated once ids are unambiguous.\n// (2) graph rules (R8 reachability, R9 cycles) — gated ONLY on the reference-INTEGRITY\n// subset that genuinely makes traversal meaningless, NOT on every phase-1 issue.\n// The traversal walks `gateOf(eventId)` → gate.inputIds (+ inhibit conditionId)\n// seeded at topId, so it is corrupted by: duplicate-id (ambiguous first-wins\n// node), unknown-input (walks a phantom node), gate-on-non-intermediate /\n// transfer-with-gate (attaches a gate to a leaf, fabricating descent),\n// event-with-two-gates (gateOf's first-match silently picks one), inhibit-\n// condition (a non-conditioning conditionId is queued as a phantom node), and\n// top-not-intermediate (the BFS frontier is rooted at a non-node). Defects that\n// do NOT impair traversal — vote-threshold, gate-arity (k/arity are never read),\n// top-as-input, conditioning-as-input, event-without-gate, intermediate-reused\n// (all reference real, walkable nodes) — do NOT suppress the graph phase, so e.g.\n// a bad vote k alongside an unreachable event reports BOTH in one throw.\n//\n// Tolerated, by design (drawn as declared, never converted):\n// - repeated LEAF events (basic/undeveloped/house/transfer) in several gates' inputs\n// — that IS the standard repeated-event notation (drawn once per reference; hooks\n// are disambiguated with data-instance, see ./layout.ts);\n// - a conditioning event attached to more than one inhibit gate (one oval per gate);\n// - vote gates with k=1 or k=n (logically OR/AND — converting would be interpretation);\n// - empty labels (drawn empty; the <title> is still present).\n\nimport type { FaultTreeEvent, FaultTreeGate, FaultTreeInput } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type FaultTreeIssueCode =\n | \"duplicate-id\"\n | \"top-not-intermediate\"\n | \"top-as-input\"\n | \"gate-on-non-intermediate\"\n | \"transfer-with-gate\"\n | \"event-with-two-gates\"\n | \"event-without-gate\"\n | \"intermediate-reused\"\n | \"unknown-input\"\n | \"conditioning-as-input\"\n | \"inhibit-condition\"\n | \"gate-arity\"\n | \"vote-threshold\"\n | \"unreachable-event\"\n | \"cycle\";\n\nexport interface FaultTreeIssue {\n code: FaultTreeIssueCode;\n message: string;\n}\n\n/** Thrown by computeFaultTreeLayout / faultTreeSvg on a structurally invalid tree. */\nexport class FaultTreeValidationError extends Error {\n readonly issues: readonly FaultTreeIssue[];\n\n constructor(issues: readonly FaultTreeIssue[]) {\n super(`invalid fault tree: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"FaultTreeValidationError\";\n this.issues = issues;\n }\n}\n\n/** \"1 and 3\" / \"1, 2 and 3\" — deterministic listing for issue messages. */\nfunction listIds(ids: readonly number[]): string {\n if (ids.length === 1) return String(ids[0]);\n return `${ids.slice(0, -1).join(\", \")} and ${ids[ids.length - 1]}`;\n}\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable\n * across engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly FaultTreeIssue[]): readonly FaultTreeIssue[] {\n const unique = new Map<string, FaultTreeIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically\n * sorted (code, then message) — array order of `events`/`gates` never changes the\n * result. Empty input (no events AND no gates) is valid by definition (the renderer's\n * empty-but-valid SVG case) and reports no issues.\n */\nexport function faultTreeIssues(input: FaultTreeInput): readonly FaultTreeIssue[] {\n if (input.events.length === 0 && input.gates.length === 0) return [];\n\n const issues: FaultTreeIssue[] = [];\n const push = (code: FaultTreeIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── R1: duplicate ids (per namespace — hooks must be unique). Any duplicate makes\n // the structure ambiguous, so this is phase 0 and short-circuits the rest (below). ─\n const eventById = new Map<number, FaultTreeEvent>();\n const dupEventIds = new Set<number>();\n for (const e of input.events) {\n if (eventById.has(e.id)) dupEventIds.add(e.id);\n else eventById.set(e.id, e);\n }\n for (const id of [...dupEventIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate event id ${id}`);\n }\n const gateById = new Map<number, FaultTreeGate>();\n const dupGateIds = new Set<number>();\n for (const g of input.gates) {\n if (gateById.has(g.id)) dupGateIds.add(g.id);\n else gateById.set(g.id, g);\n }\n for (const id of [...dupGateIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate gate id ${id}`);\n }\n\n // ── Phase 0: duplicate ids short-circuit everything else. The lookup maps below are\n // first-occurrence-wins, so every downstream reference rule would validate whichever\n // duplicate row happened to be declared first — making the issue list depend on the\n // `events`/`gates` ARRAY ORDER, in direct violation of this function's documented\n // order-invariance. Rules evaluated over an ambiguous first-wins structure are as\n // meaningless as the graph rules over dangling references, so we report ONLY the\n // duplicate-id issues and stop (the structural defect already forces a throw). This\n // extends the existing phase doctrine one level up: duplicate ids → reference rules →\n // graph rules, each phase gated on the prior being clean enough to be meaningful. ──\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n const gates = [...gateById.values()].sort((a, b) => a.id - b.id);\n\n // ── R2: the declared top must be an existing intermediate event. ─────────────────\n const top = eventById.get(input.topId);\n if (top === undefined || top.kind !== \"intermediate\") {\n push(\"top-not-intermediate\", `topId ${input.topId} is not an intermediate event`);\n }\n\n // ── Per-gate reference/arity rules (R3, R4, R10–R14). ───────────────────────────\n const conditioningAsInput = new Set<number>();\n for (const g of gates) {\n const out = eventById.get(g.eventId);\n if (out !== undefined && out.kind === \"transfer\") {\n // R13 — transfer-in marks \"developed elsewhere\": a leaf by definition.\n push(\"transfer-with-gate\", `transfer event ${g.eventId} cannot have a gate`);\n } else if (out === undefined || out.kind !== \"intermediate\") {\n // R4 — only rectangles are developed through a gate.\n push(\"gate-on-non-intermediate\", `gate ${g.id} resolves non-intermediate event ${g.eventId}`);\n }\n\n // R10 — a gate IS a logic combination; INHIBIT is single-input-plus-condition.\n if (g.type === \"inhibit\") {\n if (g.inputIds.length !== 1) push(\"gate-arity\", `inhibit gate ${g.id} needs exactly 1 input`);\n } else if (g.inputIds.length < 2) {\n push(\"gate-arity\", `${g.type} gate ${g.id} needs ≥2 inputs`);\n }\n\n // R12 — a voting threshold outside the integers 1..n is meaningless. Number.isInteger\n // also rejects NaN/±Infinity and fractional k (k is a plain `number`, so JSON can\n // carry those) — drawing \"NaN/2\" or \"1.5/2\" would repair a meaningless threshold by\n // rendering it, which the reject-never-repair doctrine forbids.\n if (g.type === \"vote\" && (!Number.isInteger(g.k) || g.k < 1 || g.k > g.inputIds.length)) {\n push(\"vote-threshold\", `vote gate ${g.id}: k=${g.k} of ${g.inputIds.length}`);\n }\n\n // R11a — the oval attaches to a gate; inhibit must reference a conditioning event.\n if (g.type === \"inhibit\") {\n const cond = eventById.get(g.conditionId);\n if (cond === undefined || cond.kind !== \"conditioning\") {\n push(\"inhibit-condition\", `inhibit gate ${g.id} conditionId ${g.conditionId} is not a conditioning event`);\n }\n }\n\n for (const inputId of g.inputIds) {\n const child = eventById.get(inputId);\n if (child === undefined) {\n // Dangling input — silently dropping it would alter the declared logic.\n push(\"unknown-input\", `gate ${g.id} input ${inputId} is not a declared event`);\n continue;\n }\n // R3 — the top is the tree apex, never an input.\n if (inputId === input.topId) push(\"top-as-input\", `top event ${input.topId} is used as a gate input`);\n // R11b — a conditioning event is never a tree node (NUREG-0492: it restricts a gate).\n if (child.kind === \"conditioning\") conditioningAsInput.add(inputId);\n }\n }\n for (const id of [...conditioningAsInput].sort((a, b) => a - b)) {\n push(\"conditioning-as-input\", `conditioning event ${id} used as a gate input`);\n }\n\n // ── R5/R6: exactly one gate per intermediate event. ─────────────────────────────\n const gatesByEvent = new Map<number, number[]>();\n for (const g of gates) {\n const arr = gatesByEvent.get(g.eventId) ?? [];\n arr.push(g.id);\n gatesByEvent.set(g.eventId, arr);\n }\n for (const [eventId, gateIds] of [...gatesByEvent.entries()].sort((a, b) => a[0] - b[0])) {\n if (gateIds.length > 1) {\n push(\"event-with-two-gates\", `event ${eventId} is resolved by gates ${listIds(gateIds.sort((a, b) => a - b))}`);\n }\n }\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if (e.kind === \"intermediate\" && !gatesByEvent.has(e.id)) {\n // R6 — a rectangle without a gate falsely claims development; the diamond\n // (undeveloped) is the standard's own symbol for \"not developed further\".\n push(\"event-without-gate\", `intermediate event ${e.id} has no gate — declare it kind \"undeveloped\" instead`);\n }\n }\n\n // ── R7: an intermediate may feed only ONE gate input — duplicating whole subtrees\n // silently is synthesis; the standard's answer is the transfer triangle. ───────\n const intermediateRefs = new Map<number, number[]>(); // event id → referencing gate ids\n for (const g of gates) {\n for (const inputId of g.inputIds) {\n if (eventById.get(inputId)?.kind !== \"intermediate\") continue;\n const arr = intermediateRefs.get(inputId) ?? [];\n arr.push(g.id);\n intermediateRefs.set(inputId, arr);\n }\n }\n for (const [eventId, gateIds] of [...intermediateRefs.entries()].sort((a, b) => a[0] - b[0])) {\n if (gateIds.length > 1) {\n push(\n \"intermediate-reused\",\n `intermediate event ${eventId} feeds gates ${listIds(gateIds.sort((a, b) => a - b))} — repeat it via a \"transfer\" event`,\n );\n }\n }\n\n // ── Graph rules (R8 reachability, R9 cycles) — phase 2. Gated ONLY on the reference-\n // INTEGRITY codes that corrupt the traversal itself (see the module header for the\n // per-code justification), NOT on every phase-1 issue: a meaningless vote k or wrong\n // arity leaves the graph fully walkable, so suppressing R8/R9 for them would hide an\n // honest issue and break the \"throw with ALL issues\" doctrine. ─────────────────────\n const GRAPH_BLOCKING: ReadonlySet<FaultTreeIssueCode> = new Set([\n \"duplicate-id\",\n \"unknown-input\",\n \"gate-on-non-intermediate\",\n \"transfer-with-gate\",\n \"event-with-two-gates\",\n \"inhibit-condition\",\n \"top-not-intermediate\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n const gateOf = (eventId: number): FaultTreeGate | undefined => gates.find((g) => g.eventId === eventId);\n\n // R8 — every declared event must be reachable from the top (silently dropping\n // declared data violates honesty). Conditioning events reach through their gate.\n const reachable = new Set<number>();\n const queue: number[] = [input.topId];\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (reachable.has(id)) continue;\n reachable.add(id);\n const g = gateOf(id);\n if (g === undefined) continue;\n queue.push(...g.inputIds);\n if (g.type === \"inhibit\") queue.push(g.conditionId);\n }\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if (!reachable.has(e.id)) push(\"unreachable-event\", `event ${e.id} is declared but unreachable from the top`);\n }\n\n // R9 — cycle detection over the whole event graph (event → its gate's inputs).\n // Iterative coloring DFS, start nodes ascending, children in declared order; each\n // distinct cycle is reported once, rotated to start at its smallest event id so\n // the message is identical for any array order of the same input.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = gateOf(frame.id)?.inputIds ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n // Back edge: the cycle is the stack slice from `child` down to the current frame.\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\"cycle\", `cycle: ${[...rotated, rotated[0]!].join(\" → \")}`);\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(e.id) ?? 0) === 0) dfs(e.id);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws FaultTreeValidationError (carrying ALL issues) when the input is invalid. */\nexport function validateFaultTree(input: FaultTreeInput): void {\n const issues = faultTreeIssues(input);\n if (issues.length > 0) throw new FaultTreeValidationError(issues);\n}\n","// PURE fault-tree layout — the single source of truth for positioning and connector\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so the\n// same input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS what the caller declared. Validation\n// (./validate.ts) THROWS on a structurally invalid tree instead of repairing it —\n// a fault tree is a safety artifact and silently altering its logic is synthesis.\n// Tolerated repetition is the standard's own notation: a repeated LEAF event\n// (basic/undeveloped/house/transfer in several gates' inputs) is drawn once per\n// reference, exactly as hand-drawn FTA repeats the same circle at each site; hooks\n// are disambiguated with a 0-based `instance` index in deterministic DFS pre-order\n// (event, then inhibit condition, then inputs in declared order). This is also the\n// forward answer for DAG-shaped trees: model the shared subtree as a `transfer` leaf.\n//\n// LAYOUT — top-down levels, exactly as every NUREG-0492 / IEC 61025 figure draws it:\n// event rectangle, short stem, gate beneath, orthogonal connector rake to children.\n// Horizontal placement is NAIVE SUBTREE-SPAN PACKING (not Reingold–Tilford contours):\n// every node carries asymmetric half-extents {spanL, spanR} covering its ENTIRE\n// subtree drawing (glyphs, labels, gate, conditioning oval, its own buses); siblings\n// are placed with disjoint intervals H_GAP apart, and the recursion makes the\n// guarantee global — a 5-line inductive overlap proof, re-verified by the test\n// harness, at the cost of some width on unbalanced trees. Label widths reserve real\n// space because nodeW comes from estimateTextWidth over the wrapped lines and the\n// emitter draws with the same core metrics: what is proven is what is drawn.\n//\n// GATE-CLEARANCE INVARIANT (directly asserted in test/fault-tree/layout.test.ts):\n// every gate glyph bottom at depth d sits strictly ABOVE the child bus y, because\n// rowTop(d+1) = rowTop(d) + rowH(d) + gateZone(d) + CORRIDOR reserves the full gate\n// zone and busY = rowTop(d+1) − CORRIDOR/2 leaves CORRIDOR/2 of air below it.\n\nimport { CHAR_W, clampLabel, estimateTextWidth, wrapLabel, wrapLabelBalanced, type Point } from \"../core\";\nimport { FAULT_TREE_TITLE_LABELS_EN, type FaultTreeTitleLabels } from \"./labels\";\nimport { validateFaultTree } from \"./validate\";\nimport type { FaultTreeEvent, FaultTreeEventKind, FaultTreeGate, FaultTreeInput, GateType } from \"./types\";\n\nexport { FaultTreeValidationError, faultTreeIssues, validateFaultTree, type FaultTreeIssue, type FaultTreeIssueCode } from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render) ──────\n/** Node label font size (px). */\nexport const FT_LABEL_FONT = 12;\n/** Line height for stacked label lines (px). */\nexport const FT_LABEL_LINE_H = 14;\n/** Short-code font size (px) — drawn inside primary-event glyphs. */\nexport const CODE_FONT = 10;\n/** Gap from a leaf glyph's bottom to the top of its first label line. */\nexport const LABEL_GAP = 6;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────\nconst PADDING = 32;\n/** Min horizontal air between two sibling subtree intervals. */\nconst H_GAP = 28;\n/** Vertical band between a row's gate zone and the next row (the bus lives mid-way). */\nconst CORRIDOR = 30;\n/** Vertical stem from an event's bottom edge to its gate's top. */\nconst STEM = 10;\n/** Horizontal gap between an inhibit gate's right vertex and its conditioning node. */\nconst COND_GAP = 14;\n\n// Gate glyph boxes (NUREG-0492 distinctive shapes, drawn pointing up).\nconst GATE_W = 44;\nconst GATE_H = 36;\n/** XOR = the OR shape + a detached concave arc 5px below the base (ANSI/IEEE 91). */\nconst XOR_H = GATE_H + 5;\nconst INHIBIT_W = 36;\nconst INHIBIT_H = 46;\n/** Y of the inhibit hexagon's side-vertex midpoint (the condition line's anchor). */\nconst INHIBIT_CY = 23;\n\n// ── Namespaced element ids (one element kind per numeric block, extending the\n// genogram convention) — every data-edge-id stays traceable to its source row. ──\nexport const FT_STEM_ID_BASE = 1_000_000; // + gate id\nexport const FT_DROP_ID_BASE = 2_000_000; // + gate id\nexport const FT_BUS_ID_BASE = 3_000_000; // + gate id\nexport const FT_RISER_ID_BASE = 4_000_000; // + child event id\nexport const FT_CONDITION_ID_BASE = 5_000_000; // + gate id\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────\n\nexport interface FaultTreeNode {\n eventId: number;\n kind: FaultTreeEventKind;\n /** 0-based DFS pre-order instance index; null when the event is drawn once. */\n instance: number | null;\n /** Glyph center x. */\n cx: number;\n /** Glyph top y (leaf labels hang below the glyph; the rect IS the glyph). */\n top: number;\n /** Full node box (glyph + label block) — the packing reserved exactly this. */\n nodeW: number;\n nodeH: number;\n glyphW: number;\n glyphH: number;\n /** Wrapped display lines — inside the rect (intermediate) or below the glyph. */\n labelLines: string[];\n /** Top of the first label line's box; null when the label sits inside the rect. */\n labelTop: number | null;\n /** Clamped display code drawn inside a non-rect glyph; null = none. */\n code: string | null;\n /** Depth of the row this node lives in (a conditioning node: its gate's row). */\n depth: number;\n /** Verbatim <title> text (event.title ?? \"code · label\" ?? label). */\n title: string;\n}\n\nexport interface FaultTreeGateNode {\n gateId: number;\n type: GateType;\n cx: number;\n /** Glyph top y (all gates of a row are top-aligned at rowBottom + STEM). */\n top: number;\n glyphW: number;\n /** Full glyph height incl. the XOR's detached arc — top + glyphH = connector bottom. */\n glyphH: number;\n /** Localized gate name (vote: name + \" k/n\"). */\n title: string;\n /** \"k/n\" drawn inside a vote gate; null otherwise. */\n voteText: string | null;\n}\n\nexport type FaultTreeElementKind = \"stem\" | \"drop\" | \"bus\" | \"riser\" | \"condition\";\n\nexport interface FaultTreeElement {\n /** Namespaced id (FT_*_ID_BASE + gate id / child event id). */\n edgeId: number;\n kind: FaultTreeElementKind;\n /** Two waypoints, always axis-aligned (H or V). */\n points: Point[];\n /** Riser into a repeated-leaf instance: that instance index; else null. */\n instance: number | null;\n /** Localized gate name (condition elements: titleLabels.condition). */\n title: string;\n}\n\nexport interface FaultTreeLayout {\n width: number;\n height: number;\n /** DFS pre-order (event, condition, inputs) — repeated leaves appear per instance. */\n nodes: FaultTreeNode[];\n gates: FaultTreeGateNode[];\n elements: FaultTreeElement[];\n}\n\nexport interface FaultTreeLayoutOptions {\n /** Cap each node's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for gate/condition <title>s — English default; see locale packs. */\n titleLabels?: FaultTreeTitleLabels;\n}\n\n// ── Measurement ───────────────────────────────────────────────────────────────────\n\ninterface Measured {\n nodeW: number;\n nodeH: number;\n glyphW: number;\n glyphH: number;\n labelLines: string[];\n code: string | null;\n}\n\n/** Leaf-label wrap: tighter budget than the rect's (glyphs don't grow with text). */\nfunction wrapLeafLabel(displayLabel: string): string[] {\n const perLine = Math.min(20, Math.max(12, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n// ── Per-glyph code-char clamp — guarantees the code sits INSIDE its fixed-size\n// glyph (the design doc's \"code drawn inside the glyph\" claim), DERIVED from THIS\n// module's own metrics rather than eyeballed. Only the conditioning OVAL is\n// excluded: it GROWS to the measured code width (`rx = max(30, codeW/2 + 8)`), so\n// it never clamps — see measureEvent. The full verbatim code always survives in\n// the <title> (eventTitle), so clamping is presentation-only, never data loss.\n//\n// Geometry. The emitter (svg.ts) draws the code centered at `cx`, `text-anchor\n// \"middle\"`, its baseline (the literal `<text y>`, i.e. the code's ACTUAL drawn\n// y-position) at `top + glyphH/2 + CODE_FONT*0.32`. N chars span ±estimateTextWidth\n// (N)/2 = ±(N·CODE_FONT·CHAR_W)/2 about cx. The clamp keeps that half-span inside\n// the glyph's half-width AT THAT BASELINE Y (`codeBaselineHalfWidth` below), with a\n// couple px margin AND real-font headroom: real Helvetica caps run wider than the\n// deliberately-light CHAR_W=0.6 estimate at these small extremes (the review\n// measured ~20.3px real vs 18px estimated for a 6-char code, ≈1.13×), so we reserve\n// CODE_REAL_HEADROOM on top of the estimate. Solving for the largest integer N in\n// N·(CODE_FONT·CHAR_W·CODE_REAL_HEADROOM)/2 + CODE_MARGIN ≤ half(baseline)\n// yields (recomputed by maxCodeChars, not hand-copied): basic 5, undeveloped 5,\n// house 5, transfer 3 — the apex-up triangle is narrowest at the code's height.\nconst CODE_REAL_HEADROOM = 1.15;\nconst CODE_MARGIN = 2;\n\n/** Glyph half-width at vertical offset `y` below the glyph top, per non-rect kind. */\nfunction codeGlyphHalfAt(kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">, y: number): number {\n if (kind === \"basic\") {\n // circle r 22, center at top+22\n const dy = y - 22;\n return Math.sqrt(Math.max(0, 22 * 22 - dy * dy));\n }\n if (kind === \"undeveloped\") {\n // diamond half 24, center at top+24, linear taper to the apex/bottom\n return 24 * Math.max(0, 1 - Math.abs(y - 24) / 24);\n }\n if (kind === \"house\") {\n // walls ±22 below the eave (top+16); roof tapers linearly above it to the apex\n return y >= 16 ? 22 : (22 * y) / 16;\n }\n // transfer — apex-up triangle, base ±22 at top+35; half grows linearly from the apex\n return (22 * Math.max(0, Math.min(35, y))) / 35;\n}\n\n/** Glyph half-width at the code text's baseline (its actual drawn `<text y>`). */\nfunction codeBaselineHalfWidth(\n kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">,\n glyphH: number,\n): number {\n return codeGlyphHalfAt(kind, glyphH / 2 + CODE_FONT * 0.32);\n}\n\n/** Largest code length that, drawn, stays inside the glyph (estimator + headroom + margin). */\nexport function maxCodeChars(\n kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">,\n glyphH: number,\n): number {\n const half = codeBaselineHalfWidth(kind, glyphH);\n const perChar = (CODE_FONT * CHAR_W * CODE_REAL_HEADROOM) / 2; // half-advance with headroom\n return Math.max(1, Math.floor((half - CODE_MARGIN) / perChar));\n}\n\nfunction measureEvent(event: FaultTreeEvent, maxLabelChars: number | undefined): Measured {\n if (event.kind === \"intermediate\") {\n // The rectangle IS a text panel (the standard writes the description inside it).\n const lines = event.label === \"\" ? [] : wrapLabelBalanced(clampLabel(event.label, maxLabelChars), 3);\n const maxLineW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, FT_LABEL_FONT)), 0);\n const w = Math.max(96, maxLineW + 24);\n const h = lines.length * FT_LABEL_LINE_H + 18;\n return { nodeW: w, nodeH: h, glyphW: w, glyphH: h, labelLines: lines, code: null };\n }\n const rawCode = event.code === null || event.code === \"\" ? null : event.code;\n const lines = event.label === \"\" ? [] : wrapLeafLabel(clampLabel(event.label, maxLabelChars));\n const labelW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, FT_LABEL_FONT)), 0);\n let glyphW: number;\n let glyphH: number;\n // Fixed-size glyphs clamp the code to what their outline can hold (CODE_MAX_CHARS,\n // derived above); the conditioning OVAL instead grows to the measured code width.\n let code = rawCode;\n if (event.kind === \"basic\") {\n glyphW = 44; // circle r 22\n glyphH = 44;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"basic\", glyphH));\n } else if (event.kind === \"undeveloped\") {\n glyphW = 48; // rotated square, half 24\n glyphH = 48;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"undeveloped\", glyphH));\n } else if (event.kind === \"house\") {\n glyphW = 44; // pentagon: 24px walls + 16px roof\n glyphH = 40;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"house\", glyphH));\n } else if (event.kind === \"conditioning\") {\n // The oval reserves the FULL (only globally-capped) code width — no glyph clamp.\n code = rawCode === null ? null : clampLabel(rawCode, 6);\n const rx = Math.max(30, estimateTextWidth(code ?? \"\", CODE_FONT) / 2 + 8);\n glyphW = rx * 2;\n glyphH = 32; // ellipse ry 16\n } else {\n glyphW = 44; // transfer triangle, apex up\n glyphH = 35;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"transfer\", glyphH));\n }\n const nodeW = Math.max(glyphW, labelW);\n const nodeH = glyphH + (lines.length > 0 ? LABEL_GAP + lines.length * FT_LABEL_LINE_H : 0);\n return { nodeW, nodeH, glyphW, glyphH, labelLines: lines, code };\n}\n\nfunction eventTitle(event: FaultTreeEvent): string {\n if (event.title !== undefined) return event.title;\n return event.code !== null && event.code !== \"\" ? `${event.code} · ${event.label}` : event.label;\n}\n\n// ── Internal working tree (one node per drawn INSTANCE) ───────────────────────────\n\ninterface Inst {\n event: FaultTreeEvent;\n gate: FaultTreeGate | null;\n children: Inst[];\n /** Conditioning instance attached to an inhibit gate; positioned in the gate zone. */\n cond: Inst | null;\n depth: number;\n m: Measured;\n title: string;\n /** Per-event-id DFS pre-order sequence (becomes `instance` when the event repeats). */\n seq: number;\n // Subtree half-extents (cover the ENTIRE subtree drawing) and resolved positions.\n spanL: number;\n spanR: number;\n /** Center offset relative to the parent's center (root: unused). */\n offset: number;\n cx: number;\n}\n\n/**\n * Deterministic, overlap-proof fault-tree layout (pure function of the inputs).\n * Validates first and THROWS FaultTreeValidationError on a structurally invalid\n * tree — never sanitizes. Empty input (no events, no gates) yields an empty,\n * padded layout; `topId` is ignored in that one case.\n */\nexport function computeFaultTreeLayout(\n input: FaultTreeInput,\n opts: FaultTreeLayoutOptions = {},\n): FaultTreeLayout {\n if (input.events.length === 0 && input.gates.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], gates: [], elements: [] };\n }\n validateFaultTree(input);\n\n const titleLabels = opts.titleLabels ?? FAULT_TREE_TITLE_LABELS_EN;\n const eventById = new Map(input.events.map((e) => [e.id, e]));\n const gateByEvent = new Map(input.gates.map((g) => [g.eventId, g]));\n\n // ── Build the instance tree by DFS from the top (event → condition → inputs in\n // declared order). Validation guarantees: intermediates form a tree, leaves may\n // repeat, conditioning events never have gates or children. ───────────────────\n const allInsts: Inst[] = [];\n const seqByEvent = new Map<number, number>();\n const newInst = (event: FaultTreeEvent, gate: FaultTreeGate | null, depth: number): Inst => {\n const seq = seqByEvent.get(event.id) ?? 0;\n seqByEvent.set(event.id, seq + 1);\n const inst: Inst = {\n event,\n gate,\n children: [],\n cond: null,\n depth,\n m: measureEvent(event, opts.maxLabelChars),\n title: eventTitle(event),\n seq,\n spanL: 0,\n spanR: 0,\n offset: 0,\n cx: 0,\n };\n allInsts.push(inst);\n return inst;\n };\n const build = (eventId: number, depth: number): Inst => {\n const event = eventById.get(eventId)!;\n const gate = gateByEvent.get(eventId) ?? null;\n const inst = newInst(event, gate, depth);\n if (gate !== null) {\n if (gate.type === \"inhibit\") {\n inst.cond = newInst(eventById.get(gate.conditionId)!, null, depth);\n }\n for (const childId of gate.inputIds) inst.children.push(build(childId, depth + 1));\n }\n return inst;\n };\n const root = build(input.topId, 0);\n\n // ── Horizontal: subtree-span packing (post-order). The conditioning oval reserves\n // REAL width on the right of an inhibit-developed node — never overlaps a sibling.\n const pack = (inst: Inst): void => {\n for (const c of inst.children) pack(c);\n const condW = inst.cond !== null ? COND_GAP + inst.cond.m.nodeW : 0;\n const selfL = inst.m.nodeW / 2;\n const selfR = inst.m.nodeW / 2 + condW;\n if (inst.children.length === 0) {\n inst.spanL = selfL;\n inst.spanR = selfR;\n return;\n }\n const xs: number[] = [0];\n for (let i = 1; i < inst.children.length; i++) {\n xs.push(xs[i - 1]! + inst.children[i - 1]!.spanR + H_GAP + inst.children[i]!.spanL);\n }\n const first = inst.children[0]!;\n const last = inst.children[inst.children.length - 1]!;\n const px = (xs[0]! + xs[xs.length - 1]!) / 2;\n inst.children.forEach((c, i) => (c.offset = xs[i]! - px));\n inst.spanL = Math.max(selfL, px - (xs[0]! - first.spanL));\n inst.spanR = Math.max(selfR, xs[xs.length - 1]! + last.spanR - px);\n };\n pack(root);\n\n // Absolute centers, top-down; the root's left extent sits at PADDING.\n root.cx = PADDING + root.spanL;\n const placeX = (inst: Inst): void => {\n for (const c of inst.children) {\n c.cx = inst.cx + c.offset;\n placeX(c);\n }\n };\n placeX(root);\n\n // ── Vertical: rows by depth (per drawn instance), top-aligned; each row reserves\n // a gate zone sized to its tallest gate assembly (incl. conditioning nodes). ───\n const rowInsts: Inst[][] = [];\n const visitRows = (inst: Inst): void => {\n (rowInsts[inst.depth] ??= []).push(inst);\n for (const c of inst.children) visitRows(c);\n };\n visitRows(root);\n const depthCount = rowInsts.length;\n\n /** Vertical extent of a gate assembly below the gate's top (glyph and/or oval+label). */\n const gateExtent = (inst: Inst): number => {\n const g = inst.gate!;\n if (g.type === \"xor\") return XOR_H;\n if (g.type === \"inhibit\") {\n // Oval vertically centered on the hexagon's side vertex (INHIBIT_CY); the\n // condition node's label may extend below the hexagon bottom.\n const condBottom = INHIBIT_CY - 16 + inst.cond!.m.nodeH;\n return Math.max(INHIBIT_H, condBottom);\n }\n return GATE_H;\n };\n const rowH: number[] = [];\n const gateZone: number[] = [];\n for (let d = 0; d < depthCount; d++) {\n const insts = rowInsts[d]!;\n rowH.push(insts.reduce((m, i) => Math.max(m, i.m.nodeH), 0));\n const gated = insts.filter((i) => i.gate !== null);\n gateZone.push(gated.length === 0 ? 0 : STEM + gated.reduce((m, i) => Math.max(m, gateExtent(i)), 0));\n }\n const rowTop: number[] = [PADDING];\n for (let d = 0; d < depthCount - 1; d++) {\n rowTop.push(rowTop[d]! + rowH[d]! + gateZone[d]! + CORRIDOR);\n }\n const busY = (d: number): number => rowTop[d + 1]! - CORRIDOR / 2;\n\n const width = Math.ceil(PADDING * 2 + root.spanL + root.spanR);\n const last = depthCount - 1;\n const height = Math.ceil(rowTop[last]! + rowH[last]! + gateZone[last]! + PADDING);\n\n // ── Instance finalization: only events drawn more than once carry an index. ──────\n const instanceOf = (inst: Inst): number | null =>\n (seqByEvent.get(inst.event.id) ?? 0) > 1 ? inst.seq : null;\n\n // ── Emit nodes / gates / elements in DFS order. ───────────────────────────────────\n const nodes: FaultTreeNode[] = [];\n const gates: FaultTreeGateNode[] = [];\n const elements: FaultTreeElement[] = [];\n\n const gateTitle = (g: FaultTreeGate): string =>\n g.type === \"vote\" ? `${titleLabels.gates.vote} ${g.k}/${g.inputIds.length}` : titleLabels.gates[g.type];\n\n const pushNode = (inst: Inst, top: number): void => {\n const isRect = inst.event.kind === \"intermediate\";\n const labelTop = !isRect && inst.m.labelLines.length > 0 ? top + inst.m.glyphH + LABEL_GAP : null;\n nodes.push({\n eventId: inst.event.id,\n kind: inst.event.kind,\n instance: instanceOf(inst),\n cx: round(inst.cx),\n top: round(top),\n nodeW: round(inst.m.nodeW),\n nodeH: round(inst.m.nodeH),\n glyphW: round(inst.m.glyphW),\n glyphH: round(inst.m.glyphH),\n labelLines: inst.m.labelLines,\n labelTop: labelTop === null ? null : round(labelTop),\n code: inst.m.code,\n depth: inst.depth,\n title: inst.title,\n });\n };\n\n const emit = (inst: Inst): void => {\n const d = inst.depth;\n pushNode(inst, rowTop[d]!);\n const g = inst.gate;\n if (g === null) return;\n\n const gateTop = rowTop[d]! + rowH[d]! + STEM;\n const glyphW = g.type === \"inhibit\" ? INHIBIT_W : GATE_W;\n const glyphH = g.type === \"xor\" ? XOR_H : g.type === \"inhibit\" ? INHIBIT_H : GATE_H;\n const title = gateTitle(g);\n gates.push({\n gateId: g.id,\n type: g.type,\n cx: round(inst.cx),\n top: round(gateTop),\n glyphW,\n glyphH,\n title,\n voteText: g.type === \"vote\" ? `${g.k}/${g.inputIds.length}` : null,\n });\n\n // Conditioning node: oval centered on the hexagon's side vertex, the whole node\n // box starting COND_GAP right of the vertex so the label can never reach the gate.\n if (inst.cond !== null) {\n const cond = inst.cond;\n const nodeLeft = inst.cx + INHIBIT_W / 2 + COND_GAP;\n cond.cx = nodeLeft + cond.m.nodeW / 2;\n const condTop = gateTop + INHIBIT_CY - 16;\n pushNode(cond, condTop);\n const ovalLeft = cond.cx - cond.m.glyphW / 2;\n elements.push({\n edgeId: FT_CONDITION_ID_BASE + g.id,\n kind: \"condition\",\n points: [\n { x: round(inst.cx + INHIBIT_W / 2), y: round(gateTop + INHIBIT_CY) },\n { x: round(ovalLeft), y: round(gateTop + INHIBIT_CY) },\n ],\n instance: null,\n title: titleLabels.condition,\n });\n }\n\n // Output stem: event bottom → gate top (longer than STEM when the event is\n // shorter than its row — rows are top-aligned).\n elements.push({\n edgeId: FT_STEM_ID_BASE + g.id,\n kind: \"stem\",\n points: [\n { x: round(inst.cx), y: round(rowTop[d]! + inst.m.nodeH) },\n { x: round(inst.cx), y: round(gateTop) },\n ],\n instance: null,\n title,\n });\n // Gate drop: gate connector bottom → bus.\n const by = busY(d);\n elements.push({\n edgeId: FT_DROP_ID_BASE + g.id,\n kind: \"drop\",\n points: [\n { x: round(inst.cx), y: round(gateTop + glyphH) },\n { x: round(inst.cx), y: round(by) },\n ],\n instance: null,\n title,\n });\n // Bus: spans min→max child centers; a single-input gate degenerates to the\n // straight drop + riser (no bus element).\n if (inst.children.length > 1) {\n const xs = inst.children.map((c) => c.cx);\n elements.push({\n edgeId: FT_BUS_ID_BASE + g.id,\n kind: \"bus\",\n points: [\n { x: round(Math.min(...xs)), y: round(by) },\n { x: round(Math.max(...xs)), y: round(by) },\n ],\n instance: null,\n title,\n });\n }\n // One riser per child: bus → child glyph top (the transfer triangle's apex IS\n // its glyph top). Risers into a repeated leaf carry that instance index, since\n // their edge id (FT_RISER_ID_BASE + child event id) repeats with the leaf.\n for (const c of inst.children) {\n elements.push({\n edgeId: FT_RISER_ID_BASE + c.event.id,\n kind: \"riser\",\n points: [\n { x: round(c.cx), y: round(by) },\n { x: round(c.cx), y: round(rowTop[d + 1]!) },\n ],\n instance: instanceOf(c),\n title,\n });\n }\n for (const c of inst.children) emit(c);\n };\n emit(root);\n\n return { width, height, nodes, gates, elements };\n}\n","// Fault-tree SVG emitter — turns a computed FaultTreeLayout (./layout.ts) into a\n// SELF-CONTAINED SVG string. Pure (layout in, string out) and deterministic; it draws\n// EXACTLY what the layout computed (the overlap harness proves the layout; this\n// emitter is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — labels/codes/titles are\n// author-controlled and the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (hex colors, explicit font-family): a\n// standalone SVG has no stylesheet, no currentColor, no <defs>/<marker>;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Symbol fidelity (NUREG-0492 distinctive shapes): rectangle / circle / diamond /\n// house / oval / transfer-triangle events; AND dome, OR shield, XOR (OR + detached\n// second input curve — the ANSI/IEEE 91 distinctive shape; the legend entry\n// disambiguates), INHIBIT hexagon, VOTE (OR shield with \"k/n\" inside). Gates carry no\n// label text — the shape IS the semantics; the localized gate name rides the <title>.\n//\n// Hooks: `<g data-node-id=\"e<id>\">` per event instance and `<g data-node-id=\"g<id>\">`\n// per gate (direct-child verbatim <title>); `<g data-edge-id=\"<n>\">` per connector\n// element (namespaced ids, see ./layout.ts). Repeated-leaf instances (and their\n// risers) carry `data-instance=\"k\"` so every hook stays unambiguous.\n\nimport { FONT_FAMILY, legendBlock, xmlEscape, LEGEND_SWATCH_W, type LegendEntry } from \"../core\";\nimport { FT_LABEL_FONT, FT_LABEL_LINE_H, CODE_FONT, type FaultTreeElement, type FaultTreeGateNode, type FaultTreeLayout, type FaultTreeNode } from \"./layout\";\nimport { FAULT_TREE_SVG_LABELS_EN, type FaultTreeSvgLabels } from \"./labels\";\nimport { FAULT_TREE_EVENT_KINDS, GATE_TYPES, type FaultTreeEventKind, type GateType } from \"./types\";\n\n// Literal ink colors (zinc ramp on white — matches the genogram/ecomap emitters).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\nconst GLYPH_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport interface FaultTreeSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: FaultTreeSvgLabels;\n}\n\n// ── Event glyphs ──────────────────────────────────────────────────────────────────\n\nfunction eventGlyph(n: FaultTreeNode): string {\n const cx = n.cx;\n const top = n.top;\n if (n.kind === \"intermediate\") {\n return `<rect x=\"${round(cx - n.nodeW / 2)}\" y=\"${top}\" width=\"${n.nodeW}\" height=\"${n.nodeH}\" rx=\"2\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"basic\") {\n return `<circle cx=\"${cx}\" cy=\"${round(top + 22)}\" r=\"22\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"undeveloped\") {\n const pts = `${cx},${top} ${round(cx + 24)},${round(top + 24)} ${cx},${round(top + 48)} ${round(cx - 24)},${round(top + 24)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"house\") {\n const yB = round(top + 40);\n const eave = round(top + 16);\n const pts = `${round(cx - 22)},${yB} ${round(cx - 22)},${eave} ${cx},${top} ${round(cx + 22)},${eave} ${round(cx + 22)},${yB}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"conditioning\") {\n return `<ellipse cx=\"${cx}\" cy=\"${round(top + 16)}\" rx=\"${round(n.glyphW / 2)}\" ry=\"16\" ${GLYPH_ATTRS}/>`;\n }\n // transfer — triangle, line-to-apex (the riser ends exactly at the apex).\n const pts = `${cx},${top} ${round(cx + 22)},${round(top + 35)} ${round(cx - 22)},${round(top + 35)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n}\n\nfunction nodeSvg(n: FaultTreeNode): string {\n const pieces: string[] = [`<title>${xmlEscape(n.title)}</title>`, eventGlyph(n)];\n if (n.code !== null && n.kind !== \"intermediate\") {\n pieces.push(\n `<text x=\"${n.cx}\" y=\"${round(n.top + n.glyphH / 2 + CODE_FONT * 0.32)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${CODE_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(n.code)}</text>`,\n );\n }\n if (n.labelLines.length > 0) {\n // Inside the rect (vertically centered block) or below the glyph (labelTop).\n const firstBaseline = n.labelTop === null ? round(n.top + 19) : round(n.labelTop + 10);\n const tspans = n.labelLines\n .map((line, i) => `<tspan x=\"${n.cx}\" y=\"${round(firstBaseline + i * FT_LABEL_LINE_H)}\">${xmlEscape(line)}</tspan>`)\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${FT_LABEL_FONT}\" fill=\"${LABEL_FILL}\">${tspans}</text>`,\n );\n }\n const instance = n.instance === null ? \"\" : ` data-instance=\"${n.instance}\"`;\n return `<g data-node-id=\"e${n.eventId}\"${instance}>${pieces.join(\"\")}</g>`;\n}\n\n// ── Gate glyphs (distinctive shapes, drawn pointing up — output on top) ───────────\n\nfunction orBodyPath(cx: number, top: number, yB: number): string {\n return `M ${round(cx - 22)} ${yB} Q ${cx} ${round(yB - 14)} ${round(cx + 22)} ${yB} Q ${round(cx + 22)} ${round(top + 14)} ${cx} ${top} Q ${round(cx - 22)} ${round(top + 14)} ${round(cx - 22)} ${yB} Z`;\n}\n\nfunction gateGlyph(g: FaultTreeGateNode): string {\n const cx = g.cx;\n const top = g.top;\n const yB = round(top + 36);\n if (g.type === \"and\") {\n const d = `M ${round(cx - 22)} ${yB} L ${round(cx - 22)} ${round(yB - 14)} A 22 22 0 0 1 ${round(cx + 22)} ${round(yB - 14)} L ${round(cx + 22)} ${yB} Z`;\n return `<path d=\"${d}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"or\") {\n return `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"xor\") {\n const arc = `M ${round(cx - 22)} ${round(yB + 5)} Q ${cx} ${round(yB - 9)} ${round(cx + 22)} ${round(yB + 5)}`;\n return `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/><path d=\"${arc}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"inhibit\") {\n const pts = `${cx},${top} ${round(cx + 18)},${round(top + 12)} ${round(cx + 18)},${round(top + 34)} ${cx},${round(top + 46)} ${round(cx - 18)},${round(top + 34)} ${round(cx - 18)},${round(top + 12)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n // vote — the OR distinctive shape with the declared \"k/n\" written inside.\n return (\n `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/>` +\n `<text x=\"${cx}\" y=\"${round(yB - 10)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"9\" fill=\"${LABEL_FILL}\">${xmlEscape(g.voteText ?? \"\")}</text>`\n );\n}\n\nfunction gateSvg(g: FaultTreeGateNode): string {\n return `<g data-node-id=\"g${g.gateId}\"><title>${xmlEscape(g.title)}</title>${gateGlyph(g)}</g>`;\n}\n\n// ── Connector elements ─────────────────────────────────────────────────────────────\n\nfunction elementSvg(el: FaultTreeElement): string {\n const a = el.points[0]!;\n const b = el.points[1]!;\n const instance = el.instance === null ? \"\" : ` data-instance=\"${el.instance}\"`;\n return (\n `<g data-edge-id=\"${el.edgeId}\"${instance}><title>${xmlEscape(el.title)}</title>` +\n `<line x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/></g>`\n );\n}\n\n// ── Legend mini-glyph swatches (scaled into the 22px swatch box) ──────────────────\n\nconst MINI_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"`;\n\nfunction miniEventSwatch(kind: FaultTreeEventKind, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (kind === \"intermediate\") {\n return `<rect x=\"${round(cx - 7)}\" y=\"${round(y - 4.5)}\" width=\"14\" height=\"9\" rx=\"1\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"basic\") return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/>`;\n if (kind === \"undeveloped\") {\n return `<polygon points=\"${cx},${round(y - 7)} ${round(cx + 7)},${y} ${cx},${round(y + 7)} ${round(cx - 7)},${y}\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"house\") {\n return `<polygon points=\"${round(cx - 6)},${round(y + 5.5)} ${round(cx - 6)},${round(y - 1)} ${cx},${round(y - 5.5)} ${round(cx + 6)},${round(y - 1)} ${round(cx + 6)},${round(y + 5.5)}\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"conditioning\") return `<ellipse cx=\"${cx}\" cy=\"${y}\" rx=\"9\" ry=\"5.5\" ${MINI_ATTRS}/>`;\n return `<polygon points=\"${cx},${round(y - 5)} ${round(cx + 6)},${round(y + 5)} ${round(cx - 6)},${round(y + 5)}\" ${MINI_ATTRS}/>`;\n}\n\nfunction miniOrPath(cx: number, y: number): string {\n return `M ${round(cx - 7)} ${round(y + 5.5)} Q ${cx} ${round(y + 1)} ${round(cx + 7)} ${round(y + 5.5)} Q ${round(cx + 7)} ${round(y - 1.5)} ${cx} ${round(y - 5.5)} Q ${round(cx - 7)} ${round(y - 1.5)} ${round(cx - 7)} ${round(y + 5.5)} Z`;\n}\n\nfunction miniGateSwatch(type: GateType, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (type === \"and\") {\n const d = `M ${round(cx - 7)} ${round(y + 5.5)} L ${round(cx - 7)} ${round(y + 1.5)} A 7 7 0 0 1 ${round(cx + 7)} ${round(y + 1.5)} L ${round(cx + 7)} ${round(y + 5.5)} Z`;\n return `<path d=\"${d}\" ${MINI_ATTRS}/>`;\n }\n if (type === \"xor\") {\n return `<path d=\"${miniOrPath(cx, y)}\" ${MINI_ATTRS}/><path d=\"M ${round(cx - 7)} ${round(y + 7.5)} Q ${cx} ${round(y + 3)} ${round(cx + 7)} ${round(y + 7.5)}\" ${MINI_ATTRS}/>`;\n }\n if (type === \"inhibit\") {\n return `<polygon points=\"${cx},${round(y - 5.5)} ${round(cx + 4.5)},${round(y - 2.5)} ${round(cx + 4.5)},${round(y + 2.5)} ${cx},${round(y + 5.5)} ${round(cx - 4.5)},${round(y + 2.5)} ${round(cx - 4.5)},${round(y - 2.5)}\" ${MINI_ATTRS}/>`;\n }\n // or / vote share the OR shield mini — the legend label disambiguates the vote.\n return `<path d=\"${miniOrPath(cx, y)}\" ${MINI_ATTRS}/>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed fault-tree layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped;\n * all presentation attributes are literal. The legend lists ONLY the event kinds and\n * gate types actually present, in canonical declaration order.\n */\nexport function faultTreeLayoutSvg(layout: FaultTreeLayout, opts: FaultTreeSvgOptions = {}): string {\n const labels = opts.labels ?? FAULT_TREE_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // Connectors first, then gates, then event nodes — nodes sit on top.\n for (const el of layout.elements) parts.push(elementSvg(el));\n for (const g of layout.gates) parts.push(gateSvg(g));\n for (const n of layout.nodes) parts.push(nodeSvg(n));\n\n // ── Used-keys-only legend (core legendBlock; `legend:false` suppresses). ─────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const kindsUsed = new Set(layout.nodes.map((n) => n.kind));\n const typesUsed = new Set(layout.gates.map((g) => g.type));\n const entries: LegendEntry[] = [];\n for (const kind of FAULT_TREE_EVENT_KINDS) {\n if (!kindsUsed.has(kind)) continue;\n entries.push({ swatch: (x, y) => miniEventSwatch(kind, x, y), label: labels.events[kind] });\n }\n for (const type of GATE_TYPES) {\n if (!typesUsed.has(type)) continue;\n entries.push({ swatch: (x, y) => miniGateSwatch(type, x, y), label: labels.gates[type] });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call fault-tree render: input → { svg, layout }. Thin, honest wiring: validate\n// (throw on a structurally invalid tree — never repair), compute the pure layout,\n// emit. Callers needing finer control use computeFaultTreeLayout + faultTreeLayoutSvg\n// directly (the layout result supports hit-testing / decorating the diagram).\n\nimport { computeFaultTreeLayout, type FaultTreeLayout, type FaultTreeLayoutOptions } from \"./layout\";\nimport { faultTreeLayoutSvg } from \"./svg\";\nimport type { FaultTreeSvgLabels } from \"./labels\";\nimport type { FaultTreeInput } from \"./types\";\n\nexport interface FaultTreeRenderOptions extends FaultTreeLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: FaultTreeSvgLabels;\n}\n\nexport interface FaultTreeRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: FaultTreeLayout;\n}\n\n/**\n * Renders a fault-tree input to a self-contained SVG string. Deterministic: same\n * data → same SVG (array order never matters; a gate's `inputIds` order is honored\n * as the declared left-to-right reading order). Throws FaultTreeValidationError —\n * carrying EVERY issue, deterministically sorted — on a structurally invalid tree.\n * Empty input yields an empty-but-valid SVG; callers decide their own empty state.\n */\nexport function faultTreeSvg(input: FaultTreeInput, opts: FaultTreeRenderOptions = {}): FaultTreeRenderResult {\n const layout = computeFaultTreeLayout(input, {\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = faultTreeLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Ishikawa (fishbone / cause-and-effect) renderer — a horizontal spine running into\n// the effect head, category bones at 60°, horizontal cause twigs and ONE level of\n// diagonal sub-cause twigs — as a SELF-CONTAINED SVG string. Pure (data in, string\n// out), deterministic (same input → same SVG), no DOM, no dependencies.\n//\n// Notation (Ishikawa, *Guide to Quality Control*, JUSE 1976; ASQ template lineage):\n// the effect (\"characteristic\") is written in a box at the head of the central arrow;\n// big bones are diagonal, medium bones (causes) horizontal, small bones (sub-causes)\n// parallel to the big bone — every level drawn as an arrow converging on the effect.\n// The cartoon fish head is template folklore, not the standard, so the head is a\n// plain rectangle. Bones are at EXACTLY 60° to the spine (\"about 60°\" in the\n// literature): the angle is a constant, not an option, because every label-clearance\n// inequality below is derived from it. Beyond small bones the JUSE method itself\n// moves to why-why tables, so sub-sub-causes are typed away.\n//\n// DECLARED ORDER IS HONORED — the documented exception to the library's id-sorting\n// (ecomap) doctrine: the analyst's ordering is declared data (significant categories\n// nearest the head, alternating top/bottom; causes outward from the spine; sub-causes\n// from the bone outward). Numeric ids are still required — unique per namespace\n// (categories / causes / sub-causes), enforced by FishboneValidationError — because\n// the decoration hooks (`data-node-id`) must be unambiguous.\n//\n// HONESTY RULE: one declared category = one bone — no default 5M/6M skeleton, no\n// inferred grouping. Arrowheads are uniform notation (the diagram IS arrows\n// converging on the effect), so `arrowheads:false` toggles presentation, never data.\n//\n// Trig values are HARD-CODED literals: Math.tan/sin at runtime would make\n// byte-determinism hostage to engine-specific transcendental ulps.\n\nimport {\n FONT_FAMILY,\n LEGEND_SWATCH_W,\n clampLabel,\n estimateTextWidth,\n legendBlock,\n wrapLabel,\n wrapLabelBalanced,\n xmlEscape,\n type LegendEntry,\n} from \"../core\";\n\n// ── Input model ───────────────────────────────────────────────────────────────\n\nexport interface FishboneSubCause {\n id: number;\n /** Verbatim sub-cause text (drawn as one clamped line; full text in the <title>). */\n label: string;\n}\n\nexport interface FishboneCause {\n id: number;\n label: string;\n /** Exactly one sub-level is in scope (JUSE small bones); deeper nesting is typed away. */\n subCauses: FishboneSubCause[];\n /** Optional verbatim <title> override (defaults to the label). */\n title?: string;\n}\n\nexport interface FishboneCategory {\n id: number;\n label: string;\n causes: FishboneCause[];\n /** Optional verbatim <title> override (defaults to the label). */\n title?: string;\n}\n\nexport interface FishboneInput {\n /** The effect, written in the head box (verbatim). */\n effectLabel: string;\n /** Declared order is honored: first category nearest the head, alternating top/bottom. */\n categories: FishboneCategory[];\n}\n\n// ── Display vocabulary ────────────────────────────────────────────────────────\n\nexport interface FishboneLabels {\n /** Legend label for the cause-twig stroke (emitted only when sub-causes exist). */\n cause: string;\n /** Legend label for the sub-cause-twig stroke. */\n subCause: string;\n ariaLabel: string;\n}\n\nexport const FISHBONE_LABELS_EN: FishboneLabels = {\n cause: \"Cause\",\n subCause: \"Sub-cause\",\n ariaLabel: \"Cause-and-effect diagram (Ishikawa)\",\n};\n\n// ── Validation ────────────────────────────────────────────────────────────────\n\nexport type FishboneValidationCode = \"duplicate-id\";\n\nexport interface FishboneValidationIssue {\n /** Stable, machine-readable kebab-case code. */\n code: FishboneValidationCode;\n message: string;\n}\n\n/**\n * Thrown when ids collide within a namespace (categories / causes / sub-causes) —\n * the decoration hooks would be ambiguous. Carries ALL issues, deterministically\n * sorted (namespace order, then ascending id), never just the first. Everything\n * else (empty labels, zero causes, zero categories) is tolerated and drawn as\n * declared. The message mirrors the fault-tree shape (`invalid fishbone: …; …`)\n * so message-only logging keeps the diagram context for both modules.\n */\nexport class FishboneValidationError extends Error {\n readonly issues: readonly FishboneValidationIssue[];\n\n constructor(issues: readonly FishboneValidationIssue[]) {\n super(`invalid fishbone: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"FishboneValidationError\";\n this.issues = issues;\n }\n}\n\nfunction duplicateIds(ids: readonly number[]): number[] {\n const seen = new Set<number>();\n const dups = new Set<number>();\n for (const id of ids) {\n if (seen.has(id)) dups.add(id);\n seen.add(id);\n }\n return [...dups].sort((a, b) => a - b);\n}\n\nfunction validateIds(input: FishboneInput): void {\n const issues: FishboneValidationIssue[] = [];\n const collect = (noun: string, ids: readonly number[]): void => {\n for (const id of duplicateIds(ids)) {\n issues.push({ code: \"duplicate-id\", message: `duplicate ${noun} id ${id}` });\n }\n };\n collect(\"category\", input.categories.map((c) => c.id));\n collect(\"cause\", input.categories.flatMap((c) => c.causes.map((k) => k.id)));\n collect(\n \"sub-cause\",\n input.categories.flatMap((c) => c.causes.flatMap((k) => k.subCauses.map((s) => s.id))),\n );\n if (issues.length > 0) throw new FishboneValidationError(issues);\n}\n\n// ── Options ───────────────────────────────────────────────────────────────────\n\nexport interface FishboneSvgOptions {\n /** Display clamp per label (verbatim text stays in the <title>). */\n maxLabelChars?: number;\n /** Label font size (px); default 12. */\n fontSize?: number;\n /** Set false to suppress the legend; default true (emits only when sub-causes exist). */\n legend?: boolean;\n /** Arrowheads on spine/bones/twigs (classic Ishikawa); default true. */\n arrowheads?: boolean;\n /** Display vocabulary — English default; see `compasso/locales/pt-br`. */\n labels?: FishboneLabels;\n}\n\n// ── Geometry constants ────────────────────────────────────────────────────────\n\n// Hard-coded trig literals for the 60° bone angle (see module header).\nconst TAN60 = 1.7320508075688772;\nconst SIN60 = 0.8660254037844386;\nconst COS60 = 0.5;\n\nconst PADDING = 32;\nconst ROW_GAP = 12;\n/** Min horizontal air between adjacent same-side bone content AABBs. */\nconst BONE_GAP = 36;\nconst CAT_PAD_X = 12;\nconst CAT_PAD_Y = 8;\n/** Air between the bone's outer tip and the category box. */\nconst CAT_GAP = 12;\nconst TAIL_EXTRA = 44;\nconst HEAD_GAP = 24;\nconst HEAD_PAD_X = 14;\nconst HEAD_PAD_Y = 10;\n/** Sub-cause labels are ONE clamped line at this per-line budget (band invariant). */\nconst SUB_PER_LINE = 18;\n/** Helvetica-like glyph box at the 12px reference: ascent 11 above the baseline,\n * descent 3 below. EVERY fontSize-dependent vertical reserve is derived from these\n * (see verticalMetrics) — never used directly, so no 12px-only constant can leak\n * into the layout. */\nconst ASCENT_12 = 11;\nconst DESCENT_12 = 3;\n\n// ── fontSize-derived vertical metrics ─────────────────────────────────────────\n\ninterface VerticalMetrics {\n /** Baseline-to-glyph-top reserve (mirrors outward-stacked text on bottom bones). */\n ascent: number;\n /** Stacked-line pitch: EXACTLY ascent + descent, so consecutive baselines one\n * lineH apart give glyph bands that touch without overlapping, at any fontSize. */\n lineH: number;\n /** Innermost baseline offset from its twig: descent + 1 keeps the glyph ink 1px\n * clear of the twig stroke at any fontSize (4 at the default 12). */\n twigGap: number;\n /** Sub-twig vertical rise. blockH ≤ 2·lineH = sV − twigGap − 8 < sV, so within one\n * band the cause-label strip and the sub-label strip occupy disjoint y-slabs with\n * ≥ 8px air, and a sub-twig stays spine-ward of its label's center while crossing\n * the cause strip (both by construction, at any fontSize). */\n sV: number;\n /** First cause band starts |y| ≥ spineClear from the spine (the cross-side slab);\n * tied to the 2-line strip height so the slab tracks the type scale — anything\n * beyond the fixed ~10px bone-arrowhead reach preserves the guarantee. */\n spineClear: number;\n /** Twig length beyond its content: the bone's horizontal run across a 2-line cause\n * strip plus 25px of air — strictly above the (2·lineH + twigGap)/TAN60 + 10\n * floor the label-vs-bone clearance needs, by construction at any fontSize. */\n boneClear: number;\n /** Min horizontal air between adjacent ×1.2-padded sub-label boxes on one twig\n * (one line-height, so the air scales with the type; see the station packing). */\n subGap: number;\n}\n\n/** Derives the vertical reserves from the glyph metrics at the requested size, so\n * the slab/clearance inequalities in fishboneSvg hold BY CONSTRUCTION at any\n * fontSize. At the default 12 they reduce exactly to the original constants\n * (lineH 14, twigGap 4, sV 40, spineClear 32, boneClear 44, subGap 14), keeping\n * default output byte-stable (pinned by test/fishbone/render.test.ts). */\nfunction verticalMetrics(fontSize: number): VerticalMetrics {\n // Ceil-scaled so a reserve never rounds below the true em-scaled glyph extent.\n const ascent = Math.ceil((ASCENT_12 * fontSize) / 12);\n const descent = Math.ceil((DESCENT_12 * fontSize) / 12);\n const lineH = ascent + descent;\n const twigGap = descent + 1;\n return {\n ascent,\n lineH,\n twigGap,\n sV: 2 * lineH + twigGap + 8,\n spineClear: 2 * lineH + twigGap,\n boneClear: Math.ceil((2 * lineH + twigGap) / TAN60) + 25,\n subGap: lineH,\n };\n}\n\n// Ink (zinc ramp on white — matches the genogram/ecomap emitters). The four line\n// levels carry a decreasing stroke hierarchy (the only styled distinction a reader\n// could miss — exactly what the conditional legend names).\nconst EDGE_INK = \"#71717a\";\nconst BOX_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst SPINE_W = 2.5;\nconst SPINE_OP = 0.85;\nconst BONE_W = 2;\nconst BONE_OP = 0.8;\nconst TWIG_W = 1.5;\nconst TWIG_OP = 0.75;\nconst SUB_W = 1.2;\nconst SUB_OP = 0.7;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n/** Arrowhead polygon: tip at (tipX,tipY), pointing along the unit vector (ux,uy). */\nfunction arrowHead(tipX: number, tipY: number, ux: number, uy: number, opacity: number): string {\n const LEN = 9;\n const HALF_W = 4.5;\n const bx = tipX - ux * LEN;\n const by = tipY - uy * LEN;\n const px = -uy;\n const py = ux;\n const points = [\n `${round(tipX)},${round(tipY)}`,\n `${round(bx + px * HALF_W)},${round(by + py * HALF_W)}`,\n `${round(bx - px * HALF_W)},${round(by - py * HALF_W)}`,\n ].join(\" \");\n return `<polygon points=\"${points}\" fill=\"${EDGE_INK}\" fill-opacity=\"${opacity}\"/>`;\n}\n\nfunction lineEl(x1: number, y1: number, x2: number, y2: number, w: number, op: number): string {\n return `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${EDGE_INK}\" stroke-width=\"${w}\" stroke-opacity=\"${op}\"/>`;\n}\n\n// ── Internal measured shapes ──────────────────────────────────────────────────\n// All x positions below are relative to the bone's spine attachment; all vertical\n// positions are MAGNITUDES (distance from the spine) — the bottom side mirrors y.\n\ninterface SubBand {\n sub: FishboneSubCause;\n line: string;\n w: number;\n /** Station x on the cause twig. */\n sx: number;\n /** Outer end x of the diagonal sub-twig (= the label's center x). */\n outerX: number;\n}\n\ninterface CauseBand {\n cause: FishboneCause;\n lines: string[];\n labelW: number;\n blockH: number;\n /** Twig magnitude from the spine (the band's spine-side edge). */\n offset: number;\n bandH: number;\n /** Bone crossing at the twig's magnitude (≤ 0). */\n bx: number;\n /** Twig free end (tail-ward). */\n freeEnd: number;\n subs: SubBand[];\n}\n\ninterface Bone {\n category: FishboneCategory;\n up: boolean;\n bands: CauseBand[];\n /** Bone vertical magnitude (attach at the spine, outer end at −B / +B). */\n B: number;\n catLines: string[];\n boxW: number;\n boxH: number;\n /** Content extents relative to the attach: [ax − relL, ax + relR] contains ALL ink. */\n relL: number;\n relR: number;\n /** Absolute attach x (assigned by per-side packing). */\n ax: number;\n}\n\n/**\n * Renders a declared Ishikawa diagram to a self-contained SVG string. Deterministic:\n * same data → same SVG. Zero categories yield a valid spine+head-only SVG. Throws\n * FishboneValidationError on duplicate ids within a namespace (all issues listed).\n * The root keeps numeric width/height attributes plus a matching viewBox.\n *\n * Collision guarantee, by construction from MEASURED label widths (asserted by\n * test/fishbone/geometry.test.ts, including at non-default font sizes). Every\n * vertical reserve is derived from the glyph metrics at opts.fontSize (see\n * verticalMetrics), so the inequalities hold at ANY fontSize, not only the default:\n * 1. within a band: the cause-label strip and the sub-label strip occupy disjoint\n * y-slabs (blockH ≤ 2·lineH = sV − twigGap − 8 < sV); sub labels are x-disjoint\n * by station packing over ×1.2-padded estimates (absorbs the estimator's\n * Helvetica-caps deficit); both strips clear the slanted bone by the\n * station/boneClear inequalities;\n * 2. across bands of one bone: bands are stacked disjoint y-intervals of measured\n * heights (ROW_GAP included), and the bone crosses each slab only at its own\n * clearance-checked x;\n * 3. across bones of one side: disjoint content AABBs packed with BONE_GAP;\n * 4. across sides: open half-planes separated by the |y| < spineClear spine slab;\n * 5. head/tail: the head box sits beyond every bone's right extent + HEAD_GAP.\n * Every reserved width comes from estimateTextWidth (deliberately wide, core\n * doctrine) and the emitter draws at the same font metrics — reserved ⊇ drawn.\n */\nexport function fishboneSvg(input: FishboneInput, opts: FishboneSvgOptions = {}): string {\n validateIds(input);\n\n const fontSize = opts.fontSize ?? 12;\n const { ascent, lineH, twigGap, sV, spineClear, boneClear, subGap } = verticalMetrics(fontSize);\n const labels = opts.labels ?? FISHBONE_LABELS_EN;\n const arrows = opts.arrowheads !== false;\n\n // ── Measure every bone (declared order; even index → top, odd → bottom). ─────\n const bones: Bone[] = input.categories.map((category, idx) => {\n let cursor = spineClear;\n const bands: CauseBand[] = category.causes.map((cause) => {\n const lines = wrapLabelBalanced(clampLabel(cause.label, opts.maxLabelChars));\n const labelW = Math.max(...lines.map((l) => estimateTextWidth(l, fontSize)));\n const blockH = lines.length * lineH;\n const offset = cursor;\n const bx = -offset / TAN60;\n\n // Sub stations right→left in declared order. The first inequality keeps the\n // bone-nearest label clear of the slanted bone at the sub strip's outer edge\n // ((sV − twigGap)/TAN60 + 10 of air, which dwarfs the estimator's half-label\n // caps deficit at any fontSize). Successive stations keep the label boxes\n // disjoint with subGap air between ×1.2-PADDED estimates: CHAR_W 0.6 under-\n // reads Helvetica CAPS (≈ 0.72 em/char average), so padding each estimated\n // width by 20% restores reserved ⊇ drawn for caps-heavy labels — runs wider\n // than that (M/W walls) remain core-estimator doctrine, as everywhere else.\n const subs: SubBand[] = [];\n for (const sub of cause.subCauses) {\n const line = wrapLabel(clampLabel(sub.label, opts.maxLabelChars), SUB_PER_LINE, 1)[0]!;\n const w = estimateTextWidth(line, fontSize);\n const prev = subs.length > 0 ? subs[subs.length - 1]! : null;\n const sx =\n prev === null\n ? bx - (sV + lineH) / TAN60 - 10 - w / 2\n : prev.sx - (prev.w + w) * 0.6 - subGap;\n subs.push({ sub, line, w, sx, outerX: sx - sV / TAN60 });\n }\n\n const last = subs.length > 0 ? subs[subs.length - 1]! : null;\n const subSpan = last === null ? 0 : bx - (last.outerX - last.w / 2);\n // Twig length reserves, beyond the boneClear terms, a third term when subs\n // exist: the cause label must end BEFORE the leftmost sub-twig's outer x —\n // the diagonal sub-twigs descend through the cause-label y-slab, so a long\n // cause label hugging the free end could otherwise sit under them. (The\n // band-disjointness argument covers label strips, not the sub LINES.)\n const twigLen =\n last === null\n ? labelW + boneClear\n : Math.max(labelW + boneClear, subSpan + boneClear, labelW + (bx - last.outerX) + 10);\n\n const bandH = Math.max(blockH + twigGap, subs.length > 0 ? sV + lineH + twigGap : 0) + ROW_GAP;\n cursor += bandH;\n return { cause, lines, labelW, blockH, offset, bandH, bx, freeEnd: bx - twigLen, subs };\n });\n\n const B = cursor + 16;\n const catLines = wrapLabelBalanced(clampLabel(category.label, opts.maxLabelChars));\n const boxW = Math.max(...catLines.map((l) => estimateTextWidth(l, fontSize))) + CAT_PAD_X * 2;\n const boxH = catLines.length * lineH + CAT_PAD_Y * 2;\n const tipX = -B / TAN60;\n return {\n category,\n up: idx % 2 === 0,\n bands,\n B,\n catLines,\n boxW,\n boxH,\n // Left extent: the category box's left edge or the deepest twig free end —\n // every label sits AT or right of its twig's free end, every sub label sits\n // right of the free end too (twigLen ≥ subSpan + boneClear).\n relL: Math.max(B / TAN60 + boxW / 2, ...bands.map((b) => -b.freeEnd)),\n // Right extent: a wide category box on a short bone may overhang the attach.\n relR: Math.max(0, boxW / 2 + tipX),\n ax: 0,\n };\n });\n\n // ── Pack each side independently, right→left in declared order. ──────────────\n const cursors = { top: 0, bottom: 0 };\n for (const bone of bones) {\n const side = bone.up ? \"top\" : \"bottom\";\n bone.ax = cursors[side] - bone.relR;\n cursors[side] = bone.ax - bone.relL - BONE_GAP;\n }\n\n // ── Head box + spine extents (working coords: spine y = 0). ──────────────────\n const effLines = wrapLabelBalanced(clampLabel(input.effectLabel, opts.maxLabelChars));\n const headW = Math.max(...effLines.map((l) => estimateTextWidth(l, fontSize))) + HEAD_PAD_X * 2;\n const headH = effLines.length * lineH + HEAD_PAD_Y * 2;\n // Every bone's right extent is ≤ 0 by packing, so the head clears all of them.\n const headLeft = bones.length > 0 ? HEAD_GAP : 0;\n const tailX =\n bones.length > 0\n ? Math.min(...bones.map((b) => b.ax - b.relL)) - TAIL_EXTRA\n : headLeft - (TAIL_EXTRA + HEAD_GAP);\n\n // ── Bounds → shift positive (ecomap pattern). ────────────────────────────────\n let minY = -headH / 2;\n let maxY = headH / 2;\n for (const bone of bones) {\n const reach = bone.B + CAT_GAP + bone.boxH;\n if (bone.up) minY = Math.min(minY, -reach);\n else maxY = Math.max(maxY, reach);\n }\n const dx = PADDING - tailX;\n const dy = PADDING - minY;\n let width = headLeft + headW - tailX + PADDING * 2;\n let height = maxY - minY + PADDING * 2;\n const spineY = dy;\n\n const centeredYs = (cy: number, n: number): number[] =>\n Array.from({ length: n }, (_, i) => cy - ((n - 1) * lineH) / 2 + i * lineH + fontSize * 0.32);\n\n // Band text stacks OUTWARD from its strip's spine-side edge (magnitude e): on top\n // bones the innermost line's baseline sits twigGap beyond the edge (= descent + 1,\n // ink 1px clear of the twig at any fontSize); the bottom side mirrors with the\n // ascent so the glyphs occupy the mirrored strip.\n const bandBaselines = (e: number, n: number, up: boolean): number[] =>\n Array.from({ length: n }, (_, k) =>\n up ? spineY - (e + twigGap + (n - 1 - k) * lineH) : spineY + e + twigGap + ascent + k * lineH,\n );\n\n const textBlock = (anchor: \"start\" | \"middle\", x: number, ys: number[], lines: string[]): string =>\n `<text text-anchor=\"${anchor}\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">` +\n lines.map((line, i) => `<tspan x=\"${round(x)}\" y=\"${round(ys[i]!)}\">${xmlEscape(line)}</tspan>`).join(\"\") +\n `</text>`;\n\n const parts: string[] = [];\n\n // ── Spine (under everything), arrow into the head's left edge. ───────────────\n {\n const body = [lineEl(tailX + dx, spineY, headLeft + dx, spineY, SPINE_W, SPINE_OP)];\n if (arrows) body.push(arrowHead(headLeft + dx, spineY, 1, 0, SPINE_OP));\n parts.push(`<g data-edge-id=\"spine\"><title>${xmlEscape(labels.ariaLabel)}</title>${body.join(\"\")}</g>`);\n }\n\n // ── Bones, twigs, sub-twigs — declared order. ────────────────────────────────\n for (const bone of bones) {\n const sgn = bone.up ? -1 : 1;\n const ax = bone.ax + dx;\n const tipX = ax - bone.B / TAN60;\n\n const body = [lineEl(tipX, spineY + sgn * bone.B, ax, spineY, BONE_W, BONE_OP)];\n // The bone runs from the outer tip INTO the spine: on a top bone that direction\n // is down-right (+y), on a bottom bone up-right (−y) — opposite the side sign.\n if (arrows) body.push(arrowHead(ax, spineY, COS60, -sgn * SIN60, BONE_OP));\n const boxTop = bone.up ? spineY - bone.B - CAT_GAP - bone.boxH : spineY + bone.B + CAT_GAP;\n body.push(\n `<rect x=\"${round(tipX - bone.boxW / 2)}\" y=\"${round(boxTop)}\" width=\"${round(bone.boxW)}\" height=\"${round(bone.boxH)}\" rx=\"2\" fill=\"transparent\" stroke=\"${BOX_STROKE}\" stroke-width=\"1.5\"/>`,\n );\n body.push(textBlock(\"middle\", tipX, centeredYs(boxTop + bone.boxH / 2, bone.catLines.length), bone.catLines));\n parts.push(\n `<g data-node-id=\"b${bone.category.id}\"><title>${xmlEscape(bone.category.title ?? bone.category.label)}</title>${body.join(\"\")}</g>`,\n );\n\n for (const band of bone.bands) {\n const ty = spineY + sgn * band.offset;\n const bx = ax + band.bx;\n const freeEnd = ax + band.freeEnd;\n const cbody = [lineEl(freeEnd, ty, bx, ty, TWIG_W, TWIG_OP)];\n if (arrows) cbody.push(arrowHead(bx, ty, 1, 0, TWIG_OP));\n cbody.push(textBlock(\"start\", freeEnd + 2, bandBaselines(band.offset, band.lines.length, bone.up), band.lines));\n parts.push(\n `<g data-node-id=\"c${band.cause.id}\"><title>${xmlEscape(band.cause.title ?? band.cause.label)}</title>${cbody.join(\"\")}</g>`,\n );\n\n for (const s of band.subs) {\n const sx = ax + s.sx;\n const ox = ax + s.outerX;\n const sbody = [lineEl(ox, spineY + sgn * (band.offset + sV), sx, ty, SUB_W, SUB_OP)];\n // Parallel to the bone, pointing into the twig — same spine-ward direction.\n if (arrows) sbody.push(arrowHead(sx, ty, COS60, -sgn * SIN60, SUB_OP));\n const baseline = bone.up\n ? spineY - (band.offset + sV + twigGap)\n : spineY + band.offset + sV + twigGap + ascent;\n sbody.push(textBlock(\"middle\", ox, [baseline], [s.line]));\n parts.push(`<g data-node-id=\"s${s.sub.id}\"><title>${xmlEscape(s.sub.label)}</title>${sbody.join(\"\")}</g>`);\n }\n }\n }\n\n // ── Effect head (on top), vertically centered on the spine. ──────────────────\n {\n const x = headLeft + dx;\n parts.push(\n `<g data-node-id=\"head\"><title>${xmlEscape(input.effectLabel)}</title>` +\n `<rect x=\"${round(x)}\" y=\"${round(spineY - headH / 2)}\" width=\"${round(headW)}\" height=\"${round(headH)}\" rx=\"2\" fill=\"transparent\" stroke=\"${BOX_STROKE}\" stroke-width=\"2\"/>` +\n textBlock(\"middle\", x + headW / 2, centeredYs(spineY, effLines.length), effLines) +\n `</g>`,\n );\n }\n\n // ── Conditional legend: the fishbone is fully labeled inline — the only styled\n // distinction a reader could miss is the cause vs sub-cause stroke hierarchy,\n // so used-keys-only means: both entries when at least one sub-cause exists,\n // otherwise no legend at all. ────────────────────────────────────────────────\n const anySubs = input.categories.some((c) => c.causes.some((k) => k.subCauses.length > 0));\n if (opts.legend !== false && anySubs) {\n const entries: LegendEntry[] = [\n {\n swatch: (x, y) => lineEl(x, y, x + LEGEND_SWATCH_W, y, TWIG_W, TWIG_OP),\n label: labels.cause,\n },\n {\n swatch: (x, y) => lineEl(x, y + 5, x + LEGEND_SWATCH_W, y - 5, SUB_W, SUB_OP),\n label: labels.subCause,\n },\n ];\n const block = legendBlock(entries, height);\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// Pedigree input model — declared CLINICAL facts only. A human pedigree is a clinical\n// record: compasso draws EXACTLY what the caller declares and NEVER infers. Two declared\n// parents with no declared Mating never merge into a couple; an unaffected glyph is only\n// ever filled when the caller declares the condition; a carrier dot, a proband arrow, a\n// deceased slash all require an explicit declaration. Mode-of-inheritance is read off the\n// topology by the clinician, never asserted by the renderer.\n//\n// Notation: Bennett RL, Steinhaus French K, Resta RG, Doyle DL, \"Standardized Human\n// Pedigree Nomenclature: Update and Assessment of the Recommendations of the National\n// Society of Genetic Counselors\" (PSSC), J Genet Couns 2008; 17:424-433. Square = male,\n// circle = female, diamond = sex unknown — IDENTICAL to the genogram glyphs, so the sex\n// vocabulary (PersonSex/NodeShape) is RE-EXPORTED from ../genogram/types rather than\n// redefined (duplicating the union would be a lie). The clinical overlay (conditions,\n// carrier, proband/consultand, twins, consanguinity) is pedigree-native.\n\nimport type { PersonSex, NodeShape } from \"../genogram/types\";\nexport type { PersonSex, NodeShape };\n\n/** PSSC proband (filled arrow) / consultand (open arrow); null = neither. */\nexport type PedigreeRole = \"proband\" | \"consultand\" | null;\n\n/**\n * CLOSED life-status vocabulary. \"stillbirth\" draws an \"SB\" annotation below a full-size\n * glyph (uniform glyph metrics keep the overlap proof simple; the SB text + <title> carry\n * the fact). Pregnancy / spontaneous-loss / termination glyphs are DEFERRED (they would\n * introduce a non-square/circle/diamond glyph + gestational-age text) and are typed away\n * here — an unsupported status is a compile error, never a silent fallback.\n */\nexport const LIFE_STATUSES = [\"alive\", \"stillbirth\"] as const;\nexport type LifeStatus = (typeof LIFE_STATUSES)[number];\n\n/** PSSC twin zygosity. mz = monozygotic (tie-bar), dz = dizygotic (no bar), unknown = \"?\". */\nexport type Zygosity = \"mz\" | \"dz\" | \"unknown\";\n\n/** A condition referenced by Individual.affectedBy; drives the filled-glyph partitions. */\nexport interface Condition {\n id: number;\n /** Verbatim condition name (legend + <title>; escaped on emit). */\n label: string;\n}\n\n/**\n * A pedigree individual — declared clinical facts only; nothing inferred. Reuses the\n * genogram's exact person grammar ({ id, label, sex, deceased }) but `generation` is\n * MANDATORY and integer (a pedigree without generations is not a pedigree), and the\n * clinical overlay (affectedBy, carrier, role, lifeStatus) is pedigree-specific.\n */\nexport interface Individual {\n id: number;\n label: string;\n /** square/circle/diamond — re-exported genogram vocabulary. */\n sex: PersonSex;\n /** MANDATORY integer; smaller = older = higher row (validated, never derived here). */\n generation: number;\n /** Deceased slash (PSSC: top-left → bottom-right), reusing the genogram's exact line. */\n deceased: boolean;\n /** Asymptomatic-carrier center dot; PSSC puts it on UNAFFECTED carriers only. */\n carrier: boolean;\n /** PSSC proband (filled arrow) / consultand (open arrow); null = neither. */\n role: PedigreeRole;\n /** \"stillbirth\" → an \"SB\" annotation below the glyph. */\n lifeStatus: LifeStatus;\n /** Condition ids this individual is affected by (filled-glyph partitions, ≤4). [] = unaffected. */\n affectedBy: number[];\n /** Optional verbatim <title> override (defaults to \"<address> · label[ · affected: …]\"). */\n title?: string;\n}\n\n/**\n * A declared mating between two individuals. The pair is unordered (the layout normalizes\n * a < b). `consanguineous` draws the PSSC DOUBLE mating line — the core distinguishing\n * mark a genogram Union has no concept of (and the single biggest reason pedigree owns its\n * relational layer instead of importing the genogram's). No status vocabulary: a pedigree\n * does not draw McGoldrick divorce slashes.\n */\nexport interface Mating {\n id: number;\n partnerAId: number;\n partnerBId: number;\n /** PSSC double mating line. */\n consanguineous: boolean;\n}\n\n/** A twin group within ONE sibship: ≥2 child ids of one zygosity, all in that sibship. */\nexport interface TwinGroup {\n /** ≥2 child ids from THIS sibship that are twins of one zygosity. */\n childIds: number[];\n zygosity: Zygosity;\n}\n\n/**\n * The children of one mating, in declared left-to-right birth order (the fishbone \"declared\n * order is data\" doctrine). The sibship is a FIRST-CLASS declared object — twin zygosity\n * and birth order live here, not on the individual — so the layout draws one drop-bar per\n * DECLARED sibship and never auto-attaches a child to a mating.\n */\nexport interface Sibship {\n id: number;\n matingId: number;\n /** Child individual ids, left→right (declared order honored; PSSC birth order). */\n childIds: number[];\n /** Twin groupings among these children; [] = no twins. */\n twinGroups: TwinGroup[];\n}\n\n/** Input to the pedigree render pipeline. */\nexport interface PedigreeInput {\n conditions: Condition[];\n individuals: Individual[];\n matings: Mating[];\n sibships: Sibship[];\n}\n","// Display vocabularies — every human-readable string the pedigree emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// The split mirrors the fault-tree/genogram: TitleLabels are woven into element <title>s\n// by the LAYOUT (verbatim-preserving facts); SvgLabels are drawn by the EMITTER (legend\n// entries + accessibility text). Condition labels come from the caller's\n// `input.conditions[i].label`, not these packs (caller data, escaped on emit).\n\nimport type { NodeShape } from \"../genogram/types\";\nimport type { Zygosity } from \"./types\";\n\n/** Labels woven into element/node <title>s by the LAYOUT (verbatim-preserving). */\nexport interface PedigreeTitleLabels {\n /** Prefix → \"affected: <condition.label>, …\". */\n affected: string;\n carrier: string;\n deceased: string;\n proband: string;\n consultand: string;\n consanguineous: string;\n mating: string;\n sibship: string;\n twins: Record<Zygosity, string>;\n stillbirth: string;\n /** Used in the generation-gutter aria-style <title>, e.g. \"generation I\". */\n generation: string;\n}\n\nexport const PEDIGREE_TITLE_LABELS_EN: PedigreeTitleLabels = {\n affected: \"affected\",\n carrier: \"carrier\",\n deceased: \"deceased\",\n proband: \"proband\",\n consultand: \"consultand\",\n consanguineous: \"consanguineous mating\",\n mating: \"mating\",\n sibship: \"sibship\",\n twins: {\n mz: \"monozygotic twins\",\n dz: \"dizygotic twins\",\n unknown: \"twins, zygosity unknown\",\n },\n stillbirth: \"stillbirth\",\n generation: \"generation\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface PedigreeSvgLabels {\n shapes: Record<NodeShape, string>;\n unaffected: string;\n carrier: string;\n deceased: string;\n proband: string;\n consultand: string;\n consanguineous: string;\n twins: Record<Zygosity, string>;\n stillbirth: string;\n isolated: string;\n ariaLabel: string;\n}\n\nexport const PEDIGREE_SVG_LABELS_EN: PedigreeSvgLabels = {\n shapes: {\n square: \"Male\",\n circle: \"Female\",\n diamond: \"Sex unknown\",\n },\n unaffected: \"Unaffected\",\n carrier: \"Carrier\",\n deceased: \"Deceased\",\n proband: \"Proband\",\n consultand: \"Consultand\",\n consanguineous: \"Consanguineous mating\",\n twins: {\n mz: \"Monozygotic twins\",\n dz: \"Dizygotic twins\",\n unknown: \"Twins (zygosity unknown)\",\n },\n stillbirth: \"Stillbirth\",\n isolated: \"No recorded relatives\",\n ariaLabel: \"Pedigree chart\",\n};\n","// Pedigree validation — REJECT, never repair. A human pedigree is a CLINICAL artifact:\n// silently dropping a dangling child reference or drawing a mating to a phantom partner is\n// a medical error (mode-of-inheritance is read off the topology). This is exactly the\n// fault-tree's \"safety artifact → refuse, don't repair\" situation, and the OPPOSITE of the\n// genogram's \"elicited incrementally → filter dangling silently\". So the layout/render\n// entry points THROW PedigreeValidationError carrying EVERY issue, deduplicated and\n// deterministically sorted (by code, then message — byte comparison, no locale collation),\n// each with a STABLE kebab-case machine-readable `code`.\n//\n// THREE-PHASE gating, mirroring ./../fault-tree/validate.ts exactly — each phase gated on\n// the previous being clean ENOUGH for the next to be meaningful, NOT on \"zero issues so\n// far\" (the throw must carry ALL real issues):\n// (0) duplicate ids (per namespace: individual / mating / sibship). The lookup maps below\n// are first-occurrence-wins, so every later rule would validate whichever duplicate\n// row was declared first — making the issue list array-order-dependent. When any\n// duplicate-id exists we report ONLY those and stop.\n// (1) reference / semantic rules: partner existence + self-mating, sibship→mating\n// existence, child existence, child-of-two-sibships, twin membership, integer\n// generation, condition existence + the ≤4 quadrant cap (PSSC).\n// (2) graph rule = generation-inversion (the only rule needing the resolved parent→child\n// relation), gated ONLY on the reference-integrity subset that makes the parent→child\n// walk meaningful (unknown-partner / unknown-sibship-mating / unknown-child corrupt\n// it; a non-integer generation or a too-many-conditions defect does not).\n//\n// Tolerated, by design (drawn as declared, never repaired): empty labels (drawn empty,\n// <title> present); an individual in no mating/sibship (a founder or a loose proband —\n// drawn isolated, the genogram's isolated-group precedent); a mating with no sibship (a\n// childless declared couple — a bare mating line); `carrier` on an affected individual\n// (clinically valid — a manifesting heterozygote; the dot is just hidden under the fill).\n//\n// CROSS-GENERATION MATING is NOT rejected (avuncular unions are clinically real — §1.7);\n// only true generation-inversion (a child older than its parent row) is rejected.\n\nimport type { PedigreeInput, Individual, Mating, Sibship } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type PedigreeIssueCode =\n | \"duplicate-id\"\n | \"unknown-partner\"\n | \"self-mating\"\n | \"unknown-sibship-mating\"\n | \"unknown-child\"\n | \"child-of-two-sibships\"\n | \"twin-not-in-sibship\"\n | \"twin-group-too-small\"\n | \"twin-group-not-contiguous\"\n | \"generation-not-integer\"\n | \"unknown-condition\"\n | \"too-many-conditions\"\n | \"generation-inversion\";\n\nexport interface PedigreeIssue {\n code: PedigreeIssueCode;\n message: string;\n}\n\n/** Thrown by computePedigreeLayout / pedigreeSvg on a structurally invalid pedigree. */\nexport class PedigreeValidationError extends Error {\n readonly issues: readonly PedigreeIssue[];\n\n constructor(issues: readonly PedigreeIssue[]) {\n super(`invalid pedigree: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"PedigreeValidationError\";\n this.issues = issues;\n }\n}\n\n/** The PSSC quadrant cap: ≤4 conditions partition a glyph; beyond that needs a key/table. */\nexport const MAX_CONDITIONS_PER_INDIVIDUAL = 4;\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable across\n * engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly PedigreeIssue[]): readonly PedigreeIssue[] {\n const unique = new Map<string, PedigreeIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically sorted\n * (code, then message) — array order of individuals/matings/sibships never changes the\n * result. Empty input (no individuals AND no matings AND no sibships) is valid by\n * definition (the renderer's empty-but-valid SVG case) and reports no issues.\n */\nexport function pedigreeIssues(input: PedigreeInput): readonly PedigreeIssue[] {\n if (input.individuals.length === 0 && input.matings.length === 0 && input.sibships.length === 0) return [];\n\n const issues: PedigreeIssue[] = [];\n const push = (code: PedigreeIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── Phase 0: duplicate ids (per namespace — hooks must be unique). Any duplicate makes\n // the structure ambiguous (first-wins maps), so report ONLY these and stop. ──────────\n const individualById = new Map<number, Individual>();\n const dupIndividualIds = new Set<number>();\n for (const ind of input.individuals) {\n if (individualById.has(ind.id)) dupIndividualIds.add(ind.id);\n else individualById.set(ind.id, ind);\n }\n for (const id of [...dupIndividualIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate individual id ${id}`);\n }\n const matingById = new Map<number, Mating>();\n const dupMatingIds = new Set<number>();\n for (const m of input.matings) {\n if (matingById.has(m.id)) dupMatingIds.add(m.id);\n else matingById.set(m.id, m);\n }\n for (const id of [...dupMatingIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate mating id ${id}`);\n }\n const sibshipById = new Map<number, Sibship>();\n const dupSibshipIds = new Set<number>();\n for (const s of input.sibships) {\n if (sibshipById.has(s.id)) dupSibshipIds.add(s.id);\n else sibshipById.set(s.id, s);\n }\n for (const id of [...dupSibshipIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate sibship id ${id}`);\n }\n\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n const individuals = [...individualById.values()].sort((a, b) => a.id - b.id);\n const matings = [...matingById.values()].sort((a, b) => a.id - b.id);\n const sibships = [...sibshipById.values()].sort((a, b) => a.id - b.id);\n const conditionIds = new Set(input.conditions.map((c) => c.id));\n\n // ── Phase 1: reference / semantic rules. ──────────────────────────────────────────────\n\n // Matings reference declared individuals and are not self-matings.\n for (const m of matings) {\n if (!individualById.has(m.partnerAId)) {\n push(\"unknown-partner\", `mating ${m.id} references unknown individual ${m.partnerAId}`);\n }\n if (!individualById.has(m.partnerBId)) {\n push(\"unknown-partner\", `mating ${m.id} references unknown individual ${m.partnerBId}`);\n }\n if (m.partnerAId === m.partnerBId) {\n push(\"self-mating\", `mating ${m.id} mates individual ${m.partnerAId} with itself`);\n }\n }\n\n // Sibships reference a declared mating; child ids reference declared individuals.\n for (const s of sibships) {\n if (!matingById.has(s.matingId)) {\n push(\"unknown-sibship-mating\", `sibship ${s.id} references unknown mating ${s.matingId}`);\n }\n for (const childId of s.childIds) {\n if (!individualById.has(childId)) {\n push(\"unknown-child\", `sibship ${s.id} references unknown child ${childId}`);\n }\n }\n // Twin members must belong to THIS sibship's declared children.\n const childSet = new Set(s.childIds);\n const offending = new Set<number>();\n for (const tg of s.twinGroups) {\n for (const memberId of tg.childIds) {\n if (!childSet.has(memberId)) offending.add(memberId);\n }\n }\n for (const memberId of [...offending].sort((a, b) => a - b)) {\n push(\"twin-not-in-sibship\", `twin ${memberId} is not a child of sibship ${s.id}`);\n }\n\n // A twin group must have at least 2 members (a singleton twin is structurally incoherent).\n for (const tg of s.twinGroups) {\n if (tg.childIds.length < 2) {\n const [only] = tg.childIds;\n push(\n \"twin-group-too-small\",\n `twin group in sibship ${s.id} has only 1 member (${only ?? \"none\"}) — at least 2 required`,\n );\n }\n }\n\n // A twin group must occupy a CONTIGUOUS run within the sibship's childIds order.\n // The layout draws the MZ tie-bar assuming adjacency; a non-contiguous group would\n // cross an in-between sibling, corrupting the topology.\n for (const tg of s.twinGroups) {\n if (tg.childIds.length < 2) continue; // already caught above; skip to avoid noise\n const memberSet = new Set(tg.childIds);\n const positions = s.childIds\n .map((cid, pos) => (memberSet.has(cid) ? pos : -1))\n .filter((p) => p >= 0);\n if (positions.length === 0) continue; // all members dangling — twin-not-in-sibship covers it\n const first = positions[0]!;\n const last = positions[positions.length - 1]!;\n if (last - first !== positions.length - 1) {\n const memberList = [...tg.childIds].sort((a, b) => a - b).join(\", \");\n push(\n \"twin-group-not-contiguous\",\n `twin group [${memberList}] in sibship ${s.id} is not a contiguous run in childIds`,\n );\n }\n }\n }\n\n // An individual may belong to AT MOST one sibship (ambiguous descent otherwise).\n const sibshipsOfChild = new Map<number, number[]>();\n for (const s of sibships) {\n for (const childId of s.childIds) {\n const arr = sibshipsOfChild.get(childId) ?? [];\n arr.push(s.id);\n sibshipsOfChild.set(childId, arr);\n }\n }\n for (const [childId, sibIds] of [...sibshipsOfChild.entries()].sort((a, b) => a[0] - b[0])) {\n if (sibIds.length > 1) {\n push(\n \"child-of-two-sibships\",\n `individual ${childId} is a child of sibships ${[...sibIds].sort((a, b) => a - b).join(\", \")}`,\n );\n }\n }\n\n // Generation must be an integer (Number.isInteger also rejects NaN/±Infinity/fractions).\n for (const ind of individuals) {\n if (!Number.isInteger(ind.generation)) {\n push(\"generation-not-integer\", `individual ${ind.id} has non-integer generation ${ind.generation}`);\n }\n }\n\n // Conditions referenced by affectedBy exist; ≤4 conditions per individual (PSSC quadrant cap).\n for (const ind of individuals) {\n for (const conditionId of ind.affectedBy) {\n if (!conditionIds.has(conditionId)) {\n push(\"unknown-condition\", `individual ${ind.id} is affected by unknown condition ${conditionId}`);\n }\n }\n if (ind.affectedBy.length > MAX_CONDITIONS_PER_INDIVIDUAL) {\n push(\n \"too-many-conditions\",\n `individual ${ind.id} has ${ind.affectedBy.length} conditions — at most ${MAX_CONDITIONS_PER_INDIVIDUAL} can be drawn`,\n );\n }\n }\n\n // ── Phase 2: graph rule (generation-inversion) — gated ONLY on the reference-integrity\n // codes that corrupt the parent→child walk. A non-integer generation or a too-many-\n // conditions defect leaves the parent→child relation walkable, so it does NOT suppress\n // this phase (suppressing would hide an honest inversion, breaking the throw-with-ALL\n // doctrine). A NaN generation simply never satisfies the strict `>` comparison below. ─\n const GRAPH_BLOCKING: ReadonlySet<PedigreeIssueCode> = new Set([\n \"duplicate-id\",\n \"unknown-partner\",\n \"unknown-sibship-mating\",\n \"unknown-child\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n for (const s of sibships) {\n const mating = matingById.get(s.matingId);\n if (mating === undefined) continue;\n const a = individualById.get(mating.partnerAId);\n const b = individualById.get(mating.partnerBId);\n // A child must sit BELOW (strictly greater generation than) the LOWER of its parents\n // (the row the sibship hangs from — §1.4). Cross-generation matings are tolerated; a\n // child older than the parent row it descends from is an inversion (the tree flips).\n const parentGenerations = [a, b]\n .filter((p): p is Individual => p !== undefined && Number.isInteger(p.generation))\n .map((p) => p.generation);\n if (parentGenerations.length === 0) continue;\n const parentRow = Math.max(...parentGenerations);\n for (const childId of s.childIds) {\n const child = individualById.get(childId);\n if (child === undefined || !Number.isInteger(child.generation)) continue;\n if (child.generation <= parentRow) {\n push(\n \"generation-inversion\",\n `child ${childId} (generation ${child.generation}) is not below its parents (generation ${parentRow}) in sibship ${s.id}`,\n );\n }\n }\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws PedigreeValidationError (carrying ALL issues) when the input is invalid. */\nexport function validatePedigree(input: PedigreeInput): void {\n const issues = pedigreeIssues(input);\n if (issues.length > 0) throw new PedigreeValidationError(issues);\n}\n","// PURE pedigree layout — the single source of truth for positioning and connector\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so web/PDF/image\n// surfaces never drift. Deliberately PURE (no DOM, no clock, no randomness): the same\n// input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS what the caller declared. Validation\n// (./validate.ts) THROWS on a structurally invalid pedigree instead of repairing it — a\n// pedigree is a clinical record and silently altering its topology is a medical error.\n//\n// Notation: Bennett et al. 2008 PSSC (see ./types.ts header). Roman-numeral generations\n// (I, II, III…) in a left gutter, oldest = I on top; individuals numbered left-to-right\n// within a generation (the \"II-3\" address). Mating line (horizontal, between partners);\n// consanguineous = DOUBLE line; sibship drop-bar above sibs; one riser per child; twins\n// CONVERGE on the bar (MZ tie-bar / DZ none / unknown \"?\").\n//\n// LAYOUT — a GENERATION-ANCHORED FOREST SPAN-PACKER (the fault-tree's subtree-span packer,\n// inverted to be generation-anchored, §1.4):\n// 1. Rows by generation. Distinct generation values sorted ascending → row 0..R-1, top\n// to bottom (smaller = older = higher). Each row's y accrues prior rowHeights +\n// corridors (the fault-tree rowTop recurrence, keyed on generation not depth).\n// 2. Horizontal: a FOREST of mating subtrees. Each mating is a sub-root whose children\n// are its sibship members; we pack each subtree with asymmetric {spanL, spanR} exactly\n// like the fault-tree pack(). A child that is itself a mating partner roots its own\n// subtree below; founders/loose individuals are placed left-to-right after the forest.\n// Span intervals are disjoint by construction (the fault-tree inductive overlap proof\n// carries over — each subtree owns a disjoint x-interval), re-verified by the harness.\n// 3. Mating line at the partners' shared y (or a two-segment elbow for a cross-generation\n// mating — avuncular unions are clinically real, §1.7); consanguineous = two parallel\n// horizontals CONSANG_GAP apart.\n// 4. Twins (§1.4 / PSSC, VERIFY against Bennett et al. 2008 Fig. 2 twin panel before\n// trusting): the risers of a twin group CONVERGE to a single point on the sibship bar,\n// then split to each glyph. The route is fully ORTHOGONAL (down to a junction y,\n// HORIZONTAL to each twin's x, then DOWN to the glyph — never a diagonal fan, so the\n// overlap harness's nonOrthogonal check passes like every structural element). MZ adds\n// a short horizontal tie-bar between the convergent risers below the junction; DZ adds\n// none; unknown places a \"?\" glyph at the junction (a NODE annotation, harness-excluded\n// like the proband arrow + deceased slash).\n\nimport { clampLabel, estimateTextWidth, romanNumeral, wrapLabelBalanced, type Point } from \"../core\";\nimport { PEDIGREE_TITLE_LABELS_EN, type PedigreeTitleLabels } from \"./labels\";\nimport { validatePedigree } from \"./validate\";\nimport type { NodeShape } from \"../genogram/types\";\nimport type {\n Condition,\n Individual,\n Mating,\n PedigreeInput,\n PedigreeRole,\n Sibship,\n Zygosity,\n} from \"./types\";\n\nexport {\n PedigreeValidationError,\n pedigreeIssues,\n validatePedigree,\n type PedigreeIssue,\n type PedigreeIssueCode,\n} from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render). PREFIXED\n// (PED_*) so the root barrel's `export *` never collides with another module's value\n// constants (the v0.2 FT_LABEL_FONT rename class). ───────────────────────────────────\n/** Glyph side length / diameter (px). */\nexport const PED_GLYPH = 40;\n/** Node label font size (px). */\nexport const PED_LABEL_FONT = 12;\n/** Line height for stacked label lines (px). */\nexport const PED_LABEL_LINE_H = 14;\n/** Font size for the \"II-3\" within-generation address drawn under each glyph. */\nexport const PED_ADDRESS_FONT = 10;\n/** Gap from a glyph's bottom to the top of its first label line. */\nexport const PED_LABEL_GAP = 6;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────────\nconst PADDING = 32;\n/** Left gutter reserved for the Roman-numeral generation labels. */\nconst GUTTER = 36;\n/** Min horizontal air between two sibling/subtree intervals. */\nconst H_GAP = 28;\n/** Horizontal run of a mating line on each side of a partner glyph edge. */\nconst MATING_RUN = 22;\n/** Vertical band between a parent row's bottom and the next row (descent routes here). */\nconst CORRIDOR = 44;\n/** Drop of the twin convergence junction below the sibship bar. */\nconst TWIN_JUNCTION_DROP = 12;\n/** Gap from a hub's glyph bottom to the FIRST appended-spouse bridge dip (the genogram\n * serial-union stagger band: dips sit below the glyphs, ABOVE the labels). */\nconst BRIDGE_DIP_GAP = 10;\n/** Vertical step between successive appended-spouse bridge dips on the same row. */\nconst BRIDGE_DIP_STEP = 7;\n/** Horizontal step of each appended-spouse bridge's stub along the glyph's bottom edge, so two\n * bridges in the same row leave distinct stub columns (never a collinear shared vertical). The\n * small step keeps several distinct stubs inside the half-glyph even for a many-spouse hub. */\nconst BRIDGE_STUB_X_STEP = 3;\n\n// ── Namespaced element ids (one element kind per numeric block, extending the\n// genogram/fault-tree convention) — every data-edge-id stays traceable to its row. ──\nexport const PED_MATING_ID_BASE = 1_000_000; // + mating id (mating line; consang drawn double)\nexport const PED_DESCENT_ID_BASE = 2_000_000; // + sibship id (mating midpoint → sibship bar)\nexport const PED_SIBBAR_ID_BASE = 3_000_000; // + sibship id (the horizontal sibship bar)\nexport const PED_RISER_ID_BASE = 4_000_000; // + child individual id (bar → child)\nexport const PED_TWINBAR_ID_BASE = 5_000_000; // + (sibship id * 100 + twin ordinal) (MZ tie-bar)\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nfunction shapeForSex(sex: Individual[\"sex\"]): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────────\n\nexport interface PedigreeNode {\n individualId: number;\n shape: NodeShape;\n cx: number;\n cy: number;\n size: number;\n deceased: boolean;\n carrier: boolean;\n role: PedigreeRole;\n stillbirth: boolean;\n /** Condition ids in declared order → vertical fill partitions (≤4); [] = unaffected. */\n affectedBy: number[];\n labelLines: string[];\n /** Top of the first label line's box (below the glyph). */\n labelTop: number;\n /** \"II-3\" within-generation address. */\n addressLabel: string;\n /** Verbatim <title> text (never truncated). */\n title: string;\n}\n\nexport type PedigreeElementKind =\n | \"mating\"\n | \"mating-elbow\"\n | \"descent\"\n | \"sibship-bar\"\n | \"riser\"\n | \"twin-bar\";\n\nexport interface PedigreeElement {\n /** Namespaced id (PED_*_ID_BASE + …). */\n edgeId: number;\n kind: PedigreeElementKind;\n /** Every consecutive pair axis-aligned. */\n points: Point[];\n /** mating: draw a second parallel line (the PSSC consanguineous double line). */\n consanguineous: boolean;\n title: string;\n}\n\n/** Roman label + the y of a generation row (the left-margin gutter). */\nexport interface PedigreeGenerationLabel {\n roman: string;\n y: number;\n}\n\nexport interface PedigreeLayout {\n width: number;\n height: number;\n nodes: PedigreeNode[];\n elements: PedigreeElement[];\n generations: PedigreeGenerationLabel[];\n /** Used condition ids in declared order → assigned fill ink + verbatim label (the legend\n * keys these; label kept here so the emitter never re-derives it from a node title). */\n conditionFills: { id: number; ink: string; label: string }[];\n /** Twin zygosities actually used (drives the used-keys-only legend). */\n twinZygositiesUsed: Zygosity[];\n /** Junction points of unknown-zygosity twin groups — the emitter draws a \"?\" at each. */\n unknownTwinJunctions: Point[];\n /** Individuals in no mating and no sibship — grouped + drawn aside (genogram precedent). */\n isolatedIndividualIds: number[];\n}\n\nexport interface PedigreeLayoutOptions {\n /** Cap each node's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for <title>s — English default; see locale packs. */\n titleLabels?: PedigreeTitleLabels;\n}\n\n/**\n * Fixed condition fill ramp — the existing zinc ink array (NO new palette, §1.7). At most\n * 4 conditions are ever drawn (the PSSC quadrant cap, enforced in ./validate.ts), so 4\n * distinct, decodable solids suffice; the legend keys each one.\n */\nexport const PED_CONDITION_FILLS = [\"#52525b\", \"#a1a1aa\", \"#3f3f46\", \"#71717a\"] as const;\n\n// ── Measurement ───────────────────────────────────────────────────────────────────────\n\nfunction wrapPedigreeLabel(displayLabel: string): string[] {\n if (displayLabel === \"\") return [];\n return wrapLabelBalanced(displayLabel, 2);\n}\n\nfunction individualTitle(ind: Individual, address: string, conditionLabelById: Map<number, string>, titleLabels: PedigreeTitleLabels): string {\n if (ind.title !== undefined) return ind.title;\n const parts: string[] = [`${address} · ${ind.label}`];\n if (ind.affectedBy.length > 0) {\n const names = ind.affectedBy.map((id) => conditionLabelById.get(id) ?? String(id));\n parts.push(`${titleLabels.affected}: ${names.join(\", \")}`);\n }\n if (ind.carrier && ind.affectedBy.length === 0) parts.push(titleLabels.carrier);\n if (ind.deceased) parts.push(titleLabels.deceased);\n if (ind.role === \"proband\") parts.push(titleLabels.proband);\n else if (ind.role === \"consultand\") parts.push(titleLabels.consultand);\n if (ind.lifeStatus === \"stillbirth\") parts.push(titleLabels.stillbirth);\n return parts.join(\" · \");\n}\n\n// ── Internal working model ──────────────────────────────────────────────────────────────\n\ninterface Placed {\n ind: Individual;\n cx: number;\n /** Sub-tree half-extents (cover this individual's entire subtree drawing). */\n spanL: number;\n spanR: number;\n}\n\n/**\n * Deterministic, overlap-proof pedigree layout (pure function of the inputs). Validates\n * first and THROWS PedigreeValidationError on a structurally invalid pedigree — never\n * sanitizes. Empty input yields an empty, padded layout.\n */\nexport function computePedigreeLayout(\n input: PedigreeInput,\n opts: PedigreeLayoutOptions = {},\n): PedigreeLayout {\n if (input.individuals.length === 0 && input.matings.length === 0 && input.sibships.length === 0) {\n return {\n width: PADDING * 2,\n height: PADDING * 2,\n nodes: [],\n elements: [],\n generations: [],\n conditionFills: [],\n twinZygositiesUsed: [],\n unknownTwinJunctions: [],\n isolatedIndividualIds: [],\n };\n }\n validatePedigree(input);\n\n const titleLabels = opts.titleLabels ?? PEDIGREE_TITLE_LABELS_EN;\n const individuals = [...input.individuals].sort((a, b) => a.id - b.id);\n const individualById = new Map(individuals.map((i) => [i.id, i]));\n const matings = [...input.matings].sort((a, b) => a.id - b.id);\n const sibships = [...input.sibships].sort((a, b) => a.id - b.id);\n const conditionLabelById = new Map<number, string>(input.conditions.map((c: Condition) => [c.id, c.label]));\n\n // Normalize partner order (a < b) so the pair is unordered, deterministic geometry.\n const partnersOf = (m: Mating): [number, number] =>\n m.partnerAId <= m.partnerBId ? [m.partnerAId, m.partnerBId] : [m.partnerBId, m.partnerAId];\n\n // ── Generation rows: distinct generations ascending → row index 0..R-1. ─────────────\n const distinctGenerations = [...new Set(individuals.map((i) => i.generation))].sort((a, b) => a - b);\n const rowOfGeneration = new Map<number, number>();\n distinctGenerations.forEach((g, i) => rowOfGeneration.set(g, i));\n const rowCount = distinctGenerations.length;\n\n // ── Measure each individual's label block (used for span half-extents). ─────────────\n const labelLinesOf = new Map<number, string[]>();\n for (const ind of individuals) {\n labelLinesOf.set(ind.id, wrapPedigreeLabel(clampLabel(ind.label, opts.maxLabelChars)));\n }\n const nodeHalfWidth = (ind: Individual): number => {\n const lines = labelLinesOf.get(ind.id) ?? [];\n const labelW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, PED_LABEL_FONT)), 0);\n return Math.max(PED_GLYPH, labelW) / 2;\n };\n\n // ── Build the descent forest. A \"sibship subtree\" hangs a mating's children below it;\n // a child that is itself a mating partner roots its own mating subtree. We place by a\n // fault-tree-style post-order span pack over this forest. ──────────────────────────\n const childToSibship = new Map<number, Sibship>();\n for (const s of sibships) for (const c of s.childIds) childToSibship.set(c, s);\n const sibshipByMating = new Map<number, Sibship[]>();\n for (const s of sibships) {\n const arr = sibshipByMating.get(s.matingId) ?? [];\n arr.push(s);\n sibshipByMating.set(s.matingId, arr);\n }\n // Matings an individual partners in (declared id order for a stable tie-break).\n const matingsOfIndividual = new Map<number, Mating[]>();\n for (const m of matings) {\n for (const p of partnersOf(m)) {\n const arr = matingsOfIndividual.get(p) ?? [];\n arr.push(m);\n matingsOfIndividual.set(p, arr);\n }\n }\n\n const placedById = new Map<number, Placed>();\n // Cursor: the next free left edge for a new forest tree (kept ≥ existing extents).\n let cursorX = PADDING + GUTTER;\n\n /** Places a single individual glyph as a leaf subtree (no descent below it here). */\n const placeLeaf = (ind: Individual, leftEdge: number): Placed => {\n const half = nodeHalfWidth(ind);\n const cx = leftEdge + half;\n const placed: Placed = { ind, cx, spanL: half, spanR: half };\n placedById.set(ind.id, placed);\n return placed;\n };\n\n // To stay overlap-proof, place matings as left-to-right blocks. Each mating block =\n // [spouse glyph] over its FULL children band, with the shared (hub) partner placed once\n // and every later mating of that hub appended in a DISJOINT x-interval to the right of all\n // its earlier blocks. A child that is a partner of a LOWER mating roots that mating block\n // recursively beneath it. Founders not in any mating come last.\n const placedMatings = new Set<number>();\n const matingCount = (id: number): number => (matingsOfIndividual.get(id) ?? []).length;\n // Hub bookkeeping. A HUB is an individual in ≥2 matings (remarriage / serial union). It is\n // placed ONCE (by its first packed mating) and pinned; `hubCursor` is the next free left\n // edge to the RIGHT of every block already hung off that hub, so each subsequent spouse\n // block owns a truly disjoint interval (§1.4 invariant restored on the shared-parent path).\n // `hubSpouseSeq` counts spouses placed beside the hub so far (only the placement order).\n const hubCursor = new Map<number, number>();\n const hubSpouseSeq = new Map<number, number>();\n\n /**\n * Packs a mating subtree starting at `leftEdge`; returns the right edge consumed. The\n * sibship's children are packed FIRST into a disjoint band, the spouse is centered over\n * that band, and the partner (or the already-placed hub) sits adjacent to the spouse — so\n * the whole block (spouse + its children) owns one disjoint x-interval. A child that\n * partners a lower mating roots that mating block recursively beneath it.\n */\n const packMating = (mating: Mating, leftEdge: number): number => {\n placedMatings.add(mating.id);\n const [aId, bId] = partnersOf(mating);\n const a = individualById.get(aId)!;\n const b = individualById.get(bId)!;\n const aHalf = nodeHalfWidth(a);\n const bHalf = nodeHalfWidth(b);\n // SYMMETRIC half-separation about the pair midpoint so the descent channel (dropping\n // from the midpoint) stays clear of BOTH partner labels: each cx sits `halfSep` from the\n // midpoint, halfSep ≥ each node's half-width + MATING_RUN, so neither label box reaches\n // the midpoint (a wide label on ONE side previously crossed it — the harness caught it).\n const halfSep = Math.max(aHalf, bHalf) + MATING_RUN;\n\n const aPlaced = placedById.get(aId);\n const bPlaced = placedById.get(bId);\n // Identify the HUB partner (already placed by a prior mating, OR a fresh ≥2-mating\n // individual we now pin) and the NEW SPOUSE (the not-yet-placed partner). When neither is\n // placed and neither is a hub, it is an ordinary couple — handled in the `else` below.\n const hubId =\n aPlaced !== undefined ? aId : bPlaced !== undefined ? bId : matingCount(aId) >= 2 ? aId : matingCount(bId) >= 2 ? bId : null;\n\n // The block's children own a disjoint band starting at `blockLeft`; we recenter the\n // spouse over that band afterwards. A later mating of a hub starts at the hub's cursor.\n const blockLeft = hubId !== null && hubCursor.has(hubId) ? hubCursor.get(hubId)! : leftEdge;\n\n // ── Pack the sibship's children FIRST into [blockLeft … childrenRight], each child a leaf\n // or its own recursively-packed lower mating block — disjoint by construction. ───────\n const sibs = (sibshipByMating.get(mating.id) ?? []).sort((s1, s2) => s1.id - s2.id);\n const childIds = sibs.flatMap((s) => s.childIds);\n let childCursor = blockLeft;\n let childLeft = Number.POSITIVE_INFINITY;\n let childrenRight = blockLeft;\n let placedAnyChild = false;\n for (const childId of childIds) {\n const child = individualById.get(childId);\n if (child === undefined || placedById.has(childId)) continue;\n // The child roots a recursive mating block ONLY when it is the SENIOR (same/younger\n // generation) partner of an unplaced mating. If its only unplaced mating is to an OLDER\n // partner (an avuncular union — the child is the junior partner, e.g. uncle × niece where\n // the niece is also a sibship child here), the child is placed as a LEAF and the union is\n // drawn later as a cross-generation elbow — never fanned as a spouse block (which would\n // wrongly pin the older partner as a hub and overlap this sibship row).\n const downMating = (matingsOfIndividual.get(childId) ?? []).find((m) => {\n if (placedMatings.has(m.id)) return false;\n const [pa, pb] = partnersOf(m);\n const otherId = pa === childId ? pb : pa;\n const other = individualById.get(otherId);\n // Senior-or-equal: the child's generation is ≤ the partner's (descends or same row).\n return other === undefined || child.generation <= other.generation;\n });\n if (downMating !== undefined) {\n const right = packMating(downMating, childCursor);\n childLeft = Math.min(childLeft, placedById.get(childId)!.cx - nodeHalfWidth(child));\n childrenRight = right;\n childCursor = right + H_GAP;\n } else {\n const placed = placeLeaf(child, childCursor);\n childLeft = Math.min(childLeft, placed.cx - placed.spanL);\n childrenRight = placed.cx + placed.spanR;\n childCursor = childrenRight + H_GAP;\n }\n placedAnyChild = true;\n }\n const bandMid = placedAnyChild ? (childLeft + childrenRight) / 2 : blockLeft + halfSep;\n\n // ── Seat the partners. The SPOUSE centers over its own children band; the HUB sits one\n // halfSep to the LEFT of the spouse (so every appended spouse fans rightward and each\n // mating line is hub-edge → adjacent-spouse-edge). A pinned hub keeps its x; the spouse\n // then sits one halfSep to its RIGHT but never left of its own band. ──────────────────\n // The pair midpoint (and thus the descent origin) is recomputed from the final cx's in the\n // mating-line pass, so we only need to SEAT each partner's cx here.\n if (hubId === null) {\n // Ordinary couple: midpoint over the children band; partners ±halfSep around it.\n const pairMid = placedAnyChild ? bandMid : blockLeft + Math.max(aHalf, bHalf) + halfSep;\n placedById.set(aId, { ind: a, cx: pairMid - halfSep, spanL: aHalf, spanR: aHalf });\n placedById.set(bId, { ind: b, cx: pairMid + halfSep, spanL: bHalf, spanR: bHalf });\n } else {\n const spouseId = hubId === aId ? bId : aId;\n const spouse = individualById.get(spouseId)!;\n const spouseHalf = nodeHalfWidth(spouse);\n const hubHalf = nodeHalfWidth(individualById.get(hubId)!);\n const seq = hubSpouseSeq.get(hubId) ?? 0;\n const hubExisting = placedById.get(hubId);\n // Spouse centers over its band, but never so far left that the hub (one halfSep further\n // left, glyph half-width hubHalf) would cross blockLeft: hubCx − hubHalf ≥ blockLeft ⇒\n // spouseCx ≥ blockLeft + hubHalf + halfSep.\n const minSpouseCx = blockLeft + hubHalf + halfSep;\n let spouseCx = placedAnyChild ? Math.max(bandMid, minSpouseCx) : minSpouseCx + spouseHalf;\n if (hubExisting === undefined) {\n // First mating of this hub: pin the hub one halfSep left of the spouse.\n placedById.set(hubId, { ind: individualById.get(hubId)!, cx: spouseCx - halfSep, spanL: hubHalf, spanR: hubHalf });\n } else {\n // Later mating: the hub is pinned; the spouse fans to the right of all earlier blocks.\n spouseCx = Math.max(spouseCx, hubExisting.cx + halfSep);\n }\n placedById.set(spouseId, { ind: spouse, cx: spouseCx, spanL: spouseHalf, spanR: spouseHalf });\n hubSpouseSeq.set(hubId, seq + 1);\n }\n\n const blockRight = Math.max(\n childrenRight,\n placedById.get(aId)!.cx + nodeHalfWidth(a),\n placedById.get(bId)!.cx + nodeHalfWidth(b),\n );\n // Advance the hub's cursor past THIS block so the hub's next mating starts disjoint.\n if (hubId !== null) hubCursor.set(hubId, blockRight + H_GAP);\n return blockRight;\n };\n\n // Top matings: those whose partners are not children of any (already-traversable) sibship\n // higher up. We simply pack matings that are not yet placed, in id order, each as a new\n // forest tree; a mating reached as a descendant is consumed there (placedMatings guards\n // re-entry). Sorting by the shallower partner generation first keeps founders on top.\n const generationOfMating = (m: Mating): number => {\n const [aId, bId] = partnersOf(m);\n const a = individualById.get(aId);\n const b = individualById.get(bId);\n const gens = [a, b].filter((p): p is Individual => p !== undefined).map((p) => p.generation);\n return gens.length > 0 ? Math.min(...gens) : 0;\n };\n const rootMatings = matings\n .filter((m) => {\n // A mating is a forest ROOT when neither partner descends from a sibship (i.e. is a\n // founder pair) — those reached through a parent's sibship are packed recursively.\n const [aId, bId] = partnersOf(m);\n return !childToSibship.has(aId) && !childToSibship.has(bId);\n })\n .sort((m1, m2) => generationOfMating(m1) - generationOfMating(m2) || m1.id - m2.id);\n\n for (const m of rootMatings) {\n if (placedMatings.has(m.id)) continue;\n const right = packMating(m, cursorX);\n cursorX = right + H_GAP * 2;\n }\n // Any mating not reachable from a root (e.g. a married-in spouse whose own parents are not\n // in the pedigree but who is a descendant elsewhere) — pack remaining in id order.\n for (const m of matings) {\n if (placedMatings.has(m.id)) continue;\n const right = packMating(m, cursorX);\n cursorX = right + H_GAP * 2;\n }\n\n // Isolated individuals (no mating, no sibship membership) — drawn aside in a row group.\n const inAnyMating = new Set<number>();\n for (const m of matings) for (const p of partnersOf(m)) inAnyMating.add(p);\n const isolatedIndividualIds = individuals\n .filter((i) => !inAnyMating.has(i.id) && !childToSibship.has(i.id))\n .map((i) => i.id);\n for (const id of isolatedIndividualIds) {\n const ind = individualById.get(id)!;\n if (placedById.has(id)) continue;\n placeLeaf(ind, cursorX);\n cursorX = placedById.get(id)!.cx + nodeHalfWidth(ind) + H_GAP;\n }\n\n // Place any remaining declared individual (a child whose mating was packed already covers\n // it; this catches a stray child of an un-rooted sibship) as a trailing leaf.\n for (const ind of individuals) {\n if (placedById.has(ind.id)) continue;\n placeLeaf(ind, cursorX);\n cursorX = placedById.get(ind.id)!.cx + nodeHalfWidth(ind) + H_GAP;\n }\n\n // ── Bridge slots (post-placement, from ACTUAL adjacency). A same-generation mating whose two\n // partners have ANOTHER placed same-row individual strictly BETWEEN them needs a dipped\n // bridge line (a straight line would run through that glyph and overlap the hub's other\n // lines). Slot 0 = straight (adjacent); slot ≥ 1 = dip, staggered per ROW so co-resident\n // dips never share a depth. Driven by geometry, not placement order, so it is correct even\n // when a SPOUSE later becomes a hub for its own remarriage (both-partners-are-hubs). ──────\n const matingBridgeSlot = new Map<number, number>();\n {\n const dipSlotByRow = new Map<number, number>(); // next free dip slot per row\n // Stable order: ascending mating id, so slot assignment is deterministic.\n for (const m of [...matings].sort((m1, m2) => m1.id - m2.id)) {\n const [aId, bId] = partnersOf(m);\n const a = individualById.get(aId);\n const b = individualById.get(bId);\n if (a === undefined || b === undefined) continue;\n if (a.generation !== b.generation) continue; // cross-gen → handled as an elbow, never a dip\n const row = rowOfGeneration.get(a.generation)!;\n const loX = Math.min(placedById.get(aId)!.cx, placedById.get(bId)!.cx);\n const hiX = Math.max(placedById.get(aId)!.cx, placedById.get(bId)!.cx);\n // Any OTHER same-row placed individual whose glyph center sits strictly between them?\n const blocked = individuals.some(\n (i) =>\n i.id !== aId &&\n i.id !== bId &&\n rowOfGeneration.get(i.generation) === row &&\n placedById.has(i.id) &&\n placedById.get(i.id)!.cx > loX + 0.01 &&\n placedById.get(i.id)!.cx < hiX - 0.01,\n );\n if (!blocked) {\n matingBridgeSlot.set(m.id, 0);\n continue;\n }\n const slot = (dipSlotByRow.get(row) ?? 0) + 1;\n dipSlotByRow.set(row, slot);\n matingBridgeSlot.set(m.id, slot);\n }\n }\n\n // ── Reserve a serial-union DIP BAND per row (the genogram FIX-B precedent): an appended\n // spouse of a hub (matingBridgeSlot ≥ 1) bridges to the hub below the glyphs but ABOVE the\n // labels, so the row's labels must sit below the deepest dip. The band height is the\n // deepest slot on that row; 0 when the row has no appended-spouse bridge. ────────────────\n const rowDipBand: number[] = new Array(rowCount).fill(0);\n for (const m of matings) {\n const slot = matingBridgeSlot.get(m.id) ?? 0;\n if (slot < 1) continue;\n const [aId, bId] = partnersOf(m);\n const a = individualById.get(aId);\n const b = individualById.get(bId);\n const gens = [a, b].filter((p): p is Individual => p !== undefined).map((p) => p.generation);\n if (gens.length === 0) continue;\n const row = rowOfGeneration.get(Math.min(...gens))!; // a hub bridge is intra-row; min is safe\n rowDipBand[row] = Math.max(rowDipBand[row]!, BRIDGE_DIP_GAP + slot * BRIDGE_DIP_STEP + PED_LABEL_GAP);\n }\n\n // ── Vertical: row heights from the tallest label block in each row + the dip band; rows\n // stacked with a CORRIDOR between them (the descent routes there). ───────────────────────\n const rowHeight: number[] = new Array(rowCount).fill(0);\n for (const ind of individuals) {\n const row = rowOfGeneration.get(ind.generation)!;\n const lines = labelLinesOf.get(ind.id) ?? [];\n // glyph + dip band (label-free) + address line + label lines\n const h = PED_GLYPH + PED_LABEL_GAP + rowDipBand[row]! + (lines.length + 1) * PED_LABEL_LINE_H;\n rowHeight[row] = Math.max(rowHeight[row]!, h);\n }\n const rowTop: number[] = [PADDING];\n for (let r = 0; r < rowCount - 1; r++) {\n rowTop.push(rowTop[r]! + rowHeight[r]! + CORRIDOR);\n }\n // Glyph center y for a generation row (glyph sits at the top of its row block).\n const glyphCyOfRow = (row: number): number => rowTop[row]! + PED_GLYPH / 2;\n\n // ── Within-generation addressing: I, II, III…-<n>, numbered left-to-right by cx. ──────\n const addressByIndividual = new Map<number, string>();\n for (let row = 0; row < rowCount; row++) {\n const roman = romanNumeral(row + 1);\n const inRow = individuals\n .filter((i) => rowOfGeneration.get(i.generation) === row)\n .sort((a, b) => placedById.get(a.id)!.cx - placedById.get(b.id)!.cx || a.id - b.id);\n inRow.forEach((ind, i) => addressByIndividual.set(ind.id, `${roman}-${i + 1}`));\n }\n\n // ── Used condition fills. Keyed by condition id ASCENDING (a STABLE order independent of\n // the input.conditions array order — reordering that array must not swap inks, matching\n // the individuals/matings/sibships shuffle-invariance), the legend keys these. ─────────\n const declaredConditionIds = new Set(input.conditions.map((c) => c.id));\n const usedConditionIds = [...new Set(individuals.flatMap((i) => i.affectedBy))]\n .filter((id) => declaredConditionIds.has(id))\n .sort((x, y) => x - y);\n const conditionFills = usedConditionIds.map((id, i) => ({\n id,\n ink: PED_CONDITION_FILLS[i % PED_CONDITION_FILLS.length]!,\n label: conditionLabelById.get(id) ?? `condition ${id}`,\n }));\n\n // ── Emit nodes. ───────────────────────────────────────────────────────────────────────\n const nodes: PedigreeNode[] = [];\n for (const ind of individuals) {\n const placed = placedById.get(ind.id)!;\n const row = rowOfGeneration.get(ind.generation)!;\n const cy = glyphCyOfRow(row);\n const lines = labelLinesOf.get(ind.id) ?? [];\n const address = addressByIndividual.get(ind.id)!;\n nodes.push({\n individualId: ind.id,\n shape: shapeForSex(ind.sex),\n cx: round(placed.cx),\n cy: round(cy),\n size: PED_GLYPH,\n deceased: ind.deceased,\n carrier: ind.carrier,\n role: ind.role,\n stillbirth: ind.lifeStatus === \"stillbirth\",\n affectedBy: ind.affectedBy,\n labelLines: lines,\n // Labels sit BELOW the row's serial-union dip band (rowDipBand) so a hub's bridge dips\n // never cross a label box.\n labelTop: round(cy + PED_GLYPH / 2 + PED_LABEL_GAP + rowDipBand[row]!),\n addressLabel: address,\n title: individualTitle(ind, address, conditionLabelById, titleLabels),\n });\n }\n\n // ── Emit elements: mating lines, descents, sibship bars, risers, twin bars. ───────────\n const elements: PedigreeElement[] = [];\n const cxOf = (id: number): number => placedById.get(id)!.cx;\n const cyOf = (id: number): number => glyphCyOfRow(rowOfGeneration.get(individualById.get(id)!.generation)!);\n // Connectors attach at the GLYPH edge (uniform glyph; labels hang below, never sideways).\n const GLYPH_HALF = PED_GLYPH / 2;\n\n // Children's bar-center x per mating (min→max child cx). The descent drops from the mating\n // line at THIS x when it falls within the line span, so the straight (non-hub) descent stays\n // a single VERTICAL with no corridor bend — a bend leg would otherwise sit in the same band\n // as a hub's dipped bridge line and overlap it collinearly (the harness caught exactly that).\n const matingBarCenter = new Map<number, number>();\n for (const s of sibships) {\n const childIds = s.childIds.filter((id) => placedById.has(id));\n if (childIds.length === 0) continue;\n const xs = childIds.map(cxOf);\n const center = (Math.min(...xs) + Math.max(...xs)) / 2;\n // Several sibships of one mating share the descent origin (rare) — last write wins; the\n // descent code re-derives each sibship's own bar center, the origin only needs to be ON\n // the mating line, so any in-span value keeps the descent vertical for the common case.\n matingBarCenter.set(s.matingId, center);\n }\n\n // Mating lines (consanguineous → flagged; the emitter draws the double line).\n const matingMidpoint = new Map<number, Point>();\n // A hub's appended spouse (matingBridgeSlot ≥ 1) sits BEYOND an intermediate spouse on the\n // same row, so a straight glyph-y line would run through that spouse and overlap the hub's\n // other lines. Route it as an orthogonal elbow that DIPS into the row's reserved serial-union\n // band (rowDipBand — below the glyphs, ABOVE the labels, the genogram FIX-B precedent): a\n // stub leaves the HUB and the SPOUSE glyph BOTTOM at per-slot staggered x's (so two bridges\n // off one hub never share a vertical), drops to a per-slot dipY, and crosses below every\n // intermediate spouse glyph. The descent of a dipped mating then drops from the dip leg.\n const bridgeDipY = (slot: number): number => BRIDGE_DIP_GAP + slot * BRIDGE_DIP_STEP;\n for (const m of matings) {\n const [aId, bId] = partnersOf(m);\n const ax = cxOf(aId);\n const bx = cxOf(bId);\n const ay = cyOf(aId);\n const by = cyOf(bId);\n const leftId = ax <= bx ? aId : bId;\n const rightId = ax <= bx ? bId : aId;\n const lx = cxOf(leftId) + GLYPH_HALF;\n const rx = cxOf(rightId) - GLYPH_HALF;\n const title = m.consanguineous ? titleLabels.consanguineous : titleLabels.mating;\n const bridgeSlot = matingBridgeSlot.get(m.id) ?? 0;\n if (ay === by && bridgeSlot >= 1) {\n // Same-row mating whose spouse sits BEYOND an intermediate spouse (a hub's 2nd+ appended\n // mating) → orthogonal dip elbow in the reserved dip band. The hub is the LEFT partner by\n // construction (placed at spouse − halfSep). Stubs leave each glyph bottom at a per-slot\n // staggered x within the glyph so two bridges off one hub get distinct stub columns.\n const hubCx = cxOf(leftId);\n const spouseCx = cxOf(rightId);\n const glyphBottom = ay + GLYPH_HALF;\n const dipY = glyphBottom + bridgeDipY(bridgeSlot);\n const stubOff = Math.min(bridgeSlot * BRIDGE_STUB_X_STEP, GLYPH_HALF - 4);\n const hubStubX = hubCx + stubOff; // hub's partner is to the RIGHT → stub right-of-center\n const spouseStubX = spouseCx - stubOff; // spouse's partner is to the LEFT → left-of-center\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating-elbow\",\n points: [\n { x: round(hubStubX), y: round(glyphBottom) },\n { x: round(hubStubX), y: round(dipY) },\n { x: round(spouseStubX), y: round(dipY) },\n { x: round(spouseStubX), y: round(glyphBottom) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n // Descent hangs off the dip leg's center, already below the row's glyphs.\n matingMidpoint.set(m.id, { x: round((hubStubX + spouseStubX) / 2), y: round(dipY) });\n } else if (ay === by) {\n // Straight horizontal mating line at the shared row y.\n const y = ay;\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating\",\n points: [\n { x: round(lx), y: round(y) },\n { x: round(rx), y: round(y) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n // Drop the descent from above the children's bar center when that x stays inside the\n // LABEL-FREE channel between the partners' LABEL boxes (labels can be wider than glyphs,\n // so the channel is narrower than [lx, rx]); that keeps the descent a straight vertical\n // with no corridor bend. Otherwise drop from the pair midpoint (clear by the symmetric\n // halfSep) and let it bend in the lower corridor band. Aligning the origin matters most\n // for a hub whose appended-spouse dips occupy the upper band — a bend there would overlap\n // a dip; for plain matings the band separation keeps a bend safe either way.\n const midX = (lx + rx) / 2;\n const channelLeft = cxOf(leftId) + nodeHalfWidth(individualById.get(leftId)!);\n const channelRight = cxOf(rightId) - nodeHalfWidth(individualById.get(rightId)!);\n const barCenter = matingBarCenter.get(m.id);\n const originX =\n barCenter !== undefined && barCenter >= channelLeft && barCenter <= channelRight ? barCenter : midX;\n matingMidpoint.set(m.id, { x: round(originX), y: round(y) });\n } else {\n // Cross-generation mating → an orthogonal elbow (avuncular, §1.7). Route out of the\n // higher partner, down to the lower partner's row, then in.\n const upId = ay <= by ? aId : bId;\n const downId = ay <= by ? bId : aId;\n const upX = cxOf(upId);\n const upY = cyOf(upId);\n const downX = cxOf(downId);\n const downY = cyOf(downId);\n // When the LOWER partner is itself a placed SIBSHIP CHILD (the canonical avuncular case —\n // uncle × niece where the niece is also a sibling on her row), the up partner usually has\n // a same-row spouse between them and the niece already carries a riser into her TOP edge.\n // A naive mid-x elbow would (a) run along the up row through that spouse and (b) drop a\n // vertical collinear with the niece's riser / the sibship descent. So route the elbow\n // DOWN out of the up partner's bottom edge, across a corridor lane BELOW the up row (clear\n // of the up-row labels), and into the lower partner's nearest SIDE edge (never its top —\n // that belongs to the riser). The simple married-in-founder elbow (lower partner NOT a\n // sibship child) keeps its proven mid-x routing.\n if (childToSibship.has(downId)) {\n // Exit the up partner on the side AWAY from the lower partner (the same-row spouse, if\n // any, sits between them on the toward side), clear of the up partner's own label, drop\n // into a corridor lane BELOW the up-row labels, traverse under everything to the lower\n // partner's FAR side, then in to its side edge (its top belongs to the riser).\n const upRow = rowOfGeneration.get(individualById.get(upId)!.generation)!;\n const laneY = rowTop[upRow]! + rowHeight[upRow]! + CORRIDOR / 4 + 4;\n const downRight = downX >= upX; // lower partner is to the right\n const upExitX = upX + (downRight ? -1 : 1) * (nodeHalfWidth(individualById.get(upId)!) + 6);\n const downFarX = downX + (downRight ? 1 : -1) * (GLYPH_HALF + H_GAP / 2);\n const downSideX = downX + (downRight ? 1 : -1) * GLYPH_HALF;\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating-elbow\",\n points: [\n { x: round(upX + (downRight ? -GLYPH_HALF : GLYPH_HALF)), y: round(upY) },\n { x: round(upExitX), y: round(upY) },\n { x: round(upExitX), y: round(laneY) },\n { x: round(downFarX), y: round(laneY) },\n { x: round(downFarX), y: round(downY) },\n { x: round(downSideX), y: round(downY) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n matingMidpoint.set(m.id, { x: round(downFarX), y: round(downY) });\n } else {\n const elbowX = (upX + downX) / 2;\n elements.push({\n edgeId: PED_MATING_ID_BASE + m.id,\n kind: \"mating-elbow\",\n points: [\n { x: round(upX + (downX >= upX ? GLYPH_HALF : -GLYPH_HALF)), y: round(upY) },\n { x: round(elbowX), y: round(upY) },\n { x: round(elbowX), y: round(downY) },\n { x: round(downX + (upX >= downX ? GLYPH_HALF : -GLYPH_HALF)), y: round(downY) },\n ],\n consanguineous: m.consanguineous,\n title,\n });\n matingMidpoint.set(m.id, { x: round(elbowX), y: round(downY) });\n }\n }\n }\n\n // Descent + sibship bar + risers (+ twin convergence). Collect twin metadata for the\n // emitter's used-keys-only legend + the unknown-zygosity \"?\" marks.\n const twinZygositiesUsedSet = new Set<Zygosity>();\n const unknownTwinJunctions: Point[] = [];\n // Lane index per child-row so two descents' corridor HORIZONTALS bend at distinct y's\n // (collinear corridor overlap otherwise — the harness caught it on remarriage).\n const bendLaneByRow = new Map<number, number>();\n for (const s of sibships) {\n const childIds = s.childIds.filter((id) => individualById.has(id));\n if (childIds.length === 0) continue;\n const mid = matingMidpoint.get(s.matingId);\n const childRow = rowOfGeneration.get(individualById.get(childIds[0]!)!.generation)!;\n const barY = rowTop[childRow]! - CORRIDOR / 2;\n const lane = bendLaneByRow.get(childRow) ?? 0;\n bendLaneByRow.set(childRow, lane + 1);\n const childXs = childIds.map(cxOf);\n const barLeft = Math.min(...childXs);\n const barRight = Math.max(...childXs);\n\n // Descent: mating midpoint → sibship bar (vertical when aligned; a two-segment elbow\n // when the midpoint x differs from the bar center). The midpoint is the parents' line\n // center; the bar center is the children's center — usually identical by construction.\n // The elbow's HORIZONTAL leg bends inside the CORRIDOR (just above the bar), never at\n // mid-height — a mid-height bend would run through the parents' label row (the harness\n // caught exactly this). The vertical drop stays at mid.x, which is label-free between\n // the partners by the symmetric half-separation above.\n if (mid !== undefined) {\n const barCenterX = (barLeft + barRight) / 2;\n // Stagger the corridor bend per lane so co-resident descents never share a horizontal.\n // Bends live in the LOWER half of the corridor (near the bar), reserving the upper half\n // for hub bridge-line dips so the two families of horizontals never overlap collinearly.\n const bendY = barY - 2 - (lane % 3) * 3; // lower-half, label-free corridor\n const descentPoints: Point[] =\n Math.abs(mid.x - barCenterX) < 0.01\n ? [\n { x: round(mid.x), y: round(mid.y) },\n { x: round(mid.x), y: round(barY) },\n ]\n : [\n { x: round(mid.x), y: round(mid.y) },\n { x: round(mid.x), y: round(bendY) },\n { x: round(barCenterX), y: round(bendY) },\n { x: round(barCenterX), y: round(barY) },\n ];\n elements.push({\n edgeId: PED_DESCENT_ID_BASE + s.id,\n kind: \"descent\",\n points: descentPoints,\n consanguineous: false,\n title: titleLabels.sibship,\n });\n }\n\n // Sibship bar (horizontal) spanning min→max child x — only when ≥2 children.\n if (childIds.length > 1) {\n elements.push({\n edgeId: PED_SIBBAR_ID_BASE + s.id,\n kind: \"sibship-bar\",\n points: [\n { x: round(barLeft), y: round(barY) },\n { x: round(barRight), y: round(barY) },\n ],\n consanguineous: false,\n title: titleLabels.sibship,\n });\n }\n\n // Map each child to a twin group (if any) for the convergence routing.\n const twinGroupOfChild = new Map<number, { ordinal: number; zygosity: Zygosity; members: number[] }>();\n s.twinGroups.forEach((tg, ordinal) => {\n const members = tg.childIds.filter((id) => childIds.includes(id));\n for (const id of members) twinGroupOfChild.set(id, { ordinal, zygosity: tg.zygosity, members });\n });\n const emittedTwinOrdinals = new Set<number>();\n\n for (const childId of childIds) {\n const cx = cxOf(childId);\n const childTop = cyOf(childId) - PED_GLYPH / 2;\n const tg = twinGroupOfChild.get(childId);\n if (tg === undefined) {\n // Plain riser: bar → child glyph top (vertical).\n elements.push({\n edgeId: PED_RISER_ID_BASE + childId,\n kind: \"riser\",\n points: [\n { x: round(cx), y: round(barY) },\n { x: round(cx), y: round(childTop) },\n ],\n consanguineous: false,\n title: titleLabels.sibship,\n });\n continue;\n }\n // Twin: ORTHOGONAL convergence. One junction per twin group on the bar, at the group\n // members' center x; from the junction, drop a short stub, go horizontal to the child\n // x, then down to the glyph. VERIFY this geometry against Bennett et al. 2008 Fig. 2\n // (twin notation panel) before trusting — refs differ on the exact tie-bar/\"?\" spot.\n const memberXs = tg.members.map(cxOf);\n const junctionX = (Math.min(...memberXs) + Math.max(...memberXs)) / 2;\n const junctionY = barY + TWIN_JUNCTION_DROP;\n twinZygositiesUsedSet.add(tg.zygosity);\n // The shared down-stub from the bar to the junction (emitted once per group).\n if (!emittedTwinOrdinals.has(tg.ordinal)) {\n emittedTwinOrdinals.add(tg.ordinal);\n if (tg.zygosity === \"unknown\") {\n unknownTwinJunctions.push({ x: round(junctionX), y: round(junctionY) });\n }\n elements.push({\n edgeId: PED_RISER_ID_BASE + childId, // anchored on the first member for a stable id\n kind: \"riser\",\n points: [\n { x: round(junctionX), y: round(barY) },\n { x: round(junctionX), y: round(junctionY) },\n ],\n consanguineous: false,\n title: titleLabels.twins[tg.zygosity],\n });\n // MZ tie-bar: a short horizontal between the two outermost twin descents, just below\n // the junction (DZ → none; unknown → a \"?\" node annotation, emitted in svg.ts).\n if (tg.zygosity === \"mz\" && memberXs.length >= 2) {\n const tieY = junctionY + 6;\n elements.push({\n edgeId: PED_TWINBAR_ID_BASE + s.id * 100 + tg.ordinal,\n kind: \"twin-bar\",\n points: [\n { x: round(Math.min(...memberXs)), y: round(tieY) },\n { x: round(Math.max(...memberXs)), y: round(tieY) },\n ],\n consanguineous: false,\n title: titleLabels.twins.mz,\n });\n }\n }\n // From the junction: horizontal to the child x at the junction y, then down to glyph.\n const horizontalThenDown: Point[] =\n Math.abs(cx - junctionX) < 0.01\n ? [\n { x: round(cx), y: round(junctionY) },\n { x: round(cx), y: round(childTop) },\n ]\n : [\n { x: round(junctionX), y: round(junctionY) },\n { x: round(cx), y: round(junctionY) },\n { x: round(cx), y: round(childTop) },\n ];\n elements.push({\n edgeId: PED_RISER_ID_BASE + childId,\n kind: \"riser\",\n points: horizontalThenDown,\n consanguineous: false,\n title: titleLabels.twins[tg.zygosity],\n });\n }\n }\n\n // ── Canvas bounds: shift-positive is unnecessary (everything starts at PADDING+GUTTER),\n // width/height from the rightmost/bottommost drawn extent. ──────────────────────────\n let maxX = PADDING * 2;\n let maxY = PADDING * 2;\n for (const n of nodes) {\n const labelW = n.labelLines.reduce((m, l) => Math.max(m, estimateTextWidth(l, PED_LABEL_FONT)), 0);\n const half = Math.max(PED_GLYPH, labelW) / 2;\n maxX = Math.max(maxX, n.cx + half + PADDING);\n const labelBottom = n.labelTop + (n.labelLines.length + 1) * PED_LABEL_LINE_H;\n maxY = Math.max(maxY, labelBottom + PADDING);\n }\n for (const el of elements) {\n for (const p of el.points) {\n maxX = Math.max(maxX, p.x + PADDING);\n maxY = Math.max(maxY, p.y + PADDING);\n }\n }\n\n const generations: PedigreeGenerationLabel[] = [];\n for (let row = 0; row < rowCount; row++) {\n generations.push({ roman: romanNumeral(row + 1), y: round(glyphCyOfRow(row)) });\n }\n\n // Order zygosities canonically (mz, dz, unknown) for deterministic legend output.\n const ZYGOSITY_ORDER: readonly Zygosity[] = [\"mz\", \"dz\", \"unknown\"];\n const twinZygositiesUsed = ZYGOSITY_ORDER.filter((z) => twinZygositiesUsedSet.has(z));\n\n return {\n width: Math.ceil(maxX),\n height: Math.ceil(maxY),\n nodes,\n elements,\n generations,\n conditionFills,\n twinZygositiesUsed,\n unknownTwinJunctions,\n isolatedIndividualIds,\n };\n}\n","// Pedigree SVG emitter — turns a computed PedigreeLayout (./layout.ts) into a\n// SELF-CONTAINED SVG string. Pure (layout in, string out) and deterministic; it draws\n// EXACTLY what the layout computed (the overlap harness proves the layout; this emitter\n// is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — labels/conditions/titles are\n// author-controlled and the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (zinc hex colors, inline dasharray): a\n// standalone SVG has no stylesheet, no currentColor, no <defs>/<marker> — arrowheads\n// are explicit polygons; multi-condition partitions are explicit filled shapes;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Notation (Bennett et al. 2008 PSSC): square/circle/diamond sex glyphs; AFFECTED =\n// filled glyph (multi-condition = VERTICAL fill partitions ≤4, from the zinc ramp);\n// carrier = central dot (on unaffected glyphs); deceased = top-left→bottom-right slash;\n// proband = FILLED lower-left arrow, consultand = OPEN (outline) arrow; stillbirth = \"SB\"\n// text below; consanguineous mating = DOUBLE line; twins converge with an MZ tie-bar / no\n// bar (DZ) / a \"?\" (unknown). Roman-numeral generation labels sit in the left gutter.\n//\n// Hooks: `<g data-individual-id=\"p<id>\">` per individual (direct-child verbatim <title>);\n// `<g data-edge-id=\"<n>\">` per routed element (namespaced ids, see ./layout.ts).\n\nimport { FONT_FAMILY, legendBlock, xmlEscape, LEGEND_SWATCH_W, type LegendEntry } from \"../core\";\nimport {\n PED_ADDRESS_FONT,\n PED_LABEL_FONT,\n PED_LABEL_LINE_H,\n type PedigreeElement,\n type PedigreeLayout,\n type PedigreeNode,\n} from \"./layout\";\nimport { PEDIGREE_SVG_LABELS_EN, type PedigreeSvgLabels } from \"./labels\";\nimport type { NodeShape } from \"../genogram/types\";\nimport type { Zygosity } from \"./types\";\n\n// Literal ink colors (zinc ramp on white — matches the genogram/fault-tree emitters).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\nconst GLYPH_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n/** Parallel offset of the second consanguineous mating line (the PSSC double line). */\nconst CONSANG_GAP = 3;\n\nconst ZYGOSITIES: readonly Zygosity[] = [\"mz\", \"dz\", \"unknown\"];\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport interface PedigreeSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: PedigreeSvgLabels;\n}\n\n// ── Glyph outline + multi-condition vertical fill partitions ──────────────────────────\n\nfunction glyphOutline(shape: NodeShape, cx: number, cy: number, half: number): string {\n if (shape === \"square\") {\n return `<rect x=\"${round(cx - half)}\" y=\"${round(cy - half)}\" width=\"${half * 2}\" height=\"${half * 2}\" ${GLYPH_ATTRS}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${GLYPH_ATTRS}/>`;\n }\n return `<polygon points=\"${cx},${round(cy - half)} ${round(cx + half)},${cy} ${cx},${round(cy + half)} ${round(cx - half)},${cy}\" ${GLYPH_ATTRS}/>`;\n}\n\n/**\n * The glyph's vertical extent (top, bottom) at a horizontal offset from center, so a fill\n * partition slice is CLIPPED to the glyph outline (no <clipPath> — pure geometry). Square\n * is full-height everywhere; circle/diamond taper. Returns [yTop, yBottom] at |dx|.\n */\nfunction glyphVerticalExtentAt(shape: NodeShape, cy: number, half: number, dx: number): [number, number] {\n const ax = Math.min(Math.abs(dx), half);\n if (shape === \"square\") return [cy - half, cy + half];\n if (shape === \"circle\") {\n const h = Math.sqrt(Math.max(0, half * half - ax * ax));\n return [cy - h, cy + h];\n }\n // diamond: linear taper to 0 at |dx| = half.\n const h = half - ax;\n return [cy - h, cy + h];\n}\n\n/** Vertical fill partitions (≤4) for an affected glyph, each clipped to the outline. */\nfunction fillPartitions(n: PedigreeNode, half: number, inkByCondition: Map<number, string>): string {\n const ids = n.affectedBy;\n if (ids.length === 0) return \"\";\n const cx = n.cx;\n const cy = n.cy;\n const sliceW = (half * 2) / ids.length;\n return ids\n .map((id, i) => {\n const left = cx - half + i * sliceW;\n // Sample the outline extent at a handful of x's across the slice and build a polygon\n // hugging the glyph border (top edge L→R, bottom edge R→L). Dense enough for a\n // circle/diamond to read as a clean partition.\n const SAMPLES = 8;\n const top: string[] = [];\n const bottom: string[] = [];\n for (let s = 0; s <= SAMPLES; s++) {\n const x = left + (sliceW * s) / SAMPLES;\n const [yt, yb] = glyphVerticalExtentAt(n.shape, cy, half, x - cx);\n top.push(`${round(x)},${round(yt)}`);\n bottom.push(`${round(x)},${round(yb)}`);\n }\n const pts = [...top, ...bottom.reverse()].join(\" \");\n const ink = inkByCondition.get(id) ?? GLYPH_STROKE;\n return `<polygon points=\"${pts}\" fill=\"${ink}\" stroke=\"none\"/>`;\n })\n .join(\"\");\n}\n\n// ── Node annotations (carrier dot, deceased slash, proband/consultand arrow, SB). These\n// are NODE decorations (NOT routed elements) — the deceased slash + arrows are the only\n// diagonals, harness-excluded exactly like the genogram's deceased slash. ────────────\n\nfunction carrierDot(n: PedigreeNode): string {\n // PSSC: the dot marks an UNAFFECTED carrier; a filled glyph would hide it.\n if (!n.carrier || n.affectedBy.length > 0) return \"\";\n return `<circle cx=\"${n.cx}\" cy=\"${n.cy}\" r=\"4\" fill=\"${GLYPH_STROKE}\" stroke=\"none\"/>`;\n}\n\nfunction deceasedSlash(n: PedigreeNode, half: number): string {\n if (!n.deceased) return \"\";\n // Top-left → bottom-right, reusing the genogram's exact deceased line, slightly extended\n // past the glyph so it reads over a filled glyph.\n const ext = half + 4;\n return `<line x1=\"${round(n.cx - ext)}\" y1=\"${round(n.cy - ext)}\" x2=\"${round(n.cx + ext)}\" y2=\"${round(n.cy + ext)}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`;\n}\n\nfunction probandArrow(n: PedigreeNode, half: number): string {\n if (n.role === null) return \"\";\n // An arrow at the glyph's lower-left, pointing up-right toward the glyph (PSSC). Filled\n // for the proband, open (outline only) for the consultand — one shape, two fills.\n const tipX = round(n.cx - half);\n const tipY = round(n.cy + half);\n const tailX = round(tipX - 16);\n const tailY = round(tipY + 16);\n const filled = n.role === \"proband\";\n const fill = filled ? GLYPH_STROKE : \"transparent\";\n // Shaft + a small arrowhead polygon at the tip (explicit polygon — no marker).\n const shaft = `<line x1=\"${tailX}\" y1=\"${tailY}\" x2=\"${tipX}\" y2=\"${tipY}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`;\n // Arrowhead pointing up-right (toward the glyph), two barbs off the tip.\n const head = `<polygon points=\"${tipX},${tipY} ${round(tipX - 8)},${round(tipY + 2)} ${round(tipX - 2)},${round(tipY + 8)}\" fill=\"${fill}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n return shaft + head;\n}\n\nfunction stillbirthMark(n: PedigreeNode, half: number): string {\n if (!n.stillbirth) return \"\";\n // PSSC: a stillbirth is annotated with the literal \"SB\" below the glyph (the legend uses\n // the descriptive wording). Placed just below the glyph, left of the address line.\n const y = round(n.cy + half + PED_ADDRESS_FONT);\n return `<text x=\"${round(n.cx - half - 2)}\" y=\"${y}\" text-anchor=\"end\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_ADDRESS_FONT}\" font-weight=\"bold\" fill=\"${LABEL_FILL}\">SB</text>`;\n}\n\nfunction nodeSvg(n: PedigreeNode, inkByCondition: Map<number, string>): string {\n const half = n.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(n.title)}</title>`,\n // Fill partitions sit UNDER the outline so the border stays crisp.\n fillPartitions(n, half, inkByCondition),\n glyphOutline(n.shape, n.cx, n.cy, half),\n carrierDot(n),\n deceasedSlash(n, half),\n probandArrow(n, half),\n stillbirthMark(n, half),\n ];\n // Within-generation address (\"II-3\") just below the glyph.\n const addressY = round(n.labelTop + PED_ADDRESS_FONT);\n pieces.push(\n `<text x=\"${n.cx}\" y=\"${addressY}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_ADDRESS_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(n.addressLabel)}</text>`,\n );\n if (n.labelLines.length > 0) {\n const firstBaseline = round(n.labelTop + PED_LABEL_LINE_H + 10);\n const tspans = n.labelLines\n .map((line, i) => `<tspan x=\"${n.cx}\" y=\"${round(firstBaseline + i * PED_LABEL_LINE_H)}\">${xmlEscape(line)}</tspan>`)\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_LABEL_FONT}\" fill=\"${LABEL_FILL}\">${tspans}</text>`,\n );\n }\n return `<g data-individual-id=\"p${n.individualId}\">${pieces.join(\"\")}</g>`;\n}\n\n// ── Routed elements ────────────────────────────────────────────────────────────────────\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: readonly { x: number; y: number }[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\nfunction elementSvg(el: PedigreeElement): string {\n const pts = el.points;\n const title = `<title>${xmlEscape(el.title)}</title>`;\n const stroke = `stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"`;\n const draw = (offsetY: number): string => {\n const shifted = pts.map((p) => ({ x: p.x, y: round(p.y + offsetY) }));\n if (shifted.length === 2) {\n return `<line x1=\"${shifted[0]!.x}\" y1=\"${shifted[0]!.y}\" x2=\"${shifted[1]!.x}\" y2=\"${shifted[1]!.y}\" ${stroke}/>`;\n }\n return `<path d=\"${pathData(shifted)}\" fill=\"none\" ${stroke}/>`;\n };\n const body =\n el.consanguineous && (el.kind === \"mating\" || el.kind === \"mating-elbow\")\n ? draw(-CONSANG_GAP / 2) + draw(CONSANG_GAP / 2)\n : draw(0);\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body}</g>`;\n}\n\n/** The \"?\" glyphs at unknown-zygosity twin junctions (node-style annotations from layout). */\nfunction unknownTwinMarks(layout: PedigreeLayout): string {\n return layout.unknownTwinJunctions\n .map(\n (p) =>\n `<text x=\"${round(p.x + 6)}\" y=\"${round(p.y + 4)}\" font-family=\"${FONT_FAMILY}\" font-size=\"12\" font-weight=\"bold\" fill=\"${LABEL_FILL}\">?</text>`,\n )\n .join(\"\");\n}\n\n// ── Legend mini-glyph swatches (scaled into the 22px swatch box) ──────────────────────\n\nconst MINI_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"`;\n\nfunction miniShapeSwatch(shape: NodeShape, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (shape === \"square\") return `<rect x=\"${round(cx - 6)}\" y=\"${round(y - 6)}\" width=\"12\" height=\"12\" ${MINI_ATTRS}/>`;\n if (shape === \"circle\") return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/>`;\n return `<polygon points=\"${cx},${round(y - 7)} ${round(cx + 7)},${y} ${cx},${round(y + 7)} ${round(cx - 7)},${y}\" ${MINI_ATTRS}/>`;\n}\n\nfunction miniSwatchCircle(filled: boolean, ink: string, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" fill=\"${filled ? ink : \"transparent\"}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n}\n\nfunction miniCarrierSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/><circle cx=\"${cx}\" cy=\"${y}\" r=\"2\" fill=\"${GLYPH_STROKE}\" stroke=\"none\"/>`;\n}\n\nfunction miniDeceasedSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/><line x1=\"${round(cx - 7)}\" y1=\"${round(y - 7)}\" x2=\"${round(cx + 7)}\" y2=\"${round(y + 7)}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n}\n\nfunction miniArrowSwatch(filled: boolean, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n const tipX = round(cx - 2);\n const tipY = round(y + 2);\n return (\n `<line x1=\"${round(tipX - 8)}\" y1=\"${round(tipY + 8)}\" x2=\"${tipX}\" y2=\"${tipY}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>` +\n `<polygon points=\"${tipX},${tipY} ${round(tipX - 5)},${round(tipY + 1)} ${round(tipX - 1)},${round(tipY + 5)}\" fill=\"${filled ? GLYPH_STROKE : \"transparent\"}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1\"/>`\n );\n}\n\nfunction miniConsanguineousSwatch(x: number, y: number): string {\n const x1 = round(x + 2);\n const x2 = round(x + LEGEND_SWATCH_W - 2);\n return (\n `<line x1=\"${x1}\" y1=\"${round(y - 1.5)}\" x2=\"${x2}\" y2=\"${round(y - 1.5)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${x1}\" y1=\"${round(y + 1.5)}\" x2=\"${x2}\" y2=\"${round(y + 1.5)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>`\n );\n}\n\nfunction miniTwinSwatch(zygosity: Zygosity, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n const apexY = round(y - 6);\n const baseY = round(y + 6);\n const left = round(cx - 6);\n const right = round(cx + 6);\n // Orthogonal convergence mini: an inverted Y of axis-aligned stubs.\n const stub =\n `<line x1=\"${cx}\" y1=\"${apexY}\" x2=\"${cx}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${left}\" y1=\"${y}\" x2=\"${right}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${left}\" y1=\"${y}\" x2=\"${left}\" y2=\"${baseY}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>` +\n `<line x1=\"${right}\" y1=\"${y}\" x2=\"${right}\" y2=\"${baseY}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>`;\n if (zygosity === \"mz\") {\n return stub + `<line x1=\"${left}\" y1=\"${round(y + 3)}\" x2=\"${right}\" y2=\"${round(y + 3)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"/>`;\n }\n if (zygosity === \"unknown\") {\n return stub + `<text x=\"${round(cx + 8)}\" y=\"${round(y + 3)}\" font-family=\"${FONT_FAMILY}\" font-size=\"9\" fill=\"${LABEL_FILL}\">?</text>`;\n }\n return stub;\n}\n\n/**\n * Emits a self-contained SVG for a computed pedigree layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal. The legend lists ONLY the features actually used.\n */\nexport function pedigreeLayoutSvg(layout: PedigreeLayout, opts: PedigreeSvgOptions = {}): string {\n const labels = opts.labels ?? PEDIGREE_SVG_LABELS_EN;\n const inkByCondition = new Map(layout.conditionFills.map((c) => [c.id, c.ink]));\n const parts: string[] = [];\n\n // Routed elements first, then unknown-twin \"?\" marks, then nodes on top.\n for (const el of layout.elements) parts.push(elementSvg(el));\n parts.push(unknownTwinMarks(layout));\n for (const n of layout.nodes) parts.push(nodeSvg(n, inkByCondition));\n\n // Roman-numeral generation gutter (left margin).\n for (const g of layout.generations) {\n parts.push(\n `<text x=\"${round(16)}\" y=\"${round(g.y + PED_LABEL_FONT * 0.32)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PED_LABEL_FONT}\" font-weight=\"bold\" fill=\"${LABEL_FILL}\">${xmlEscape(g.roman)}</text>`,\n );\n }\n\n // ── Used-keys-only legend (core legendBlock; `legend:false` suppresses). ─────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: LegendEntry[] = [];\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({ swatch: (x, y) => miniShapeSwatch(shape, x, y), label: labels.shapes[shape] });\n }\n // One row per USED condition (sex-neutral circle filled with that condition's ink).\n for (const c of layout.conditionFills) {\n entries.push({ swatch: (x, y) => miniSwatchCircle(true, c.ink, x, y), label: c.label });\n }\n if (layout.nodes.some((n) => n.affectedBy.length === 0)) {\n entries.push({ swatch: (x, y) => miniSwatchCircle(false, GLYPH_STROKE, x, y), label: labels.unaffected });\n }\n if (layout.nodes.some((n) => n.carrier && n.affectedBy.length === 0)) {\n entries.push({ swatch: miniCarrierSwatch, label: labels.carrier });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({ swatch: miniDeceasedSwatch, label: labels.deceased });\n }\n if (layout.nodes.some((n) => n.role === \"proband\")) {\n entries.push({ swatch: (x, y) => miniArrowSwatch(true, x, y), label: labels.proband });\n }\n if (layout.nodes.some((n) => n.role === \"consultand\")) {\n entries.push({ swatch: (x, y) => miniArrowSwatch(false, x, y), label: labels.consultand });\n }\n if (layout.nodes.some((n) => n.stillbirth)) {\n entries.push({ swatch: () => \"\", label: labels.stillbirth });\n }\n if (layout.elements.some((el) => el.consanguineous)) {\n entries.push({ swatch: miniConsanguineousSwatch, label: labels.consanguineous });\n }\n const twinsUsed = new Set(layout.twinZygositiesUsed);\n for (const z of ZYGOSITIES) {\n if (!twinsUsed.has(z)) continue;\n entries.push({ swatch: (x, y) => miniTwinSwatch(z, x, y), label: labels.twins[z] });\n }\n if (layout.isolatedIndividualIds.length > 0) {\n entries.push({ swatch: () => \"\", label: labels.isolated });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call pedigree render: input → { svg, layout }. Thin, honest wiring: validate (throw\n// on a structurally invalid pedigree — never repair), compute the pure layout, emit.\n// Callers needing finer control use computePedigreeLayout + pedigreeLayoutSvg directly (the\n// layout result supports hit-testing / decorating the diagram).\n\nimport { computePedigreeLayout, type PedigreeLayout, type PedigreeLayoutOptions } from \"./layout\";\nimport { pedigreeLayoutSvg } from \"./svg\";\nimport type { PedigreeSvgLabels } from \"./labels\";\nimport type { PedigreeInput } from \"./types\";\n\nexport interface PedigreeRenderOptions extends PedigreeLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: PedigreeSvgLabels;\n}\n\nexport interface PedigreeRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: PedigreeLayout;\n}\n\n/**\n * Renders a pedigree input to a self-contained SVG string. Deterministic: same data → same\n * SVG (array order never matters; a sibship's `childIds` order is honored as the declared\n * left-to-right birth order). Throws PedigreeValidationError — carrying EVERY issue,\n * deterministically sorted — on a structurally invalid pedigree. Empty input yields an\n * empty-but-valid SVG; callers decide their own empty state.\n */\nexport function pedigreeSvg(input: PedigreeInput, opts: PedigreeRenderOptions = {}): PedigreeRenderResult {\n const layout = computePedigreeLayout(input, {\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = pedigreeLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Display vocabularies — every human-readable string the phylo tree emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// Title labels are woven into element/node <title>s by the LAYOUT (verbatim-preserving:\n// a branch's actual length / a clade's actual support always rides the title, even when\n// the drawn diagram omits them). Svg labels are drawn by the EMITTER (legend, aria).\n\nimport type { PhyloMode } from \"./types\";\n\n/** Labels woven into <title>s by the LAYOUT (verbatim-preserving). */\nexport interface PhyloTitleLabels {\n /** \"branch length\" → \"branch length: 0.123\" when a length is present. */\n branchLength: string;\n /** \"support\" → \"support: 95\" when a support value is present. */\n support: string;\n clade: string;\n tip: string;\n root: string;\n}\n\nexport const PHYLO_TITLE_LABELS_EN: PhyloTitleLabels = {\n branchLength: \"branch length\",\n support: \"support\",\n clade: \"clade\",\n tip: \"tip\",\n root: \"root\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface PhyloSvgLabels {\n support: string;\n scaleBar: string;\n alignedTip: string;\n /** Aria label switches on the layout's render mode. */\n ariaLabel: Record<PhyloMode, string>;\n}\n\nexport const PHYLO_SVG_LABELS_EN: PhyloSvgLabels = {\n support: \"Support value (bootstrap/posterior)\",\n scaleBar: \"Scale: substitutions per site\",\n alignedTip: \"Aligned tip (true position dotted)\",\n ariaLabel: {\n cladogram: \"Phylogenetic tree (cladogram)\",\n phylogram: \"Phylogenetic tree (phylogram)\",\n },\n};\n","// Phylo validation — the MIDDLE doctrine. A phylogenetic tree is not a safety artifact\n// like a fault tree (an incomplete/exploratory tree is a legitimate thing to draw), but\n// unlike a genogram a tree MUST be a tree to lay out (a cycle or a forest has no\n// root-anchored x). So we throw PhyloValidationError carrying a MINIMAL closed code set\n// that rejects only what makes layout impossible or ambiguous — never what is merely\n// incomplete. The shape (sorted kebab-case { code, message } issues, three-phase gating)\n// is the fault-tree's, verbatim.\n//\n// Every problem is reported, not just the first: issues are aggregated, deduplicated and\n// sorted deterministically (by code, then message — byte comparison, no locale collation),\n// each carrying a STABLE kebab-case `code`. Validation runs in THREE phases, each gated on\n// the prior being clean ENOUGH for the next to be meaningful (NOT on \"zero issues so far\",\n// so a defect in one phase never hides an honest issue from a later one):\n// (0) duplicate ids (per namespace). The lookup maps below are first-occurrence-wins, so\n// every reference rule would otherwise depend on array order — violating this\n// function's documented order-invariance. Any duplicate-id issue → report ONLY those\n// and stop (the duplicate already forces a throw, present in every permutation).\n// (1) reference + structural-tree rules: unknown-endpoint (an edge to a phantom node),\n// unknown-root, multiple-parents (a node with ≥2 incoming edges — a DAG, not a tree),\n// negative-length (a meaningless distance — reject, never clamp), tip-with-children\n// (a declared isTip flag contradicting topology). All evaluated once ids are\n// unambiguous; none requires a clean graph walk.\n// (2) graph rules: cycle (a back-edge in the parent→child walk) and disconnected-node\n// (a node unreachable from root). Gated ONLY on the reference-INTEGRITY subset that\n// corrupts the traversal itself — duplicate-id (ambiguous first-wins node),\n// unknown-endpoint (walks a phantom node), unknown-root (the BFS frontier roots at a\n// non-node), multiple-parents (the child-set is ambiguous). negative-length and\n// tip-with-children leave the graph fully walkable, so they do NOT suppress the graph\n// phase: a negative length alongside an unreachable node reports BOTH in one throw.\n//\n// Tolerated, by design (drawn as declared, never converted):\n// - empty labels (drawn empty; the <title> is still present);\n// - missing support (null/absent — drawn unlabeled);\n// - a single-node tree (root only, no edges — a valid degenerate tree, one tip);\n// - null lengths (phylogram → 0) and zero-length branches (a node directly above its\n// parent's x — a real polytomy/zero-support resolution, NOT an error);\n// - unbalanced / ladderized topology (declared child order honored, never auto-sorted).\n\nimport type { PhyloInput, PhyloNode } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type PhyloIssueCode =\n | \"duplicate-id\"\n | \"unknown-endpoint\"\n | \"unknown-root\"\n | \"multiple-parents\"\n | \"cycle\"\n | \"disconnected-node\"\n | \"tip-with-children\"\n | \"negative-length\";\n\nexport interface PhyloIssue {\n code: PhyloIssueCode;\n message: string;\n}\n\n/** Thrown by computePhyloLayout / phyloSvg on a structurally un-layout-able tree. */\nexport class PhyloValidationError extends Error {\n readonly issues: readonly PhyloIssue[];\n\n constructor(issues: readonly PhyloIssue[]) {\n super(`invalid phylo tree: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"PhyloValidationError\";\n this.issues = issues;\n }\n}\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable\n * across engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly PhyloIssue[]): readonly PhyloIssue[] {\n const unique = new Map<string, PhyloIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically\n * sorted (code, then message) — array order of `nodes`/`edges` never changes the result.\n * Empty input (no nodes AND no edges) is valid by definition (the renderer's\n * empty-but-valid SVG case) and reports no issues.\n */\nexport function phyloIssues(input: PhyloInput): readonly PhyloIssue[] {\n if (input.nodes.length === 0 && input.edges.length === 0) return [];\n\n const issues: PhyloIssue[] = [];\n const push = (code: PhyloIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── R1: duplicate ids (per namespace — hooks must be unique). Any duplicate makes the\n // structure ambiguous, so this is phase 0 and short-circuits the rest (below). ─────\n const nodeById = new Map<number, PhyloNode>();\n const dupNodeIds = new Set<number>();\n for (const n of input.nodes) {\n if (nodeById.has(n.id)) dupNodeIds.add(n.id);\n else nodeById.set(n.id, n);\n }\n for (const id of [...dupNodeIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate node id ${id}`);\n }\n const dupEdgeIds = new Set<number>();\n const seenEdgeIds = new Set<number>();\n for (const e of input.edges) {\n if (seenEdgeIds.has(e.id)) dupEdgeIds.add(e.id);\n else seenEdgeIds.add(e.id);\n }\n for (const id of [...dupEdgeIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate edge id ${id}`);\n }\n\n // ── Phase 0: duplicate ids short-circuit everything else (see module header). ────────\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n // ── R2: the declared root must be an existing node. ──────────────────────────────────\n if (!nodeById.has(input.rootId)) {\n push(\"unknown-root\", `rootId ${input.rootId} is not a declared node`);\n }\n\n // ── Per-edge reference / structural rules. The child→parent map drives the graph\n // phase: built only from edges with BOTH endpoints declared (a phantom endpoint\n // would seed a non-existent node). ────────────────────────────────────────────────\n const incomingByChild = new Map<number, number[]>(); // child id → parent ids (declared edges only)\n for (const e of [...input.edges].sort((a, b) => a.id - b.id)) {\n const knownParent = nodeById.has(e.parentId);\n const knownChild = nodeById.has(e.childId);\n if (!knownParent) push(\"unknown-endpoint\", `edge ${e.id} parentId ${e.parentId} is not a declared node`);\n if (!knownChild) push(\"unknown-endpoint\", `edge ${e.id} childId ${e.childId} is not a declared node`);\n // R4 — a non-finite or negative distance is meaningless. Reject (never clamp): drawing\n // it would silently reinterpret the data AND a non-finite length poisons the phylogram\n // scale (cumulative dist → Infinity, scale → 0, x → padLeft + Infinity·0 = NaN, and the\n // whole SVG emits viewBox=\"0 0 NaN …\"). `Number.isFinite` is false for NaN/+Inf/-Inf,\n // so the one guard covers every corrupt SPECIFIED value; null stays valid (→ 0 in the\n // phylogram, the legitimate \"unspecified\" branch).\n if (e.length !== null && (!Number.isFinite(e.length) || e.length < 0)) {\n push(\"negative-length\", `edge ${e.id} has non-finite or negative length ${e.length}`);\n }\n if (knownParent && knownChild) {\n const arr = incomingByChild.get(e.childId) ?? [];\n arr.push(e.parentId);\n incomingByChild.set(e.childId, arr);\n }\n }\n\n // R3 — a tree node has at most ONE parent; ≥2 incoming edges is a DAG (un-layout-able\n // with a single root-anchored x). Reported per child, ascending.\n const childIdsWithEdges = new Set<number>();\n for (const e of input.edges) childIdsWithEdges.add(e.childId);\n for (const [childId, parents] of [...incomingByChild.entries()].sort((a, b) => a[0] - b[0])) {\n if (parents.length > 1) {\n push(\"multiple-parents\", `node ${childId} has ${parents.length} parents`);\n }\n }\n\n // R5 — isTip is DERIVED: a node with an outgoing edge is internal, a node with none is a\n // tip. A declared isTip flag that contradicts the topology is reported (honesty rule —\n // we draw the declared topology, we never invent or suppress a leaf because of a flag).\n const hasChildren = new Set<number>();\n for (const e of input.edges) {\n if (nodeById.has(e.parentId)) hasChildren.add(e.parentId);\n }\n for (const n of [...nodeById.values()].sort((a, b) => a.id - b.id)) {\n if (n.isTip === true && hasChildren.has(n.id)) {\n push(\"tip-with-children\", `node ${n.id} is declared a tip but has children`);\n } else if (n.isTip === false && !hasChildren.has(n.id)) {\n push(\"tip-with-children\", `node ${n.id} is declared internal but has no children`);\n }\n }\n\n // ── Graph rules (cycle, disconnected-node) — phase 2. Gated ONLY on the reference-\n // INTEGRITY codes that corrupt the traversal (see the module header), NOT on every\n // phase-1 issue: a negative length or a contradicted tip flag leaves the graph fully\n // walkable, so suppressing the graph phase for them would hide an honest issue. ─────\n const GRAPH_BLOCKING: ReadonlySet<PhyloIssueCode> = new Set<PhyloIssueCode>([\n \"duplicate-id\",\n \"unknown-endpoint\",\n \"unknown-root\",\n \"multiple-parents\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n // Children of a node in declared edge order (stable-sorted by edge id), declared edges\n // only — every endpoint is known here (no unknown-endpoint survived the gate).\n const childrenOf = new Map<number, number[]>();\n for (const e of [...input.edges].sort((a, b) => a.id - b.id)) {\n const arr = childrenOf.get(e.parentId) ?? [];\n arr.push(e.childId);\n childrenOf.set(e.parentId, arr);\n }\n\n // R6 — cycle detection over the parent→child graph (coloring DFS, start nodes\n // ascending, children in declared order). Each distinct cycle is reported once,\n // rotated to start at its smallest node id so the message is array-order-independent.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = childrenOf.get(frame.id) ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\"cycle\", `cycle: ${[...rotated, rotated[0]!].join(\" → \")}`);\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n for (const n of [...nodeById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(n.id) ?? 0) === 0) dfs(n.id);\n }\n\n // R7 — every declared node must be reachable from the root (a forest has no single\n // root-anchored x). Silently dropping a declared component violates honesty.\n const reachable = new Set<number>();\n const queue: number[] = [input.rootId];\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (reachable.has(id)) continue;\n reachable.add(id);\n for (const childId of childrenOf.get(id) ?? []) queue.push(childId);\n }\n for (const n of [...nodeById.values()].sort((a, b) => a.id - b.id)) {\n if (!reachable.has(n.id)) push(\"disconnected-node\", `node ${n.id} is unreachable from the root`);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws PhyloValidationError (carrying ALL issues) when the input is un-layout-able. */\nexport function validatePhylo(input: PhyloInput): void {\n const issues = phyloIssues(input);\n if (issues.length > 0) throw new PhyloValidationError(issues);\n}\n","// PURE phylo layout — the single source of truth for positioning and connector routing.\n// The emitter (./svg.ts) draws EXACTLY what this computes, so web / PDF / image pipelines\n// can never drift. Deliberately PURE — no DOM, no Node APIs, no clock, no randomness —\n// so the same input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS the declared topology. Validation\n// (./validate.ts) THROWS on an un-layout-able tree (cycle, forest, DAG) rather than\n// repairing it. A branch length absent from the cladogram x is NEVER lost: it always\n// rides the branch element's <title>. A tip is DERIVED (no outgoing edge); we never\n// invent or suppress a leaf.\n//\n// LAYOUT — the classic tidy-tree (the textbook phylogeny algorithm):\n// * Tip ordering: one DFS from rootId, children in DECLARED edge order (stable-sorted\n// by edge id for determinism — the cladistics \"declared order is the analyst's\n// ladderization choice, never auto-sorted\"). Tips numbered 0..L-1 in DFS-visit order.\n// * Leaf y: tip i → y = top + i·ROW_SLOT + ROW_SLOT/2. Equal disjoint slots ⇒ no\n// vertical overlap by construction (the genogram's column bands, transposed 90°).\n// * Internal y = midpoint of its children's y ((min+max)/2), computed post-order.\n// Horizontal:\n// * cladogram: x = padLeft + depth·LEVEL_W; tips right-aligned to maxDepth's x; a dotted\n// EXTENSION segment fills from a tip's true depth-x to the alignment line (FigTree).\n// * phylogram: x = padLeft + cumulativeLength(root→node)·SCALE, SCALE = drawW/maxRootTip\n// (fit-to-width). null/0 lengths contribute 0 ⇒ a node sits directly above its parent\n// (a zero-length branch — valid, NOT an error). Tips not right-aligned unless alignTips.\n// Edges = rectangular elbows (orthogonal, harness-clean): one shared VERTICAL \"clade bar\"\n// per parent spanning min→max child y at the parent's x, plus one HORIZONTAL \"branch\" per\n// child from parentX to childX at childY. Overlap proof: tips own disjoint y-bands; an\n// internal node's y is strictly between its children's bands ⇒ clade bars nest without\n// overlap; branches live at distinct child-y's. Same inductive structure as the fault\n// tree, transposed.\n\nimport { clampLabel, estimateTextWidth, type Point } from \"../core\";\nimport { PHYLO_TITLE_LABELS_EN, type PhyloTitleLabels } from \"./labels\";\nimport { validatePhylo } from \"./validate\";\nimport type { PhyloInput, PhyloMode, PhyloNode } from \"./types\";\n\nexport { PhyloValidationError, phyloIssues, validatePhylo, type PhyloIssue, type PhyloIssueCode } from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render) ───────────\n/** Tip-label font size (px). */\nexport const PHYLO_LABEL_FONT = 12;\n/** Vertical slot per tip (px) — equal slots guarantee vertical disjointness. */\nexport const PHYLO_ROW_SLOT = 22;\n/** Support-value font size (px) — drawn just left of an internal node. */\nexport const PHYLO_SUPPORT_FONT = 10;\n/** Gap from a tip point to the start of its label text. */\nexport const PHYLO_LABEL_GAP = 8;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────────\nconst PADDING = 32;\n/** Horizontal level width per topological depth (cladogram x; phylogram fallback). */\nconst PHYLO_LEVEL_W = 72;\n/** Tip dot radius (a small filled marker at each node point). */\nconst PHYLO_TIP_R = 2.5;\n/** Reserved gap to the left of an internal node for its support text (when showSupport). */\nconst SUPPORT_GAP = 4;\n/** Vertical gap reserved below the tree for the scale bar assembly. */\nconst SCALEBAR_ZONE = 34;\n/** Drawn length cap (in px) of the available width for the tree body. */\nconst MIN_DRAW_W = PHYLO_LEVEL_W; // a degenerate single-depth tree still gets one level\n/** Phylogram-only x nudge (px) for an INTERNAL child whose zero/null branch lands it at\n * exactly its parent's x. Without it, the child's clade bar and the parent's clade bar are\n * two collinear verticals (double-drawn line, ambiguous polytomy). One pixel right gives\n * the child's bar its own vertical while preserving the \"directly above the parent\" read; a\n * TIP at the parent's x needs no nudge (a tip has no clade bar). PRESENTATION-only — the\n * verbatim 0/null length still rides the branch element's <title>. */\nconst PHYLO_ZERO_NUDGE = 1;\n\n// ── Namespaced element-id blocks (one element kind per numeric block; every\n// data-edge-id stays traceable to its source node) ─────────────────────────────────\nexport const PHYLO_CLADEBAR_ID_BASE = 1_000_000; // + parent node id (the vertical bar)\nexport const PHYLO_BRANCH_ID_BASE = 2_000_000; // + child node id (the horizontal branch)\nexport const PHYLO_EXTENSION_ID_BASE = 3_000_000; // + tip node id (dotted right-align extension)\nexport const PHYLO_ROOTSTUB_ID_BASE = 4_000_000; // + root id (the short left stub into the root)\nexport const PHYLO_SCALEBAR_ID = 5_000_000; // the labelled scale-bar segment\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────────\n\nexport interface PhyloLayoutNode {\n nodeId: number;\n isTip: boolean;\n /** Node point center. */\n cx: number;\n cy: number;\n /** Bootstrap/posterior; null when absent (always in the <title> regardless). */\n support: number | null;\n /** Tip label as a single clamped line, drawn right of the tip point; [] for internals. */\n labelLines: string[];\n /** x where the tip label text starts (after PHYLO_LABEL_GAP); the tip's drawn-x for an\n * aligned tip is the alignment line, so the label always clears the tip point. */\n labelLeft: number;\n /** Edges from the root (a tip in cladogram mode keeps its TRUE depth here). */\n depth: number;\n /** Verbatim <title> text (node.title ?? label + branch-length/support). */\n title: string;\n}\n\nexport type PhyloElementKind = \"clade-bar\" | \"branch\" | \"extension\" | \"root-stub\" | \"scale-bar\";\n\nexport interface PhyloElement {\n /** Namespaced id (PHYLO_*_ID_BASE + parent/child/tip/root id, or PHYLO_SCALEBAR_ID). */\n edgeId: number;\n kind: PhyloElementKind;\n /** Consecutive pairs axis-aligned (clade-bar = V, branch/extension/scale-bar = H). */\n points: Point[];\n /** Drawn dotted (extension + scale-bar ticks are NOT here — only the extension leader). */\n dotted: boolean;\n /** Branch: the verbatim length for the <title>; null otherwise / unspecified. */\n length: number | null;\n title: string;\n}\n\nexport interface PhyloScaleBar {\n /** Branch-length value the bar represents (a nice round step). */\n length: number;\n /** Bar's left x and baseline y. */\n x: number;\n y: number;\n /** Drawn pixel length of the bar (length·SCALE). */\n pxLength: number;\n /** Displayed numeric label (the value, trimmed of trailing zeros). */\n valueLabel: string;\n}\n\nexport interface PhyloLayout {\n width: number;\n height: number;\n mode: PhyloMode;\n /** DFS pre-order (root first, then children in declared edge order). */\n nodes: PhyloLayoutNode[];\n elements: PhyloElement[];\n /** Present only in phylogram mode with scaleBar !== false and a non-degenerate scale. */\n scaleBar: PhyloScaleBar | null;\n /** True when the layout reserved left-margin space for support text AND any internal\n * node carries a support value — the emitter draws support text iff this is set. */\n showSupport: boolean;\n}\n\nexport interface PhyloLayoutOptions {\n /** \"cladogram\" (default) | \"phylogram\". */\n mode?: PhyloMode;\n /** Dotted tip-alignment extensions. cladogram default true; phylogram default false. */\n alignTips?: boolean;\n /** Reserve left margin + draw support text at internal nodes. Default false. */\n showSupport?: boolean;\n /** Draw the phylogram scale bar (ignored in cladogram). Default true. */\n scaleBar?: boolean;\n /** Cap each tip's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for node/branch <title>s — English default. */\n titleLabels?: PhyloTitleLabels;\n}\n\n// ── niceScaleStep — the largest power-of-ten × {1, 2, 5} that is ≤ maxLen/4. A pure\n// function so the scale bar is a stable, \"nice\" round number regardless of the data's\n// exact range (the standard FigTree/ggtree scale-bar value). maxLen ≤ 0 → 0. ─────────\nexport function niceScaleStep(maxLen: number): number {\n if (!(maxLen > 0)) return 0;\n const target = maxLen / 4;\n const exp = Math.floor(Math.log10(target));\n const pow = Math.pow(10, exp);\n // A small relative tolerance so a value imperceptibly below a boundary (e.g. 0.2/4 =\n // 0.04999999999999999 from float rounding) still selects the intended \"nice\" step —\n // the scale value is presentation-only and snapping to the boundary is the honest read.\n const tol = target * 1e-9;\n for (const mult of [5, 2, 1]) {\n const step = mult * pow;\n if (step <= target + tol) return step;\n }\n // target < pow (only when log10 rounding leaves a gap) → the next decade down's 5×.\n return 5 * Math.pow(10, exp - 1);\n}\n\n/** Trims a numeric scale value to a short label (\"0.50\" → \"0.5\", \"1.0\" → \"1\"). */\nfunction trimNumber(n: number): string {\n if (Number.isInteger(n)) return String(n);\n return String(Number(n.toPrecision(6))).replace(/0+$/, \"\").replace(/\\.$/, \"\");\n}\n\n// ── Internal working node ──────────────────────────────────────────────────────────────\n\ninterface Work {\n node: PhyloNode;\n children: Work[];\n depth: number;\n /** Cumulative root→node branch length (phylogram); 0 for null/zero lengths. */\n dist: number;\n /** Length of the edge INTO this node (the root's is null). */\n inLength: number | null;\n cx: number;\n cy: number;\n}\n\nfunction nodeTitle(\n node: PhyloNode,\n isTip: boolean,\n isRoot: boolean,\n inLength: number | null,\n labels: PhyloTitleLabels,\n): string {\n if (node.title !== undefined) return node.title;\n const role = isRoot ? labels.root : isTip ? labels.tip : labels.clade;\n const head = node.label === \"\" ? role : node.label;\n const parts: string[] = [head];\n if (inLength !== null) parts.push(`${labels.branchLength}: ${trimNumber(inLength)}`);\n if (!isTip && node.support !== undefined && node.support !== null) {\n parts.push(`${labels.support}: ${trimNumber(node.support)}`);\n }\n return parts.join(\" · \");\n}\n\n/**\n * Deterministic, overlap-proof phylo layout (pure function of the inputs). Validates\n * first and THROWS PhyloValidationError on an un-layout-able tree — never sanitizes.\n * Empty input (no nodes, no edges) yields an empty, padded layout; `rootId` is ignored\n * in that one case.\n */\nexport function computePhyloLayout(input: PhyloInput, opts: PhyloLayoutOptions = {}): PhyloLayout {\n const mode: PhyloMode = opts.mode ?? \"cladogram\";\n if (input.nodes.length === 0 && input.edges.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, mode, nodes: [], elements: [], scaleBar: null, showSupport: false };\n }\n validatePhylo(input);\n\n const titleLabels = opts.titleLabels ?? PHYLO_TITLE_LABELS_EN;\n const alignTips = opts.alignTips ?? (mode === \"cladogram\");\n const showSupport = opts.showSupport ?? false;\n const wantScaleBar = (opts.scaleBar ?? true) && mode === \"phylogram\";\n\n const nodeById = new Map(input.nodes.map((n) => [n.id, n]));\n // Children of a node in declared edge order (stable by edge id) — the validated tree\n // guarantees every endpoint exists and each node has ≤1 parent.\n const childrenOf = new Map<number, number[]>();\n const inLengthByChild = new Map<number, number | null>();\n for (const e of [...input.edges].sort((a, b) => a.id - b.id)) {\n (childrenOf.get(e.parentId) ?? childrenOf.set(e.parentId, []).get(e.parentId)!).push(e.childId);\n inLengthByChild.set(e.childId, e.length);\n }\n\n // ── Build the working tree by DFS from the root (children in declared order). ─────────\n const allWork: Work[] = [];\n const build = (nodeId: number, depth: number, dist: number): Work => {\n const node = nodeById.get(nodeId)!;\n const inLength = inLengthByChild.get(nodeId) ?? null;\n const work: Work = { node, children: [], depth, dist, inLength, cx: 0, cy: 0 };\n allWork.push(work);\n for (const childId of childrenOf.get(nodeId) ?? []) {\n const childLen = inLengthByChild.get(childId);\n const add = childLen === null || childLen === undefined ? 0 : Math.max(0, childLen);\n work.children.push(build(childId, depth + 1, dist + add));\n }\n return work;\n };\n const root = build(input.rootId, 0, 0);\n\n const isTip = (w: Work): boolean => w.children.length === 0;\n\n // ── Vertical: equal leaf slots in DFS order; internal y = midpoint of children. ───────\n const top = PADDING;\n let tipIndex = 0;\n const assignY = (w: Work): void => {\n if (isTip(w)) {\n w.cy = top + tipIndex * PHYLO_ROW_SLOT + PHYLO_ROW_SLOT / 2;\n tipIndex += 1;\n return;\n }\n for (const c of w.children) assignY(c);\n const ys = w.children.map((c) => c.cy);\n w.cy = (Math.min(...ys) + Math.max(...ys)) / 2;\n };\n assignY(root);\n const tipCount = tipIndex;\n\n // ── Horizontal: depth-x (cladogram) or cumulative-length-x (phylogram, fit-to-width). ─\n const maxDepth = allWork.reduce((m, w) => Math.max(m, w.depth), 0);\n const maxDist = allWork.reduce((m, w) => Math.max(m, w.dist), 0);\n\n // Left margin: PADDING + reserved support-text width (only when showSupport AND any\n // internal node actually carries a support value — measured space, the house rule).\n const supportNodes = allWork.filter(\n (w) => !isTip(w) && w.node.support !== undefined && w.node.support !== null,\n );\n // Effective flag: support text is drawn ONLY when requested AND at least one internal\n // node actually carries a value (the layout reserves the margin for exactly that text).\n const effectiveShowSupport = showSupport && supportNodes.length > 0;\n const supportMargin = effectiveShowSupport\n ? supportNodes.reduce(\n (m, w) => Math.max(m, estimateTextWidth(trimNumber(w.node.support as number), PHYLO_SUPPORT_FONT)),\n 0,\n ) + SUPPORT_GAP\n : 0;\n const padLeft = PADDING + supportMargin;\n\n // Tip-label widths reserve real space on the right so the canvas always contains them.\n const tipLabelW = allWork\n .filter(isTip)\n .reduce((m, w) => Math.max(m, estimateTextWidth(clampLabel(w.node.label, opts.maxLabelChars), PHYLO_LABEL_FONT)), 0);\n const labelReserve = (tipCount > 0 ? PHYLO_LABEL_GAP + tipLabelW : 0) + PADDING;\n\n // Phylogram scale: fit the deepest root-to-tip distance to the available draw width\n // (the genogram's fit-to-container ethos). The width tracks topological depth so a deep\n // tree gets room; MIN_DRAW_W keeps a shallow tree (e.g. a single split) drawable.\n const phylogramScaled = mode === \"phylogram\" && maxDist > 0;\n const drawW = Math.max(MIN_DRAW_W, maxDepth * PHYLO_LEVEL_W);\n const scale = phylogramScaled ? drawW / maxDist : 0;\n\n const xOf = (w: Work): number => {\n if (phylogramScaled) return padLeft + w.dist * scale;\n return padLeft + w.depth * PHYLO_LEVEL_W; // cladogram (or degenerate phylogram)\n };\n for (const w of allWork) w.cx = xOf(w);\n\n // Phylogram-only de-collinearity nudge. A zero/null-length branch lands an INTERNAL child\n // at exactly its parent's x, so the child's clade bar and the parent's clade bar become\n // two collinear verticals (a double-drawn line that reads as an ambiguous polytomy). We\n // push such a child PHYLO_ZERO_NUDGE px right of the parent's FINAL x so its bar lives on\n // its own vertical — preserving the \"directly above the parent\" read (one pixel). A TIP at\n // the parent's x is fine (no clade bar), so it is never nudged. Pre-order so a chain of\n // zero-length internals each clears its own (already-nudged) parent — the monotone\n // cx(child) ≥ cx(parent) invariant is preserved, strictly. Purely positional: the verbatim\n // 0/null length is untouched (it still rides the branch element's <title>).\n if (phylogramScaled) {\n const nudge = (w: Work): void => {\n for (const c of w.children) {\n if (!isTip(c) && c.cx <= w.cx + 1e-6) c.cx = w.cx + PHYLO_ZERO_NUDGE;\n nudge(c);\n }\n };\n nudge(root);\n }\n\n // The alignment line for right-aligned tips. `alignTips` defaults true in cladogram\n // (the defining right-aligned look) and false in phylogram (the x IS the data); setting\n // it false in cladogram drops both the alignment AND the dotted extensions. Internals\n // keep their computed x; only TIPS are pushed to the line. In cladogram the line is the\n // deepest depth-x; in phylogram (alignTips:true) it is the rightmost tip's own x.\n const tipsAligned = alignTips;\n const maxTipX = allWork.filter(isTip).reduce((m, w) => Math.max(m, w.cx), padLeft);\n const alignX = phylogramScaled ? maxTipX : padLeft + maxDepth * PHYLO_LEVEL_W;\n const tipDrawX = (w: Work): number => (tipsAligned ? alignX : w.cx);\n\n // ── Canvas size. ──────────────────────────────────────────────────────────────────────\n const rightmost = tipsAligned ? alignX : allWork.reduce((m, w) => Math.max(m, w.cx), padLeft);\n const treeBottom = top + (tipCount > 0 ? tipCount * PHYLO_ROW_SLOT : PHYLO_ROW_SLOT);\n const scaleBarPx = wantScaleBar && maxDist > 0 ? niceScaleStep(maxDist) * scale : 0;\n const hasScaleBar = wantScaleBar && maxDist > 0 && scaleBarPx > 0;\n const width = Math.ceil(rightmost + labelReserve);\n const height = Math.ceil(treeBottom + (hasScaleBar ? SCALEBAR_ZONE : 0) + PADDING / 2);\n\n // ── Emit nodes (DFS pre-order) + elements. ────────────────────────────────────────────\n const nodes: PhyloLayoutNode[] = [];\n const elements: PhyloElement[] = [];\n\n const branchTitle = (w: Work): string => {\n if (w.inLength !== null) return `${titleLabels.branchLength}: ${trimNumber(w.inLength)}`;\n return titleLabels.branchLength;\n };\n\n // Root stub: a short horizontal lead-in to the root point (left of it), so a root with\n // a single child still reads as a tree origin. Drawn from padLeft − stub to the root x.\n const ROOT_STUB = 14;\n const rootDrawX = isTip(root) ? tipDrawX(root) : root.cx;\n elements.push({\n edgeId: PHYLO_ROOTSTUB_ID_BASE + root.node.id,\n kind: \"root-stub\",\n points: [\n { x: round(Math.max(PADDING / 2, rootDrawX - ROOT_STUB)), y: round(root.cy) },\n { x: round(rootDrawX), y: round(root.cy) },\n ],\n dotted: false,\n length: null,\n title: titleLabels.root,\n });\n\n const emit = (w: Work): void => {\n const tip = isTip(w);\n const isRoot = w === root;\n const drawX = tip ? tipDrawX(w) : w.cx;\n const support = w.node.support === undefined ? null : w.node.support;\n const labelLine = tip && w.node.label !== \"\" ? [clampLabel(w.node.label, opts.maxLabelChars)] : [];\n nodes.push({\n nodeId: w.node.id,\n isTip: tip,\n cx: round(drawX),\n cy: round(w.cy),\n support,\n labelLines: labelLine,\n labelLeft: round(drawX + PHYLO_TIP_R + PHYLO_LABEL_GAP),\n depth: w.depth,\n title: nodeTitle(w.node, tip, isRoot, w.inLength, titleLabels),\n });\n\n // Aligned tip → a dotted EXTENSION from its true branch-end x to the alignment line.\n if (tip && tipsAligned && w.cx < alignX - 1e-6) {\n elements.push({\n edgeId: PHYLO_EXTENSION_ID_BASE + w.node.id,\n kind: \"extension\",\n points: [\n { x: round(w.cx), y: round(w.cy) },\n { x: round(alignX), y: round(w.cy) },\n ],\n dotted: true,\n length: null,\n title: titleLabels.tip,\n });\n }\n\n if (w.children.length === 0) return;\n\n // One shared VERTICAL clade bar at the parent's x, spanning min→max child y.\n const childYs = w.children.map((c) => c.cy);\n const barTop = Math.min(...childYs);\n const barBottom = Math.max(...childYs);\n if (barBottom - barTop > 1e-6) {\n elements.push({\n edgeId: PHYLO_CLADEBAR_ID_BASE + w.node.id,\n kind: \"clade-bar\",\n points: [\n { x: round(w.cx), y: round(barTop) },\n { x: round(w.cx), y: round(barBottom) },\n ],\n dotted: false,\n length: null,\n title: isRoot ? titleLabels.root : titleLabels.clade,\n });\n }\n\n // One HORIZONTAL branch per child: parentX → childX at childY (the rectangular elbow).\n for (const c of w.children) {\n elements.push({\n edgeId: PHYLO_BRANCH_ID_BASE + c.node.id,\n kind: \"branch\",\n points: [\n { x: round(w.cx), y: round(c.cy) },\n { x: round(c.cx), y: round(c.cy) },\n ],\n dotted: false,\n length: c.inLength,\n title: branchTitle(c),\n });\n }\n for (const c of w.children) emit(c);\n };\n emit(root);\n\n // ── Scale bar (phylogram only): a labelled horizontal segment in the dead space below\n // the tree. Its value is a niceScaleStep of the deepest distance. ───────────────────\n let scaleBar: PhyloScaleBar | null = null;\n if (hasScaleBar) {\n const stepLen = niceScaleStep(maxDist);\n const barX = padLeft;\n const barY = treeBottom + SCALEBAR_ZONE / 2;\n scaleBar = {\n length: stepLen,\n x: round(barX),\n y: round(barY),\n pxLength: round(scaleBarPx),\n valueLabel: trimNumber(stepLen),\n };\n elements.push({\n edgeId: PHYLO_SCALEBAR_ID,\n kind: \"scale-bar\",\n points: [\n { x: round(barX), y: round(barY) },\n { x: round(barX + scaleBarPx), y: round(barY) },\n ],\n dotted: false,\n length: stepLen,\n title: `${titleLabels.branchLength}: ${trimNumber(stepLen)}`,\n });\n }\n\n return { width, height, mode, nodes, elements, scaleBar, showSupport: effectiveShowSupport };\n}\n","// Phylo SVG emitter — turns a computed PhyloLayout (./layout.ts) into a SELF-CONTAINED\n// SVG string. Pure (layout in, string out) and deterministic; it draws EXACTLY what the\n// layout computed (the overlap harness proves the layout; this emitter is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — labels/titles are author-controlled and\n// the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (hex colors, explicit font-family, inline\n// dasharray): a standalone SVG has no stylesheet, no currentColor, no <defs>/<marker>;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Drawing: rectangular (\"square elbow\") tree — a vertical clade bar per internal node + a\n// horizontal branch per child; aligned tips get a dotted extension leader; a small filled\n// dot marks each node point; tip labels sit left-anchored to the right of the tip; support\n// values (when showSupport baked the margin in) draw text-anchor:end just left of the\n// internal node. The phylogram scale bar is a first-class drawn element below the tree.\n//\n// Hooks: `<g data-node-id=\"n<id>\">` per node (direct-child verbatim <title>);\n// `<g data-edge-id=\"<n>\">` per element (namespaced ids, see ./layout.ts).\n\nimport { FONT_FAMILY, legendBlock, xmlEscape, LEGEND_SWATCH_W, type LegendEntry } from \"../core\";\nimport {\n PHYLO_LABEL_FONT,\n PHYLO_SUPPORT_FONT,\n type PhyloElement,\n type PhyloLayout,\n type PhyloLayoutNode,\n} from \"./layout\";\nimport { PHYLO_SVG_LABELS_EN, type PhyloSvgLabels } from \"./labels\";\n\n// Literal ink colors (zinc ramp on white — matches every other compasso emitter).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport interface PhyloSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: PhyloSvgLabels;\n}\n\n// ── Node points + tip labels + support text ───────────────────────────────────────────\n\nfunction nodeSvg(n: PhyloLayoutNode, showSupport: boolean): string {\n const pieces: string[] = [`<title>${xmlEscape(n.title)}</title>`];\n // A small filled dot marks every node point (tip and internal).\n pieces.push(`<circle cx=\"${n.cx}\" cy=\"${n.cy}\" r=\"2.5\" fill=\"${GLYPH_STROKE}\"/>`);\n // Tip label: single clamped line, left-anchored right of the tip point.\n if (n.labelLines.length > 0) {\n pieces.push(\n `<text x=\"${n.labelLeft}\" y=\"${round(n.cy + PHYLO_LABEL_FONT * 0.32)}\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_LABEL_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(n.labelLines[0]!)}</text>`,\n );\n }\n // Internal support value: text-anchor:end just left of the node (margin reserved in\n // the layout). Drawn only when requested AND the value is present.\n if (showSupport && !n.isTip && n.support !== null) {\n pieces.push(\n `<text x=\"${round(n.cx - 4)}\" y=\"${round(n.cy - 3)}\" text-anchor=\"end\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_SUPPORT_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(String(n.support))}</text>`,\n );\n }\n return `<g data-node-id=\"n${n.nodeId}\">${pieces.join(\"\")}</g>`;\n}\n\n// ── Connector elements (clade bars, branches, dotted extensions, root stub, scale bar) ──\n\nfunction elementSvg(el: PhyloElement): string {\n const a = el.points[0]!;\n const b = el.points[1]!;\n const dash = el.dotted ? ` stroke-dasharray=\"2,3\"` : \"\";\n const opacity = el.kind === \"extension\" ? \"0.5\" : \"0.75\";\n return (\n `<g data-edge-id=\"${el.edgeId}\"><title>${xmlEscape(el.title)}</title>` +\n `<line x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"${opacity}\"${dash}/></g>`\n );\n}\n\n// ── Scale-bar value label (drawn separately from its segment element) ──────────────────\n\nfunction scaleBarLabelSvg(layout: PhyloLayout): string {\n const bar = layout.scaleBar;\n if (bar === null) return \"\";\n // Small end ticks frame the bar; the value sits centered above it.\n const tick = (x: number): string =>\n `<line x1=\"${x}\" y1=\"${round(bar.y - 3)}\" x2=\"${x}\" y2=\"${round(bar.y + 3)}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>`;\n return (\n tick(bar.x) +\n tick(round(bar.x + bar.pxLength)) +\n `<text x=\"${round(bar.x + bar.pxLength / 2)}\" y=\"${round(bar.y - 6)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_SUPPORT_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(bar.valueLabel)}</text>`\n );\n}\n\n// ── Legend mini-swatches ───────────────────────────────────────────────────────────────\n\nfunction supportSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n return (\n `<circle cx=\"${cx}\" cy=\"${y}\" r=\"2.5\" fill=\"${GLYPH_STROKE}\"/>` +\n `<text x=\"${round(cx + 5)}\" y=\"${round(y + PHYLO_SUPPORT_FONT * 0.32)}\" font-family=\"${FONT_FAMILY}\" font-size=\"${PHYLO_SUPPORT_FONT}\" fill=\"${LABEL_FILL}\">95</text>`\n );\n}\n\nfunction scaleSwatch(x: number, y: number): string {\n return `<line x1=\"${round(x)}\" y1=\"${y}\" x2=\"${round(x + LEGEND_SWATCH_W)}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>`;\n}\n\nfunction alignedTipSwatch(x: number, y: number): string {\n return `<line x1=\"${round(x)}\" y1=\"${y}\" x2=\"${round(x + LEGEND_SWATCH_W)}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.5\" stroke-dasharray=\"2,3\"/>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed phylo layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal. The legend is minimal and used-keys-only: a phylo\n * tree is self-labelling (tips carry names), so often it has zero entries.\n *\n * `showSupport` is read off the layout's reserved margin: the emitter draws the support\n * text only when a support value was reserved (any internal node has a non-null support\n * AND the support margin > PADDING). This keeps the emitter pinned to the layout — it\n * never reserves what the layout didn't, nor draws what it can't fit.\n */\nexport function phyloLayoutSvg(layout: PhyloLayout, opts: PhyloSvgOptions = {}): string {\n const labels = opts.labels ?? PHYLO_SVG_LABELS_EN;\n // showSupport is a layout-affecting option (it reserves left margin), so the layout\n // bakes the resolved flag in — the emitter reads it off the layout and never re-decides.\n const showSupport = layout.showSupport;\n\n const parts: string[] = [];\n\n // Connectors first, then node points/labels — points sit on top.\n for (const el of layout.elements) parts.push(elementSvg(el));\n parts.push(scaleBarLabelSvg(layout));\n for (const n of layout.nodes) parts.push(nodeSvg(n, showSupport));\n\n // ── Used-keys-only legend (core legendBlock; `legend:false` suppresses). ──────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: LegendEntry[] = [];\n if (showSupport) entries.push({ swatch: supportSwatch, label: labels.support });\n if (layout.scaleBar !== null) entries.push({ swatch: scaleSwatch, label: labels.scaleBar });\n if (layout.elements.some((e) => e.kind === \"extension\")) {\n entries.push({ swatch: alignedTipSwatch, label: labels.alignedTip });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel[layout.mode])}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call phylo render: input → { svg, layout }. Thin, honest wiring: validate (throw on\n// an un-layout-able tree — never repair), compute the pure layout, emit. Callers needing\n// finer control use computePhyloLayout + phyloLayoutSvg directly (the layout result\n// supports hit-testing / decorating the diagram).\n\nimport { computePhyloLayout, type PhyloLayout, type PhyloLayoutOptions } from \"./layout\";\nimport { phyloLayoutSvg } from \"./svg\";\nimport type { PhyloSvgLabels } from \"./labels\";\nimport type { PhyloInput } from \"./types\";\n\nexport interface PhyloRenderOptions extends PhyloLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: PhyloSvgLabels;\n}\n\nexport interface PhyloRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: PhyloLayout;\n}\n\n/**\n * Renders a phylo input to a self-contained SVG string. Deterministic: same data → same\n * SVG (array order never matters; a node's children are drawn in declared edge order, the\n * analyst's ladderization choice, never auto-sorted). Throws PhyloValidationError —\n * carrying EVERY issue, deterministically sorted — on an un-layout-able tree (cycle,\n * forest, DAG, dangling reference). Empty input yields an empty-but-valid SVG.\n */\nexport function phyloSvg(input: PhyloInput, opts: PhyloRenderOptions = {}): PhyloRenderResult {\n const layout = computePhyloLayout(input, {\n ...(opts.mode !== undefined ? { mode: opts.mode } : {}),\n ...(opts.alignTips !== undefined ? { alignTips: opts.alignTips } : {}),\n ...(opts.showSupport !== undefined ? { showSupport: opts.showSupport } : {}),\n ...(opts.scaleBar !== undefined ? { scaleBar: opts.scaleBar } : {}),\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = phyloLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Org-chart input model — declared facts only. compasso draws EXACTLY who the caller\n// declares reports to whom: every reporting line carries its declared `kind` (the line\n// STYLE is a semantic claim only the author may make), every box is a declared position,\n// and the ROOT is never declared — it is READ from topology (a position that is no solid\n// edge's report). There is deliberately NO `level`/`depth`/`isManager`/`order` field on\n// the input: depth is derived from the declared solid edges, not trusted from a flag (the\n// honesty rule). Multi-root forests (holding cos, co-CEOs, pre-merger) are real and\n// tolerated, never an error.\n\n/**\n * CLOSED reporting vocabulary — a line is drawn ONLY for a declared relationship, styled\n * ONLY by a declared kind. No inference, no synthesis.\n * - \"line\" — solid PRIMARY reporting line; defines the tree spine (a node's row & parent).\n * - \"assistant\" — solid SIDE-STEM staff/EA role; STILL a structural child of exactly one\n * manager (it sets the report's row = manager.depth + 1 band), but drawn\n * beside the manager's stem above the line-report bus rather than packed\n * into the sibling rake.\n * - \"dotted\" — dashed secondary/matrix line. NON-STRUCTURAL: never defines a row or a\n * parent; an OVERLAY between two already-placed boxes (dotted-line-manager\n * convention).\n */\nexport const ORG_REPORT_KINDS = [\"line\", \"assistant\", \"dotted\"] as const;\nexport type OrgReportKind = (typeof ORG_REPORT_KINDS)[number];\n\n/**\n * CLOSED vacancy vocabulary. A box is vacant ONLY when DECLARED so — never inferred from\n * an empty name. A vacant box may legitimately carry a name (a departed incumbent or a\n * target hire); both are drawn.\n */\nexport const ORG_VACANCIES = [\"filled\", \"vacant\"] as const;\nexport type OrgVacancy = (typeof ORG_VACANCIES)[number];\n\n/**\n * A declared organizational position (one box). `name`/`title`/`subtitle` are verbatim\n * (always kept in the <title>); empty strings / nulls are drawn as declared.\n */\nexport interface OrgPosition {\n id: number;\n /** Verbatim person/role name — line 1 of the box. \"\" allowed (drawn empty; <title> intact). */\n name: string;\n /** Verbatim job title — line 2 (smaller). null = name-only box. */\n title: string | null;\n /**\n * OPTIONAL third line (department/unit), verbatim, measured into boxW like the others.\n * null = none. NOT a metrics/compensation field — that interpretive cut stands.\n */\n subtitle: string | null;\n /**\n * \"vacant\" → dashed box + inset open-seat frame + localized \"(vago)\" marker line.\n * A box is vacant ONLY when DECLARED so — never inferred from an empty name.\n * (validation defaults an absent value → \"filled\").\n */\n vacancy: OrgVacancy;\n /** Verbatim <title> override; defaults below (see svg.ts). */\n hover?: string;\n /**\n * Caller-asserted annotation flag. compasso never decides what \"annotated\" MEANS —\n * it only draws a discreet dot at the box's upper-right when true. Default undefined\n * === not annotated (backward-compatible).\n */\n annotated?: boolean;\n}\n\n/**\n * One row per DECLARED relationship, manager → report. There is no `order` column in\n * v0.4.0 — sibling order among reports is by ascending `reportId`.\n */\nexport interface OrgReport {\n id: number;\n /** Manager — drawn ABOVE. */\n managerId: number;\n /** Report — drawn BELOW (line) or side-stemmed (assistant). */\n reportId: number;\n /** Reporting-line kind (validation defaults an absent value → \"line\"). */\n kind: OrgReportKind;\n /** Verbatim relationship label (e.g. \"interim\", \"matrix\") for the <title>; null = none. */\n label?: string | null;\n /**\n * Caller-asserted annotation flag. compasso never decides what \"annotated\" MEANS —\n * it only draws a discreet tick at the edge's midpoint when true. Default undefined\n * === not annotated (backward-compatible).\n */\n annotated?: boolean;\n}\n\n/** Input to the org-chart render pipeline — flat, id-referenced rows, never nested. */\nexport interface OrgChartInput {\n positions: OrgPosition[];\n reports: OrgReport[];\n}\n\n/**\n * Presentation-only derived box style (solid = filled, dashed = vacant). Computed in\n * render.ts / svg.ts from `vacancy` — NOT an input field.\n */\nexport type OrgBoxStyle = \"solid\" | \"dashed\";\n","// Display vocabularies — every human-readable string the org chart emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// Split, mirroring fault-tree/genogram: `OrgChartTitleLabels` is woven into element/box\n// <title>s by the LAYOUT (verbatim-preserving — the localized kind word rides each line's\n// <title>, never the map); `OrgChartSvgLabels` is drawn by the EMITTER (legend, aria).\n// `reportKinds` is a `Record<OrgReportKind, string>` so a missing kind is a compile error\n// (`pnpm typecheck` is the completeness guard).\n\nimport type { OrgReportKind } from \"./types\";\n\n/** Labels woven into element/box <title>s by the LAYOUT (verbatim-preserving). */\nexport interface OrgChartTitleLabels {\n reportKinds: Record<OrgReportKind, string>;\n /** The \"(vacant)\" box marker line, drawn inside a vacant box. */\n vacant: string;\n}\n\nexport const ORG_CHART_TITLE_LABELS_EN: OrgChartTitleLabels = {\n reportKinds: { line: \"Reports to\", assistant: \"Assistant to\", dotted: \"Dotted-line report to\" },\n vacant: \"(vacant)\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface OrgChartSvgLabels {\n legend: { line: string; assistant: string; dotted: string; vacant: string };\n ariaLabel: string;\n}\n\nexport const ORG_CHART_SVG_LABELS_EN: OrgChartSvgLabels = {\n legend: { line: \"Reports to\", assistant: \"Assistant\", dotted: \"Dotted-line / matrix\", vacant: \"Vacant position\" },\n ariaLabel: \"Organizational chart\",\n};\n","// Org-chart validation — REJECT, never repair. The genogram silently filters dangling\n// references because a family map is elicited incrementally; an org chart is an\n// AUTHORITATIVE artifact whose meaning is \"who answers to whom\", so drawing a structurally\n// invalid chart (a dropped line, a synthesized parent) misstates the hierarchy and is\n// worse than refusing. The honest escape hatch for a node with two real bosses is the\n// dotted line — keep ONE solid reporting line, make the rest kind:\"dotted\".\n//\n// Every problem is reported, not just the first: issues are aggregated, deduplicated and\n// sorted deterministically (by code, then message), each carrying a STABLE kebab-case\n// `code`. Validation runs in THREE phases, each gated on the previous being clean ENOUGH\n// for the next to be meaningful — not on \"zero issues so far\", so a defect in one phase\n// never silently hides an honest issue from a later one (the throw carries ALL real\n// issues, not just the first phase's):\n// (0) duplicate ids (per namespace — positions AND reports). The lookup maps are\n// first-occurrence-wins, so EVERY reference rule below would validate whichever\n// duplicate row was declared first — making the issue list depend on array order,\n// violating this function's documented order-invariance. When any duplicate-id issue\n// exists we report ONLY those and stop (the duplicate already forces a throw).\n// (1) reference / semantic rules: unknown manager/report endpoints, self-loops, a node\n// with ≥2 SOLID structural parents, and an assistant that itself manages a solid edge\n// (v0.4.0 scopes assistants as side-stem LEAVES — a non-leaf assistant would silently\n// drop its subtree, so we REJECT rather than repair). Evaluated once ids are unambiguous.\n// (2) graph rule (cycle over the SOLID-edge graph) — gated ONLY on the reference-\n// INTEGRITY subset that genuinely corrupts traversal: duplicate-id (ambiguous\n// first-wins node), unknown-manager / unknown-report (walks a phantom node), and\n// multiple-managers (the instance-tree build picks one of two solid parents and\n// would walk an ambiguous structure). `self-report` does NOT block: it references a\n// real, walkable node, and the DFS defensively skips `from === to` solid edges.\n//\n// Tolerated, by design (drawn as declared, never an error):\n// - FOREST — zero/one/many roots (no invented super-root, no inter-tree connector);\n// - dotted edges crossing between forest trees, dotted-only cycles, a dotted edge sharing\n// a solid pair's direction (dotted is NON-structural — never triggers cycle or\n// multiple-managers); a dotted edge into an already-solid-parented box is FINE;\n// - empty name/title/subtitle (drawn empty; the <title> is still present);\n// - a vacant box with a name (departed incumbent / target hire).\n\nimport type { OrgChartInput, OrgPosition, OrgReport } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type OrgChartIssueCode =\n | \"duplicate-id\"\n | \"unknown-manager\"\n | \"unknown-report\"\n | \"self-report\"\n | \"multiple-managers\"\n | \"assistant-has-reports\"\n | \"too-many-matrix-edges\"\n | \"cycle\";\n\n/**\n * Routing capacity: the max number of dotted (matrix) connections one position can be an\n * endpoint of (as manager OR report). Each such edge must escape that box's edge to a\n * box-free column at a distinct (column, exit-y) slot; a finite box edge holds only finitely\n * many clean orthogonal exits, so beyond this the escape columns/exit-rows would collide.\n * 5 is the conservative bound proven collision-free even for the shortest single-line box —\n * a position with more matrix lines than this is rejected rather than misdrawn (the\n * reject-don't-repair doctrine). Realistic matrix orgs sit far below it.\n */\nexport const ORG_MAX_MATRIX_EDGES_PER_NODE = 5;\n\nexport interface OrgChartIssue {\n code: OrgChartIssueCode;\n message: string;\n}\n\n/** Thrown by computeOrgChartLayout / orgChartSvg on a structurally invalid chart. */\nexport class OrgChartValidationError extends Error {\n readonly issues: readonly OrgChartIssue[];\n\n constructor(issues: readonly OrgChartIssue[]) {\n super(`invalid org chart: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"OrgChartValidationError\";\n this.issues = issues;\n }\n}\n\n/** \"1 and 3\" / \"1, 2 and 3\" — deterministic listing for issue messages. */\nfunction listIds(ids: readonly number[]): string {\n if (ids.length === 1) return String(ids[0]);\n return `${ids.slice(0, -1).join(\", \")} and ${ids[ids.length - 1]}`;\n}\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable\n * across engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly OrgChartIssue[]): readonly OrgChartIssue[] {\n const unique = new Map<string, OrgChartIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Graph-phase gating set: the cycle DFS runs only when no reference-INTEGRITY issue\n * corrupts the traversal. duplicate-id / unknown-manager / unknown-report make a walked\n * node ambiguous or phantom; multiple-managers makes the instance-tree's \"pick one solid\n * parent\" build ambiguous. self-report does NOT block (real walkable node; the DFS skips\n * the self-loop defensively).\n */\nconst GRAPH_BLOCKING: ReadonlySet<OrgChartIssueCode> = new Set<OrgChartIssueCode>([\n \"duplicate-id\",\n \"unknown-manager\",\n \"unknown-report\",\n \"multiple-managers\",\n]);\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically sorted\n * (code, then message) — array order of `positions`/`reports` never changes the result.\n * Empty input (no positions AND no reports) is valid by definition (the renderer's\n * empty-but-valid SVG case) and reports no issues. A forest (zero/one/many roots) is\n * valid and never reported.\n */\nexport function orgChartIssues(input: OrgChartInput): readonly OrgChartIssue[] {\n if (input.positions.length === 0 && input.reports.length === 0) return [];\n\n const issues: OrgChartIssue[] = [];\n const push = (code: OrgChartIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── Phase 0: duplicate ids (per namespace — positions and reports are two namespaces;\n // hooks must be unique). Any duplicate makes the structure ambiguous, so this\n // short-circuits the rest (below). ─────────────────────────────────────────────────\n const positionById = new Map<number, OrgPosition>();\n const dupPositionIds = new Set<number>();\n for (const p of input.positions) {\n if (positionById.has(p.id)) dupPositionIds.add(p.id);\n else positionById.set(p.id, p);\n }\n for (const id of [...dupPositionIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate position id ${id}`);\n }\n const reportById = new Map<number, OrgReport>();\n const dupReportIds = new Set<number>();\n for (const r of input.reports) {\n if (reportById.has(r.id)) dupReportIds.add(r.id);\n else reportById.set(r.id, r);\n }\n for (const id of [...dupReportIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate report id ${id}`);\n }\n\n // Duplicate ids short-circuit everything else: the lookup maps above are\n // first-occurrence-wins, so every downstream reference rule would validate whichever\n // duplicate row happened to be declared first — making the issue list depend on the\n // ARRAY ORDER, in direct violation of this function's documented order-invariance. We\n // report ONLY the duplicate-id issues and stop (the structural defect already forces a\n // throw, and is present in every permutation).\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n const reports = [...reportById.values()].sort((a, b) => a.id - b.id);\n\n // ── Phase 1: reference / semantic rules. ─────────────────────────────────────────────\n // Endpoints must reference declared positions; a box may not report to itself; a node\n // has exactly ONE structural parent. `solidParents` accumulates the SOLID (line|assistant)\n // parent edge ids per report position to fire multiple-managers regardless of kind mix.\n const solidParents = new Map<number, number[]>(); // reportId → solid edge ids\n const assistantReportEdge = new Map<number, number>(); // position → first assistant edge it is the report of\n const solidManagedEdges = new Map<number, number[]>(); // managerId → solid edge ids it manages\n const dottedDegree = new Map<number, number>(); // position → # dotted edges it is an endpoint of (mgr or rep)\n for (const r of reports) {\n const hasManager = positionById.has(r.managerId);\n const hasReport = positionById.has(r.reportId);\n if (!hasManager) {\n push(\"unknown-manager\", `report ${r.id} managerId ${r.managerId} is not a declared position`);\n }\n if (!hasReport) {\n push(\"unknown-report\", `report ${r.id} reportId ${r.reportId} is not a declared position`);\n }\n // R: a box reporting to itself is meaningless and self-loops layout — on ANY kind.\n if (r.managerId === r.reportId) {\n push(\"self-report\", `report ${r.id} has managerId === reportId (${r.managerId})`);\n }\n // A SOLID edge (line | assistant) is a structural parent — accumulate even when an\n // endpoint is unknown, so a node with two solid parents is still flagged (the codes\n // are independent facts). dotted is NON-structural and excluded here.\n if (r.kind !== \"dotted\") {\n const arr = solidParents.get(r.reportId) ?? [];\n arr.push(r.id);\n solidParents.set(r.reportId, arr);\n // Track each position's SOLID down-edges (it is the manager of) so a non-leaf\n // assistant — a position that is an assistant-report yet manages a solid edge — is\n // caught below. `reports` is id-sorted, so the lowest edge id lands first.\n const managed = solidManagedEdges.get(r.managerId) ?? [];\n managed.push(r.id);\n solidManagedEdges.set(r.managerId, managed);\n }\n // First (lowest-id) assistant edge that makes this position an assistant-report. A\n // self-loop assistant is excluded — `self-report` already carries that fact and the\n // position never legitimately becomes a side-stem leaf.\n if (r.kind === \"assistant\" && r.managerId !== r.reportId && !assistantReportEdge.has(r.reportId)) {\n assistantReportEdge.set(r.reportId, r.id);\n }\n // Per-position dotted (matrix) degree, for the routing-capacity cap below. A dotted edge\n // makes BOTH endpoints escape their box edge, so each declared endpoint counts once;\n // self-loops (already `self-report`) and phantom endpoints (already `unknown-*`) are\n // excluded — they never reach the router.\n if (r.kind === \"dotted\" && r.managerId !== r.reportId) {\n if (positionById.has(r.managerId)) dottedDegree.set(r.managerId, (dottedDegree.get(r.managerId) ?? 0) + 1);\n if (positionById.has(r.reportId)) dottedDegree.set(r.reportId, (dottedDegree.get(r.reportId) ?? 0) + 1);\n }\n }\n // multiple-managers fires whenever a position is the report of ≥2 SOLID edges, regardless\n // of kind — including one `line` parent AND one `assistant` parent (still two structural\n // parents; the instance-tree DFS would be ambiguous about which owns the row). There is\n // no \"which kind wins\" tiebreak — it is rejected. Escape hatch: keep one solid line, make\n // the rest kind:\"dotted\".\n for (const [reportId, edgeIds] of [...solidParents.entries()].sort((a, b) => a[0] - b[0])) {\n if (edgeIds.length > 1) {\n push(\n \"multiple-managers\",\n `position ${reportId} is the report of solid edges ${listIds(edgeIds.sort((a, b) => a - b))} — keep one solid line, make the rest kind \"dotted\"`,\n );\n }\n }\n\n // assistant-has-reports: v0.4.0 draws an assistant as a side-stem LEAF, so a position\n // that is an assistant-report AND manages a solid (line|assistant) edge would have its\n // entire subtree silently dropped. REJECT it (reject-don't-repair) — keep the lowest\n // managed solid edge id in the message so the author knows which line to recut. Ascending\n // position id for a deterministic, array-order-invariant list.\n for (const [positionId, assistEdgeId] of [...assistantReportEdge.entries()].sort((a, b) => a[0] - b[0])) {\n const managed = solidManagedEdges.get(positionId);\n if (managed !== undefined && managed.length > 0) {\n const firstManaged = Math.min(...managed);\n push(\n \"assistant-has-reports\",\n `position ${positionId} is an assistant (report of edge ${assistEdgeId}) but manages solid edge ${firstManaged} — assistants are leaves`,\n );\n }\n }\n\n // too-many-matrix-edges: a position that is an endpoint of more dotted (matrix) edges than\n // the router can place distinct box-free escape slots for (see ORG_MAX_MATRIX_EDGES_PER_NODE).\n // Reject rather than misdraw (overlapping/colliding lines). Ascending position id for a\n // deterministic, array-order-invariant list.\n for (const [positionId, count] of [...dottedDegree.entries()].sort((a, b) => a[0] - b[0])) {\n if (count > ORG_MAX_MATRIX_EDGES_PER_NODE) {\n push(\n \"too-many-matrix-edges\",\n `position ${positionId} has ${count} dotted (matrix) connections — at most ${ORG_MAX_MATRIX_EDGES_PER_NODE} are supported per position`,\n );\n }\n }\n\n // ── Phase 2: graph rule (cycle over the SOLID-edge graph). Gated ONLY on the reference-\n // INTEGRITY codes that corrupt the traversal itself (see GRAPH_BLOCKING). dotted edges\n // are EXCLUDED — a matrix back-link is legal and never a cycle. ─────────────────────\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n // Adjacency manager → reports over SOLID edges only, in ascending reportId so the DFS\n // walks children deterministically (array-order-invariant). `from === to` self-loops\n // are skipped defensively (self-report carries that fact as its own code).\n const solidChildren = new Map<number, number[]>();\n for (const r of reports) {\n if (r.kind === \"dotted\") continue;\n if (r.managerId === r.reportId) continue;\n const arr = solidChildren.get(r.managerId) ?? [];\n arr.push(r.reportId);\n solidChildren.set(r.managerId, arr);\n }\n for (const arr of solidChildren.values()) arr.sort((a, b) => a - b);\n\n // Iterative coloring DFS, start nodes ascending; each distinct cycle is reported once,\n // rotated to start at its smallest position id so the message is identical for any\n // array order of the same input.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = solidChildren.get(frame.id) ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n // Back edge: the cycle is the stack slice from `child` down to the current frame.\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\"cycle\", `cycle: ${[...rotated, rotated[0]!].join(\" → \")}`);\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n for (const p of [...positionById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(p.id) ?? 0) === 0) dfs(p.id);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws OrgChartValidationError (carrying ALL issues) when the input is invalid. */\nexport function validateOrgChart(input: OrgChartInput): void {\n const issues = orgChartIssues(input);\n if (issues.length > 0) throw new OrgChartValidationError(issues);\n}\n","// PURE org-chart layout — the single source of truth for box positioning and connector\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so every surface\n// (web, PDF, image pipelines) stays pinned together and can never drift.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so the same\n// input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS what the caller declared. There is NO\n// `level`/`depth`/`order` field on the input — depth is READ from the declared solid\n// edges (line|assistant) and the root is READ from topology (a position that is no solid\n// edge's report). Validation (./validate.ts) THROWS on a structurally invalid chart\n// instead of repairing it — an org chart is an authoritative artifact and silently\n// altering who-answers-to-whom is synthesis. Forests (zero/one/many roots) are tolerated.\n//\n// LAYOUT — top-down rows, exactly as every org chart draws it: manager box, short stem\n// down to a sibling bus, drops to each line-report box. Horizontal placement is NAIVE\n// SUBTREE-SPAN PACKING (the fault-tree `pack` transposed top-down, NOT Reingold–Tilford\n// contours): every subtree carries asymmetric half-extents {halfL, halfR}; siblings are\n// placed with disjoint intervals ORG_SIBLING_GAP apart, the recursion makes the guarantee\n// global (a 5-line inductive overlap proof, re-verified by the test harness), at the cost\n// of some width on unbalanced trees. Label widths reserve REAL space because boxW comes\n// from estimateTextWidth over the wrapped lines and the emitter draws with the same core\n// metrics — what is proven is what is drawn.\n//\n// CORRIDOR-GROW INVARIANT (asserted in test/org-chart/layout.test.ts): a manager's\n// assistant stack hangs in the corridor between its row and the next; the corridor grows\n// to clear the tallest stack, so every manager box bottom AND every assistant box bottom\n// sits strictly ABOVE the child bus y (the fault-tree gate-clearance analog).\n//\n// DOTTED/MATRIX overlay → a reserved RIGHT-MARGIN GUTTER (the decisive graft): after the\n// solid tree is placed, each dotted edge routes as a 3-segment orthogonal elbow into a\n// per-edge lane at x > every box's right edge — box-free by construction.\n\nimport { clampLabel, estimateTextWidth, wrapLabelBalanced, type Point, packSubtree, allocateLanes, type PackNode, type PackGaps, type PackResult } from \"../core\";\nimport { ORG_CHART_TITLE_LABELS_EN, type OrgChartTitleLabels } from \"./labels\";\nimport { validateOrgChart } from \"./validate\";\nimport type { OrgBoxStyle, OrgChartInput, OrgPosition, OrgReport } from \"./types\";\n\nexport {\n OrgChartValidationError,\n orgChartIssues,\n validateOrgChart,\n type OrgChartIssue,\n type OrgChartIssueCode,\n} from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render) ──────\n/** Name line font size (px). */\nexport const ORG_LABEL_FONT = 12;\n/** Title + subtitle + vacant marker font size (px). */\nexport const ORG_TITLE_FONT = 10;\n/** Line height for stacked label lines inside a box (px). */\nexport const ORG_LABEL_LINE_H = 14;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────\n/** Canvas padding on every side. */\nconst PADDING = 32;\n/** Min horizontal air between two sibling subtree intervals. */\nconst ORG_SIBLING_GAP = 28;\n/** Min horizontal air between two forest trees. */\nconst ORG_TREE_GAP = 56;\n/** Base vertical band between a row and the next (the bus lives mid-way). */\nconst ORG_CORRIDOR = 30;\n/** Minimum box width (boxes never shrink below this even with tiny labels). */\nconst ORG_MIN_BOX_W = 120;\n/** Horizontal padding inside a box (each side). */\nconst ORG_BOX_PAD_X = 12;\n/** Vertical padding inside a box (each side). */\nconst ORG_BOX_PAD_Y = 9;\n/** Horizontal gap from a manager's stem to an assistant box (reserved into ownHalfL). */\nconst ORG_ASSIST_GAP = 24;\n/** Vertical gap between stacked assistant bands (and below the last one). */\nconst ORG_ASSIST_BAND_DROP = 14;\n/** Horizontal gap from the tree's right edge to the first dotted gutter lane. */\nconst ORG_MATRIX_GUTTER_GAP = 28;\n/** Horizontal pitch between adjacent dotted gutter lanes. */\nconst ORG_MATRIX_LANE_PITCH = 14;\n/** Horizontal step between adjacent escape-vertical lanes that share a column. The GLOBAL\n * greedy first-fit (STEP 6 / FIX 2) nudges any y-overlapping coincident vertical by\n * lane*ORG_MATRIX_ESCAPE_STEP in the endpoint's escape direction until its column is clear of\n * every already-placed vertical; box-freeness holds while lane*STEP stays inside the MEASURED\n * box-free band to that side (distance to the nearest real box edge overlapping the vertical's\n * y-span). The router asserts (escape-column-overflow) rather than misdraw if a nudge exceeds\n * the band. */\nconst ORG_MATRIX_ESCAPE_STEP = 2;\n\n// ── Namespaced element ids (one element kind per numeric block, fault-tree convention)\n// — every data-edge-id stays traceable to its source row. ───────────────────────\nexport const ORG_STEM_ID_BASE = 1_000_000; // + managerId (manager box bottom → bus level)\nexport const ORG_BUS_ID_BASE = 2_000_000; // + managerId (horizontal sibling bus)\nexport const ORG_DROP_ID_BASE = 3_000_000; // + reportId (bus → line-report box top)\nexport const ORG_ASSIST_ID_BASE = 4_000_000; // + reportId (side-stem elbow to assistant)\nexport const ORG_DOTTED_ID_BASE = 5_000_000; // + report.id (matrix gutter route)\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// A box's LEFT/RIGHT edge AS DRAWN. svg.ts draws the rect at left = round(node.cx −\n// node.boxW/2) from the EMITTED (rounded) node geometry (node.cx === round(cx), node.boxW\n// === round(boxW)); width is node.boxW. Any segment that attaches to a box edge (the assist\n// elbow, the dotted matrix stub) MUST target these exact values — deriving the edge from raw\n// cx/boxW (or from a sibling expression like managerCx − gap) rounds DIFFERENTLY and lands\n// the endpoint a sub-cent INSIDE the box (a real off-by-0.01 in the emitted SVG, flagged by\n// the overlap harness). boxW is an exact multiple of 0.01, so drawnLeft + boxW === the box's\n// own right edge. Box CENTERS (stem/drop x) already use round(cx) === node.cx and are fine.\nconst drawnLeftEdge = (cx: number, boxW: number): number => round(round(cx) - round(boxW) / 2);\nconst drawnRightEdge = (cx: number, boxW: number): number => drawnLeftEdge(cx, boxW) + round(boxW);\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────\n\nexport type OrgElementKind = \"stem\" | \"bus\" | \"drop\" | \"assist\" | \"dotted\";\n\nexport interface OrgNode {\n positionId: number;\n /** Box center x. */\n cx: number;\n /** Box top y. */\n top: number;\n boxW: number;\n boxH: number;\n /** \"solid\" = filled, \"dashed\" = vacant (presentation-only derived value). */\n style: OrgBoxStyle;\n /** Wrapped display lines per family (drawn centered, stacked, by font size). */\n nameLines: string[];\n titleLines: string[];\n subtitleLines: string[];\n /** Localized \"(vago)\" marker line; null on filled boxes. */\n vacantMarker: string | null;\n /** True for side-branched assistant nodes (legend + harness use it). */\n isAssistant: boolean;\n /** Depth of the row this node lives in (assistant: its manager's row + 1 band). */\n depth: number;\n /** Verbatim <title> text. */\n title: string;\n /** True when the caller declared this position annotated. Drives the dot marker in svg.ts. */\n annotated: boolean;\n}\n\nexport interface OrgElement {\n /** Namespaced id (ORG_*_ID_BASE + managerId / reportId / report.id). */\n edgeId: number;\n kind: OrgElementKind;\n /** ≥2 waypoints, every consecutive pair axis-aligned (H or V). */\n points: Point[];\n /** True only on \"dotted\" elements. */\n dashed: boolean;\n /** Verbatim <title> text (woven from the title-label pack). */\n title: string;\n /** True when the source OrgReport was declared annotated. Drives the tick marker in svg.ts.\n * stem/bus: not 1:1 with a report — annotated:false by design (documented choice). */\n annotated: boolean;\n}\n\nexport interface OrgChartLayout {\n width: number;\n height: number;\n nodes: OrgNode[];\n elements: OrgElement[];\n /** Forest order, ascending id. */\n rootPositionIds: number[];\n}\n\nexport interface OrgChartLayoutOptions {\n /** Cap each box's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for box/element <title>s — English default; see locale packs. */\n titleLabels?: OrgChartTitleLabels;\n}\n\n// ── PURE span-packer (Judge-1 seam) ────────────────────────────────────────────────\n// packSubtree, PackNode, PackGaps, PackResult — LIFTED to src/core/layered.ts.\n// Re-exported from there via src/core/index.ts and imported at the top of this file.\n// The seam comment, types and function are preserved verbatim in core/layered.ts.\n// Unit-tested directly in test/org-chart/pack-subtree.test.ts (imports from \"../../src/org-chart\").\n\n// Re-export so external callers that import from \"../../src/org-chart\" keep working.\nexport type { PackNode, PackGaps, PackResult };\nexport { packSubtree };\n\n// ── Box measurement (via core text metrics; what is reserved is what is drawn) ──────\n\ninterface Measured {\n boxW: number;\n boxH: number;\n nameLines: string[];\n titleLines: string[];\n subtitleLines: string[];\n vacantMarker: string | null;\n}\n\nfunction measurePosition(\n position: OrgPosition,\n maxLabelChars: number | undefined,\n vacantWord: string,\n): Measured {\n const nameLines =\n position.name === \"\" ? [] : wrapLabelBalanced(clampLabel(position.name, maxLabelChars), 2);\n const titleLines =\n position.title === null ? [] : wrapLabelBalanced(clampLabel(position.title, maxLabelChars), 2);\n const subtitleLines =\n position.subtitle === null ? [] : wrapLabelBalanced(clampLabel(position.subtitle, maxLabelChars), 1);\n const vacantMarker = position.vacancy === \"vacant\" ? vacantWord : null;\n\n let innerW = 0;\n for (const l of nameLines) innerW = Math.max(innerW, estimateTextWidth(l, ORG_LABEL_FONT));\n for (const l of titleLines) innerW = Math.max(innerW, estimateTextWidth(l, ORG_TITLE_FONT));\n for (const l of subtitleLines) innerW = Math.max(innerW, estimateTextWidth(l, ORG_TITLE_FONT));\n if (vacantMarker !== null) innerW = Math.max(innerW, estimateTextWidth(vacantMarker, ORG_TITLE_FONT));\n\n const boxW = Math.max(ORG_MIN_BOX_W, innerW + ORG_BOX_PAD_X * 2);\n const lineCount =\n nameLines.length + titleLines.length + subtitleLines.length + (vacantMarker !== null ? 1 : 0);\n const boxH = ORG_BOX_PAD_Y * 2 + lineCount * ORG_LABEL_LINE_H;\n return { boxW, boxH, nameLines, titleLines, subtitleLines, vacantMarker };\n}\n\nfunction positionTitle(position: OrgPosition, vacantWord: string): string {\n if (position.hover !== undefined) return position.hover;\n if (position.title !== null) {\n return position.name === \"\" ? position.title : `${position.name} — ${position.title}`;\n }\n if (position.name !== \"\") return position.name;\n return vacantWord; // vacant box with no name & no title — append the vacant word\n}\n\n// ── Internal working node (one per declared position; org positions never repeat) ──\n\ninterface Inst {\n position: OrgPosition;\n m: Measured;\n style: OrgBoxStyle;\n title: string;\n depth: number;\n /** Line-report children (ascending reportId), placed into the sibling rake. */\n lineChildren: Inst[];\n /** Assistant children (ascending reportId), side-stemmed left of the stem. */\n assistants: { inst: Inst; report: OrgReport }[];\n /** Reserved left/right half-extents of THIS node's own box (+ assistant reservation). */\n ownHalfL: number;\n ownHalfR: number;\n /** Subtree half-extents after packing. */\n spanL: number;\n spanR: number;\n /** Offset of each line-child center relative to this node's center. */\n offsets: number[];\n /** Absolute box center x (resolved top-down). */\n cx: number;\n /** Report row that made this an assistant (for the assist element's title/id). */\n assistReport: OrgReport | null;\n /** Absolute box top y for an assistant (set during emit; line nodes use rowTop[depth]). */\n assistTop: number;\n}\n\n/**\n * Deterministic, overlap-proof org-chart layout (pure function of the inputs). Validates\n * first and THROWS OrgChartValidationError on a structurally invalid chart — never\n * sanitizes. Empty input (no positions AND no reports) yields an empty, padded layout.\n */\nexport function computeOrgChartLayout(\n input: OrgChartInput,\n opts: OrgChartLayoutOptions = {},\n): OrgChartLayout {\n if (input.positions.length === 0 && input.reports.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], rootPositionIds: [] };\n }\n validateOrgChart(input);\n\n const titleLabels = opts.titleLabels ?? ORG_CHART_TITLE_LABELS_EN;\n const vacantWord = titleLabels.vacant;\n const positionById = new Map(input.positions.map((p) => [p.id, p]));\n\n // Solid (line|assistant) edges only define the tree. id-sort for order-independence;\n // sibling order among reports is by ascending reportId.\n const reports = [...input.reports].sort((a, b) => a.id - b.id);\n const solidReports = reports.filter((r) => r.kind !== \"dotted\");\n\n // Build per-manager child buckets (line-reports + assistants), each ascending reportId.\n const lineChildIds = new Map<number, OrgReport[]>();\n const assistChildIds = new Map<number, OrgReport[]>();\n const solidParentReportId = new Set<number>(); // positions that have a solid parent\n for (const r of solidReports) {\n solidParentReportId.add(r.reportId);\n const bucket = r.kind === \"assistant\" ? assistChildIds : lineChildIds;\n const arr = bucket.get(r.managerId) ?? [];\n arr.push(r);\n bucket.set(r.managerId, arr);\n }\n for (const arr of lineChildIds.values()) arr.sort((a, b) => a.reportId - b.reportId);\n for (const arr of assistChildIds.values()) arr.sort((a, b) => a.reportId - b.reportId);\n\n // Roots: positions that are no solid edge's reportId, ascending id (forest order).\n const rootPositionIds = input.positions\n .map((p) => p.id)\n .filter((id) => !solidParentReportId.has(id))\n .sort((a, b) => a - b);\n\n // ── Build the instance tree per root over solid edges (each position once). ────────\n const newInst = (position: OrgPosition, depth: number, assistReport: OrgReport | null): Inst => {\n const m = measurePosition(position, opts.maxLabelChars, vacantWord);\n return {\n position,\n m,\n style: position.vacancy === \"vacant\" ? \"dashed\" : \"solid\",\n title: positionTitle(position, vacantWord),\n depth,\n lineChildren: [],\n assistants: [],\n ownHalfL: m.boxW / 2,\n ownHalfR: m.boxW / 2,\n spanL: 0,\n spanR: 0,\n offsets: [],\n cx: 0,\n assistReport,\n assistTop: 0,\n };\n };\n\n const allInsts: Inst[] = [];\n const build = (positionId: number, depth: number, assistReport: OrgReport | null): Inst => {\n const position = positionById.get(positionId)!;\n const inst = newInst(position, depth, assistReport);\n allInsts.push(inst);\n // Assistants live in the manager's corridor band: same row index as a line-report\n // (depth+1) for measurement, but they do NOT advance the row — STEP 4 handles that.\n for (const r of assistChildIds.get(positionId) ?? []) {\n const a = build(r.reportId, depth + 1, r);\n inst.assistants.push({ inst: a, report: r });\n }\n for (const r of lineChildIds.get(positionId) ?? []) {\n inst.lineChildren.push(build(r.reportId, depth + 1, null));\n }\n return inst;\n };\n const roots = rootPositionIds.map((id) => build(id, 0, null));\n\n // ── STEP 3 — assistant side-stem reservation (per-side LEFT, before packing). An\n // assistant adds ORG_ASSIST_GAP + max(assistantBoxW) to the manager's ownHalfL.\n // Vertical stacking never widens further. ─────────────────────────────────────────\n for (const inst of allInsts) {\n if (inst.assistants.length > 0) {\n const widest = inst.assistants.reduce((m, a) => Math.max(m, a.inst.m.boxW), 0);\n inst.ownHalfL = inst.m.boxW / 2 + ORG_ASSIST_GAP + widest;\n }\n }\n\n // ── STEP 2 — horizontal span-pack (post-order) via the PURE packSubtree. ───────────\n const gaps: PackGaps = { siblingGap: ORG_SIBLING_GAP };\n const pack = (inst: Inst): void => {\n for (const c of inst.lineChildren) pack(c);\n const result = packSubtree(\n {\n ownHalfL: inst.ownHalfL,\n ownHalfR: inst.ownHalfR,\n children: inst.lineChildren.map((c) => ({ halfL: c.spanL, halfR: c.spanR })),\n },\n gaps,\n );\n inst.spanL = result.halfL;\n inst.spanR = result.halfR;\n inst.offsets = result.offsets;\n };\n for (const root of roots) pack(root);\n\n // Absolute centers, top-down; forest trees laid left→right ORG_TREE_GAP apart.\n let cursor = PADDING;\n for (const root of roots) {\n root.cx = cursor + root.spanL;\n const placeX = (inst: Inst): void => {\n inst.lineChildren.forEach((c, i) => {\n c.cx = inst.cx + inst.offsets[i]!;\n placeX(c);\n });\n };\n placeX(root);\n cursor = root.cx + root.spanR + ORG_TREE_GAP;\n }\n const canvasRight = roots.length === 0 ? PADDING : cursor - ORG_TREE_GAP; // last root's right edge\n\n // ── STEP 4 — vertical rows by declared depth, with the corridor grown for assistants.\n const rowInsts: Inst[][] = [];\n for (const inst of allInsts) (rowInsts[inst.depth] ??= []).push(inst);\n const depthCount = rowInsts.length;\n\n // Assistant stack height hanging below a manager (sum of assistant boxH + band drops).\n const assistStackH = (inst: Inst): number => {\n if (inst.assistants.length === 0) return 0;\n return (\n inst.assistants.reduce((s, a) => s + a.inst.m.boxH + ORG_ASSIST_BAND_DROP, 0) + ORG_ASSIST_BAND_DROP\n );\n };\n\n const rowH: number[] = [];\n for (let d = 0; d < depthCount; d++) {\n // Row height = tallest LINE-REPORT box in the row (assistants excluded — they hang\n // in the corridor band, not the row). Assistants share a depth index but are not\n // line-children of anyone, so filter them out here.\n const lineBoxes = (rowInsts[d] ?? []).filter((i) => i.assistReport === null);\n rowH.push(lineBoxes.reduce((m, i) => Math.max(m, i.m.boxH), 0));\n }\n\n // Assistant zone below row d: the tallest assistant stack hanging off any manager in\n // row d. Reserved ABOVE the corridor (the fault-tree gateZone analog) so the bus sits\n // CORRIDOR/2 below the BOTTOM of every assistant stack — every assistant box (and its\n // elbow) is strictly above the bus, and every drop (busY → next row) is below it.\n const assistZone: number[] = [];\n for (let d = 0; d < depthCount; d++) {\n let tallest = 0;\n for (const inst of rowInsts[d] ?? []) tallest = Math.max(tallest, assistStackH(inst));\n assistZone.push(tallest);\n }\n\n const rowTop: number[] = [PADDING];\n for (let d = 0; d < depthCount - 1; d++) {\n rowTop.push(rowTop[d]! + rowH[d]! + assistZone[d]! + ORG_CORRIDOR);\n }\n const busY = (d: number): number => rowTop[d + 1]! - ORG_CORRIDOR / 2;\n\n const last = depthCount - 1;\n // The last row's managers cannot have line-reports below them, but a leaf manager in\n // the last row carries no assistants of its own row index either (assistants share the\n // child's depth) — assistZone[last] folds any trailing assistant stack into the height.\n const height = Math.ceil(rowTop[last]! + rowH[last]! + assistZone[last]! + PADDING);\n\n // ── Emit nodes + solid rake elements (DFS order per root). ─────────────────────────\n const nodes: OrgNode[] = [];\n const elements: OrgElement[] = [];\n\n const reportTitle = (kind: OrgReport[\"kind\"], label: string | null | undefined): string => {\n const word = titleLabels.reportKinds[kind];\n return label !== null && label !== undefined ? `${word} · ${label}` : word;\n };\n\n const pushNode = (inst: Inst): void => {\n nodes.push({\n positionId: inst.position.id,\n cx: round(inst.cx),\n top: round(rowTop[inst.depth]!),\n boxW: round(inst.m.boxW),\n boxH: round(inst.m.boxH),\n style: inst.style,\n nameLines: inst.m.nameLines,\n titleLines: inst.m.titleLines,\n subtitleLines: inst.m.subtitleLines,\n vacantMarker: inst.m.vacantMarker,\n isAssistant: inst.assistReport !== null,\n depth: inst.depth,\n title: inst.title,\n annotated: inst.position.annotated ?? false,\n });\n };\n\n const emit = (inst: Inst): void => {\n const d = inst.depth;\n\n // Assistants: top-aligned bands hanging in this manager's corridor (below its row),\n // each its own band-y, the box LEFT of the stem (right edge faces the stem), the\n // elbow a 2-segment orthogonal polyline staying in the reserved left gutter.\n let bandY = rowTop[d]! + rowH[d]! + ORG_ASSIST_BAND_DROP;\n for (const { inst: a, report } of inst.assistants) {\n // Reserved left gutter: stem at inst.cx; assistant box right edge ORG_ASSIST_GAP left.\n const assistRight = inst.cx - ORG_ASSIST_GAP;\n a.cx = assistRight - a.m.boxW / 2;\n // Position the assistant box top at the band-y; its row index (depth) is the same\n // band as a line-report but rowTop[depth] is the line-report row — override per box.\n const assistTop = bandY;\n a.assistTop = assistTop;\n const assistMidY = assistTop + a.m.boxH / 2;\n nodes.push({\n positionId: a.position.id,\n cx: round(a.cx),\n top: round(assistTop),\n boxW: round(a.m.boxW),\n boxH: round(a.m.boxH),\n style: a.style,\n nameLines: a.m.nameLines,\n titleLines: a.m.titleLines,\n subtitleLines: a.m.subtitleLines,\n vacantMarker: a.m.vacantMarker,\n isAssistant: true,\n depth: a.depth,\n title: a.title,\n annotated: a.position.annotated ?? false,\n });\n // Elbow: from the stem at the assistant's mid-y, horizontally LEFT to the box's\n // right edge (2 axis-aligned segments via 3 waypoints; first segment degenerate is\n // avoided because the stem x ≠ box-right x by ORG_ASSIST_GAP). The endpoint must land\n // on the assistant's DRAWN right edge — round(assistRight) (= managerCx − gap) rounds\n // a sub-cent off the box's own round(node.cx − node.boxW/2) edge (seed-103792 sliver).\n elements.push({\n edgeId: ORG_ASSIST_ID_BASE + report.reportId,\n kind: \"assist\",\n points: [\n { x: round(inst.cx), y: round(assistMidY) },\n { x: drawnRightEdge(a.cx, a.m.boxW), y: round(assistMidY) },\n ],\n dashed: false,\n title: reportTitle(\"assistant\", report.label),\n annotated: report.annotated ?? false,\n });\n bandY += a.m.boxH + ORG_ASSIST_BAND_DROP;\n }\n\n pushNode(inst);\n\n // Solid rake to line-reports (none → no stem/bus/drop).\n if (inst.lineChildren.length === 0) return;\n const by = busY(d);\n const boxBottom = rowTop[d]! + inst.m.boxH;\n\n // stem: manager box bottom-center → bus level. Vertical. (Lengthens to busY when the\n // box is shorter than its row's tallest — the row is top-aligned.)\n // stem/bus are not 1:1 with a single OrgReport — annotated:false by design (documented\n // in OrgElement.annotated). The drop IS 1:1 with the child's incoming line report.\n elements.push({\n edgeId: ORG_STEM_ID_BASE + inst.position.id,\n kind: \"stem\",\n points: [\n { x: round(inst.cx), y: round(boxBottom) },\n { x: round(inst.cx), y: round(by) },\n ],\n dashed: false,\n title: reportTitle(\"line\", null),\n annotated: false,\n });\n\n const childCxs = inst.lineChildren.map((c) => c.cx);\n // bus: only for ≥2 line-reports (a single report degenerates to stem + drop on one x).\n // bus is not 1:1 with a single OrgReport — annotated:false by design.\n if (inst.lineChildren.length > 1) {\n elements.push({\n edgeId: ORG_BUS_ID_BASE + inst.position.id,\n kind: \"bus\",\n points: [\n { x: round(Math.min(...childCxs)), y: round(by) },\n { x: round(Math.max(...childCxs)), y: round(by) },\n ],\n dashed: false,\n title: reportTitle(\"line\", null),\n annotated: false,\n });\n }\n\n // drop: bus → each line-report box top-center. Vertical.\n // drops are 1:1 with each child's incoming line report — propagate annotated.\n const lineReports = lineChildIds.get(inst.position.id) ?? [];\n const lineReportByChildId = new Map(lineReports.map((r) => [r.reportId, r]));\n for (const c of inst.lineChildren) {\n const lineReport = lineReportByChildId.get(c.position.id);\n elements.push({\n edgeId: ORG_DROP_ID_BASE + c.position.id,\n kind: \"drop\",\n points: [\n { x: round(c.cx), y: round(by) },\n { x: round(c.cx), y: round(rowTop[c.depth]!) },\n ],\n dashed: false,\n title: reportTitle(\"line\", null),\n annotated: lineReport?.annotated ?? false,\n });\n }\n\n for (const c of inst.lineChildren) emit(c);\n };\n for (const root of roots) emit(root);\n\n // ── STEP 6 — dotted/matrix overlay → reserved RIGHT-MARGIN GUTTER (vertical lane) +\n // a bottom traverse channel (horizontal runs). The decisive graft is the gutter at\n // x > every box's right edge — box-free by construction for the vertical lane. The\n // horizontal runs that REACH the gutter cannot sit at a box's mid-y (they would\n // cross intervening same-row boxes — the \"distant columns of same row\" adversarial\n // case), so each endpoint ESCAPES its box to a box-free column, drops into a bottom\n // channel below every box, and traverses horizontally there. A box-free escape\n // column exists at the SUBTREE right edge (cx + spanR): descendants live inside\n // [cx−spanL, cx+spanR] so their interiors never cross that boundary x, and the next\n // sibling subtree starts ORG_SIBLING_GAP further right. A GLOBAL escape-vertical lane\n // allocation (below) keeps every coincident drop (a shared endpoint's fan, a same-column\n // rep/mgr pair, OR two distinct nodes whose subtree-right boundary equals the same x)\n // from double-drawing. Result is fully orthogonal AND box-free; the harness proves it.\n //\n // Escape geometry per node: the box edge a dotted stub exits and the box-free column it\n // escapes to, SIDE-AWARE. A packed LINE node escapes RIGHT: stub exits its right edge\n // (cx + boxW/2) to the subtree-boundary column (cx + spanR), box-free because descendants\n // live inside [cx−spanL, cx+spanR] and the next sibling starts ORG_SIBLING_GAP further\n // right. An ASSISTANT is NOT packed and sits LEFT of its manager's stem — its right edge\n // is INSIDE the main line-report column, so escaping right would pierce those boxes\n // (defect B). It escapes LEFT instead: stub exits its left edge (cx − boxW/2) into its\n // RESERVED left gutter (cleared in STEP 3 via ORG_ASSIST_GAP), a small box-free band.\n // `side` (+1 right / −1 left) makes the per-endpoint slot offset push AWAY from the box,\n // staying box-free in either gutter.\n interface Escape {\n side: 1 | -1;\n /** Box edge the stub exits (right edge when side=+1, left edge when side=−1). */\n boxEdge: number;\n /** Box-free escape column the stub reaches (with slot 0). */\n escCol: number;\n midY: number;\n boxH: number;\n }\n // FIX 1 — an assistant escapes at its MANAGER's subtree-LEFT boundary, not at its own\n // leftEdge−gap. The own-leftEdge column is box-free only inside the assistant's OWN\n // corridor band; descending to the bottom channel it crosses line-report/assistant boxes\n // in LOWER rows that sit at that x (root cause 1). The manager's WHOLE subtree lives\n // inside [managerCx−spanL, managerCx+spanR], so managerCx−spanL is to the LEFT of every\n // box in the manager's subtree — the strip there is the manager's reserved left gutter,\n // clear down the entire canvas (the next left sibling is ORG_SIBLING_GAP further left).\n // The box-exit stub still leaves the assistant's LEFT edge and runs left to that column\n // at the assistant's band-y (box-free: that row strip is the manager's left gutter).\n const instByPos = new Map(allInsts.map((i) => [i.position.id, i]));\n const escapeByPos = new Map<number, Escape>();\n for (const inst of allInsts) {\n const isAssist = inst.assistReport !== null;\n const boxTop = isAssist ? inst.assistTop : rowTop[inst.depth]!;\n // Attach the matrix stub at the box edges AS DRAWN (seed-7763 dotted#0 × box#p1 sliver).\n const leftEdge = drawnLeftEdge(inst.cx, inst.m.boxW);\n const rightEdge = drawnRightEdge(inst.cx, inst.m.boxW);\n if (isAssist) {\n const managerInst = instByPos.get(inst.assistReport!.managerId)!;\n escapeByPos.set(inst.position.id, {\n side: -1,\n boxEdge: leftEdge,\n escCol: managerInst.cx - managerInst.spanL,\n midY: boxTop + inst.m.boxH / 2,\n boxH: inst.m.boxH,\n });\n } else {\n escapeByPos.set(inst.position.id, {\n side: 1,\n boxEdge: rightEdge,\n escCol: inst.cx + inst.spanR,\n midY: boxTop + inst.m.boxH / 2,\n boxH: inst.m.boxH,\n });\n }\n }\n\n const nodeById = new Map(nodes.map((n) => [n.positionId, n]));\n const dottedReports = reports.filter(\n (r) => r.kind === \"dotted\" && nodeById.has(r.managerId) && nodeById.has(r.reportId) && r.managerId !== r.reportId,\n );\n // Bottom channel sits below the tallest box bottom in the whole canvas.\n let maxBoxBottom = PADDING;\n for (const n of nodes) maxBoxBottom = Math.max(maxBoxBottom, n.top + n.boxH);\n\n let laneCount = 0;\n let channelLanes = 0;\n if (dottedReports.length > 0) {\n // Right-gutter vertical lanes packed by the two endpoints' y-interval (ascending\n // report.id — dottedReports is already id-sorted). Non-overlapping edges share a lane.\n const laneOf = new Map<number, number>();\n laneCount = allocateLanes(\n dottedReports.map((r) => {\n const rep = escapeByPos.get(r.reportId)!;\n const mgr = escapeByPos.get(r.managerId)!;\n return {\n lo: Math.min(rep.midY, mgr.midY),\n hi: Math.max(rep.midY, mgr.midY),\n set: (lane: number) => laneOf.set(r.id, lane),\n };\n }),\n );\n // Each edge gets TWO bottom-channel y-lanes (report-side + manager-side traverse) so\n // the two horizontals never collinear-overlap each other; indexed by edge order.\n channelLanes = dottedReports.length * 2;\n const channelTop = maxBoxBottom + ORG_MATRIX_GUTTER_GAP;\n // Per-endpoint exit-Y slots: when ONE box is the endpoint of several dotted edges (a\n // node that is the dotted target of N managers — the matrix fan), each edge must exit\n // that box's edge at a DISTINCT y, else their horizontal stubs collinear-overlap.\n // Spread the exit y's around the box mid-y, bounded inside the box's edge.\n const exitSlot = new Map<number, number>(); // positionId → next slot index\n const nextExitY = (posId: number, mid: number, boxH: number): number => {\n const slot = exitSlot.get(posId) ?? 0;\n exitSlot.set(posId, slot + 1);\n if (slot === 0) return mid;\n // Alternate above/below the mid-y; stay within ±(boxH/2 − 6) of the box center.\n const step = Math.min(6, Math.max(2, (boxH / 2 - 6) / Math.max(1, Math.ceil(slot / 2))));\n const sign = slot % 2 === 1 ? -1 : 1;\n return mid + sign * Math.ceil(slot / 2) * step;\n };\n\n // ── Per-edge x-INDEPENDENT geometry, computed FIRST (the escape-column x is decided\n // globally afterwards). exitY spreads same-node rows; chY is unique per edge. ──────\n interface EdgeGeom {\n r: (typeof dottedReports)[number];\n i: number;\n repMidY: number;\n mgrMidY: number;\n repBoxEdge: number;\n mgrBoxEdge: number;\n repChY: number;\n mgrChY: number;\n laneX: number;\n repEscX: number; // filled by the global escape-vertical lane allocation\n mgrEscX: number;\n }\n const geoms: EdgeGeom[] = dottedReports.map((r, i) => {\n const rep = escapeByPos.get(r.reportId)!;\n const mgr = escapeByPos.get(r.managerId)!;\n return {\n r,\n i,\n repMidY: round(nextExitY(r.reportId, rep.midY, rep.boxH)),\n mgrMidY: round(nextExitY(r.managerId, mgr.midY, mgr.boxH)),\n repBoxEdge: round(rep.boxEdge),\n mgrBoxEdge: round(mgr.boxEdge),\n repChY: round(channelTop + (2 * i) * ORG_MATRIX_LANE_PITCH),\n mgrChY: round(channelTop + (2 * i + 1) * ORG_MATRIX_LANE_PITCH),\n laneX: round(canvasRight + ORG_MATRIX_GUTTER_GAP + laneOf.get(r.id)! * ORG_MATRIX_LANE_PITCH),\n repEscX: 0,\n mgrEscX: 0,\n };\n });\n\n // ── GLOBAL escape-vertical LANE ALLOCATION (replaces the per-position slot nudge and the\n // rep===mgr special-case — both subsumed). Every dotted edge owns TWO escape verticals\n // (report side, manager side); each draws over the y-interval [min(exitY,chY),\n // max(exitY,chY)]. We GROUP verticals by `${round(escCol)}:${side}` — same base column\n // AND same escape direction — then run allocateLanes over the group's y-intervals: a\n // vertical's column x = round(escCol + side*lane*STEP). Disjoint-y verticals share a lane\n // (same x, never a double-draw because they don't overlap); OVERLAPPING-y verticals get\n // distinct lanes (distinct x). This is overlap-proof for the escape-column class BY\n // CONSTRUCTION and uniformly subsumes the three observed failure modes: same-node fan\n // (same column, overlapping y → distinct lanes), same-column rep/mgr pair in a single-\n // child chain (the old fix-C special case), AND the cross-node coincidence (two distinct\n // nodes whose subtree-right boundary equals the same x — Root vs Boss C: base 448,\n // overlapping y → lanes 0 and 1).\n //\n // BOX-FREE BOUND (geometry-exact, MEASURED — not a fixed gap): a right-escaping (line) node's\n // base escCol = cx + spanR is the subtree's right boundary; all its descendant boxes live\n // inside [cx−spanL, cx+spanR], so the base column AND the band immediately to its right are\n // box-free until the NEXT box (an immediate right sibling subtree starts ORG_SIBLING_GAP away;\n // a pure right-leaning chain with no right sibling has the whole right margin clear). A left-\n // escaping assistant's base is leftEdge−ORG_ASSIST_ESCAPE_GAP, box-free leftward through its\n // reserved ORG_ASSIST_GAP gutter. Nudged columns march in `side` by lane*STEP, deeper into that\n // band. Rather than assume a fixed gutter width, we MEASURE the actual band per group: the\n // distance from escCol to the nearest real box edge on the escape side that vertically overlaps\n // the group's combined y-span (canvasRight/left-margin when none blocks). A coincident base\n // column is only produced by a right-leaning spine (each ancestor's cx+spanR equals the spine-\n // tip's right edge — many verticals, but their tip subtree is the RIGHTMOST so the margin to\n // their right is wide) or a fan into one node (per-node dotted degree capped at 5 in\n // validate.ts, ORG_MAX_MATRIX_EDGES_PER_NODE). The GUARANTEE: the deepest lane (lanes−1)*STEP\n // stays strictly inside the measured band, or we ASSERT (escape-column-overflow) rather than\n // misdraw. This is overlap-proof for the escape-column class BY CONSTRUCTION against the real\n // geometry; the harness is the oracle on every corpus case (incl. a depth-5 spine with 10\n // coincident verticals on one base column, which the wide margin absorbs).\n interface EscVert {\n escCol: number;\n side: 1 | -1;\n lo: number;\n hi: number;\n assign: (x: number) => void;\n }\n const verts: EscVert[] = [];\n for (const g of geoms) {\n const rep = escapeByPos.get(g.r.reportId)!;\n const mgr = escapeByPos.get(g.r.managerId)!;\n verts.push({\n escCol: rep.escCol,\n side: rep.side,\n lo: Math.min(g.repMidY, g.repChY),\n hi: Math.max(g.repMidY, g.repChY),\n assign: (x) => (g.repEscX = x),\n });\n verts.push({\n escCol: mgr.escCol,\n side: mgr.side,\n lo: Math.min(g.mgrMidY, g.mgrChY),\n hi: Math.max(g.mgrMidY, g.mgrChY),\n assign: (x) => (g.mgrEscX = x),\n });\n }\n // FIX 2 — GLOBAL greedy first-fit (replaces the per-group allocateLanes, which de-conflicted\n // only WITHIN one base-column group → a nudged column from group X could land on group Y's\n // column with overlapping y, double-drawing — root cause 2). Here NO two y-overlapping escape\n // verticals ever share a final x, across ALL groups. Each vertical starts at its base column and\n // steps in its escape `side` by ORG_MATRIX_ESCAPE_STEP until its x is clear of every already-placed\n // vertical it shares y with. Collinear-overlap = 0 BY CONSTRUCTION, globally (subsumes both the\n // per-group fan de-confliction AND the cross-group coincidence). Deterministic processing order\n // (edge id, then side) → byte-stable output. Box-free BAND is still measured per vertical and the\n // existing escape-column-overflow assertion fires rather than misdraw; with FIX 1 + the per-node\n // cap of 5 it should never fire on realistic input (the fuzzer confirms).\n //\n // The de-confliction nudge marches in the SAME direction the stub exits (`side`) — AWAY from the\n // node's box, into its box-free band. A LINE node's base column is its subtree-RIGHT boundary\n // (cx+spanR); everything to its right is clear out to canvasRight, so it nudges RIGHT. An ASSISTANT\n // escapes at its manager's subtree-LEFT boundary (managerCx−spanL, FIX 1); EVERY box in that\n // subtree lives to its right (a descendant box's left edge may sit EXACTLY on the boundary), so the\n // box-free room is to the LEFT — toward the canvas edge / the previous tree's gutter — and it nudges\n // LEFT. Nudging the assistant right would step straight into the leftmost descendant box, nudging\n // left stays in the clear margin. The box-exit stub runs from the assistant's left edge to the\n // (nudged) column at the assistant's band-y, box-free either way.\n const VERT_EPS = 0.01;\n // Stable processing order = edge id, then side (report-side before manager-side). `verts` is\n // built [rep0, mgr0, rep1, mgr1, …] over the id-sorted geoms, so the natural index ALREADY\n // encodes (edgeId asc, rep<mgr); make it explicit so a refactor of `verts` can't perturb it.\n const ordered = verts\n .map((v, idx) => ({ v, key: geoms[Math.floor(idx / 2)]!.r.id * 2 + (idx % 2) }))\n .sort((a, b) => a.key - b.key)\n .map((e) => e.v);\n const placed: { x: number; lo: number; hi: number }[] = [];\n const yOverlap = (aLo: number, aHi: number, bLo: number, bHi: number): boolean =>\n Math.min(aHi, bHi) - Math.max(aLo, bLo) > VERT_EPS;\n for (const v of ordered) {\n // Box-free band on the escape side, MEASURED from the real boxes that vertically overlap THIS\n // vertical's y-span: the candidate may march up to (but not into) the nearest box edge on that\n // side. The base column itself is box-free by construction (subtree-right boundary on the right;\n // manager's subtree-left boundary on the left). With no box in the way the band runs to the tree's\n // right edge (canvasRight) on the right, or to the CANVAS edge (x=0) on the left — NOT to PADDING,\n // because the leftmost tree's left boundary sits at PADDING yet the margin down to x=0 is clear.\n let band = v.side === 1 ? Math.max(canvasRight - v.escCol, ORG_MATRIX_GUTTER_GAP) : v.escCol;\n for (const n of nodes) {\n const bLeft = n.cx - n.boxW / 2;\n const bRight = n.cx + n.boxW / 2;\n if (n.top + n.boxH <= v.lo + VERT_EPS || n.top >= v.hi - VERT_EPS) continue; // no y-overlap\n if (v.side === 1 && bLeft > v.escCol + VERT_EPS) band = Math.min(band, bLeft - v.escCol);\n else if (v.side === -1 && bRight < v.escCol - VERT_EPS) band = Math.min(band, v.escCol - bRight);\n }\n let lane = 0;\n let candidate = round(v.escCol);\n // Step away from the box (in `side`) until the candidate column is clear of every placed vertical\n // that shares y with this one.\n while (placed.some((p) => Math.abs(p.x - candidate) < VERT_EPS && yOverlap(p.lo, p.hi, v.lo, v.hi))) {\n lane += 1;\n candidate = round(v.escCol + v.side * lane * ORG_MATRIX_ESCAPE_STEP);\n }\n // A lane-0 vertical sits on its base column — box-free BY CONSTRUCTION, so it needs no band\n // check. A NUDGED vertical must stay strictly inside the measured box-free band, else we assert\n // rather than misdraw.\n if (lane > 0 && lane * ORG_MATRIX_ESCAPE_STEP >= band - VERT_EPS) {\n throw new Error(\n `org-chart: escape-column-overflow — escape vertical nudged ${lane * ORG_MATRIX_ESCAPE_STEP}px from its base column exceeds the ${round(band)}px box-free band`,\n );\n }\n placed.push({ x: candidate, lo: v.lo, hi: v.hi });\n v.assign(candidate);\n }\n\n for (const g of geoms) {\n // 8 waypoints (box edge → escape column → channel → lane → channel → escape column →\n // box edge). Collapse a DEGENERATE first/last stub: a leaf line node's box edge IS its\n // escape column (boxW/2 === spanR with lane 0), so the box-exit and the down-escape\n // share an x → drop the duplicate point so \"every consecutive pair axis-aligned\" holds\n // by construction (no zero-length segment).\n elements.push({\n edgeId: ORG_DOTTED_ID_BASE + g.r.id,\n kind: \"dotted\",\n points: collapseDegenerate([\n { x: g.repBoxEdge, y: g.repMidY }, // out the report box's edge\n { x: g.repEscX, y: g.repMidY }, // → box-free escape column (in own gutter lane)\n { x: g.repEscX, y: g.repChY }, // → down into the bottom traverse channel\n { x: g.laneX, y: g.repChY }, // → across (below all boxes) to the right gutter lane\n { x: g.laneX, y: g.mgrChY }, // → down the right gutter (right of every box)\n { x: g.mgrEscX, y: g.mgrChY }, // → back across (below all boxes) to the manager column\n { x: g.mgrEscX, y: g.mgrMidY }, // → up the box-free escape column\n { x: g.mgrBoxEdge, y: g.mgrMidY }, // → into the manager box's edge\n ]),\n dashed: true,\n title: reportTitle(\"dotted\", g.r.label),\n annotated: g.r.annotated ?? false,\n });\n }\n }\n\n const width =\n dottedReports.length > 0\n ? Math.ceil(canvasRight + ORG_MATRIX_GUTTER_GAP + (laneCount - 1) * ORG_MATRIX_LANE_PITCH + ORG_MATRIX_GUTTER_GAP + PADDING)\n : Math.ceil(canvasRight + PADDING);\n\n // When dotted edges exist the bottom traverse channel hangs below every box; grow the\n // height to cover the deepest channel lane + padding (else solid-tree height stands).\n const finalHeight =\n channelLanes > 0\n ? Math.ceil(maxBoxBottom + ORG_MATRIX_GUTTER_GAP + (channelLanes - 1) * ORG_MATRIX_LANE_PITCH + PADDING)\n : height;\n\n return { width, height: finalHeight, nodes, elements, rootPositionIds };\n}\n\n/** Drop consecutive duplicate waypoints (a zero-length segment) so the routed polyline\n * keeps the \"≥2 waypoints, every consecutive pair axis-aligned over a positive length\"\n * contract by construction — e.g. a leaf line node whose box edge IS its escape column.\n * A two-point result is preserved even if degenerate (cannot happen here: the channel\n * detour guarantees ≥4 distinct points), so the OrgElement.points ≥2 invariant holds. */\nfunction collapseDegenerate(points: Point[]): Point[] {\n const out: Point[] = [];\n for (const p of points) {\n const prev = out[out.length - 1];\n if (prev === undefined || prev.x !== p.x || prev.y !== p.y) out.push(p);\n }\n return out;\n}\n\n// allocateLanes — LIFTED to src/core/layered.ts; imported at the top of this file.\n","// Org-chart SVG emitter — turns a computed OrgChartLayout (./layout.ts) into a\n// SELF-CONTAINED SVG string. Pure (layout in, string out) and deterministic; it draws\n// EXACTLY what the layout computed (the overlap harness proves the layout; this emitter\n// is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — names/titles/subtitles/titles are\n// author-controlled and the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (hex colors, explicit font-family): a\n// standalone SVG has no stylesheet, no currentColor, no <defs>/<marker>;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Notation (zinc ramp on white): box rect rx=2 (filled → solid stroke; vacant → dashed\n// stroke + a 3px-inset open-seat frame); centered stacked tspans differentiated by font\n// SIZE (name 12, title/subtitle/vacant 10), never weight; solid stem/bus/drop/assist\n// edges as #71717a w1.5 op .75; dotted via EDGE_STROKE.distant (dasharray 4,4 op .55).\n// NO markers/arrowheads — direction is encoded by manager-above/report-below.\n//\n// Hooks: `<g data-node-id=\"p<id>\">` per box (direct-child verbatim <title>);\n// `<g data-edge-id=\"<n>\">` per element (<title> first), namespaced ids from ./layout.ts.\n\nimport {\n annotationDot,\n annotationSwatch,\n annotationTick,\n EDGE_STROKE,\n FONT_FAMILY,\n legendBlock,\n pathData,\n xmlEscape,\n LEGEND_SWATCH_W,\n type LegendEntry,\n} from \"../core\";\nimport {\n ORG_LABEL_FONT,\n ORG_LABEL_LINE_H,\n ORG_TITLE_FONT,\n type OrgChartLayout,\n type OrgElement,\n type OrgNode,\n} from \"./layout\";\nimport { ORG_CHART_SVG_LABELS_EN, type OrgChartSvgLabels } from \"./labels\";\n\n// Literal ink colors (zinc ramp on white — matches the genogram/ecomap/fault-tree emitters).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\nconst GLYPH_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\nconst VACANT_DASH = `stroke-dasharray=\"6,4\"`;\n/** The dotted/matrix line presentation, reused from the core style table (NOT a judgment). */\nconst DOTTED = EDGE_STROKE.distant; // { width: 1.5, dash: [4, 4], opacity: 0.55 }\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// Box vertical padding (mirrors layout ORG_BOX_PAD_Y; the text baseline math needs it).\nconst ORG_BOX_PAD_Y = 9;\n\nexport interface OrgChartSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: OrgChartSvgLabels;\n /**\n * Legend label for the annotation row. When provided AND at least one node or element\n * is annotated, one legend row is appended (used-keys-only pattern). The library\n * supplies no default — the caller owns the wording (domain-agnostic).\n */\n annotationLabel?: string;\n}\n\n// ── Box ─────────────────────────────────────────────────────────────────────────────\n\nfunction boxSvg(n: OrgNode): string {\n const left = round(n.cx - n.boxW / 2);\n const pieces: string[] = [`<title>${xmlEscape(n.title)}</title>`];\n\n // Rect: filled → solid stroke; vacant → dashed stroke + a 3px-inset open-seat frame.\n if (n.style === \"dashed\") {\n pieces.push(\n `<rect x=\"${left}\" y=\"${n.top}\" width=\"${n.boxW}\" height=\"${n.boxH}\" rx=\"2\" ${GLYPH_ATTRS} ${VACANT_DASH}/>`,\n );\n const ix = round(left + 3);\n const iy = round(n.top + 3);\n const iw = round(n.boxW - 6);\n const ih = round(n.boxH - 6);\n pieces.push(`<rect x=\"${ix}\" y=\"${iy}\" width=\"${iw}\" height=\"${ih}\" rx=\"2\" ${GLYPH_ATTRS} ${VACANT_DASH}/>`);\n } else {\n pieces.push(`<rect x=\"${left}\" y=\"${n.top}\" width=\"${n.boxW}\" height=\"${n.boxH}\" rx=\"2\" ${GLYPH_ATTRS}/>`);\n }\n\n // Centered stacked tspans: name (12) → title (10) → subtitle (10) → vacant marker (10).\n // Differentiated by font SIZE, not weight. Each text element groups one font size so\n // a single <text font-size> covers its tspans (baseline stepping by ORG_LABEL_LINE_H).\n let lineIndex = 0;\n const firstBaseline = (i: number): number =>\n round(n.top + ORG_BOX_PAD_Y + ORG_LABEL_LINE_H / 2 + i * ORG_LABEL_LINE_H + ORG_LABEL_FONT * 0.32);\n\n const textBlock = (lines: string[], font: number): string => {\n if (lines.length === 0) return \"\";\n const tspans = lines\n .map((line, i) => `<tspan x=\"${n.cx}\" y=\"${firstBaseline(lineIndex + i)}\">${xmlEscape(line)}</tspan>`)\n .join(\"\");\n lineIndex += lines.length;\n return `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${font}\" fill=\"${LABEL_FILL}\">${tspans}</text>`;\n };\n\n pieces.push(textBlock(n.nameLines, ORG_LABEL_FONT));\n pieces.push(textBlock(n.titleLines, ORG_TITLE_FONT));\n pieces.push(textBlock(n.subtitleLines, ORG_TITLE_FONT));\n if (n.vacantMarker !== null) pieces.push(textBlock([n.vacantMarker], ORG_TITLE_FONT));\n\n // Annotation dot: upper-right corner of the glyph, inset 4px so it sits on/near the box.\n if (n.annotated) pieces.push(annotationDot(round(n.cx + n.boxW / 2) - 4, n.top + 4));\n\n return `<g data-node-id=\"p${n.positionId}\">${pieces.filter((p) => p !== \"\").join(\"\")}</g>`;\n}\n\n// ── Connector elements ───────────────────────────────────────────────────────────────\n\nfunction elementSvg(el: OrgElement): string {\n const head = `<g data-edge-id=\"${el.edgeId}\"><title>${xmlEscape(el.title)}</title>`;\n const tick = el.annotated ? annotationTick(el.points) : \"\";\n if (el.dashed) {\n const dash = DOTTED.dash === null ? \"\" : ` stroke-dasharray=\"${DOTTED.dash[0]},${DOTTED.dash[1]}\"`;\n return (\n head +\n `<path d=\"${pathData(el.points)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${DOTTED.width}\" stroke-opacity=\"${DOTTED.opacity}\"${dash}/>${tick}</g>`\n );\n }\n // Solid stem/bus/drop = single segment <line>; assist = 2-segment <path>.\n if (el.points.length === 2) {\n const a = el.points[0]!;\n const b = el.points[1]!;\n return (\n head +\n `<line x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>${tick}</g>`\n );\n }\n return head + `<path d=\"${pathData(el.points)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>${tick}</g>`;\n}\n\n// ── Legend mini-swatches (scaled into the 22px swatch box) ─────────────────────────\n\nconst MINI_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"`;\n\nfunction lineSwatch(x: number, y: number): string {\n const x1 = round(x + 2);\n const x2 = round(x + LEGEND_SWATCH_W - 2);\n return `<line x1=\"${x1}\" y1=\"${y}\" x2=\"${x2}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>`;\n}\n\nfunction assistantSwatch(x: number, y: number): string {\n // A short stem + side-elbow into a small box (the side-stem convention in miniature).\n const stemX = round(x + LEGEND_SWATCH_W - 4);\n const boxX = round(x + 1);\n return (\n `<line x1=\"${stemX}\" y1=\"${round(y - 4)}\" x2=\"${stemX}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n `<line x1=\"${stemX}\" y1=\"${y}\" x2=\"${round(boxX + 8)}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n `<rect x=\"${boxX}\" y=\"${round(y - 3.5)}\" width=\"8\" height=\"7\" rx=\"1\" ${MINI_ATTRS}/>`\n );\n}\n\nfunction dottedSwatch(x: number, y: number): string {\n const x1 = round(x + 2);\n const x2 = round(x + LEGEND_SWATCH_W - 2);\n const dash = DOTTED.dash === null ? \"\" : ` stroke-dasharray=\"${DOTTED.dash[0]},${DOTTED.dash[1]}\"`;\n return `<line x1=\"${x1}\" y1=\"${y}\" x2=\"${x2}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${DOTTED.width}\" stroke-opacity=\"${DOTTED.opacity}\"${dash}/>`;\n}\n\nfunction vacantSwatch(x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n const bx = round(cx - 8);\n const by = round(y - 5);\n return (\n `<rect x=\"${bx}\" y=\"${by}\" width=\"16\" height=\"10\" rx=\"1\" ${MINI_ATTRS} stroke-dasharray=\"3,2\"/>` +\n `<rect x=\"${round(bx + 2)}\" y=\"${round(by + 2)}\" width=\"12\" height=\"6\" rx=\"1\" ${MINI_ATTRS} stroke-dasharray=\"3,2\"/>`\n );\n}\n\n/**\n * Emits a self-contained SVG for a computed org-chart layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal. The legend lists ONLY the features actually\n * present (a solid line, an assistant, a dotted edge, a vacant box), in canonical order.\n */\nexport function orgChartLayoutSvg(layout: OrgChartLayout, opts: OrgChartSvgOptions = {}): string {\n const labels = opts.labels ?? ORG_CHART_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // Elements first, then boxes (boxes sit on top), then legend.\n for (const el of layout.elements) parts.push(elementSvg(el));\n for (const n of layout.nodes) parts.push(boxSvg(n));\n\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const hasSolid = layout.elements.some((e) => e.kind === \"stem\" || e.kind === \"bus\" || e.kind === \"drop\");\n const hasAssistant = layout.nodes.some((n) => n.isAssistant);\n const hasDotted = layout.elements.some((e) => e.kind === \"dotted\");\n const hasVacant = layout.nodes.some((n) => n.style === \"dashed\");\n const entries: LegendEntry[] = [];\n if (hasSolid) entries.push({ swatch: lineSwatch, label: labels.legend.line });\n if (hasAssistant) entries.push({ swatch: assistantSwatch, label: labels.legend.assistant });\n if (hasDotted) entries.push({ swatch: dottedSwatch, label: labels.legend.dotted });\n if (hasVacant) entries.push({ swatch: vacantSwatch, label: labels.legend.vacant });\n // Annotation row: only when label is provided AND at least one node or element is\n // annotated (used-keys-only pattern, consistent with the other legend rows).\n if (\n opts.annotationLabel !== undefined &&\n (layout.nodes.some((n) => n.annotated) || layout.elements.some((e) => e.annotated))\n ) {\n entries.push({ swatch: annotationSwatch, label: opts.annotationLabel });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call org-chart render: input → { svg, layout }. Thin, honest wiring: validate\n// (throw on a structurally invalid chart — never repair), compute the pure layout, emit.\n// Callers needing finer control use computeOrgChartLayout + orgChartLayoutSvg directly\n// (the layout result supports hit-testing / decorating the diagram).\n\nimport { computeOrgChartLayout, type OrgChartLayout, type OrgChartLayoutOptions } from \"./layout\";\nimport { orgChartLayoutSvg } from \"./svg\";\nimport type { OrgChartSvgLabels } from \"./labels\";\nimport type { OrgChartInput } from \"./types\";\n\nexport interface OrgChartRenderOptions extends OrgChartLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: OrgChartSvgLabels;\n /**\n * Legend label for the annotation row. Forwarded to orgChartLayoutSvg. When provided\n * AND at least one node or element is annotated, a legend row is appended.\n * The library supplies no default — the caller owns the wording.\n */\n annotationLabel?: string;\n}\n\nexport interface OrgChartRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: OrgChartLayout;\n}\n\n/**\n * Renders an org-chart input to a self-contained SVG string. Deterministic: same data →\n * same SVG (array order never matters; sibling order among reports is the ascending\n * reportId). Throws OrgChartValidationError — carrying EVERY issue, deterministically\n * sorted — on a structurally invalid chart. Empty input yields an empty-but-valid SVG;\n * callers decide their own empty state.\n */\nexport function orgChartSvg(input: OrgChartInput, opts: OrgChartRenderOptions = {}): OrgChartRenderResult {\n const layout = computeOrgChartLayout(input, {\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = orgChartLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n ...(opts.annotationLabel !== undefined ? { annotationLabel: opts.annotationLabel } : {}),\n });\n return { svg, layout };\n}\n","// PRISMA 2020 flow diagram — input model.\n// Declared facts only: the caller declares boxes, arrows, and variant.\n// NO arithmetic anywhere — honesty rule: the author's figures are drawn faithfully,\n// never summed, reconciled, or validated for mathematical consistency.\n\n/** The three standard PRISMA phases, in display order. */\nexport const PRISMA_PHASES = [\"identification\", \"screening\", \"included\"] as const;\nexport type PrismaPhase = (typeof PRISMA_PHASES)[number];\n\n/** Main-column step vs right side-box (exclusion reasons). */\nexport const PRISMA_BOX_KINDS = [\"flow\", \"exclusion\"] as const;\nexport type PrismaBoxKind = (typeof PRISMA_BOX_KINDS)[number];\n\n/** Single-column default + two-column prior variant. */\nexport const PRISMA_COLUMNS = [\"main\", \"new\", \"previous\"] as const;\nexport type PrismaColumn = (typeof PRISMA_COLUMNS)[number];\n\n/**\n * A single count line in a box. `n: null` draws the localized \"n = —\" token.\n * NEVER inferred or summed — each figure is verbatim as the author declared it.\n */\nexport interface PrismaCount {\n label: string;\n n: number | null;\n}\n\n/**\n * A single PRISMA box — a flow step or an exclusion reason side-box.\n *\n * @property id Unique identifier (within the boxes namespace).\n * @property phase Which band the box belongs to.\n * @property kind \"flow\" = main-column step; \"exclusion\" = right side-box.\n * @property column Which column within the band. Validation defaults absent → \"main\".\n * @property rank Declared vertical order within (phase, column), 0-based top→down.\n * This is the AUTHOR's claim, never derived.\n * @property heading Verbatim header text (e.g. \"Records identified from:\"), or null.\n * @property counts Verbatim count lines (zero allowed).\n * @property title Optional <title> override; defaults to heading + counts.\n */\nexport interface PrismaBox {\n id: number;\n phase: PrismaPhase;\n kind: PrismaBoxKind;\n column: PrismaColumn;\n rank: number;\n heading: string | null;\n counts: PrismaCount[];\n title?: string;\n}\n\n/**\n * A declared flow arrow. Direction is determined by geometry (flow→exclusion = horizontal;\n * flow→flow = vertical). NO direction flag — the layout decides from box positions.\n */\nexport interface PrismaArrow {\n id: number;\n fromId: number;\n toId: number;\n}\n\n/**\n * The full input for one PRISMA diagram.\n *\n * @property variant \"flow\" = standard single-column;\n * \"flow-with-prior\" = two-column (new + previous sources, with merge arrow);\n * \"flow-other-methods\" = parallel new + other-sources stacks in the main column.\n * @property boxes Declared PRISMA boxes.\n * @property arrows Declared flow arrows.\n */\nexport interface PrismaInput {\n variant: \"flow\" | \"flow-with-prior\" | \"flow-other-methods\";\n boxes: PrismaBox[];\n arrows: PrismaArrow[];\n}\n","// PRISMA 2020 validation — REJECT-WITH-CODES.\n// Three-phase pipeline: duplicate-id short-circuit → reference/semantic → graph.\n// Empty input (no boxes AND no arrows) → valid, never throws.\n// NO arithmetic anywhere — the honesty rule is non-negotiable.\n\nimport type { PrismaInput, PrismaPhase } from \"./types\";\nimport { PRISMA_PHASES } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; public contract). */\nexport type PrismaIssueCode =\n | \"duplicate-id\"\n | \"unknown-arrow-endpoint\"\n | \"self-arrow\"\n | \"non-finite-count\"\n | \"invalid-variant-column\"\n | \"arrow-skips-backward\";\n\nexport interface PrismaIssue {\n code: PrismaIssueCode;\n message: string;\n}\n\n/** Thrown by computePrismaLayout / prismaSvg on structurally invalid input. */\nexport class PrismaValidationError extends Error {\n readonly issues: readonly PrismaIssue[];\n\n constructor(issues: readonly PrismaIssue[]) {\n super(`invalid PRISMA diagram: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"PrismaValidationError\";\n this.issues = issues;\n }\n}\n\n/**\n * Deduplicates and sorts issues deterministically (by code, then byte-message).\n * Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly PrismaIssue[]): readonly PrismaIssue[] {\n const unique = new Map<string, PrismaIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code\n ? a.code < b.code ? -1 : 1\n : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically sorted.\n * Empty input (no boxes AND no arrows) → valid (returns []).\n */\nexport function prismaIssues(input: PrismaInput): readonly PrismaIssue[] {\n if (input.boxes.length === 0 && input.arrows.length === 0) return [];\n\n const issues: PrismaIssue[] = [];\n const push = (code: PrismaIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── Phase 0: duplicate ids (per namespace — phase-0 short-circuit). ──────────────\n // Both namespaces checked together; any duplicate makes downstream rules order-dependent.\n const boxById = new Map<number, (typeof input.boxes)[number]>();\n const dupBoxIds = new Set<number>();\n for (const b of input.boxes) {\n if (boxById.has(b.id)) dupBoxIds.add(b.id);\n else boxById.set(b.id, b);\n }\n for (const id of [...dupBoxIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate box id ${id}`);\n }\n\n const arrowById = new Map<number, (typeof input.arrows)[number]>();\n const dupArrowIds = new Set<number>();\n for (const a of input.arrows) {\n if (arrowById.has(a.id)) dupArrowIds.add(a.id);\n else arrowById.set(a.id, a);\n }\n for (const id of [...dupArrowIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate arrow id ${id}`);\n }\n\n if (issues.length > 0) return sortIssues(issues);\n\n // ── Phase 1: reference + semantic rules. ────────────────────────────────────────\n\n // R1: unknown arrow endpoints.\n for (const arrow of [...arrowById.values()].sort((a, b) => a.id - b.id)) {\n if (!boxById.has(arrow.fromId)) {\n push(\"unknown-arrow-endpoint\", `arrow ${arrow.id} fromId ${arrow.fromId} is not a declared box`);\n }\n if (!boxById.has(arrow.toId)) {\n push(\"unknown-arrow-endpoint\", `arrow ${arrow.id} toId ${arrow.toId} is not a declared box`);\n }\n // R2: self-arrow.\n if (arrow.fromId === arrow.toId) {\n push(\"self-arrow\", `arrow ${arrow.id} has fromId === toId (${arrow.fromId})`);\n }\n }\n\n // R3: non-finite counts. null is legal; NaN/±Infinity is not.\n for (const box of [...boxById.values()].sort((a, b) => a.id - b.id)) {\n for (const count of box.counts) {\n if (count.n !== null && !Number.isFinite(count.n)) {\n push(\"non-finite-count\", `box ${box.id} count \"${count.label}\" has non-finite n: ${String(count.n)}`);\n }\n }\n }\n\n // R4: invalid-variant-column — \"previous\" column only valid in \"flow-with-prior\".\n if (input.variant !== \"flow-with-prior\") {\n for (const box of [...boxById.values()].sort((a, b) => a.id - b.id)) {\n if (box.column === \"previous\") {\n push(\n \"invalid-variant-column\",\n `box ${box.id} has column \"previous\" but variant is \"${input.variant}\"`,\n );\n }\n }\n }\n\n // ── Phase 2: graph rules. GRAPH_BLOCKING-gated. ─────────────────────────────────\n const GRAPH_BLOCKING: ReadonlySet<PrismaIssueCode> = new Set([\n \"duplicate-id\",\n \"unknown-arrow-endpoint\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n // R5: arrow-skips-backward — toId's box is in an EARLIER phase band than fromId's.\n // EXCEPTION: a flow→exclusion arrow within the SAME band is never \"backward\"\n // (side-boxes are horizontal, same-band).\n const phaseIndex = new Map<PrismaPhase, number>();\n for (let i = 0; i < PRISMA_PHASES.length; i++) phaseIndex.set(PRISMA_PHASES[i]!, i);\n\n for (const arrow of [...arrowById.values()].sort((a, b) => a.id - b.id)) {\n const fromBox = boxById.get(arrow.fromId)!;\n const toBox = boxById.get(arrow.toId)!;\n const fromPhaseIdx = phaseIndex.get(fromBox.phase)!;\n const toPhaseIdx = phaseIndex.get(toBox.phase)!;\n\n // Same-band flow→exclusion exception.\n if (\n fromBox.kind === \"flow\" &&\n toBox.kind === \"exclusion\" &&\n fromBox.phase === toBox.phase\n ) {\n continue;\n }\n\n if (toPhaseIdx < fromPhaseIdx) {\n push(\n \"arrow-skips-backward\",\n `arrow ${arrow.id} goes backward: from phase \"${fromBox.phase}\" to \"${toBox.phase}\"`,\n );\n }\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws PrismaValidationError (carrying ALL issues) when the input is invalid. */\nexport function validatePrisma(input: PrismaInput): void {\n const issues = prismaIssues(input);\n if (issues.length > 0) throw new PrismaValidationError(issues);\n}\n","// PRISMA 2020 display vocabularies.\n// Split into title labels (woven into <title>s by layout) and SVG labels (legend/aria).\n// English defaults inline; pt-BR in src/locales/pt-br.ts.\n\n/** Labels woven into element <title>s — phase names, count token, arrow kind words. */\nexport interface PrismaTitleLabels {\n /** Display names for each phase band (left gutter label). */\n phases: {\n identification: string;\n screening: string;\n included: string;\n };\n /** Localized token for n=null counts (\"n = —\" in EN/PT-BR). */\n nullCount: string;\n /** Arrow kind words used in <title>s. */\n arrowKinds: {\n flow: string;\n exclusion: string;\n merge: string;\n };\n}\n\n/** Labels drawn by the SVG emitter (legend entries, accessibility aria-label). */\nexport interface PrismaSvgLabels {\n legend: {\n flow: string;\n exclusion: string;\n };\n ariaLabel: string;\n}\n\nexport const PRISMA_TITLE_LABELS_EN: PrismaTitleLabels = {\n phases: {\n identification: \"Identification\",\n screening: \"Screening\",\n included: \"Included\",\n },\n nullCount: \"n = —\",\n arrowKinds: {\n flow: \"Flow\",\n exclusion: \"Exclusion\",\n merge: \"Merge\",\n },\n};\n\nexport const PRISMA_SVG_LABELS_EN: PrismaSvgLabels = {\n legend: {\n flow: \"Main flow\",\n exclusion: \"Excluded\",\n },\n ariaLabel: \"PRISMA 2020 flow diagram\",\n};\n","// PRISMA 2020 pure layout — the single source of truth for positioning and routing.\n// The emitter (./svg.ts) draws EXACTLY what this computes; no geometry is re-derived\n// downstream. Pure + deterministic (no DOM, no clock, no randomness).\n//\n// LAYOUT SUMMARY:\n// - Bands stack top→down via core/bandStack in fixed PRISMA_PHASES order.\n// - Each flow column owns a COLUMN BLOCK = [flow sub-column | EXCL_GAP | exclusion\n// sub-column]. Blocks are GLOBAL (widths are the max box width in that column across\n// ALL phases) and disjoint by construction (single block at contentLeft, or two blocks\n// packed as disjoint siblings via core/packSubtree with PRISMA_COL_GAP between them).\n// - Within a band, a column's flow boxes stack by (rank, id) at the flow sub-column x;\n// that SAME column's exclusion boxes stack by (rank, id) at the exclusion sub-column x —\n// PER COLUMN, so an exclusion always sits to the right of ITS OWN column's flow box.\n// - Band height = max over columns of max(column flow-stack total, column excl-stack total),\n// where a stack total = Σ(boxH) + PRISMA_BOX_PAD_Y between consecutive boxes. Reserving\n// the STACKED total (not the tallest single box) is what lets multiple flow steps share a\n// band (the canonical screening column: screened → sought → assessed) without spilling.\n// - Arrows are all orthogonal (H/V only):\n// * flow→flow same-column (within a band, adjacent ranks; or across bands): vertical drop\n// on the box-center x (box-free because the column is a single vertical stack).\n// * flow→flow cross-column or with multiple arrivals (merge/fan-in): orthogonal elbow via\n// a unique approach_x spread across the target box width — no collinear vertical stubs.\n// * flow→exclusion: a direct horizontal from the source's right edge to its own column's\n// exclusion box left edge, at the exclusion box's center y. The strip between a flow\n// sub-column and ITS OWN exclusion sub-column is box-free (only this column lives in the\n// block), so no detour is ever needed — the per-column block is what kills it.\n//\n// OVERLAP INVARIANTS:\n// 1. Boxes: disjoint by construction — disjoint bands (bandStack recurrence) × disjoint\n// column blocks (packSubtree / single block) × within a block, flow and exclusion\n// sub-columns separated by PRISMA_EXCL_GAP.\n// 2. flow→exclusion arrows: each at the unique center y of its (stacked) exclusion box,\n// inside its own column's box-free flow→excl strip → no collinear, no box crossing.\n// 3. flow→flow drops: one per source on its column's center x (single stack ⇒ box-free),\n// adjacent-rank drops are short and consecutive (no intervening box).\n// 4. Merge/fan-in arrows: each uses a unique approach_x (spread across target box width) so\n// no two arrows share a collinear vertical stub into the same target box.\n//\n// NO ARITHMETIC VALIDATION — the honesty rule. Figures are drawn faithfully as declared.\n\nimport {\n bandStack,\n measureCompartmentBox,\n packSubtree,\n wrapLabelBalanced,\n type Point,\n} from \"../core\";\nimport { PRISMA_TITLE_LABELS_EN, type PrismaTitleLabels } from \"./labels\";\nimport { validatePrisma } from \"./validate\";\nimport { PRISMA_PHASES, type PrismaInput, type PrismaPhase } from \"./types\";\n\nexport {\n PrismaValidationError,\n prismaIssues,\n validatePrisma,\n type PrismaIssue,\n type PrismaIssueCode,\n} from \"./validate\";\nexport type { Point };\n\n// ── Geometry constants ────────────────────────────────────────────────────────\nexport const PRISMA_PADDING = 32;\n/** Left gutter reserved for rotated band labels (never overlaps boxes). */\nexport const PRISMA_BAND_LABEL_W = 40;\n/** Horizontal gap between two flow columns. */\nexport const PRISMA_COL_GAP = 56;\n/** Vertical corridor between bands. */\nexport const PRISMA_CORRIDOR = 30;\nexport const PRISMA_BOX_PAD_X = 12;\nexport const PRISMA_BOX_PAD_Y = 10;\nexport const PRISMA_LINE_H = 14;\nexport const PRISMA_MIN_BOX_W = 200;\n/** Gap between the right edge of ALL flow columns and the left edge of exclusion boxes. */\nexport const PRISMA_EXCL_GAP = 48;\nexport const PRISMA_HEADING_FONT = 12;\nexport const PRISMA_COUNT_FONT = 10;\n/** Vertical margin added below band bottom for corridor routing. */\nconst PRISMA_ROUTE_MARGIN = 10;\n/** Pitch between unique corridor y-levels for multiple arrows from same source. */\nconst PRISMA_ROUTE_PITCH = 10;\n\n// ── Namespaced edge-id blocks ─────────────────────────────────────────────────\nexport const PRISMA_FLOW_ARROW_BASE = 1_000_000; // + arrow.id\nexport const PRISMA_EXCL_ARROW_BASE = 2_000_000; // + arrow.id\nexport const PRISMA_MERGE_ARROW_BASE = 3_000_000; // + arrow.id\n\n// ── Layout types ──────────────────────────────────────────────────────────────\n\n/** A positioned PRISMA box with all metrics needed by the emitter and harness. */\nexport interface PrismaLayoutBox {\n id: number;\n phase: PrismaPhase;\n kind: \"flow\" | \"exclusion\";\n /** Center x. */\n cx: number;\n /** Top y. */\n top: number;\n boxW: number;\n boxH: number;\n rows: { lines: string[]; top: number; font: number }[];\n dividerYs: number[];\n heading: string | null;\n countLines: string[];\n title: string;\n}\n\n/** A routed element (arrow segment polyline). */\nexport interface PrismaLayoutElement {\n edgeId: number;\n kind: \"flow\" | \"exclusion\" | \"merge\";\n points: Point[];\n title: string;\n headDir: \"down\" | \"right\" | \"left\" | \"up\";\n}\n\n/** The positioned PRISMA layout. */\nexport interface PrismaLayout {\n width: number;\n height: number;\n boxes: PrismaLayoutBox[];\n elements: PrismaLayoutElement[];\n bands: {\n phase: PrismaPhase;\n rowTop: number;\n rowH: number;\n labelX: number;\n centerY: number;\n }[];\n variant: PrismaInput[\"variant\"];\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction wrapHeading(h: string | null): string[] {\n if (h === null || h === \"\") return [];\n return wrapLabelBalanced(h);\n}\n\nfunction countLine(label: string, n: number | null, nullToken: string): string {\n const nStr = n === null ? nullToken : String(n);\n return `${label}: n = ${nStr}`;\n}\n\nfunction buildCountLines(counts: { label: string; n: number | null }[], nullToken: string): string[] {\n return counts.map((c) => countLine(c.label, c.n, nullToken));\n}\n\nfunction boxTitle(\n box: { heading: string | null; counts: { label: string; n: number | null }[]; title?: string },\n nullToken: string,\n): string {\n if (box.title !== undefined) return box.title;\n const parts: string[] = [];\n if (box.heading !== null && box.heading !== \"\") parts.push(box.heading);\n for (const c of box.counts) parts.push(countLine(c.label, c.n, nullToken));\n return parts.join(\"; \") || \"(box)\";\n}\n\n// ── Main layout function ──────────────────────────────────────────────────────\n\nexport interface PrismaLayoutOpts {\n labels?: PrismaTitleLabels;\n validate?: boolean;\n}\n\nexport function computePrismaLayout(input: PrismaInput, opts: PrismaLayoutOpts = {}): PrismaLayout {\n if (opts.validate !== false) validatePrisma(input);\n\n const labels: PrismaTitleLabels = opts.labels ?? PRISMA_TITLE_LABELS_EN;\n const nullToken = labels.nullCount;\n\n // ── 1. Measure each box ────────────────────────────────────────────────────\n const COMP_OPTS = {\n padX: PRISMA_BOX_PAD_X,\n padY: PRISMA_BOX_PAD_Y,\n lineH: PRISMA_LINE_H,\n minW: PRISMA_MIN_BOX_W,\n sepPad: 0,\n };\n\n const boxMetrics = new Map<number, {\n boxW: number; boxH: number;\n rows: { lines: string[]; top: number; font: number }[];\n dividerYs: number[];\n headingLines: string[];\n countLines: string[];\n }>();\n\n for (const b of input.boxes) {\n const headingLines = wrapHeading(b.heading);\n const cLines = buildCountLines(b.counts, nullToken);\n const metrics = measureCompartmentBox(\n [\n { lines: headingLines, font: PRISMA_HEADING_FONT },\n { lines: cLines, font: PRISMA_COUNT_FONT },\n ],\n COMP_OPTS,\n );\n boxMetrics.set(b.id, {\n boxW: metrics.boxW, boxH: metrics.boxH,\n rows: metrics.rows, dividerYs: metrics.dividerYs,\n headingLines, countLines: cLines,\n });\n }\n\n // ── 2. Group boxes by (phase, column, kind) ────────────────────────────────\n type FlowCol = \"main\" | \"new\" | \"previous\";\n type GroupKey = `${PrismaPhase}:${FlowCol}:${\"flow\" | \"exclusion\"}`;\n\n const boxesByKey = new Map<GroupKey, typeof input.boxes[number][]>();\n for (const b of input.boxes) {\n const key: GroupKey = `${b.phase}:${b.column as FlowCol}:${b.kind}`;\n const arr = boxesByKey.get(key) ?? [];\n arr.push(b);\n boxesByKey.set(key, arr);\n }\n for (const arr of boxesByKey.values()) {\n arr.sort((a, b) => a.rank !== b.rank ? a.rank - b.rank : a.id - b.id);\n }\n const groupOf = (phase: PrismaPhase, col: FlowCol, kind: \"flow\" | \"exclusion\") =>\n boxesByKey.get(`${phase}:${col}:${kind}`) ?? [];\n\n const flowCols: FlowCol[] =\n input.variant === \"flow-with-prior\" ? [\"new\", \"previous\"] :\n input.variant === \"flow-other-methods\" ? [\"main\", \"new\"] :\n [\"main\"];\n\n // ── 3. GLOBAL per-column blocks: [flow sub-column | EXCL_GAP | exclusion sub-column] ──\n // Each column owns a block whose widths are the max box width in that column across ALL\n // phases (so every band's column shares one x). A column with no exclusion box reserves no\n // exclusion sub-column. Blocks pack left→right as disjoint siblings (PRISMA_COL_GAP between\n // block AABBs). A column that carries ONLY exclusion boxes (e.g. a shared \"main\" duplicates\n // box in the prior variant) becomes a trailing exclusion-only block to the right of the flow\n // blocks (flowW = 0) — its arrows are the one cross-column case (routed via a detour below).\n const contentLeft = PRISMA_PADDING + PRISMA_BAND_LABEL_W;\n\n function maxColW(col: FlowCol, kind: \"flow\" | \"exclusion\"): number {\n let w = 0;\n for (const phase of PRISMA_PHASES) {\n for (const b of groupOf(phase, col, kind)) {\n const bw = boxMetrics.get(b.id)!.boxW;\n if (bw > w) w = bw;\n }\n }\n return w;\n }\n const colHasFlow = (col: FlowCol): boolean =>\n PRISMA_PHASES.some((phase) => groupOf(phase, col, \"flow\").length > 0);\n const colHasExcl = (col: FlowCol): boolean =>\n PRISMA_PHASES.some((phase) => groupOf(phase, col, \"exclusion\").length > 0);\n\n // Exclusion-only columns (have exclusion boxes but are not a flow column) → trailing blocks.\n const exclOnlyCols: FlowCol[] = ([\"main\", \"new\", \"previous\"] as const).filter(\n (col) => !flowCols.includes(col) && colHasExcl(col),\n );\n const placedCols: FlowCol[] = [...flowCols, ...exclOnlyCols];\n\n // Per-column geometry: flow x-center, optional exclusion x-center, total block width.\n interface ColGeom {\n flowW: number; // 0 ⇒ exclusion-only column (no flow sub-column)\n exclW: number; // 0 ⇒ no exclusion sub-column in this column\n blockW: number;\n flowCx: number; // absolute, set in the placement pass; meaningful only when flowW > 0\n exclCx: number; // absolute; meaningful only when exclW > 0\n }\n const colGeom = new Map<FlowCol, ColGeom>();\n for (const col of placedCols) {\n const flowW = colHasFlow(col) ? Math.max(PRISMA_MIN_BOX_W, maxColW(col, \"flow\")) : 0;\n const exclW = maxColW(col, \"exclusion\");\n const blockW =\n flowW > 0 && exclW > 0 ? flowW + PRISMA_EXCL_GAP + exclW :\n flowW > 0 ? flowW :\n exclW;\n colGeom.set(col, { flowW, exclW, blockW, flowCx: 0, exclCx: 0 });\n }\n\n // Place each column block; within a block the flow sub-column is left-aligned and the\n // exclusion sub-column (if any) sits at flowRight + EXCL_GAP (or at blockLeft when flowW=0).\n function placeBlock(col: FlowCol, blockLeft: number): void {\n const g = colGeom.get(col)!;\n if (g.flowW > 0) g.flowCx = round(blockLeft + g.flowW / 2);\n if (g.exclW > 0) {\n const exclLeft = g.flowW > 0 ? blockLeft + g.flowW + PRISMA_EXCL_GAP : blockLeft;\n g.exclCx = round(exclLeft + g.exclW / 2);\n }\n }\n\n if (placedCols.length === 1) {\n placeBlock(placedCols[0]!, contentLeft);\n } else {\n // Pack all column BLOCKS as disjoint siblings (PRISMA_COL_GAP between block AABBs).\n const packed = packSubtree(\n { ownHalfL: 0, ownHalfR: 0,\n children: placedCols.map((col) => {\n const half = colGeom.get(col)!.blockW / 2;\n return { halfL: half, halfR: half };\n }),\n },\n { siblingGap: PRISMA_COL_GAP },\n );\n const totalW = packed.halfL + packed.halfR;\n const blockCx = round(contentLeft + totalW / 2);\n placedCols.forEach((col, i) => {\n const w = colGeom.get(col)!.blockW;\n placeBlock(col, round(blockCx + packed.offsets[i]! - w / 2));\n });\n }\n\n // Right-most drawn x (for the canvas width).\n let totalRight = contentLeft;\n for (const col of placedCols) {\n const g = colGeom.get(col)!;\n const r = g.exclW > 0 ? round(g.exclCx + g.exclW / 2) : round(g.flowCx + g.flowW / 2);\n if (r > totalRight) totalRight = r;\n }\n\n // ── 4. Per-(phase, column) RANK ROWS ───────────────────────────────────────\n // Within a column a flow box and its same-rank exclusion box MUST share a vertical level\n // (the exclusion sits directly to the right of its flow box). So rows are indexed by the\n // DECLARED rank: a row's height is the tallest box (flow OR exclusion) at that rank, and\n // ranks stack top→down by rowH + PRISMA_BOX_PAD_Y. The flow box draws at flowCx, the\n // exclusion box at exclCx, BOTH at the rank's row-top — keeping a same-rank flow→excl\n // horizontal box-free and aligning all stacked steps. Reserving the stacked total (not the\n // tallest single box) lets a multi-step screening column (screened → sought → assessed)\n // share one band; the old max-single-box reserve spilled ranks ≥ 1 into the next band.\n interface RankRow { rank: number; rowH: number; top: number; }\n // rowsByCol[phase][col] = ordered rank rows (top set after the band's rowTop is known).\n const rowsByCol = new Map<string, RankRow[]>();\n const rowsKey = (phase: PrismaPhase, col: FlowCol) => `${phase}:${col}`;\n\n function buildRankRows(phase: PrismaPhase, col: FlowCol): RankRow[] {\n const byRank = new Map<number, number>(); // rank → tallest box height at that rank\n for (const kind of [\"flow\", \"exclusion\"] as const) {\n for (const b of groupOf(phase, col, kind)) {\n const h = boxMetrics.get(b.id)!.boxH;\n const prev = byRank.get(b.rank) ?? 0;\n if (h > prev) byRank.set(b.rank, h);\n }\n }\n const ranks = [...byRank.keys()].sort((a, b) => a - b);\n return ranks.map((rank) => ({ rank, rowH: byRank.get(rank)!, top: 0 }));\n }\n for (const phase of PRISMA_PHASES) {\n for (const col of placedCols) {\n rowsByCol.set(rowsKey(phase, col), buildRankRows(phase, col));\n }\n }\n\n // A column's total stacked height = Σ(rowH) + (rows−1)·PRISMA_BOX_PAD_Y.\n function colStackH(rows: RankRow[]): number {\n if (rows.length === 0) return 0;\n let h = 0;\n for (const r of rows) h += r.rowH + PRISMA_BOX_PAD_Y;\n return h - PRISMA_BOX_PAD_Y; // last row has no trailing pad\n }\n function bandRowH(phase: PrismaPhase): number {\n let maxH = 0;\n let any = false;\n for (const col of placedCols) {\n const rows = rowsByCol.get(rowsKey(phase, col))!;\n if (rows.length > 0) any = true;\n const h = colStackH(rows);\n if (h > maxH) maxH = h;\n }\n if (!any) return PRISMA_LINE_H * 2 + PRISMA_BOX_PAD_Y * 4; // empty band: gutter only\n return maxH;\n }\n\n const bandRowHs = PRISMA_PHASES.map((phase) => ({\n rowH: bandRowH(phase),\n zoneH: 0,\n }));\n\n const stacked = bandStack(bandRowHs, { padding: PRISMA_PADDING, corridor: PRISMA_CORRIDOR });\n\n // ── 5. Position all boxes ─────────────────────────────────────────────────\n // Each rank row's top is the band rowTop plus the cumulative height of the rows above it.\n // Every box at rank k draws at its row's top — flow at flowCx, exclusion at exclCx.\n const layoutBoxes: PrismaLayoutBox[] = [];\n const lboxById = new Map<number, PrismaLayoutBox>();\n\n function placeBox(\n b: typeof input.boxes[number],\n phase: PrismaPhase,\n kind: \"flow\" | \"exclusion\",\n cx: number,\n top: number,\n ): void {\n const m = boxMetrics.get(b.id)!;\n const t = round(top);\n const title = boxTitle(b, nullToken);\n const lbox: PrismaLayoutBox = {\n id: b.id, phase, kind, cx: round(cx), top: t,\n boxW: m.boxW, boxH: m.boxH,\n rows: m.rows.map((r) => ({ ...r, top: round(t + r.top) })),\n dividerYs: m.dividerYs.map((d) => round(t + d)),\n heading: b.heading, countLines: m.countLines, title,\n };\n layoutBoxes.push(lbox);\n lboxById.set(b.id, lbox);\n }\n\n for (let phaseIdx = 0; phaseIdx < PRISMA_PHASES.length; phaseIdx++) {\n const phase = PRISMA_PHASES[phaseIdx]!;\n const bandTop = stacked.rowTop[phaseIdx]!;\n for (const col of placedCols) {\n const g = colGeom.get(col)!;\n const rows = rowsByCol.get(rowsKey(phase, col))!;\n const topByRank = new Map<number, number>();\n let y = bandTop;\n for (const r of rows) {\n r.top = round(y);\n topByRank.set(r.rank, r.top);\n y = round(y + r.rowH + PRISMA_BOX_PAD_Y);\n }\n if (g.flowW > 0) {\n for (const b of groupOf(phase, col, \"flow\")) {\n placeBox(b, phase, \"flow\", g.flowCx, topByRank.get(b.rank)!);\n }\n }\n if (g.exclW > 0) {\n for (const b of groupOf(phase, col, \"exclusion\")) {\n placeBox(b, phase, \"exclusion\", g.exclCx, topByRank.get(b.rank)!);\n }\n }\n }\n }\n\n // ── 6. Route arrows ───────────────────────────────────────────────────────\n //\n // ROUTING INVARIANTS (proof that collisions == []):\n //\n // A. FLOW → EXCLUSION, SAME COLUMN (the common case):\n // A direct horizontal at the exclusion box's center y, from the source flow box's right\n // edge to the exclusion box's left edge. The strip between a column's flow sub-column and\n // ITS OWN exclusion sub-column is box-free by construction (only this column lives in the\n // block, and the two sub-columns are separated by PRISMA_EXCL_GAP), so the segment crosses\n // no box. Each exclusion box in the column has a unique center y (vertical stack) → distinct\n // horizontals → no collinear double-draw.\n //\n // B. FLOW → EXCLUSION, CROSS COLUMN (a shared exclusion column, e.g. a \"main\" duplicates box\n // in the prior variant — the one case a column's flow box points at another column's box):\n // The direct horizontal would cross an intervening column's box, so detour through the\n // box-free inter-column gap and the corridor below the band, using a per-source-arrow unique\n // x on every vertical leg and a unique y on every horizontal leg:\n // (srcRight, exclMidY) → (fenceX, exclMidY) → (fenceX, corridorY)\n // → (exclFenceX, corridorY) → (exclFenceX, exclMidY) → (exclLeft, exclMidY)\n // fenceX (in the inter-column gap) and exclFenceX (just left of the target excl box) are\n // unique per arrow → no collinear vertical; corridorY and exclMidY are unique per arrow\n // → no collinear horizontal. The corridor sits below the band (bandRowH reserves the full\n // stacked height, so it is below every box) → the corridor legs are box-free.\n //\n // C. FLOW → FLOW, SAME COLUMN:\n // A vertical drop on the column's center x, from the source box bottom to the target box top.\n // The column is a single vertical stack, so the strip on its center x between two boxes is\n // box-free; adjacent ranks make the drop short and consecutive (no intervening box).\n //\n // D. FLOW → FLOW, CROSS COLUMN or FAN-IN (merge):\n // An orthogonal elbow via the corridor below the source band, entering the target box top at\n // a unique approach_x spread across the target box width → no two incoming arrows share a\n // collinear vertical stub into the same target box.\n\n const elements: PrismaLayoutElement[] = [];\n const boxById = new Map(input.boxes.map((b) => [b.id, b]));\n\n // Build phase index for backward-arrow check.\n const phaseIndexMap = new Map<PrismaPhase, number>(\n PRISMA_PHASES.map((p, i) => [p, i]),\n );\n\n // Helper: bottom y of a layout box.\n function boxBottom(lb: PrismaLayoutBox): number {\n return round(lb.top + lb.boxH);\n }\n\n // Helper: band bottom y (rowTop + rowH).\n function bandBottom(phase: PrismaPhase): number {\n const idx = PRISMA_PHASES.indexOf(phase);\n return round(stacked.rowTop[idx]! + bandRowHs[idx]!.rowH);\n }\n\n // ── Count arrows per target box (for merge approach-x spread) ────────────────\n // For flow→flow arrows, count how many arrows arrive at each target box.\n // This determines the spread of approach_x to avoid collinear vertical stubs.\n const arrowsToBox = new Map<number, number[]>(); // toId → [arrowId, ...]\n for (const arrow of input.arrows) {\n const toBox = boxById.get(arrow.toId);\n const fromBox = boxById.get(arrow.fromId);\n if (toBox === undefined || fromBox === undefined) continue;\n if (fromBox.kind === \"flow\" && toBox.kind === \"flow\") {\n const arr = arrowsToBox.get(arrow.toId) ?? [];\n arr.push(arrow.id);\n arrowsToBox.set(arrow.toId, arr);\n }\n }\n\n // Track per-target arrival index (for unique approach_x assignment).\n const arrowToBoxArrivalIdx = new Map<number, number>(); // arrowId → arrival index at target\n\n // ── Excl arrow index tracking per source box ──────────────────────────────\n const exclArrowIndexBySource = new Map<number, number>(); // sourceId → next index\n\n for (const arrow of input.arrows) {\n const fromLBox = lboxById.get(arrow.fromId);\n const toLBox = lboxById.get(arrow.toId);\n if (fromLBox === undefined || toLBox === undefined) continue;\n\n const fromBox = boxById.get(arrow.fromId)!;\n const toBox = boxById.get(arrow.toId)!;\n\n const isExclusion = fromBox.kind === \"flow\" && toBox.kind === \"exclusion\";\n const isFlowToFlow = fromBox.kind === \"flow\" && toBox.kind === \"flow\";\n\n if (isExclusion) {\n // ── Flow → Exclusion ────────────────────────────────────────────────\n const idx = exclArrowIndexBySource.get(arrow.fromId) ?? 0;\n exclArrowIndexBySource.set(arrow.fromId, idx + 1);\n\n const srcRight = round(fromLBox.cx + fromLBox.boxW / 2);\n const exclMidY = round(toLBox.top + toLBox.boxH / 2);\n const eLeft = round(toLBox.cx - toLBox.boxW / 2);\n\n // Same column ⇒ the flow→excl strip is box-free ⇒ a direct horizontal suffices.\n // Cross column (shared exclusion) ⇒ detour around the intervening boxes.\n const sameColumn = fromBox.column === toBox.column;\n\n let points: Point[];\n\n if (sameColumn) {\n // Direct: unique y per excl box guarantees no collinear with other direct arrows.\n points = [\n { x: round(srcRight), y: round(exclMidY) },\n { x: round(eLeft), y: round(exclMidY) },\n ];\n } else {\n // Detour via the inter-column gap and the corridor below the band.\n // fenceX_i: unique x just right of the source box (in its block's right margin / gap).\n // exclFenceX_i: unique x just left of the target excl box (inside the gap before it).\n // corridorY_i: unique y below the band (the band reserves the full stacked height).\n const colGapStep = round(PRISMA_COL_GAP / 8); // ~7px per slot\n const exclGapStep = round(PRISMA_EXCL_GAP / 8); // ~6px per slot\n\n const fenceX = round(srcRight + (idx + 1) * colGapStep);\n const exclFenceX = round(eLeft - (idx + 1) * exclGapStep);\n const bBotY = bandBottom(fromBox.phase);\n const corridorY = round(bBotY + PRISMA_ROUTE_MARGIN + idx * PRISMA_ROUTE_PITCH);\n\n points = [\n { x: round(srcRight), y: round(exclMidY) }, // exit source right at excl center y\n { x: round(fenceX), y: round(exclMidY) }, // horizontal into inter-col gap (unique y)\n { x: round(fenceX), y: round(corridorY) }, // vertical at unique x in inter-col gap\n { x: round(exclFenceX), y: round(corridorY) }, // horizontal in corridor (unique y)\n { x: round(exclFenceX), y: round(exclMidY) }, // vertical at unique x left of excl box\n { x: round(eLeft), y: round(exclMidY) }, // horizontal into excl box (unique y)\n ];\n }\n\n elements.push({\n edgeId: PRISMA_EXCL_ARROW_BASE + arrow.id,\n kind: \"exclusion\",\n points,\n title: `${labels.arrowKinds.exclusion}: ${fromLBox.title} → ${toLBox.title}`,\n headDir: \"right\",\n });\n } else if (isFlowToFlow) {\n // ── Flow → Flow ─────────────────────────────────────────────────────\n const fromPhaseIdx = phaseIndexMap.get(fromBox.phase)!;\n const toPhaseIdx = phaseIndexMap.get(toBox.phase)!;\n const isSamePhase = fromBox.phase === toBox.phase;\n const isSameCol = fromBox.column === toBox.column;\n const isForward = toPhaseIdx >= fromPhaseIdx;\n\n // Arrival index for unique approach_x at target.\n const arrivals = arrowsToBox.get(arrow.toId) ?? [];\n let arrivalIdx = arrowToBoxArrivalIdx.get(arrow.id) ?? 0;\n if (!arrowToBoxArrivalIdx.has(arrow.id)) {\n arrivalIdx = arrivals.indexOf(arrow.id);\n arrowToBoxArrivalIdx.set(arrow.id, arrivalIdx);\n }\n const nArrivals = arrivals.length;\n // Spread approach_x across the target box width.\n // With n arrows, divide target box into n+1 slots and use slots 1..n.\n const APPROACH_SPREAD = round(toLBox.boxW / 4); // use middle half of box\n const spreadStep = nArrivals > 1 ? round(APPROACH_SPREAD / (nArrivals - 1)) : 0;\n const approachX = round(toLBox.cx - APPROACH_SPREAD / 2 + arrivalIdx * spreadStep);\n const toTop = toLBox.top;\n\n if (isSamePhase && isSameCol) {\n // Same-column same-phase (adjacent ranks in one stack): a short straight vertical drop\n // on the shared box-center x. Source and target share cx (one column ⇒ one x), and the\n // PAD-sized gap between them is box-free, so no elbow / approach-x spread is needed; a\n // diagonal would only appear if we offset to approachX, which is wrong here.\n const fromBottom = boxBottom(fromLBox);\n const fromCx = round(fromLBox.cx);\n const toCx = round(toLBox.cx);\n const dropX = fromCx === toCx ? fromCx : toCx; // identical in practice; defensive\n elements.push({\n edgeId: PRISMA_FLOW_ARROW_BASE + arrow.id,\n kind: \"flow\",\n points: [\n { x: fromCx, y: round(fromBottom) },\n { x: dropX, y: round(toTop) },\n ],\n title: `${labels.arrowKinds.flow}: ${fromLBox.title} → ${toLBox.title}`,\n headDir: \"down\",\n });\n } else if (isSameCol && isForward) {\n // Same-column cross-phase downward: vertical drop from fromCx to toCx.\n // If same cx, this is a clean vertical line; if cx differs (shouldn't in global scheme),\n // use the approach_x for unique routing.\n const fromBottom = boxBottom(fromLBox);\n if (nArrivals <= 1 && round(fromLBox.cx) === round(toLBox.cx)) {\n // Single arrow, same cx: clean straight vertical.\n elements.push({\n edgeId: PRISMA_FLOW_ARROW_BASE + arrow.id,\n kind: \"flow\",\n points: [\n { x: round(fromLBox.cx), y: round(fromBottom) },\n { x: round(toLBox.cx), y: round(toTop) },\n ],\n title: `${labels.arrowKinds.flow}: ${fromLBox.title} → ${toLBox.title}`,\n headDir: \"down\",\n });\n } else {\n // Multiple arrows or different cx: use elbow routing.\n const phIdx = phaseIndexMap.get(fromBox.phase)!;\n const elbowY = round(stacked.rowTop[phIdx]! + bandRowHs[phIdx]!.rowH + PRISMA_CORRIDOR / 2);\n elements.push({\n edgeId: PRISMA_FLOW_ARROW_BASE + arrow.id,\n kind: \"flow\",\n points: [\n { x: round(fromLBox.cx), y: round(fromBottom) },\n { x: round(fromLBox.cx), y: round(elbowY) },\n { x: round(approachX), y: round(elbowY) },\n { x: round(approachX), y: round(toTop) },\n ],\n title: `${labels.arrowKinds.flow}: ${fromLBox.title} → ${toLBox.title}`,\n headDir: \"down\",\n });\n }\n } else {\n // Cross-column or cross-phase merge arrow.\n // Route: (fromCx, fromBottom) → (fromCx, elbowY) → (approachX, elbowY) → (approachX, toTop)\n // elbowY = mid-corridor below the FROM band.\n const fromBottom = boxBottom(fromLBox);\n const phIdx = phaseIndexMap.get(fromBox.phase)!;\n const elbowY = round(stacked.rowTop[phIdx]! + bandRowHs[phIdx]!.rowH + PRISMA_CORRIDOR / 2);\n\n const fromCx = round(fromLBox.cx);\n if (round(fromCx) === round(approachX)) {\n // Same x: straight vertical.\n elements.push({\n edgeId: PRISMA_MERGE_ARROW_BASE + arrow.id,\n kind: \"merge\",\n points: [\n { x: fromCx, y: round(fromBottom) },\n { x: round(approachX), y: round(toTop) },\n ],\n title: `${labels.arrowKinds.merge}: ${fromLBox.title} → ${toLBox.title}`,\n headDir: \"down\",\n });\n } else {\n elements.push({\n edgeId: PRISMA_MERGE_ARROW_BASE + arrow.id,\n kind: \"merge\",\n points: [\n { x: fromCx, y: round(fromBottom) },\n { x: fromCx, y: round(elbowY) },\n { x: round(approachX), y: round(elbowY) },\n { x: round(approachX), y: round(toTop) },\n ],\n title: `${labels.arrowKinds.merge}: ${fromLBox.title} → ${toLBox.title}`,\n headDir: \"down\",\n });\n }\n }\n }\n // Backward arrows (validation catches them but layout tolerates silently).\n }\n\n // ── 7. Canvas dimensions ───────────────────────────────────────────────────\n const canvasH = stacked.height;\n const canvasW = round(totalRight + PRISMA_PADDING);\n\n // ── 8. Band metadata ───────────────────────────────────────────────────────\n const bands = PRISMA_PHASES.map((phase, i) => {\n const rowTop = stacked.rowTop[i]!;\n const rowH = bandRowHs[i]!.rowH;\n return {\n phase,\n rowTop,\n rowH,\n labelX: PRISMA_PADDING,\n centerY: round(rowTop + rowH / 2),\n };\n });\n\n return {\n width: canvasW,\n height: canvasH,\n boxes: layoutBoxes,\n elements,\n bands,\n variant: input.variant,\n };\n}\n","// PRISMA 2020 SVG emitter — draws EXACTLY what layout.ts computed.\n// Literal presentation attributes only; no CSS, no <defs>, no <marker>.\n// All text interpolations are xmlEscape'd.\n// Arrowheads are explicit <polygon>s from core/glyph.\n\nimport {\n FONT_FAMILY,\n arrowFilledPoints,\n glyphInset,\n legendBlock,\n pathData,\n xmlEscape,\n type LegendEntry,\n} from \"../core\";\nimport {\n PRISMA_BAND_LABEL_W,\n type PrismaLayout,\n type PrismaLayoutBox,\n type PrismaLayoutElement,\n} from \"./layout\";\nimport {\n PRISMA_SVG_LABELS_EN,\n PRISMA_TITLE_LABELS_EN,\n type PrismaSvgLabels,\n type PrismaTitleLabels,\n} from \"./labels\";\nimport type { PrismaPhase } from \"./types\";\n\n// ── Presentation constants ────────────────────────────────────────────────────\nconst BOX_STROKE = \"#52525b\";\nconst BOX_STROKE_W = 2;\nconst BOX_FILL = \"#fff\";\nconst BOX_RX = 2;\nconst HEADING_FILL = \"#3f3f46\";\nconst COUNT_FILL = \"#52525b\";\nconst ARROW_STROKE = \"#71717a\";\nconst ARROW_STROKE_W = 1.5;\nconst ARROW_FILL = \"#71717a\";\nconst BAND_LABEL_FILL = \"#52525b\";\nconst BAND_LABEL_FONT = 11;\n\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\n// ── Box emitter ───────────────────────────────────────────────────────────────\n\nfunction emitBox(b: PrismaLayoutBox): string {\n const x = round(b.cx - b.boxW / 2);\n const y = b.top;\n const parts: string[] = [];\n\n // Outer rect\n parts.push(\n `<rect x=\"${x}\" y=\"${y}\" width=\"${b.boxW}\" height=\"${b.boxH}\" ` +\n `rx=\"${BOX_RX}\" fill=\"${BOX_FILL}\" stroke=\"${BOX_STROKE}\" stroke-width=\"${BOX_STROKE_W}\"/>`,\n );\n\n // Dividers (between heading and counts compartment)\n for (const dy of b.dividerYs) {\n parts.push(\n `<line x1=\"${x}\" y1=\"${dy}\" x2=\"${round(x + b.boxW)}\" y2=\"${dy}\" ` +\n `stroke=\"${BOX_STROKE}\" stroke-width=\"1\"/>`,\n );\n }\n\n // Text rows: first compartment = heading (bold by size), second = counts (regular, left-aligned)\n for (let ri = 0; ri < b.rows.length; ri++) {\n const row = b.rows[ri]!;\n const isHeading = ri === 0;\n const font = row.font;\n const fill = isHeading ? HEADING_FILL : COUNT_FILL;\n const textX = isHeading\n ? round(b.cx) // heading: centered\n : round(x + 8); // counts: left-aligned with small indent\n\n for (let li = 0; li < row.lines.length; li++) {\n const line = row.lines[li]!;\n const textY = round(row.top + li * 14 + font); // 14 = PRISMA_LINE_H\n const anchorAttr = isHeading ? ` text-anchor=\"middle\"` : \"\";\n const weightAttr = isHeading ? ` font-weight=\"bold\"` : \"\";\n parts.push(\n `<text x=\"${textX}\" y=\"${textY}\" font-family=\"${FONT_FAMILY}\" ` +\n `font-size=\"${font}\" fill=\"${fill}\"${anchorAttr}${weightAttr}>${xmlEscape(line)}</text>`,\n );\n }\n }\n\n return parts.join(\"\");\n}\n\n// ── Arrow emitter ─────────────────────────────────────────────────────────────\n\nfunction emitArrow(el: PrismaLayoutElement): string {\n const points = el.points;\n if (points.length < 2) return \"\";\n\n // The line stops short by glyphInset before the terminal point\n const inset = glyphInset(el.headDir, \"arrow\");\n const last = points[points.length - 1]!;\n\n // Shorten the last segment by inset\n let lineEndX = last.x;\n let lineEndY = last.y;\n if (el.headDir === \"down\") lineEndY = round(last.y - inset);\n else if (el.headDir === \"right\") lineEndX = round(last.x - inset);\n else if (el.headDir === \"left\") lineEndX = round(last.x + inset);\n else lineEndY = round(last.y + inset); // \"up\"\n\n // Build shortened polyline\n const linePoints = [\n ...points.slice(0, points.length - 1).map((p) => ({ x: p.x, y: p.y })),\n { x: lineEndX, y: lineEndY },\n ];\n\n const pathStr = pathData(linePoints);\n const arrowPts = arrowFilledPoints({ x: last.x, y: last.y }, el.headDir);\n\n return (\n `<title>${xmlEscape(el.title)}</title>` +\n `<path d=\"${pathStr}\" stroke=\"${ARROW_STROKE}\" stroke-width=\"${ARROW_STROKE_W}\" fill=\"none\"/>` +\n `<polygon points=\"${arrowPts}\" fill=\"${ARROW_FILL}\" stroke=\"none\"/>`\n );\n}\n\n// ── Band label emitter (rotated, left gutter — decoration) ────────────────────\n\nfunction emitBandLabel(\n phase: PrismaPhase,\n labelX: number,\n centerY: number,\n bandTitleLabels: PrismaTitleLabels,\n): string {\n const text = bandTitleLabels.phases[phase];\n const gutterCx = round(labelX + PRISMA_BAND_LABEL_W / 2);\n return (\n `<text x=\"${gutterCx}\" y=\"${round(centerY)}\" font-family=\"${FONT_FAMILY}\" ` +\n `font-size=\"${BAND_LABEL_FONT}\" fill=\"${BAND_LABEL_FILL}\" text-anchor=\"middle\" ` +\n `transform=\"rotate(-90,${gutterCx},${round(centerY)})\">${xmlEscape(text)}</text>`\n );\n}\n\n// ── Legend ────────────────────────────────────────────────────────────────────\n\nfunction buildLegendEntries(\n layout: PrismaLayout,\n svgLabels: PrismaSvgLabels,\n): LegendEntry[] {\n const hasFlow = layout.boxes.some((b) => b.kind === \"flow\");\n const hasExcl = layout.boxes.some((b) => b.kind === \"exclusion\");\n const entries: LegendEntry[] = [];\n\n if (hasFlow) {\n entries.push({\n label: svgLabels.legend.flow,\n swatch: (x, cy) => (\n `<rect x=\"${x}\" y=\"${round(cy - 6)}\" width=\"22\" height=\"12\" rx=\"2\" ` +\n `fill=\"${BOX_FILL}\" stroke=\"${BOX_STROKE}\" stroke-width=\"2\"/>`\n ),\n });\n }\n if (hasExcl) {\n entries.push({\n label: svgLabels.legend.exclusion,\n swatch: (x, cy) => (\n `<rect x=\"${x}\" y=\"${round(cy - 6)}\" width=\"22\" height=\"12\" rx=\"2\" ` +\n `fill=\"${BOX_FILL}\" stroke=\"${BOX_STROKE}\" stroke-width=\"2\" stroke-dasharray=\"4,2\"/>`\n ),\n });\n }\n return entries;\n}\n\n// ── Main emitter ──────────────────────────────────────────────────────────────\n\nexport interface PrismaSvgOpts {\n svgLabels?: PrismaSvgLabels;\n titleLabels?: PrismaTitleLabels;\n legend?: boolean;\n}\n\n/**\n * Emits the SVG string for a pre-computed PRISMA layout.\n * All coordinates come from the layout; no geometry is re-derived here.\n */\nexport function prismaLayoutSvg(layout: PrismaLayout, opts: PrismaSvgOpts = {}): string {\n const svgLabels: PrismaSvgLabels = opts.svgLabels ?? PRISMA_SVG_LABELS_EN;\n const bandTitleLabels: PrismaTitleLabels = opts.titleLabels ?? PRISMA_TITLE_LABELS_EN;\n const doLegend = opts.legend !== false;\n\n // ── Collect SVG parts ─────────────────────────────────────────────────────\n const parts: string[] = [];\n\n // Band labels (rotated, decoration)\n for (const band of layout.bands) {\n parts.push(emitBandLabel(band.phase, band.labelX, band.centerY, bandTitleLabels));\n }\n\n // Boxes\n for (const b of layout.boxes) {\n const boxSvg = emitBox(b);\n parts.push(`<g data-node-id=\"b${b.id}\"><title>${xmlEscape(b.title)}</title>${boxSvg}</g>`);\n }\n\n // Arrows\n for (const el of layout.elements) {\n const arrowSvg = emitArrow(el);\n parts.push(`<g data-edge-id=\"${el.edgeId}\">${arrowSvg}</g>`);\n }\n\n let w = layout.width;\n let h = layout.height;\n\n // Legend\n let legendSvg = \"\";\n if (doLegend) {\n const entries = buildLegendEntries(layout, svgLabels);\n const lb = legendBlock(entries, h);\n legendSvg = lb.svg;\n if (entries.length > 0) {\n w = Math.max(w, lb.width + 32 * 2);\n h = lb.height;\n }\n }\n\n w = round(w);\n h = round(h);\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${w}\" height=\"${h}\" viewBox=\"0 0 ${w} ${h}\" ` +\n `role=\"img\" aria-label=\"${xmlEscape(svgLabels.ariaLabel)}\">` +\n parts.join(\"\") +\n legendSvg +\n `</svg>`\n );\n}\n","// PRISMA 2020 one-call render wrapper.\n// prismaSvg(input, opts) → { svg, layout }\n// Validates, computes layout, emits SVG — the three-step pipeline in one call.\n\nimport { computePrismaLayout, type PrismaLayout, type PrismaLayoutOpts } from \"./layout\";\nimport { prismaLayoutSvg, type PrismaSvgOpts } from \"./svg\";\nimport type { PrismaInput } from \"./types\";\n\nexport type PrismaRenderOpts = PrismaLayoutOpts & PrismaSvgOpts;\n\n/** Compute layout + emit SVG in one call. Returns both for callers that need the layout. */\nexport function prismaSvg(\n input: PrismaInput,\n opts: PrismaRenderOpts = {},\n): { svg: string; layout: PrismaLayout } {\n const layout = computePrismaLayout(input, opts);\n const svg = prismaLayoutSvg(layout, opts);\n return { svg, layout };\n}\n","// UML class diagram input model — declared facts only.\n// compasso does NOT compute UML positions: the caller supplies (col, row) for\n// every class. packGrid guarantees zero box overlap; edges route in box-free\n// gutter channels. This is the honest, overlap-provable answer for a general\n// graph where auto-layout cannot be proven overlap-free (see docs/design/prisma-uml.md).\n\n// ── Visibility ────────────────────────────────────────────────────────────────\n\nexport const UML_VISIBILITIES = [\"public\", \"private\", \"protected\", \"package\"] as const;\nexport type UmlVisibility = (typeof UML_VISIBILITIES)[number];\n\n/** Universal OMG notation glyphs — NOT localized. */\nexport const UML_VIS_GLYPH: Record<UmlVisibility, string> = {\n public: \"+\",\n private: \"-\",\n protected: \"#\",\n package: \"~\",\n};\n\n// ── Feature (attribute / operation line) ──────────────────────────────────────\n\nexport interface UmlFeature {\n /** null = no visibility marker drawn. */\n visibility: UmlVisibility | null;\n /**\n * Verbatim signature text — drawn AS GIVEN, NEVER parsed.\n * e.g. \"name: String\" / \"getName(): String\".\n */\n text: string;\n /** When true, a <line> underline is drawn under the text run. */\n isStatic?: boolean;\n}\n\n// ── Class ─────────────────────────────────────────────────────────────────────\n\nexport interface UmlClass {\n id: number;\n /** Verbatim name; italic rendering when isAbstract. */\n name: string;\n /**\n * «interface»/«enumeration»/«abstract» line above name; verbatim, drawn only\n * when declared (not null). Caller includes the guillemets when desired.\n */\n stereotype: string | null;\n isAbstract?: boolean;\n attributes: UmlFeature[];\n operations: UmlFeature[];\n /**\n * DECLARED grid cell (the escape hatch for a general graph).\n * Non-negative integers required on every class.\n */\n col: number;\n row: number;\n /** <title> override. */\n title?: string;\n}\n\n// ── Relationship ──────────────────────────────────────────────────────────────\n\nexport const UML_RELATIONSHIPS = [\n \"association\",\n \"directed-association\",\n \"aggregation\",\n \"composition\",\n \"generalization\",\n \"realization\",\n \"dependency\",\n] as const;\nexport type UmlRelationshipKind = (typeof UML_RELATIONSHIPS)[number];\n\nexport interface UmlRelationship {\n id: number;\n kind: UmlRelationshipKind;\n /** Direction per-kind via RELATION_GLYPHS; generalization: source=subclass, target=superclass. */\n sourceId: number;\n targetId: number;\n /** Verbatim multiplicity strings — NEVER parsed/validated. null = none drawn. */\n sourceMultiplicity: string | null;\n targetMultiplicity: string | null;\n /** Verbatim role names at the ends. null = none drawn. */\n sourceRole: string | null;\n targetRole: string | null;\n /** Verbatim relationship name drawn at mid-edge. null = none drawn. */\n label: string | null;\n /** <title> override. */\n title?: string;\n}\n\n// ── Glyph map ─────────────────────────────────────────────────────────────────\n\n/**\n * The five distinct glyph shapes used for UML relationship ends.\n * \"none\" = plain line terminus (no arrowhead or decoration).\n */\nexport type GlyphKind =\n | \"none\"\n | \"open-arrow\"\n | \"hollow-triangle\"\n | \"hollow-diamond\"\n | \"solid-diamond\";\n\n/**\n * RELATION_GLYPHS — the single source of truth mapping a relationship kind to\n * its standard UML end decorations and line style.\n * The caller picks a KIND and the standard glyph follows — they cannot mis-state\n * a glyph (the honesty-rule encoding).\n *\n * Glyph placement convention:\n * - aggregation/composition: diamond at the WHOLE (source side)\n * - generalization/realization: triangle at the SUPERTYPE (target side)\n * - directed-association/dependency: open-arrow at the TARGET\n */\nexport const RELATION_GLYPHS: Record<\n UmlRelationshipKind,\n { sourceEnd: GlyphKind; targetEnd: GlyphKind; line: \"solid\" | \"dashed\" }\n> = {\n association: { sourceEnd: \"none\", targetEnd: \"none\", line: \"solid\" },\n \"directed-association\": { sourceEnd: \"none\", targetEnd: \"open-arrow\", line: \"solid\" },\n aggregation: { sourceEnd: \"hollow-diamond\", targetEnd: \"none\", line: \"solid\" },\n composition: { sourceEnd: \"solid-diamond\", targetEnd: \"none\", line: \"solid\" },\n generalization: { sourceEnd: \"none\", targetEnd: \"hollow-triangle\", line: \"solid\" },\n realization: { sourceEnd: \"none\", targetEnd: \"hollow-triangle\", line: \"dashed\" },\n dependency: { sourceEnd: \"none\", targetEnd: \"open-arrow\", line: \"dashed\" },\n};\n\n// ── Input ─────────────────────────────────────────────────────────────────────\n\nexport interface UmlInput {\n classes: UmlClass[];\n relationships: UmlRelationship[];\n}\n","// UML class-diagram validation — REJECT-WITH-CODES, never repair.\n// A class diagram is an authoritative model artifact; drawing a structurally\n// invalid diagram misstates the model. Three-phase pipeline:\n// (0) duplicate-id — short-circuit. First-occurrence-wins maps make every\n// downstream rule depend on array order; we report ONLY duplicates and stop.\n// (1) reference / semantic rules: unknown-endpoint, negative-cell, cell-collision,\n// self-generalization.\n// (2) graph rules (generalization-cycle) — gated on duplicate-id + unknown-endpoint\n// (phantom/ambiguous nodes corrupt traversal). Self-association is LEGAL and\n// drawn as a side-loop — it is NEVER a graph error here.\n//\n// Empty input (no classes AND no relationships) → valid empty SVG, never throws.\n\nimport type { UmlClass, UmlInput, UmlRelationship, UmlRelationshipKind } from \"./types\";\n\nexport type UmlIssueCode =\n | \"duplicate-id\"\n | \"unknown-endpoint\"\n | \"negative-cell\"\n | \"cell-collision\"\n | \"self-generalization\"\n | \"generalization-cycle\"\n | \"too-many-side-edges\";\n\nexport interface UmlIssue {\n code: UmlIssueCode;\n message: string;\n}\n\nexport class UmlValidationError extends Error {\n readonly issues: readonly UmlIssue[];\n constructor(issues: readonly UmlIssue[]) {\n super(`invalid UML class diagram: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"UmlValidationError\";\n this.issues = issues;\n }\n}\n\nfunction sortIssues(issues: readonly UmlIssue[]): readonly UmlIssue[] {\n const unique = new Map<string, UmlIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code\n ? a.code < b.code\n ? -1\n : 1\n : a.message < b.message\n ? -1\n : a.message > b.message\n ? 1\n : 0,\n );\n}\n\nconst GRAPH_BLOCKING: ReadonlySet<UmlIssueCode> = new Set<UmlIssueCode>([\n \"duplicate-id\",\n \"unknown-endpoint\",\n]);\n\n/** Inheritance-only edge kinds: the cycle check only walks these. */\nconst INHERITANCE_KINDS: ReadonlySet<UmlRelationshipKind> = new Set<UmlRelationshipKind>([\n \"generalization\",\n \"realization\",\n]);\n\n/**\n * Computes ALL validation issues for the input, deduplicated and sorted deterministically.\n * Empty input → []. Empty SVG is always valid.\n */\nexport function umlIssues(input: UmlInput): readonly UmlIssue[] {\n if (input.classes.length === 0 && input.relationships.length === 0) return [];\n\n const issues: UmlIssue[] = [];\n const push = (code: UmlIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── Phase 0: duplicate ids (classes namespace + relationships namespace) ─────\n const classById = new Map<number, UmlClass>();\n const dupClassIds = new Set<number>();\n for (const c of input.classes) {\n if (classById.has(c.id)) dupClassIds.add(c.id);\n else classById.set(c.id, c);\n }\n for (const id of [...dupClassIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate class id ${id}`);\n }\n\n const relById = new Map<number, UmlRelationship>();\n const dupRelIds = new Set<number>();\n for (const r of input.relationships) {\n if (relById.has(r.id)) dupRelIds.add(r.id);\n else relById.set(r.id, r);\n }\n for (const id of [...dupRelIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate relationship id ${id}`);\n }\n\n // Duplicate ids short-circuit: downstream rules depend on first-occurrence-wins maps.\n if (issues.length > 0) return sortIssues(issues);\n\n const rels = [...relById.values()].sort((a, b) => a.id - b.id);\n\n // ── Phase 1: reference / semantic rules ──────────────────────────────────────\n\n // unknown-endpoint\n for (const r of rels) {\n if (!classById.has(r.sourceId)) {\n push(\"unknown-endpoint\", `relationship ${r.id} sourceId ${r.sourceId} is not a declared class`);\n }\n if (!classById.has(r.targetId)) {\n push(\"unknown-endpoint\", `relationship ${r.id} targetId ${r.targetId} is not a declared class`);\n }\n }\n\n // negative-cell: col/row must be non-negative integers (catches NaN, Infinity, floats)\n for (const c of [...classById.values()].sort((a, b) => a.id - b.id)) {\n if (!Number.isInteger(c.col) || c.col < 0) {\n push(\"negative-cell\", `class ${c.id} col ${c.col} must be a non-negative integer`);\n }\n if (!Number.isInteger(c.row) || c.row < 0) {\n push(\"negative-cell\", `class ${c.id} row ${c.row} must be a non-negative integer`);\n }\n }\n\n // cell-collision: two classes same (col, row)\n const cellKey = (c: UmlClass): string => `${c.col},${c.row}`;\n const cellToClasses = new Map<string, number[]>();\n for (const c of [...classById.values()].sort((a, b) => a.id - b.id)) {\n const key = cellKey(c);\n const arr = cellToClasses.get(key) ?? [];\n arr.push(c.id);\n cellToClasses.set(key, arr);\n }\n for (const [key, ids] of [...cellToClasses.entries()].sort()) {\n if (ids.length > 1) {\n push(\n \"cell-collision\",\n `classes ${ids.sort((a, b) => a - b).join(\", \")} all declare cell (${key})`,\n );\n }\n }\n\n // self-generalization: generalization/realization from a class to itself.\n // Self-ASSOCIATION is LEGAL (reflexive reference) and never flagged here.\n for (const r of rels) {\n if (\n (r.kind === \"generalization\" || r.kind === \"realization\") &&\n r.sourceId === r.targetId\n ) {\n push(\n \"self-generalization\",\n `relationship ${r.id} is a ${r.kind} from class ${r.sourceId} to itself`,\n );\n }\n }\n\n // ── Phase 2: generalization-cycle — gated on GRAPH_BLOCKING codes ────────────\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n // Adjacency: source → target over generalization/realization only.\n // Self-associations (sourceId === targetId) are already legal; self-generalizations\n // were caught above. The DFS skips self-edges defensively.\n const inheritanceChildren = new Map<number, number[]>();\n for (const r of rels) {\n if (!INHERITANCE_KINDS.has(r.kind)) continue;\n if (r.sourceId === r.targetId) continue; // self-generalization already flagged\n const arr = inheritanceChildren.get(r.sourceId) ?? [];\n arr.push(r.targetId);\n inheritanceChildren.set(r.sourceId, arr);\n }\n for (const arr of inheritanceChildren.values()) arr.sort((a, b) => a - b);\n\n // Iterative coloring DFS — identical pattern to org-chart/validate.ts.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = inheritanceChildren.get(frame.id) ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\n \"generalization-cycle\",\n `generalization cycle: ${[...rotated, rotated[0]!].join(\" → \")}`,\n );\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n\n for (const c of [...classById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(c.id) ?? 0) === 0) dfs(c.id);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws UmlValidationError (carrying ALL issues) when the input is invalid. */\nexport function validateUml(input: UmlInput): void {\n const issues = umlIssues(input);\n if (issues.length > 0) throw new UmlValidationError(issues);\n}\n\n/**\n * Build a `too-many-side-edges` issue. A box side can hold only finitely many incident-edge\n * ports: the router spreads N ports along the side as a symmetric zigzag of pitch `pitch`, so the\n * outermost port sits `floor(N/2)·pitch` from the side midpoint (up AND down). Beyond the side's\n * CLEAR vertical band the outermost port's stub/glyph spills past the box and crosses a neighbour —\n * a segment-through-box / glyph-box hit. N arrowhead glyphs simply cannot fit on one short box\n * edge; the honest, house-consistent answer is to REJECT (mirroring org-chart's\n * `too-many-matrix-edges`), never to mis-draw. The message names the class + side + observed\n * count + capacity so the author knows which fan-in to split. `boxH`/`rowGap`/`pitch` are the\n * measured geometry the router uses, so the cap is the TRUE clean capacity for THAT box.\n *\n * The clear band is `boxH/2 + rowGap/2 − glyphHalf`:\n * - `boxH/2` — the box's own half-height (ports start on the box edge).\n * - `rowGap/2` — only HALF the box-free row gutter, NOT the whole gap. The gutter above (and\n * below) the box is SHARED with the neighbouring row's box, which may ALSO fan in on the same\n * side and spill its own ports DOWN (resp. up) into that same gutter. If each box could claim\n * the WHOLE gutter, two adjacent boxes' outermost ports/glyphs would meet in the middle of the\n * shared gutter (a glyph-glyph hit between edges targeting DIFFERENT boxes — the residual #4\n * class). Capping each box at half the gutter guarantees the two spills meet at most at the\n * gutter midline, never overlapping.\n * - `−glyphHalf` — the outermost port carries a glyph whose AABB extends `glyphHalf` PAST the\n * port-y; reserving it keeps the glyph (not just the port stub) inside the half-gutter, so it\n * can never dip across the midline into the neighbour's half (nor into a full-column-wide\n * neighbour box).\n * floor(N/2) ≤ K ⇒ N ≤ 2K+1, with K = floor((boxH/2 + rowGap/2 − glyphHalf) / pitch). K is\n * clamped ≥ 0 so a sub-glyph box still admits the single centre port (offset 0).\n */\nexport function sideCapacity(boxH: number, rowGap: number, pitch: number, glyphHalf: number): number {\n const clear = boxH / 2 + rowGap / 2 - glyphHalf;\n const k = Math.max(0, Math.floor(clear / pitch));\n return 2 * k + 1;\n}\n\n/** Construct the `too-many-side-edges` issue for an over-capacity box side. */\nexport function sideCapacityIssue(\n classId: number,\n side: \"left\" | \"right\",\n count: number,\n capacity: number,\n): UmlIssue {\n return {\n code: \"too-many-side-edges\",\n message: `class ${classId} has ${count} edges on its ${side} side — at most ${capacity} fit without a port stub spilling through a neighbouring box`,\n };\n}\n","// UML class-diagram display vocabularies. Split into TitleLabels (woven into <title>s\n// by the layout) and SvgLabels (drawn by the emitter: legend, aria). English defaults\n// here; pt-BR in src/locales/pt-br.ts (anti-drift import pattern in tests).\n\nimport type { UmlRelationshipKind, UmlVisibility } from \"./types\";\n\n/** Labels woven into element/box <title>s by the LAYOUT (verbatim-preserving). */\nexport interface UmlTitleLabels {\n /** Display name for each relationship kind (in <title>s). */\n kinds: Record<UmlRelationshipKind, string>;\n /** Display name for each visibility level (in feature <title>s). */\n visibilities: Record<UmlVisibility, string>;\n}\n\nexport const UML_TITLE_LABELS_EN: UmlTitleLabels = {\n kinds: {\n association: \"association\",\n \"directed-association\": \"directed association\",\n aggregation: \"aggregation\",\n composition: \"composition\",\n generalization: \"generalization\",\n realization: \"realization\",\n dependency: \"dependency\",\n },\n visibilities: {\n public: \"public\",\n private: \"private\",\n protected: \"protected\",\n package: \"package\",\n },\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface UmlSvgLabels {\n legend: Record<UmlRelationshipKind, string>;\n ariaLabel: string;\n}\n\nexport const UML_SVG_LABELS_EN: UmlSvgLabels = {\n legend: {\n association: \"Association\",\n \"directed-association\": \"Directed association\",\n aggregation: \"Aggregation\",\n composition: \"Composition\",\n generalization: \"Generalization\",\n realization: \"Realization\",\n dependency: \"Dependency\",\n },\n ariaLabel: \"UML class diagram\",\n};\n","// UML class-diagram layout — DECLARED-POSITION model.\n//\n// The caller supplies (col, row) for every class. packGrid guarantees zero box overlap.\n// Edges route in box-free gutter channels between grid cells; every routed segment runs\n// on a gutter centerline (never inside a cell) or is a port stub terminating ON the box\n// perimeter, so segment-through-box-interior is provably zero.\n//\n// ── The routing thesis (uniform across ALL edge cases) ───────────────────────\n// An edge NEVER transits cell airspace. It:\n// 1. exits its source box on a SIDE (left or right) into the ADJACENT vertical gutter,\n// 2. travels ONLY on gutter centerlines (vertical gutters between columns, horizontal\n// gutters between rows), turning only at gutter intersections,\n// 3. enters the target on a SIDE (left or right) from an adjacent vertical gutter.\n// Because every box exits/enters horizontally, the terminal (glyph-bearing) segment is\n// ALWAYS normal to a vertical side → the glyph faces left/right and can never be\n// collapsed or rotated by waypoint dedup. The column's/row's own centerline is NEVER a\n// transit lane (a third box may sit on it); only the box-free gutters between cells are.\n//\n// Concrete route (3 gutters, degenerating cleanly):\n// src --H stub--> srcV gutter --V--> H gutter --H--> tgtV gutter --V--> H stub--> tgt\n// For same-column endpoints srcV == tgtV (one vertical gutter beside the column, box-free\n// for the whole column height), so the route runs that single gutter past the intervening\n// box. For same-row endpoints the H gutter sits above/below the shared row.\n//\n// Key invariants (asserted by test/uml/_overlap-harness.ts on an adversarial + fuzzed corpus):\n// - packGrid → disjoint cell AABBs → zero box-box overlap (2-D packSubtree induction).\n// - Every transit leg lies on a gutter centerline (offset by a lane within the box-free\n// strip) → segment-through-box-interior = 0; terminal stubs end on the box perimeter.\n// - allocateLanes per gutter strip (around reserved text AABBs) → no collinear-double-draw.\n// - Per-relationship-id port slots on each side, spaced ≥ max(glyph extent)+2 → parallel\n// edges and their glyph AABBs never overlap.\n// - All segments are axis-aligned → non-orthogonal = 0.\n//\n// Self-association: an orthogonal U in the cell's own right-margin lane, its glyph-bearing\n// end stopped short by glyphInset so the diamond sits OUTSIDE the box; a per-relationship-id\n// lane key keeps parallel self-loops on distinct offsets.\n\nimport {\n allocateLanes,\n estimateTextWidth,\n measureCompartmentBox,\n packGrid,\n type CompartmentMetrics,\n type GridResult,\n type Point,\n} from \"../core\";\nimport { UML_TITLE_LABELS_EN, type UmlTitleLabels } from \"./labels\";\nimport {\n sideCapacity,\n sideCapacityIssue,\n UmlValidationError,\n validateUml,\n type UmlIssue,\n} from \"./validate\";\nimport {\n glyphInset,\n GLYPH_TRI_HALF,\n type Dir,\n} from \"../core\";\nimport {\n RELATION_GLYPHS,\n UML_VIS_GLYPH,\n type GlyphKind,\n type UmlClass,\n type UmlFeature,\n type UmlInput,\n type UmlRelationship,\n} from \"./types\";\n\nexport {\n UmlValidationError,\n umlIssues,\n validateUml,\n sideCapacity,\n sideCapacityIssue,\n type UmlIssue,\n type UmlIssueCode,\n} from \"./validate\";\nexport type { Point };\n\n// ── Geometry constants ───────────────────────────────────────────────────────\n\n/** Canvas padding on all sides. */\nexport const UML_PADDING = 32;\n/** Horizontal gutter between adjacent columns. Box-free channel. */\nexport const UML_COL_GAP = 64;\n/** Vertical gutter between adjacent rows. Box-free channel. */\nexport const UML_ROW_GAP = 56;\n/** Horizontal padding inside a box (each side). */\nexport const UML_BOX_PAD_X = 10;\n/** Vertical padding inside a box (each side). */\nexport const UML_BOX_PAD_Y = 8;\n/** Height of a single text line inside a box. */\nexport const UML_LINE_H = 15;\n/** Minimum box width. */\nexport const UML_MIN_BOX_W = 120;\n/** Font size for the name/stereotype compartment. */\nexport const UML_NAME_FONT = 12;\n/** Font size for attributes and operations. */\nexport const UML_FEAT_FONT = 11;\n/** Padding below/above compartment dividers (reserved for future use; geometry uses 0). */\nexport const UML_SEP_PAD = 4;\n/** Pitch between adjacent port offsets on the same box side. */\nexport const UML_PORT_PITCH = 12;\n/** Width of the self-association side-loop lane (right margin). */\nexport const UML_SELF_LOOP_W = 28;\n/** Font size for edge labels (multiplicity, role, mid-edge label). */\nexport const UML_LABEL_FONT = 10;\n\n// ── Namespaced element-id blocks ─────────────────────────────────────────────\n// One block per element kind; every data-edge-id traces back to its source.\n/** Routing elements (inter-cell routed edge polylines). */\nexport const UML_ASSOC_ROUTE_BASE = 1_000_000;\n/** Glyph polygons (decoration, harness-excluded). */\nexport const UML_GLYPH_BASE = 2_000_000;\n/** Self-association loops. */\nexport const UML_SELF_LOOP_BASE = 3_000_000;\n\n// ── Internal routing constants ────────────────────────────────────────────────\n\n/**\n * Minimum length of a glyph-bearing terminal stub, in addition to the glyph inset.\n * Guarantees the terminal segment is long enough that no dedup can collapse it and\n * the glyph (which sits between the stub end and the box) is fully accounted. Must be\n * ≥ 1 so the stub never degenerates to a point.\n */\nconst MIN_TERMINAL_STUB = 4;\n\n// ── Layout types ──────────────────────────────────────────────────────────────\n\n/** A positioned UML class box with its measurement metrics. */\nexport interface UmlBoxNode {\n classId: number;\n /** Box center x (from packGrid). */\n cx: number;\n /** Box center y (from packGrid). */\n cy: number;\n /** Box left edge = cx - boxW/2. */\n boxW: number;\n /** Box height. */\n boxH: number;\n /** Compartment metrics (3 compartments: header / attributes / operations). */\n metrics: CompartmentMetrics;\n /** Display title (from UmlClass.title or computed). */\n title: string;\n /** Grid column index. */\n col: number;\n /** Grid row index. */\n row: number;\n}\n\n/** A small reserved text AABB (multiplicity / role / mid-edge label). */\nexport interface UmlTextBox {\n relId: number;\n /** Which text this is (for the emitter to draw the right string at the same anchor). */\n slot: \"src-mult\" | \"src-role\" | \"tgt-mult\" | \"tgt-role\" | \"label\";\n /** Verbatim string. */\n text: string;\n /** Top-left x of the reserved AABB. */\n x: number;\n /** Top-left y of the reserved AABB. */\n y: number;\n w: number;\n h: number;\n /** Text anchor: where the emitter places x (left by default). */\n anchor: \"start\" | \"middle\";\n}\n\n/** A routed edge element (inter-cell or self-loop). */\nexport interface UmlEdgeElement {\n edgeId: number;\n relId: number;\n /** Ordered waypoints forming the polyline. */\n points: Point[];\n kind: \"route\" | \"self-loop\";\n /** <title> text — the relationship's `title` override, else the LOCALIZED kind word. */\n title: string;\n}\n\n/** The complete positioned UML layout. */\nexport interface UmlLayout {\n nodes: UmlBoxNode[];\n elements: UmlEdgeElement[];\n /** Reserved text AABBs for multiplicity/role/label (drawn at these anchors by svg.ts). */\n textBoxes: UmlTextBox[];\n /** Total canvas width (before legend). */\n canvasW: number;\n /** Total canvas height (before legend). */\n canvasH: number;\n /** The grid result (column/row widths and heights, for harness). */\n grid: GridResult;\n /** colX[c] = left edge of column c (derived from grid + padding). */\n colX: number[];\n /** rowY[r] = top edge of row r (derived from grid + padding). */\n rowY: number[];\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n/** Feature line formatted with visibility prefix. */\nfunction featureLine(f: UmlFeature): string {\n const prefix = f.visibility !== null ? UML_VIS_GLYPH[f.visibility] + \" \" : \"\";\n return prefix + f.text;\n}\n\n/**\n * Measures the three-compartment box for a UML class.\n * Compartment 0: stereotype (if any) + name lines.\n * Compartment 1: attributes (features).\n * Compartment 2: operations (features).\n */\nfunction measureClass(cls: UmlClass): CompartmentMetrics {\n const nameLines: string[] = [];\n if (cls.stereotype !== null) nameLines.push(cls.stereotype);\n nameLines.push(cls.name);\n\n const attrLines = cls.attributes.map(featureLine);\n const opLines = cls.operations.map(featureLine);\n\n return measureCompartmentBox(\n [\n { lines: nameLines, font: UML_NAME_FONT },\n { lines: attrLines, font: UML_FEAT_FONT },\n { lines: opLines, font: UML_FEAT_FONT },\n ],\n {\n padX: UML_BOX_PAD_X,\n padY: UML_BOX_PAD_Y,\n lineH: UML_LINE_H,\n minW: UML_MIN_BOX_W,\n sepPad: UML_SEP_PAD,\n },\n );\n}\n\n/** Compute the left/right/top/bottom edge of a box. */\nfunction boxEdges(node: UmlBoxNode): { left: number; right: number; top: number; bottom: number } {\n const left = round(node.cx - node.boxW / 2);\n const right = round(left + node.boxW);\n const top = round(node.cy - node.boxH / 2);\n const bottom = round(top + node.boxH);\n return { left, right, top, bottom };\n}\n\n/**\n * Compute the inset for a glyph end on a given side.\n * Returns 0 for \"none\" glyphs (no inset needed).\n */\nfunction glyphInsetForKind(gk: GlyphKind): number {\n switch (gk) {\n case \"none\": return 0;\n case \"open-arrow\": return glyphInset(\"right\", \"arrow\");\n case \"hollow-triangle\": return glyphInset(\"right\", \"triangle\");\n case \"hollow-diamond\":\n case \"solid-diamond\": return glyphInset(\"right\", \"diamond\");\n }\n}\n\n/**\n * Largest glyph perpendicular half-extent over all kinds (the triangle, half = 8). Two\n * glyph AABBs centered on their ports don't overlap iff their port separation ≥ h1 + h2;\n * spacing every port on a side by ≥ 2·MAX + 2 covers the worst case (two triangles) and\n * keeps glyph AABBs apart regardless of which kinds share the side (design line 205).\n */\nconst MAX_GLYPH_HALF = GLYPH_TRI_HALF;\n/** Per-side port pitch: clears the largest glyph AABB on either neighbour. */\nconst GLYPH_SLOT_PITCH = Math.max(UML_PORT_PITCH, MAX_GLYPH_HALF * 2 + 2);\n\n/**\n * Port offset for a port slot, spread around the side midpoint as a zigzag:\n * slot 0 → 0, slot 1 → +pitch, slot 2 → −pitch, slot 3 → +2·pitch, …\n */\nfunction portOffset(slotIndex: number, slotSize: number): number {\n if (slotIndex === 0) return 0;\n const sign = slotIndex % 2 === 1 ? 1 : -1;\n const dist = Math.ceil(slotIndex / 2);\n return sign * dist * slotSize;\n}\n\n/**\n * Center of a vertical SIDE (left/right) of a box, offset by `dy` along the side.\n * Ports always sit on a vertical side so the terminal stub is horizontal.\n */\nfunction sidePort(node: UmlBoxNode, side: \"left\" | \"right\", dy: number): Point {\n const { left, right } = boxEdges(node);\n const x = side === \"right\" ? right : left;\n return { x, y: round(node.cy + dy) };\n}\n\n/** Left edge (right face of the left box) of the vertical gutter right of `colIdx`. */\nfunction vGutterLeft(colIdx: number, colX: number[], grid: GridResult): number {\n return round(colX[colIdx]! + grid.colW[colIdx]!);\n}\n\n/** Margin from a gutter wall to the first lane (keeps lanes strictly inside the gutter). */\nconst V_GUTTER_MARGIN = 6;\n\n/** Centerline y of the horizontal gutter BELOW row `rowIdx`. */\nfunction horizontalGutterY(rowIdx: number, rowY: number[], grid: GridResult): number {\n return round(rowY[rowIdx]! + grid.rowH[rowIdx]! + UML_ROW_GAP / 2);\n}\n\n/** Move a point `dist` units in the given cardinal direction. */\nfunction moveAlongDir(p: Point, dir: Dir, dist: number): Point {\n switch (dir) {\n case \"right\": return { x: round(p.x + dist), y: p.y };\n case \"left\": return { x: round(p.x - dist), y: p.y };\n case \"down\": return { x: p.x, y: round(p.y + dist) };\n case \"up\": return { x: p.x, y: round(p.y - dist) };\n }\n}\n\n/**\n * Remove only INTERIOR collinear/duplicate points (three consecutive points on the\n * same axis collapse to two; exact duplicates collapse). The FIRST and LAST points\n * (the glyph-bearing terminals) are NEVER dropped, so a terminal stub can never be\n * collapsed and the glyph direction is always the side normal.\n */\nfunction simplifyWaypoints(pts: Point[]): Point[] {\n // First drop exact consecutive duplicates.\n const dedup: Point[] = [pts[0]!];\n for (let i = 1; i < pts.length; i++) {\n const prev = dedup[dedup.length - 1]!;\n const cur = pts[i]!;\n if (Math.abs(cur.x - prev.x) > 1e-6 || Math.abs(cur.y - prev.y) > 1e-6) dedup.push(cur);\n }\n if (dedup.length <= 2) return dedup;\n // Drop interior points that are collinear with their neighbours (keep endpoints).\n const out: Point[] = [dedup[0]!];\n for (let i = 1; i < dedup.length - 1; i++) {\n const a = out[out.length - 1]!;\n const b = dedup[i]!;\n const c = dedup[i + 1]!;\n const abH = Math.abs(a.y - b.y) <= 1e-6;\n const bcH = Math.abs(b.y - c.y) <= 1e-6;\n const abV = Math.abs(a.x - b.x) <= 1e-6;\n const bcV = Math.abs(b.x - c.x) <= 1e-6;\n if ((abH && bcH) || (abV && bcV)) continue; // b is collinear → skip\n out.push(b);\n }\n out.push(dedup[dedup.length - 1]!);\n return out;\n}\n\n// ── Route planning + two-pass lane allocation ────────────────────────────────────\n//\n// The router runs in TWO passes so lanes pack tightly (only y-/x-overlapping legs get\n// distinct lanes, via core/allocateLanes) and never collapse together at a hard clamp:\n// Pass A — build a RoutePlan per edge: exit/entry sides, the two vertical-gutter\n// columns, the source/target port y's, and the horizontal-gutter row.\n// Lane allocation — per (vertical gutter, side) allocate lanes by the leg's y-interval;\n// per horizontal gutter allocate lanes by the H-leg's x-interval.\n// Pass B — assemble the final waypoints from the allocated lane coordinates.\n\n/** Per-edge routing skeleton (Pass A output). */\ninterface RoutePlan {\n rel: UmlRelationship;\n srcNode: UmlBoxNode;\n tgtNode: UmlBoxNode;\n srcSide: \"left\" | \"right\";\n tgtSide: \"left\" | \"right\";\n srcVCol: number; // vertical gutter index (gutter right of this column)\n tgtVCol: number;\n srcInset: number;\n tgtInset: number;\n srcPortY: number;\n tgtPortY: number;\n /** Horizontal-gutter selector: a row gutter index, or a special padding band key. */\n hKind: \"row\" | \"pad-top\";\n hRow: number;\n /**\n * A self-association is a degenerate route: both ports on the SAME box's right side, the\n * connecting leg a single vertical run in the right gutter (ONE V-lane shared by both\n * arms). Routed through the SAME gutter-lane allocator as ordinary edges so its segments\n * are spaced from every route in that gutter (no shared-gutter overlap).\n */\n isSelfLoop: boolean;\n /** Filled by lane allocation (Pass B reads these). */\n srcVx: number;\n tgtVx: number;\n hY: number;\n}\n\n/** Choose exit/entry sides + the two adjacent vertical gutters for an edge. */\nfunction chooseSides(\n srcNode: UmlBoxNode,\n tgtNode: UmlBoxNode,\n maxCol: number,\n): { srcSide: \"left\" | \"right\"; tgtSide: \"left\" | \"right\"; srcVCol: number; tgtVCol: number } {\n const sc = srcNode.col;\n const tc = tgtNode.col;\n if (tc > sc) return { srcSide: \"right\", tgtSide: \"left\", srcVCol: sc, tgtVCol: tc - 1 };\n if (tc < sc) return { srcSide: \"left\", tgtSide: \"right\", srcVCol: sc - 1, tgtVCol: tc };\n // Same column: ONE gutter beside the column (box-free for the whole column height).\n // Prefer the right gutter; fall back to the left gutter for the last (rightmost) column;\n // for a SINGLE-column diagram (no inter-column gutter on either side) route through the\n // open RIGHT MARGIN (gutter index = maxCol; right of the last column, box-free by padding).\n if (sc < maxCol) return { srcSide: \"right\", tgtSide: \"right\", srcVCol: sc, tgtVCol: sc };\n if (sc > 0) return { srcSide: \"left\", tgtSide: \"left\", srcVCol: sc - 1, tgtVCol: sc - 1 };\n return { srcSide: \"right\", tgtSide: \"right\", srcVCol: sc, tgtVCol: sc }; // sc === 0 === maxCol → right margin\n}\n\n/** Base centerline y of the horizontal gutter a plan uses (before its lane offset). */\nfunction hBaseY(plan: RoutePlan, rowY: number[], grid: GridResult): number {\n if (plan.hKind === \"pad-top\") return round(UML_PADDING / 2);\n return horizontalGutterY(plan.hRow, rowY, grid);\n}\n\n/** The box-free y-extent [lo, hi] of the horizontal gutter a plan transits. */\nfunction hBandBounds(plan: RoutePlan, rowY: number[], grid: GridResult): { lo: number; hi: number } {\n if (plan.hKind === \"pad-top\") return { lo: 0, hi: round(rowY[0] ?? UML_PADDING) };\n const lo = round(rowY[plan.hRow]! + grid.rowH[plan.hRow]!);\n const hi = round(rowY[plan.hRow + 1]!);\n return { lo, hi };\n}\n\n/** EPS for \"two horizontal runs share the same y\" / \"two lanes coincide\". Two lanes farther\n * apart than this never read as collinear under the harness (whose y-EPS is far smaller). */\nconst LANE_EPS = 0.5;\n/** EPS for \"two horizontal runs overlap in x\". Kept WELL below the harness's overlap EPS so the\n * allocator never under-counts an x-overlap the harness would flag (any real overlap conflicts). */\nconst X_OVERLAP_EPS = 1e-4;\n\n/**\n * A horizontal run that participates in per-gutter lane de-confliction. `lo`/`hi` are its\n * x-interval; a PINNED run (a port stub) sits at a fixed `y` that the floating main legs must\n * avoid; a FLOATING run (a main gutter leg) has `y === null` and is assigned one by the\n * allocator. Two horizontal runs collinear-overlap iff they share a y (±LANE_EPS) AND their\n * x-intervals overlap — exactly what `collinearOverlaps` flags — so the allocator's job is to\n * give every floating run a y distinct from every pinned/other-floating run it overlaps in x.\n */\ninterface HRun {\n lo: number;\n hi: number;\n /** Fixed y for a pinned stub; null for a floating main leg (assigned by allocateHorizontal). */\n y: number | null;\n /** Setter called with the resolved y (no-op for pinned runs). */\n set: (y: number) => void;\n}\n\n/**\n * Assign every FLOATING run a y inside the gutter band [base − usableHalf, base + usableHalf]\n * such that NO two horizontal runs (floating-vs-floating OR floating-vs-pinned port stub) ever\n * share a y (±LANE_EPS) while overlapping in x — the per-gutter half of the no-collinear-double-\n * draw invariant. Pinned stubs keep their fixed y (a terminal must land ON its port); only the\n * box-free main legs move.\n *\n * Candidate y's are evenly spaced across the band; the count is `floatCount + pinnedInBand + 1`.\n * As long as the resulting spacing `2·usableHalf / candidateCount` exceeds `2·LANE_EPS`, every\n * already-placed run's y lands within LANE_EPS of AT MOST one candidate, so ≤ (float+pinned)\n * candidates are ever blocked and the `+1` guarantees a free track for each floating run (worst\n * case: every run mutually overlaps in x → a clique needing ≤ float+pinned distinct tracks). The\n * spacing condition holds for any realistic diagram (it would take ~50 horizontal runs sharing\n * ONE gutter band to violate it — far past any valid fan-out). Greedy by x-interval (the\n * `allocateLanes` discipline): each floating run takes the lowest candidate y not blocked by an\n * already-placed run it overlaps in x. Over-supplying tracks only ever tightens the spacing —\n * never exhausts the box-free band (the wide-but-correct mode).\n */\nfunction allocateHorizontal(runs: HRun[], base: number, usableHalf: number): void {\n const floating = runs.filter((r) => r.y === null);\n if (floating.length === 0) return;\n const pinned = runs.filter((r) => r.y !== null);\n // Candidate y tracks: strictly more than the max chromatic number of the conflict graph\n // (floating + pinned-in-band), so a free track always exists (spacing argument above).\n const trackCount = floating.length + pinned.length + 1;\n const candidates: number[] =\n trackCount <= 1 || usableHalf <= 0\n ? [base]\n : Array.from({ length: trackCount }, (_, k) =>\n round(base - usableHalf + ((k + 0.5) * (2 * usableHalf)) / trackCount),\n );\n // Placed runs accumulate (pinned first, so floating legs avoid the fixed stub y's).\n const placed: { lo: number; hi: number; y: number }[] = pinned.map((r) => ({ lo: r.lo, hi: r.hi, y: r.y! }));\n // Deterministic order: by x-interval start then span (mirrors allocateLanes' input order).\n const ordered = [...floating].sort((a, b) => a.lo - b.lo || a.hi - b.hi);\n for (const run of ordered) {\n let chosen = candidates[0]!;\n for (const cy of candidates) {\n const collides = placed.some(\n (q) => Math.abs(q.y - cy) <= LANE_EPS && Math.min(run.hi, q.hi) - Math.max(run.lo, q.lo) > X_OVERLAP_EPS,\n );\n if (!collides) {\n chosen = cy;\n break;\n }\n }\n run.set(chosen);\n placed.push({ lo: run.lo, hi: run.hi, y: chosen });\n }\n}\n\n/**\n * Apply the glyph inset to the polyline endpoints so the drawn LINE stops short of the\n * box edge by the glyph length (the polygon is drawn from the inset point to the port).\n * The terminal segment direction is preserved (horizontal), so the glyph faces the side\n * normal. Returns a new point array with the first/last points pulled inward by the inset.\n */\nfunction applyGlyphInsets(\n pts: Point[],\n srcInset: number,\n tgtInset: number,\n): Point[] {\n if (pts.length < 2) return pts;\n const out = pts.map((p) => ({ ...p }));\n if (srcInset > 0) {\n const p0 = out[0]!;\n const p1 = out[1]!;\n // Terminal stub is horizontal: inset along x toward p1.\n const dir: Dir = p1.x >= p0.x ? \"right\" : \"left\";\n out[0] = moveAlongDir(p0, dir, srcInset);\n }\n if (tgtInset > 0) {\n const pn = out[out.length - 1]!;\n const pm = out[out.length - 2]!;\n const dir: Dir = pm.x >= pn.x ? \"right\" : \"left\";\n out[out.length - 1] = moveAlongDir(pn, dir, tgtInset);\n }\n return out;\n}\n\n// ── Text AABB reservation ────────────────────────────────────────────────────\n\n/**\n * Reserve a small text AABB near a port (multiplicity/role) or mid-edge (label), so a\n * long role/label name is accounted for and never silently overflows a cell or a parallel\n * lane (design line 206). The AABBs are placed in the gutter beside the edge terminal; the\n * emitter draws each string at the SAME anchor the layout reserved.\n */\nfunction reserveTextBox(\n relId: number,\n slot: UmlTextBox[\"slot\"],\n text: string,\n anchorX: number,\n anchorY: number,\n anchor: \"start\" | \"middle\",\n): UmlTextBox {\n const w = round(estimateTextWidth(text, UML_LABEL_FONT));\n const h = round(UML_LABEL_FONT * 1.2);\n const x = anchor === \"middle\" ? round(anchorX - w / 2) : round(anchorX);\n // The baseline sits at anchorY + font*0.8 in the emitter; the AABB top is anchorY.\n const y = round(anchorY);\n return { relId, slot, text, x, y, w, h, anchor };\n}\n\n// ── Main layout function ──────────────────────────────────────────────────────\n\n/**\n * Computes the full positioned layout for a UML class diagram.\n *\n * @param input The validated UML diagram input.\n * @param labels Display vocabulary (defaults to English) — woven into <title>s by svg.ts\n * via the kind word; threaded through so localized titles are honored.\n */\nexport function computeUmlLayout(\n input: UmlInput,\n labels: UmlTitleLabels = UML_TITLE_LABELS_EN,\n): UmlLayout {\n validateUml(input);\n\n /** <title> for a relationship: its override, else the localized kind word. */\n const relTitle = (rel: UmlRelationship): string => rel.title ?? labels.kinds[rel.kind];\n\n // Empty input → minimal empty canvas.\n if (input.classes.length === 0) {\n return {\n nodes: [],\n elements: [],\n textBoxes: [],\n canvasW: UML_PADDING * 2,\n canvasH: UML_PADDING * 2,\n grid: { cellX: [], cellY: [], colW: [], rowH: [] },\n colX: [],\n rowY: [],\n };\n }\n\n // Sort classes/relationships by id for determinism.\n const classes = [...input.classes].sort((a, b) => a.id - b.id);\n const rels = [...input.relationships].sort((a, b) => a.id - b.id);\n\n // ── Step 1: Measure each class box ────────────────────────────────────────\n const metricsMap = new Map<number, CompartmentMetrics>();\n for (const cls of classes) metricsMap.set(cls.id, measureClass(cls));\n\n // ── Step 2: packGrid → cell centers ───────────────────────────────────────\n const gridCells = classes.map((cls) => ({\n col: cls.col,\n row: cls.row,\n w: metricsMap.get(cls.id)!.boxW,\n h: metricsMap.get(cls.id)!.boxH,\n }));\n const grid = packGrid(gridCells, { colGap: UML_COL_GAP, rowGap: UML_ROW_GAP });\n\n // Derive colX and rowY (left/top origins) from packGrid output.\n const colX: number[] = [];\n {\n let x = UML_PADDING;\n for (let c = 0; c < grid.colW.length; c++) {\n colX.push(round(x));\n x = round(x + grid.colW[c]! + UML_COL_GAP);\n }\n }\n const rowY: number[] = [];\n {\n let y = UML_PADDING;\n for (let r = 0; r < grid.rowH.length; r++) {\n rowY.push(round(y));\n y = round(y + grid.rowH[r]! + UML_ROW_GAP);\n }\n }\n\n // Build nodes with absolute positions.\n const nodeByClassId = new Map<number, UmlBoxNode>();\n const nodes: UmlBoxNode[] = [];\n for (const cls of classes) {\n const metrics = metricsMap.get(cls.id)!;\n const cx = round(colX[cls.col]! + grid.colW[cls.col]! / 2);\n const cy = round(rowY[cls.row]! + grid.rowH[cls.row]! / 2);\n const title =\n cls.title ??\n (cls.stereotype !== null ? `«${cls.stereotype}» ${cls.name}` : cls.name);\n const node: UmlBoxNode = {\n classId: cls.id,\n cx,\n cy,\n boxW: metrics.boxW,\n boxH: metrics.boxH,\n metrics,\n title,\n col: cls.col,\n row: cls.row,\n };\n nodes.push(node);\n nodeByClassId.set(cls.id, node);\n }\n\n // ── Step 3: Route edges (two-pass) ─────────────────────────────────────────\n\n const maxCol = grid.colW.length - 1;\n const maxRow = grid.rowH.length - 1;\n\n // ── Side-capacity guard (reject-with-code, never mis-draw) ──────────────────\n // Count how many ports each (class, side) would hold — using the EXACT side assignment the\n // router applies below (chooseSides for ordinary edges; both ports on the RIGHT for a\n // self-loop), so the cap matches the layout exactly. A side that holds more ports than its\n // measured CLEAR vertical band can fit at the glyph-safe port pitch is INFEASIBLE: the\n // outermost zigzag port spills past the box and its stub crosses the neighbour box (a\n // segment-through-box hit). We REJECT it (mirroring org-chart's too-many-matrix-edges)\n // rather than draw a lie. The capacity is derived per box from its OWN height + the box-free\n // row gutter, so it is ≥ the true clean capacity the router handles and never rejects a\n // feasible diagram (proven clean ≥10 on the worst-case short box).\n const sideCount = new Map<string, number>();\n const bumpSide = (classId: number, side: \"left\" | \"right\"): void => {\n const key = `${classId}:${side}`;\n sideCount.set(key, (sideCount.get(key) ?? 0) + 1);\n };\n for (const rel of rels) {\n const srcNode = nodeByClassId.get(rel.sourceId);\n const tgtNode = nodeByClassId.get(rel.targetId);\n if (!srcNode || !tgtNode) continue; // validation already caught unknown endpoints\n if (rel.sourceId === rel.targetId) {\n // Self-association: two arm ports, both on the source's RIGHT side.\n bumpSide(srcNode.classId, \"right\");\n bumpSide(srcNode.classId, \"right\");\n continue;\n }\n const { srcSide, tgtSide } = chooseSides(srcNode, tgtNode, maxCol);\n bumpSide(srcNode.classId, srcSide);\n bumpSide(tgtNode.classId, tgtSide);\n }\n {\n const capIssues: UmlIssue[] = [];\n for (const node of nodes) {\n const cap = sideCapacity(node.boxH, UML_ROW_GAP, GLYPH_SLOT_PITCH, MAX_GLYPH_HALF);\n for (const side of [\"left\", \"right\"] as const) {\n const count = sideCount.get(`${node.classId}:${side}`) ?? 0;\n if (count > cap) capIssues.push(sideCapacityIssue(node.classId, side, count, cap));\n }\n }\n if (capIssues.length > 0) {\n // Deterministic order: by classId then side (matches node order + the side tuple above).\n throw new UmlValidationError(capIssues);\n }\n }\n\n // Per-box, per-side port-slot counter. Ports on one side step by GLYPH_SLOT_PITCH so any\n // two glyph AABBs on a side stay apart (worst case: two triangles). Counter is bumped per\n // relationship, so parallel edges between the same pair land on distinct ports.\n const sidePortSlot = new Map<string, number>();\n const nextSidePort = (classId: number, side: \"left\" | \"right\"): number => {\n const key = `${classId}:${side}`;\n const idx = sidePortSlot.get(key) ?? 0;\n sidePortSlot.set(key, idx + 1);\n return idx;\n };\n\n const elements: UmlEdgeElement[] = [];\n const textBoxes: UmlTextBox[] = [];\n\n // ── Pass A: build a RoutePlan per edge (self-loops are degenerate plans) ───────\n const plans: RoutePlan[] = [];\n for (const rel of rels) {\n const srcNode = nodeByClassId.get(rel.sourceId);\n const tgtNode = nodeByClassId.get(rel.targetId);\n if (!srcNode || !tgtNode) continue; // validation already caught unknown endpoints\n\n const glyphs = RELATION_GLYPHS[rel.kind];\n const srcInset = glyphInsetForKind(glyphs.sourceEnd);\n const tgtInset = glyphInsetForKind(glyphs.targetEnd);\n\n if (rel.sourceId === rel.targetId) {\n // Self-association: both ports on the RIGHT side; both arms share ONE V-lane in the\n // right gutter of the class's own column. The two arm ports consume the right-side slot\n // counter (glyph AABBs spaced from every route glyph), and the shared V-lane is packed by\n // the gutter's V-allocator (spaced from every route in that gutter). For the last column\n // the \"right gutter\" is the open right margin (box-free by padding).\n const vCol = srcNode.col;\n const armDy1 = portOffset(nextSidePort(srcNode.classId, \"right\"), GLYPH_SLOT_PITCH);\n const armDy2 = portOffset(nextSidePort(srcNode.classId, \"right\"), GLYPH_SLOT_PITCH);\n plans.push({\n rel, srcNode, tgtNode,\n srcSide: \"right\", tgtSide: \"right\",\n srcVCol: vCol, tgtVCol: vCol,\n srcInset, tgtInset,\n srcPortY: round(srcNode.cy + armDy1),\n tgtPortY: round(srcNode.cy + armDy2),\n hKind: \"row\", hRow: 0, // unused for self-loops (no H-leg)\n isSelfLoop: true,\n srcVx: 0, tgtVx: 0, hY: 0,\n });\n continue;\n }\n\n const { srcSide, tgtSide, srcVCol, tgtVCol } = chooseSides(srcNode, tgtNode, maxCol);\n const srcPortDy = portOffset(nextSidePort(srcNode.classId, srcSide), GLYPH_SLOT_PITCH);\n const tgtPortDy = portOffset(nextSidePort(tgtNode.classId, tgtSide), GLYPH_SLOT_PITCH);\n\n // Horizontal-gutter selection.\n const sr = srcNode.row;\n const tr = tgtNode.row;\n let hKind: \"row\" | \"pad-top\";\n let hRow: number;\n if (sr !== tr) {\n hKind = \"row\"; hRow = Math.min(sr, tr);\n } else if (maxRow >= 1) {\n hKind = \"row\"; hRow = sr < maxRow ? sr : sr - 1;\n } else {\n hKind = \"pad-top\"; hRow = -1; // single-row diagram → box-free top padding band\n }\n\n plans.push({\n rel, srcNode, tgtNode,\n srcSide, tgtSide, srcVCol, tgtVCol,\n srcInset, tgtInset,\n srcPortY: round(srcNode.cy + srcPortDy),\n tgtPortY: round(tgtNode.cy + tgtPortDy),\n hKind, hRow,\n isSelfLoop: false,\n srcVx: 0, tgtVx: 0, hY: 0,\n });\n }\n\n // ── Lane allocation ───────────────────────────────────────────────────────────\n // Vertical legs: per (gutter col, side), allocate by the leg's y-interval. Only legs\n // that OVERLAP in y get distinct lanes (allocateLanes packs the rest), so the half-gutter\n // is never exhausted for non-conflicting legs.\n //\n // The V-leg's far end is its H-gutter lane y, which isn't fixed until H-lanes are packed\n // (a circular dependency). We break it CONSERVATIVELY: the V-leg interval extends to the\n // FAR WALL of the H-gutter band (hBase ± halfBand), which contains every possible H-lane\n // y. Over-reserving only ever yields MORE distinct lanes (a wider, still-correct diagram —\n // the accepted failure mode); it can never miss a real V-leg overlap.\n const hHalfBand = (p: RoutePlan): number =>\n p.hKind === \"pad-top\" ? round(UML_PADDING / 2) : round(UML_ROW_GAP / 2);\n // A V-leg item: its y-interval (extended to the H-gutter band so any H-lane is covered),\n // its glyph inset (so even-spacing clears the largest glyph in the group), and a setter.\n type VItem = { lo: number; hi: number; inset: number; lane: number; set: (x: number) => void };\n const vByKey = new Map<string, VItem[]>();\n const pushV = (col: number, side: \"left\" | \"right\", portY: number, hBase: number, half: number, inset: number, set: (x: number) => void): void => {\n // The V-leg connects portY to the route's H-gutter lane y (`hY`), which `allocateHorizontal`\n // can place ANYWHERE inside the gutter band [hBase − half, hBase + half] (in EITHER direction\n // from portY — a near-band portY can end up with hY on the far side of it). So the V-leg's\n // true y-interval is [min(portY, hY), max(portY, hY)] ⊆ [min(portY, hBase − half), max(portY,\n // hBase + half)]. Reserve that FULL two-sided span — covering the band on BOTH sides of portY,\n // not just the side hBase happens to fall on — so the lane allocator never under-counts a\n // V-leg overlap (the residual: a self-loop V-leg and a route V-leg got the SAME lane because\n // the one-sided extension missed the hY that landed on the opposite side of portY, then the\n // route's H-leg pulled its V-leg back across the self-loop → a sub-px collinear double-draw).\n const lo = Math.min(portY, round(hBase - half));\n const hi = Math.max(portY, round(hBase + half));\n const key = `${col}:${side}`;\n const arr = vByKey.get(key) ?? [];\n arr.push({ lo, hi, inset, lane: 0, set });\n vByKey.set(key, arr);\n };\n for (const p of plans) {\n if (p.isSelfLoop) {\n // ONE shared V-lane: the U's vertical run spans both arm ports. Both srcVx and tgtVx\n // become the same x (the lane), so the U is a clean rectangle in the gutter.\n const lo = Math.min(p.srcPortY, p.tgtPortY);\n const hi = Math.max(p.srcPortY, p.tgtPortY);\n const key = `${p.srcVCol}:right`;\n const arr = vByKey.get(key) ?? [];\n arr.push({ lo, hi, inset: Math.max(p.srcInset, p.tgtInset), lane: 0, set: (x) => { p.srcVx = x; p.tgtVx = x; } });\n vByKey.set(key, arr);\n continue;\n }\n if (p.srcVCol === p.tgtVCol && p.srcSide === p.tgtSide) {\n // SAME-COLUMN edge: both legs share ONE gutter strip on the same side. Route them on a\n // SINGLE shared V-lane (srcVx === tgtVx) so the run is a clean vertical past the\n // intervening box, with the two horizontal port stubs joining it — NO sub-epsilon H jog\n // between two near-coincident lanes (root-cause #1 of the residual collinear-double-draw:\n // two distinct lanes 1.84px apart connected by a 1.84px horizontal jog). The shared lane\n // spans both port y's so its interval covers the whole vertical run.\n const lo = Math.min(p.srcPortY, p.tgtPortY);\n const hi = Math.max(p.srcPortY, p.tgtPortY);\n const key = `${p.srcVCol}:${p.srcSide}`;\n const arr = vByKey.get(key) ?? [];\n arr.push({ lo, hi, inset: Math.max(p.srcInset, p.tgtInset), lane: 0, set: (x) => { p.srcVx = x; p.tgtVx = x; } });\n vByKey.set(key, arr);\n continue;\n }\n const hBase = hBaseY(p, rowY, grid);\n const half = hHalfBand(p);\n pushV(p.srcVCol, p.srcSide, p.srcPortY, hBase, half, p.srcInset, (x) => { p.srcVx = x; });\n pushV(p.tgtVCol, p.tgtSide, p.tgtPortY, hBase, half, p.tgtInset, (x) => { p.tgtVx = x; });\n }\n // Per (gutter, side): allocate lanes by y-interval, then EVEN-SPACE the lanes across the\n // half-gutter band [wall+maxBaseGap, center] (right) / [center, wall−maxBaseGap] (left).\n // Even spacing (not fixed-pitch) means an arbitrary number of legs always fits inside the\n // box-free half-gutter without two lanes ever clamping to the same x (the prior bug). The\n // band's inner edge clears the LARGEST glyph in the group, so every leg's glyph is clear.\n for (const [key, items] of vByKey.entries()) {\n const side = key.endsWith(\":right\") ? \"right\" : \"left\";\n const col = Number(key.slice(0, key.lastIndexOf(\":\")));\n const laneCount = allocateLanes(\n items.map((it) => ({ lo: it.lo, hi: it.hi, set: (l: number) => { it.lane = l; } })),\n );\n const left = vGutterLeft(col, colX, grid);\n const right = round(left + UML_COL_GAP);\n const center = round((left + right) / 2);\n const maxBaseGap = Math.max(...items.map((it) => Math.max(V_GUTTER_MARGIN, it.inset + MIN_TERMINAL_STUB)));\n for (const it of items) {\n let x: number;\n if (side === \"right\") {\n const lo = left + maxBaseGap;\n const hi = center - 1;\n x = laneCount <= 1 ? lo : lo + (it.lane * (hi - lo)) / (laneCount - 1);\n } else {\n const hi = right - maxBaseGap;\n const lo = center + 1;\n x = laneCount <= 1 ? hi : hi - (it.lane * (hi - lo)) / (laneCount - 1);\n }\n it.set(round(x));\n }\n }\n\n // Horizontal runs: per horizontal gutter, de-conflict EVERY horizontal sub-run of EVERY route\n // — not just the \"main\" gutter leg, but also the two terminal PORT STUBS whose port-y can spill\n // into a gutter band when a heavily-fanned box's ports zigzag past its own height. The main leg\n // FLOATS (assigned a band y); a port stub is PINNED at its port-y (the terminal must land ON the\n // port). A floating main leg gets a y distinct from every pinned stub AND every other main leg\n // it overlaps in x → no two routed horizontal segments are ever collinear-coincident (root-cause\n // #2 of the residual: a main leg at hY landing on a foreign route's port-stub at the same y).\n //\n // Each route is keyed by its own gutter (where its main leg lives). A port stub joins the gutter\n // key whose band [base ± usableHalf] CONTAINS its port-y — that is the only band a floating leg\n // could collide with it in. Stubs whose y sits inside a box's own row, or in the bottom padding,\n // fall into no gutter band and conflict with nothing.\n const usableHalfOf = (kind: \"row\" | \"pad-top\"): number =>\n Math.max(0, (kind === \"pad-top\" ? round(UML_PADDING / 2) : round(UML_ROW_GAP / 2)) - 3);\n // Gather each gutter's base + usableHalf so we can bin pinned stubs by their y.\n const gutterKey = (p: RoutePlan): string => (p.hKind === \"pad-top\" ? \"pad-top\" : `row:${p.hRow}`);\n type GutterMeta = { base: number; usableHalf: number };\n const gutterMeta = new Map<string, GutterMeta>();\n for (const p of plans) {\n if (p.isSelfLoop) continue;\n const key = gutterKey(p);\n if (!gutterMeta.has(key)) gutterMeta.set(key, { base: hBaseY(p, rowY, grid), usableHalf: usableHalfOf(p.hKind) });\n }\n const hRunsByKey = new Map<string, HRun[]>();\n const pushRun = (key: string, run: HRun): void => {\n const arr = hRunsByKey.get(key) ?? [];\n arr.push(run);\n hRunsByKey.set(key, arr);\n };\n // Bin a pinned horizontal stub (a terminal at a fixed port-y) into every gutter band whose\n // floating-leg range [base ± usableHalf] contains its y — the only bands a floating leg could\n // collide with it in. A stub inside a box's own row / the bottom padding hits no band.\n const pinStub = (yy: number, a: number, b: number): void => {\n for (const [gk, meta] of gutterMeta.entries()) {\n if (yy >= meta.base - meta.usableHalf - LANE_EPS && yy <= meta.base + meta.usableHalf + LANE_EPS) {\n pushRun(gk, { lo: Math.min(a, b), hi: Math.max(a, b), y: yy, set: () => {} });\n }\n }\n };\n for (const p of plans) {\n if (p.isSelfLoop) {\n // A self-loop is a U: its two horizontal ARMS are port stubs at the two arm port-y's,\n // x-interval [box edge ↔ shared V-lane]. They have NO floating leg (the U closes\n // vertically), so they only ever act as PINNED obstacles the floating main legs avoid.\n const sideX = p.srcSide === \"right\" ? boxEdges(p.srcNode).right : boxEdges(p.srcNode).left;\n pinStub(p.srcPortY, sideX, p.srcVx);\n pinStub(p.tgtPortY, sideX, p.tgtVx);\n continue;\n }\n const key = gutterKey(p);\n // FLOATING main leg — only when the two V-lanes differ (same-column edges share one V-lane,\n // so simplifyWaypoints drops the zero-length main leg; pinning a phantom run there would\n // wrongly block the band). The setter writes p.hY.\n if (Math.abs(p.srcVx - p.tgtVx) > LANE_EPS) {\n pushRun(key, { lo: Math.min(p.srcVx, p.tgtVx), hi: Math.max(p.srcVx, p.tgtVx), y: null, set: (y) => { p.hY = round(y); } });\n } else {\n p.hY = p.srcPortY; // no main leg; keep hY harmless (Pass B collapses the duplicate point)\n }\n // PINNED port stubs at their port-y, x-interval [port.x ↔ vx].\n const srcPortX = p.srcSide === \"right\" ? boxEdges(p.srcNode).right : boxEdges(p.srcNode).left;\n const tgtPortX = p.tgtSide === \"right\" ? boxEdges(p.tgtNode).right : boxEdges(p.tgtNode).left;\n pinStub(p.srcPortY, srcPortX, p.srcVx);\n pinStub(p.tgtPortY, tgtPortX, p.tgtVx);\n }\n for (const [key, runs] of hRunsByKey.entries()) {\n const meta = gutterMeta.get(key)!;\n allocateHorizontal(runs, meta.base, meta.usableHalf);\n }\n\n // ── Pass B: assemble waypoints from the allocated lane coordinates ────────────\n for (const p of plans) {\n const srcPort: Point = sidePort(p.srcNode, p.srcSide, p.srcPortY - p.srcNode.cy);\n const tgtPort: Point = sidePort(p.tgtNode, p.tgtSide, p.tgtPortY - p.tgtNode.cy);\n\n if (p.isSelfLoop) {\n // U: srcArm → V-lane → down/up → tgtArm. The two arms are horizontal at the two port\n // y's; the vertical run is the shared V-lane (srcVx === tgtVx). The glyph-bearing ends\n // are inset so the diamond sits OUTSIDE the box (in the gutter), never inward.\n const raw: Point[] = [\n srcPort,\n { x: p.srcVx, y: srcPort.y },\n { x: p.srcVx, y: tgtPort.y },\n tgtPort,\n ];\n const portPts = simplifyWaypoints(raw);\n const pts = applyGlyphInsets(portPts, p.srcInset, p.tgtInset);\n const edgeId = UML_SELF_LOOP_BASE + p.rel.id;\n elements.push({ edgeId, relId: p.rel.id, points: pts, kind: \"self-loop\", title: relTitle(p.rel) });\n reserveSelfLoopText(p.rel, p, textBoxes);\n continue;\n }\n\n const raw: Point[] = [\n srcPort,\n { x: p.srcVx, y: srcPort.y },\n { x: p.srcVx, y: p.hY },\n { x: p.tgtVx, y: p.hY },\n { x: p.tgtVx, y: tgtPort.y },\n tgtPort,\n ];\n const portPts = simplifyWaypoints(raw);\n const pts = applyGlyphInsets(portPts, p.srcInset, p.tgtInset);\n const edgeId = UML_ASSOC_ROUTE_BASE + p.rel.id;\n elements.push({ edgeId, relId: p.rel.id, points: pts, kind: \"route\", title: relTitle(p.rel) });\n reserveRouteText(p.rel, p, hBandBounds(p, rowY, grid), textBoxes);\n }\n\n // ── Step 4: Compute canvas size (include self-loop margins + text boxes) ────\n let maxRight = 0;\n let maxBottom = 0;\n for (const node of nodes) {\n const { right, bottom } = boxEdges(node);\n if (right > maxRight) maxRight = right;\n if (bottom > maxBottom) maxBottom = bottom;\n }\n for (const el of elements) {\n for (const pt of el.points) {\n if (pt.x > maxRight) maxRight = pt.x;\n if (pt.y > maxBottom) maxBottom = pt.y;\n }\n }\n for (const tb of textBoxes) {\n if (tb.x + tb.w > maxRight) maxRight = tb.x + tb.w;\n if (tb.y + tb.h > maxBottom) maxBottom = tb.y + tb.h;\n }\n\n const canvasW = round(maxRight + UML_PADDING);\n const canvasH = round(maxBottom + UML_PADDING);\n\n return { nodes, elements, textBoxes, canvasW, canvasH, grid, colX, rowY };\n}\n\n/**\n * Reserve text AABBs for a routed edge's multiplicity/role/label.\n *\n * ALL edge text is anchored INSIDE a box-free gutter band (the horizontal row-gutter the\n * edge transits, at p.hY), never in the narrow vertical strips beside a box. The horizontal\n * row-gutter is box-free across the ENTIRE canvas width (no cell occupies it), so a text AABB\n * placed there — at any x, any length — can NEVER overlap a cell interior, regardless of how\n * long the role/label string is (the honesty rule keeps it verbatim; over-long text just runs\n * along the box-free band). This is the design's \"reserve text into gutter space\" requirement.\n * The src/tgt mult+role stack near their V-leg x (where it meets the gutter); the label sits\n * at the gutter's H-leg midpoint. Parallel-edge lane y's (p.hY) already differ per edge.\n */\nfunction reserveRouteText(\n rel: UmlRelationship,\n p: RoutePlan,\n band: { lo: number; hi: number },\n out: UmlTextBox[],\n): void {\n const textH = round(UML_LABEL_FONT * 1.2);\n // Two stacked rows (multiplicity ABOVE the line, role BELOW), both CLAMPED into the box-free\n // band [lo, hi]. The band is ROW_GAP (56) tall (or the top padding) — comfortably fits two\n // 12px rows — so clamping never lets a text AABB poke into an adjacent cell, no matter the\n // edge's H-lane offset or how long the verbatim string is (it runs along the box-free band).\n const clampY = (y: number): number => round(Math.max(band.lo + 1, Math.min(y, band.hi - 1 - textH)));\n const above = clampY(p.hY - textH - 1);\n const below = clampY(p.hY + 1);\n const srcX = round(p.srcVx + 3);\n const tgtX = round(p.tgtVx + 3);\n\n if (rel.sourceMultiplicity !== null) {\n out.push(reserveTextBox(rel.id, \"src-mult\", rel.sourceMultiplicity, srcX, above, \"start\"));\n }\n if (rel.sourceRole !== null) {\n out.push(reserveTextBox(rel.id, \"src-role\", rel.sourceRole, srcX, below, \"start\"));\n }\n if (rel.targetMultiplicity !== null) {\n out.push(reserveTextBox(rel.id, \"tgt-mult\", rel.targetMultiplicity, tgtX, above, \"start\"));\n }\n if (rel.targetRole !== null) {\n out.push(reserveTextBox(rel.id, \"tgt-role\", rel.targetRole, tgtX, below, \"start\"));\n }\n if (rel.label !== null) {\n const midX = round((p.srcVx + p.tgtVx) / 2);\n out.push(reserveTextBox(rel.id, \"label\", rel.label, midX, above, \"middle\"));\n }\n}\n\n/**\n * Reserve text AABBs for a self-loop's multiplicity/role/label, anchored in the box-free\n * vertical gutter strip just RIGHT of the loop's V-lane (never overlapping the loop's OWN box),\n * stacked at each arm's y. The strip is box-free for the full column height. KNOWN LIMITATION\n * (design-accepted, the \"wide-but-non-overlapping\" doctrine): a self-association role/label far\n * wider than the inter-column gutter may read toward the next column — multiplicities (the common\n * case) are short and always fit. Verbatim, never parsed.\n */\nfunction reserveSelfLoopText(rel: UmlRelationship, p: RoutePlan, out: UmlTextBox[]): void {\n const x0 = round(p.srcVx + 3);\n const srcY = p.srcPortY;\n const tgtY = p.tgtPortY;\n if (rel.sourceMultiplicity !== null) {\n out.push(reserveTextBox(rel.id, \"src-mult\", rel.sourceMultiplicity, x0, round(srcY - UML_LABEL_FONT - 1), \"start\"));\n }\n if (rel.sourceRole !== null) {\n out.push(reserveTextBox(rel.id, \"src-role\", rel.sourceRole, x0, round(srcY + 1), \"start\"));\n }\n if (rel.targetMultiplicity !== null) {\n out.push(reserveTextBox(rel.id, \"tgt-mult\", rel.targetMultiplicity, x0, round(tgtY - UML_LABEL_FONT - 1), \"start\"));\n }\n if (rel.targetRole !== null) {\n out.push(reserveTextBox(rel.id, \"tgt-role\", rel.targetRole, x0, round(tgtY + 1), \"start\"));\n }\n if (rel.label !== null) {\n out.push(reserveTextBox(rel.id, \"label\", rel.label, x0, round((srcY + tgtY) / 2 - UML_LABEL_FONT / 2), \"start\"));\n }\n}\n\n// ── One-call wrapper (render.ts) ──────────────────────────────────────────────\n// Exported from index.ts via render.ts.\n","// UML class-diagram SVG emitter — turns a computed UmlLayout into a SELF-CONTAINED SVG\n// string. Pure (layout in, string out) and deterministic; draws EXACTLY what the layout\n// computed (the overlap harness proves the layout; this emitter is pinned to it).\n//\n// House rules (AGENTS.md):\n// - xmlEscape EVERY interpolated string.\n// - Literal presentation attributes only (hex colors, explicit font-family).\n// No CSS, no currentColor, no <defs>, no <marker>.\n// - All glyphs are EXPLICIT <polygon>/<polyline> from core/glyph.\n// - round() every coordinate — 2-decimal, byte-deterministic output.\n\nimport {\n EDGE_STROKE,\n FONT_FAMILY,\n legendBlock,\n xmlEscape,\n LEGEND_SWATCH_W,\n type LegendEntry,\n arrowOpenPoints,\n trianglePoints,\n diamondPoints,\n type Dir,\n} from \"../core\";\nimport {\n UML_BOX_PAD_X,\n UML_FEAT_FONT,\n UML_LABEL_FONT,\n UML_LINE_H,\n UML_NAME_FONT,\n type UmlBoxNode,\n type UmlEdgeElement,\n type UmlLayout,\n type UmlTextBox,\n} from \"./layout\";\nimport { UML_SVG_LABELS_EN, type UmlSvgLabels } from \"./labels\";\nimport {\n RELATION_GLYPHS,\n UML_RELATIONSHIPS,\n UML_VIS_GLYPH,\n type GlyphKind,\n type UmlFeature,\n type UmlInput,\n type UmlRelationship,\n type UmlRelationshipKind,\n} from \"./types\";\n\n// ── Ink colors (zinc ramp on white, matching the house style) ────────────────\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Glyph emitters ────────────────────────────────────────────────────────────\n\n/**\n * Emit the glyph polygon/polyline for a relationship end.\n * `tip` = the point where the glyph apex sits (on the box edge).\n * `dir` = the direction from the line toward the box (the tip points in this direction).\n */\nfunction emitGlyph(\n gk: GlyphKind,\n tip: { x: number; y: number },\n dir: Dir,\n): string {\n switch (gk) {\n case \"none\":\n return \"\";\n case \"open-arrow\": {\n const pts = arrowOpenPoints(tip, dir);\n return `<polyline points=\"${pts}\" fill=\"none\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n }\n case \"hollow-triangle\": {\n const pts = trianglePoints(tip, dir);\n return `<polygon points=\"${pts}\" fill=\"#fff\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n }\n case \"hollow-diamond\": {\n const pts = diamondPoints(tip, dir);\n return `<polygon points=\"${pts}\" fill=\"#fff\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n }\n case \"solid-diamond\": {\n const pts = diamondPoints(tip, dir);\n return `<polygon points=\"${pts}\" fill=\"${GLYPH_STROKE}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`;\n }\n }\n}\n\n/** Direction FROM the target box back along the edge (for target glyph). */\nfunction glyphDir(firstPt: { x: number; y: number }, secondPt: { x: number; y: number }): Dir {\n const dx = secondPt.x - firstPt.x;\n const dy = secondPt.y - firstPt.y;\n if (Math.abs(dx) >= Math.abs(dy)) {\n return dx >= 0 ? \"left\" : \"right\"; // target tip faces LEFT when line comes from right\n }\n return dy >= 0 ? \"up\" : \"down\";\n}\n\n// ── Box emitter ────────────────────────────────────────────────────────────────\n\n/** Feature line with optional static underline. */\nfunction featureSvg(\n f: UmlFeature,\n x: number,\n y: number,\n font: number,\n): string {\n const prefix = f.visibility !== null ? UML_VIS_GLYPH[f.visibility] + \" \" : \"\";\n const text = prefix + f.text;\n const baseline = round(y + font * 0.8);\n let out = `<text x=\"${x}\" y=\"${baseline}\" font-family=\"${FONT_FAMILY}\" font-size=\"${font}\" fill=\"${LABEL_FILL}\">${xmlEscape(text)}</text>`;\n if (f.isStatic) {\n // Underline: a <line> just below the text baseline\n const lineY = round(baseline + 1);\n const approxW = round(text.length * font * 0.6);\n out += `<line x1=\"${x}\" y1=\"${lineY}\" x2=\"${round(x + approxW)}\" y2=\"${lineY}\" stroke=\"${LABEL_FILL}\" stroke-width=\"0.8\"/>`;\n }\n return out;\n}\n\nfunction boxSvg(node: UmlBoxNode, cls: { attributes: UmlFeature[]; operations: UmlFeature[]; isAbstract?: boolean; stereotype: string | null }): string {\n const left = round(node.cx - node.boxW / 2);\n const top = round(node.cy - node.boxH / 2);\n const metrics = node.metrics;\n const pieces: string[] = [];\n\n pieces.push(`<title>${xmlEscape(node.title)}</title>`);\n\n // Box rect\n pieces.push(\n `<rect x=\"${left}\" y=\"${top}\" width=\"${node.boxW}\" height=\"${node.boxH}\" rx=\"2\" fill=\"#fff\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"/>`,\n );\n\n // Divider lines between compartments\n for (const dy of metrics.dividerYs) {\n const y = round(top + dy);\n pieces.push(\n `<line x1=\"${left}\" y1=\"${y}\" x2=\"${round(left + node.boxW)}\" y2=\"${y}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"0.75\"/>`,\n );\n }\n\n // Compartment 0: stereotype + name\n const compartment0 = metrics.rows[0]!;\n const textX = round(left + node.boxW / 2); // centered\n let lineIdx = 0;\n\n if (cls.stereotype !== null) {\n // Stereotype line: «...» — render verbatim (caller includes guillemets as desired)\n const stereoY = round(top + compartment0.top + lineIdx * UML_LINE_H + UML_NAME_FONT * 0.8);\n pieces.push(\n `<text x=\"${textX}\" y=\"${stereoY}\" font-family=\"${FONT_FAMILY}\" font-size=\"${UML_NAME_FONT}\" fill=\"${LABEL_FILL}\" text-anchor=\"middle\">${xmlEscape(cls.stereotype)}</text>`,\n );\n lineIdx++;\n }\n\n // Name line: italic if abstract\n const nameY = round(top + compartment0.top + lineIdx * UML_LINE_H + UML_NAME_FONT * 0.8);\n const nameStyle = cls.isAbstract ? ` font-style=\"italic\"` : \"\";\n // Get the class name (last line of compartment 0)\n const nameText = metrics.rows[0]!.lines[lineIdx] ?? \"\";\n pieces.push(\n `<text x=\"${textX}\" y=\"${nameY}\" font-family=\"${FONT_FAMILY}\" font-size=\"${UML_NAME_FONT}\" fill=\"${LABEL_FILL}\" text-anchor=\"middle\"${nameStyle}>${xmlEscape(nameText)}</text>`,\n );\n\n // Compartment 1: attributes (left-aligned)\n const attrCompartment = metrics.rows[1]!;\n const attrX = round(left + UML_BOX_PAD_X);\n for (let i = 0; i < cls.attributes.length; i++) {\n const f = cls.attributes[i]!;\n const fy = round(top + attrCompartment.top + i * UML_LINE_H);\n pieces.push(featureSvg(f, attrX, fy, UML_FEAT_FONT));\n }\n\n // Compartment 2: operations (left-aligned)\n const opCompartment = metrics.rows[2]!;\n const opX = round(left + UML_BOX_PAD_X);\n for (let i = 0; i < cls.operations.length; i++) {\n const f = cls.operations[i]!;\n const fy = round(top + opCompartment.top + i * UML_LINE_H);\n pieces.push(featureSvg(f, opX, fy, UML_FEAT_FONT));\n }\n\n return `<g data-node-id=\"c${node.classId}\">${pieces.join(\"\")}</g>`;\n}\n\n// ── Edge emitter ───────────────────────────────────────────────────────────────\n\nfunction edgeSvg(\n el: UmlEdgeElement,\n rel: UmlRelationship,\n textBoxes: UmlTextBox[],\n): string {\n const glyphs = RELATION_GLYPHS[rel.kind];\n const isDashed = glyphs.line === \"dashed\";\n const stroke = isDashed ? EDGE_STROKE.distant : { width: 1.5, dash: null as null, opacity: 0.7 };\n\n const strokeAttrs = isDashed\n ? `stroke=\"${EDGE_INK}\" stroke-width=\"${stroke.width}\" stroke-dasharray=\"4,4\" opacity=\"${stroke.opacity}\"`\n : `stroke=\"${EDGE_INK}\" stroke-width=\"${stroke.width}\" opacity=\"${stroke.opacity}\"`;\n\n // <title> = the layout-woven localized kind word (or the rel.title override).\n const pts = el.points;\n const pieces: string[] = [`<title>${xmlEscape(el.title)}</title>`];\n\n if (pts.length >= 2) {\n // Main line\n pieces.push(`<polyline points=\"${pts.map((p) => `${p.x},${p.y}`).join(\" \")}\" fill=\"none\" ${strokeAttrs}/>`);\n\n // Source glyph: at the START of the line (pts[0]). The line was inset so pts[0] is the\n // glyph BASE-tip; the glyph points back toward the source box (the side normal).\n if (glyphs.sourceEnd !== \"none\") {\n const tip = pts[0]!;\n const next = pts[1]!;\n const dir = glyphDir(tip, next);\n pieces.push(emitGlyph(glyphs.sourceEnd, tip, dir));\n }\n\n // Target glyph: at the END of the line (pts[last]).\n if (glyphs.targetEnd !== \"none\") {\n const tip = pts[pts.length - 1]!;\n const prev = pts[pts.length - 2]!;\n const dir = glyphDir(tip, prev);\n pieces.push(emitGlyph(glyphs.targetEnd, tip, dir));\n }\n\n // Multiplicity / role / mid-edge label — drawn at the LAYOUT-RESERVED anchors\n // (the same AABBs the overlap harness checks; what layout reserves is what svg draws).\n for (const tb of textBoxes) {\n if (tb.relId !== rel.id) continue;\n const italic = tb.slot === \"src-role\" || tb.slot === \"tgt-role\" ? ` font-style=\"italic\"` : \"\";\n const anchor = tb.anchor === \"middle\" ? ` text-anchor=\"middle\"` : \"\";\n const drawX = tb.anchor === \"middle\" ? round(tb.x + tb.w / 2) : tb.x;\n const baseline = round(tb.y + UML_LABEL_FONT * 0.8);\n pieces.push(\n `<text x=\"${drawX}\" y=\"${baseline}\" font-family=\"${FONT_FAMILY}\" font-size=\"${UML_LABEL_FONT}\" fill=\"${LABEL_FILL}\"${anchor}${italic}>${xmlEscape(tb.text)}</text>`,\n );\n }\n }\n\n return `<g data-edge-id=\"${el.edgeId}\">${pieces.join(\"\")}</g>`;\n}\n\n// ── Legend ─────────────────────────────────────────────────────────────────────\n\nfunction makeSwatchLine(isDashed: boolean): (x: number, y: number) => string {\n return (x, y) => {\n const attrs = isDashed\n ? `stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-dasharray=\"4,4\"`\n : `stroke=\"${EDGE_INK}\" stroke-width=\"1.5\"`;\n return `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" ${attrs}/>`;\n };\n}\n\n// ── Main emitter ──────────────────────────────────────────────────────────────\n\nexport interface UmlSvgOptions {\n /** Set false to suppress the legend (default true). */\n legend?: boolean;\n /** Display vocabulary — English default; see locale packs. */\n labels?: UmlSvgLabels;\n}\n\n/**\n * Emits a self-contained SVG string from a computed UmlLayout + the original input.\n * The input is needed for class attributes/operations/stereotype data that the layout\n * only stores in the metrics.\n */\nexport function umlLayoutSvg(\n layout: UmlLayout,\n input: UmlInput,\n opts: UmlSvgOptions = {},\n): string {\n const labels = opts.labels ?? UML_SVG_LABELS_EN;\n const showLegend = opts.legend !== false;\n\n const classMap = new Map(input.classes.map((c) => [c.id, c]));\n const relMap = new Map(input.relationships.map((r) => [r.id, r]));\n\n const parts: string[] = [];\n\n // Boxes\n for (const node of layout.nodes) {\n const cls = classMap.get(node.classId)!;\n parts.push(boxSvg(node, cls));\n }\n\n // Edges\n for (const el of layout.elements) {\n const rel = relMap.get(el.relId);\n if (!rel) continue;\n parts.push(edgeSvg(el, rel, layout.textBoxes));\n }\n\n let canvasW = layout.canvasW;\n let canvasH = layout.canvasH;\n\n // Legend\n if (showLegend) {\n // Collect which kinds are used\n const usedKinds = new Set<UmlRelationshipKind>(\n input.relationships.map((r) => r.kind),\n );\n const entries: LegendEntry[] = [];\n for (const kind of UML_RELATIONSHIPS) {\n if (!usedKinds.has(kind)) continue;\n const isDashed = RELATION_GLYPHS[kind].line === \"dashed\";\n entries.push({\n swatch: makeSwatchLine(isDashed),\n label: labels.legend[kind],\n });\n }\n if (entries.length > 0) {\n const block = legendBlock(entries, canvasH);\n parts.push(block.svg);\n canvasH = block.height;\n canvasW = Math.max(canvasW, block.width);\n }\n }\n\n const roundedW = round(canvasW);\n const roundedH = round(canvasH);\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${roundedW}\" height=\"${roundedH}\" viewBox=\"0 0 ${roundedW} ${roundedH}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call wrapper — validates, lays out, and emits in one step.\n\nimport { computeUmlLayout, type UmlLayout } from \"./layout\";\nimport { umlLayoutSvg, type UmlSvgOptions } from \"./svg\";\nimport { UML_TITLE_LABELS_EN, type UmlTitleLabels } from \"./labels\";\nimport type { UmlInput } from \"./types\";\n\nexport interface UmlRenderOptions extends UmlSvgOptions {\n /**\n * Title-bar vocabulary woven into each element's `<title>` by the layout (the\n * localized relationship-kind word). Defaults to English; pass the pt-BR pack for\n * localized titles. The `labels` field (UmlSvgLabels) controls the legend + aria.\n */\n titleLabels?: UmlTitleLabels;\n}\n\n/**\n * Renders a UML class diagram to SVG in one call.\n *\n * @returns `{ svg, layout }` — svg is the self-contained SVG string; layout is the\n * positioned model for the overlap harness and decorating callers.\n */\nexport function umlSvg(\n input: UmlInput,\n opts: UmlRenderOptions = {},\n): { svg: string; layout: UmlLayout } {\n const layout = computeUmlLayout(input, opts.titleLabels ?? UML_TITLE_LABELS_EN);\n const svg = umlLayoutSvg(layout, input, opts);\n return { svg, layout };\n}\n"]}