compasso 0.4.0 → 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 (100) hide show
  1. package/README.md +115 -5
  2. package/dist/{chunk-ZBDABVIO.js → chunk-2NDET6O5.js} +3 -3
  3. package/dist/{chunk-ZBDABVIO.js.map → chunk-2NDET6O5.js.map} +1 -1
  4. package/dist/{chunk-Q6DVTCXD.js → chunk-3RGYLVTN.js} +18 -6
  5. package/dist/chunk-3RGYLVTN.js.map +1 -0
  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-F47C6ZEB.js → chunk-JBDA7E2O.js} +3 -3
  11. package/dist/{chunk-F47C6ZEB.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-JP4N42AY.js → chunk-PJHLWSGD.js} +3 -3
  15. package/dist/{chunk-JP4N42AY.js.map → chunk-PJHLWSGD.js.map} +1 -1
  16. package/dist/{chunk-LRHHUJFZ.js → chunk-RDH4XHA2.js} +3 -3
  17. package/dist/{chunk-LRHHUJFZ.js.map → chunk-RDH4XHA2.js.map} +1 -1
  18. package/dist/{chunk-UJVU7B44.js → chunk-WEHUSHVI.js} +31 -51
  19. package/dist/chunk-WEHUSHVI.js.map +1 -0
  20. package/dist/{chunk-RWPGGWO5.js → chunk-Z66YUOUM.js} +34 -10
  21. package/dist/chunk-Z66YUOUM.js.map +1 -0
  22. package/dist/core/index.cjs +247 -0
  23. package/dist/core/index.cjs.map +1 -1
  24. package/dist/core/index.d.cts +94 -2
  25. package/dist/core/index.d.ts +94 -2
  26. package/dist/core/index.js +1 -1
  27. package/dist/ecomap/index.cjs +34 -11
  28. package/dist/ecomap/index.cjs.map +1 -1
  29. package/dist/ecomap/index.d.cts +12 -0
  30. package/dist/ecomap/index.d.ts +12 -0
  31. package/dist/ecomap/index.js +2 -2
  32. package/dist/fault-tree/index.d.cts +2 -2
  33. package/dist/fault-tree/index.d.ts +2 -2
  34. package/dist/fault-tree/index.js +2 -2
  35. package/dist/fishbone/index.js +2 -2
  36. package/dist/genogram/index.cjs +57 -7
  37. package/dist/genogram/index.cjs.map +1 -1
  38. package/dist/genogram/index.d.cts +22 -6
  39. package/dist/genogram/index.d.ts +22 -6
  40. package/dist/genogram/index.js +2 -2
  41. package/dist/geometry-P-XGqGe7.d.cts +8 -0
  42. package/dist/geometry-P-XGqGe7.d.ts +8 -0
  43. package/dist/grid-BMgUSly1.d.cts +79 -0
  44. package/dist/grid-BMgUSly1.d.ts +79 -0
  45. package/dist/index.cjs +2360 -395
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +14 -7
  48. package/dist/index.d.ts +14 -7
  49. package/dist/index.js +10 -8
  50. package/dist/{kinship-DqEklrDN.d.ts → kinship-BF90HyyS.d.ts} +1 -1
  51. package/dist/{kinship-Dy_ijjJV.d.cts → kinship-BOUss5cT.d.cts} +1 -1
  52. package/dist/{labels-RtFw9tX1.d.cts → labels-B0aOMbHy.d.cts} +12 -0
  53. package/dist/{labels-RtFw9tX1.d.ts → labels-B0aOMbHy.d.ts} +12 -0
  54. package/dist/labels-Br8yjc3C.d.cts +29 -0
  55. package/dist/labels-Br8yjc3C.d.ts +29 -0
  56. package/dist/{labels-DNqRkWuI.d.ts → labels-CuLbFyrz.d.ts} +1 -1
  57. package/dist/labels-D1v1RWZd.d.cts +97 -0
  58. package/dist/labels-D1v1RWZd.d.ts +97 -0
  59. package/dist/{labels-CBQ_3Ec9.d.cts → labels-DhQe7I8m.d.cts} +1 -1
  60. package/dist/layered-DmZluAqe.d.cts +72 -0
  61. package/dist/layered-DmZluAqe.d.ts +72 -0
  62. package/dist/locales/pt-br.cjs +53 -0
  63. package/dist/locales/pt-br.cjs.map +1 -1
  64. package/dist/locales/pt-br.d.cts +11 -5
  65. package/dist/locales/pt-br.d.ts +11 -5
  66. package/dist/locales/pt-br.js +50 -1
  67. package/dist/locales/pt-br.js.map +1 -1
  68. package/dist/org-chart/index.cjs +138 -94
  69. package/dist/org-chart/index.cjs.map +1 -1
  70. package/dist/org-chart/index.d.cts +24 -33
  71. package/dist/org-chart/index.d.ts +24 -33
  72. package/dist/org-chart/index.js +2 -2
  73. package/dist/pedigree/index.d.cts +6 -6
  74. package/dist/pedigree/index.d.ts +6 -6
  75. package/dist/pedigree/index.js +2 -2
  76. package/dist/phylo/index.d.cts +2 -2
  77. package/dist/phylo/index.d.ts +2 -2
  78. package/dist/phylo/index.js +2 -2
  79. package/dist/prisma/index.cjs +882 -0
  80. package/dist/prisma/index.cjs.map +1 -0
  81. package/dist/prisma/index.d.cts +174 -0
  82. package/dist/prisma/index.d.ts +174 -0
  83. package/dist/prisma/index.js +4 -0
  84. package/dist/prisma/index.js.map +1 -0
  85. package/dist/{text-DuO_PwYw.d.cts → text-DDVzpwPZ.d.cts} +1 -8
  86. package/dist/{text-DuO_PwYw.d.ts → text-DDVzpwPZ.d.ts} +1 -8
  87. package/dist/{types-BnMG7TCd.d.cts → types-jE2fdM1t.d.cts} +8 -0
  88. package/dist/{types-BnMG7TCd.d.ts → types-jE2fdM1t.d.ts} +8 -0
  89. package/dist/uml/index.cjs +1214 -0
  90. package/dist/uml/index.cjs.map +1 -0
  91. package/dist/uml/index.d.cts +189 -0
  92. package/dist/uml/index.d.ts +189 -0
  93. package/dist/uml/index.js +4 -0
  94. package/dist/uml/index.js.map +1 -0
  95. package/package.json +28 -2
  96. package/dist/chunk-O3BT2O42.js +0 -145
  97. package/dist/chunk-O3BT2O42.js.map +0 -1
  98. package/dist/chunk-Q6DVTCXD.js.map +0 -1
  99. package/dist/chunk-RWPGGWO5.js.map +0 -1
  100. package/dist/chunk-UJVU7B44.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/prisma/types.ts","../../src/prisma/validate.ts","../../src/prisma/labels.ts","../../src/core/xml.ts","../../src/core/geometry.ts","../../src/core/text.ts","../../src/core/legend.ts","../../src/core/layered.ts","../../src/core/glyph.ts","../../src/core/compartment.ts","../../src/prisma/layout.ts","../../src/prisma/svg.ts","../../src/prisma/render.ts"],"names":["round","r"],"mappings":"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","file":"index.cjs","sourcesContent":["// 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","// 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","// 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","// 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","// 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"]}
@@ -0,0 +1,174 @@
1
+ import { c as PrismaTitleLabels, b as PrismaSvgLabels } from '../labels-Br8yjc3C.cjs';
2
+ export { P as PRISMA_SVG_LABELS_EN, a as PRISMA_TITLE_LABELS_EN } from '../labels-Br8yjc3C.cjs';
3
+ import { P as Point } from '../geometry-P-XGqGe7.cjs';
4
+
5
+ /** The three standard PRISMA phases, in display order. */
6
+ declare const PRISMA_PHASES: readonly ["identification", "screening", "included"];
7
+ type PrismaPhase = (typeof PRISMA_PHASES)[number];
8
+ /** Main-column step vs right side-box (exclusion reasons). */
9
+ declare const PRISMA_BOX_KINDS: readonly ["flow", "exclusion"];
10
+ type PrismaBoxKind = (typeof PRISMA_BOX_KINDS)[number];
11
+ /** Single-column default + two-column prior variant. */
12
+ declare const PRISMA_COLUMNS: readonly ["main", "new", "previous"];
13
+ type PrismaColumn = (typeof PRISMA_COLUMNS)[number];
14
+ /**
15
+ * A single count line in a box. `n: null` draws the localized "n = —" token.
16
+ * NEVER inferred or summed — each figure is verbatim as the author declared it.
17
+ */
18
+ interface PrismaCount {
19
+ label: string;
20
+ n: number | null;
21
+ }
22
+ /**
23
+ * A single PRISMA box — a flow step or an exclusion reason side-box.
24
+ *
25
+ * @property id Unique identifier (within the boxes namespace).
26
+ * @property phase Which band the box belongs to.
27
+ * @property kind "flow" = main-column step; "exclusion" = right side-box.
28
+ * @property column Which column within the band. Validation defaults absent → "main".
29
+ * @property rank Declared vertical order within (phase, column), 0-based top→down.
30
+ * This is the AUTHOR's claim, never derived.
31
+ * @property heading Verbatim header text (e.g. "Records identified from:"), or null.
32
+ * @property counts Verbatim count lines (zero allowed).
33
+ * @property title Optional <title> override; defaults to heading + counts.
34
+ */
35
+ interface PrismaBox {
36
+ id: number;
37
+ phase: PrismaPhase;
38
+ kind: PrismaBoxKind;
39
+ column: PrismaColumn;
40
+ rank: number;
41
+ heading: string | null;
42
+ counts: PrismaCount[];
43
+ title?: string;
44
+ }
45
+ /**
46
+ * A declared flow arrow. Direction is determined by geometry (flow→exclusion = horizontal;
47
+ * flow→flow = vertical). NO direction flag — the layout decides from box positions.
48
+ */
49
+ interface PrismaArrow {
50
+ id: number;
51
+ fromId: number;
52
+ toId: number;
53
+ }
54
+ /**
55
+ * The full input for one PRISMA diagram.
56
+ *
57
+ * @property variant "flow" = standard single-column;
58
+ * "flow-with-prior" = two-column (new + previous sources, with merge arrow);
59
+ * "flow-other-methods" = parallel new + other-sources stacks in the main column.
60
+ * @property boxes Declared PRISMA boxes.
61
+ * @property arrows Declared flow arrows.
62
+ */
63
+ interface PrismaInput {
64
+ variant: "flow" | "flow-with-prior" | "flow-other-methods";
65
+ boxes: PrismaBox[];
66
+ arrows: PrismaArrow[];
67
+ }
68
+
69
+ /** Stable machine-readable issue codes (kebab-case; public contract). */
70
+ type PrismaIssueCode = "duplicate-id" | "unknown-arrow-endpoint" | "self-arrow" | "non-finite-count" | "invalid-variant-column" | "arrow-skips-backward";
71
+ interface PrismaIssue {
72
+ code: PrismaIssueCode;
73
+ message: string;
74
+ }
75
+ /** Thrown by computePrismaLayout / prismaSvg on structurally invalid input. */
76
+ declare class PrismaValidationError extends Error {
77
+ readonly issues: readonly PrismaIssue[];
78
+ constructor(issues: readonly PrismaIssue[]);
79
+ }
80
+ /**
81
+ * Computes ALL validation issues for the input, deduplicated and deterministically sorted.
82
+ * Empty input (no boxes AND no arrows) → valid (returns []).
83
+ */
84
+ declare function prismaIssues(input: PrismaInput): readonly PrismaIssue[];
85
+ /** Throws PrismaValidationError (carrying ALL issues) when the input is invalid. */
86
+ declare function validatePrisma(input: PrismaInput): void;
87
+
88
+ declare const PRISMA_PADDING = 32;
89
+ /** Left gutter reserved for rotated band labels (never overlaps boxes). */
90
+ declare const PRISMA_BAND_LABEL_W = 40;
91
+ /** Horizontal gap between two flow columns. */
92
+ declare const PRISMA_COL_GAP = 56;
93
+ /** Vertical corridor between bands. */
94
+ declare const PRISMA_CORRIDOR = 30;
95
+ declare const PRISMA_BOX_PAD_X = 12;
96
+ declare const PRISMA_BOX_PAD_Y = 10;
97
+ declare const PRISMA_LINE_H = 14;
98
+ declare const PRISMA_MIN_BOX_W = 200;
99
+ /** Gap between the right edge of ALL flow columns and the left edge of exclusion boxes. */
100
+ declare const PRISMA_EXCL_GAP = 48;
101
+ declare const PRISMA_HEADING_FONT = 12;
102
+ declare const PRISMA_COUNT_FONT = 10;
103
+ declare const PRISMA_FLOW_ARROW_BASE = 1000000;
104
+ declare const PRISMA_EXCL_ARROW_BASE = 2000000;
105
+ declare const PRISMA_MERGE_ARROW_BASE = 3000000;
106
+ /** A positioned PRISMA box with all metrics needed by the emitter and harness. */
107
+ interface PrismaLayoutBox {
108
+ id: number;
109
+ phase: PrismaPhase;
110
+ kind: "flow" | "exclusion";
111
+ /** Center x. */
112
+ cx: number;
113
+ /** Top y. */
114
+ top: number;
115
+ boxW: number;
116
+ boxH: number;
117
+ rows: {
118
+ lines: string[];
119
+ top: number;
120
+ font: number;
121
+ }[];
122
+ dividerYs: number[];
123
+ heading: string | null;
124
+ countLines: string[];
125
+ title: string;
126
+ }
127
+ /** A routed element (arrow segment polyline). */
128
+ interface PrismaLayoutElement {
129
+ edgeId: number;
130
+ kind: "flow" | "exclusion" | "merge";
131
+ points: Point[];
132
+ title: string;
133
+ headDir: "down" | "right" | "left" | "up";
134
+ }
135
+ /** The positioned PRISMA layout. */
136
+ interface PrismaLayout {
137
+ width: number;
138
+ height: number;
139
+ boxes: PrismaLayoutBox[];
140
+ elements: PrismaLayoutElement[];
141
+ bands: {
142
+ phase: PrismaPhase;
143
+ rowTop: number;
144
+ rowH: number;
145
+ labelX: number;
146
+ centerY: number;
147
+ }[];
148
+ variant: PrismaInput["variant"];
149
+ }
150
+ interface PrismaLayoutOpts {
151
+ labels?: PrismaTitleLabels;
152
+ validate?: boolean;
153
+ }
154
+ declare function computePrismaLayout(input: PrismaInput, opts?: PrismaLayoutOpts): PrismaLayout;
155
+
156
+ interface PrismaSvgOpts {
157
+ svgLabels?: PrismaSvgLabels;
158
+ titleLabels?: PrismaTitleLabels;
159
+ legend?: boolean;
160
+ }
161
+ /**
162
+ * Emits the SVG string for a pre-computed PRISMA layout.
163
+ * All coordinates come from the layout; no geometry is re-derived here.
164
+ */
165
+ declare function prismaLayoutSvg(layout: PrismaLayout, opts?: PrismaSvgOpts): string;
166
+
167
+ type PrismaRenderOpts = PrismaLayoutOpts & PrismaSvgOpts;
168
+ /** Compute layout + emit SVG in one call. Returns both for callers that need the layout. */
169
+ declare function prismaSvg(input: PrismaInput, opts?: PrismaRenderOpts): {
170
+ svg: string;
171
+ layout: PrismaLayout;
172
+ };
173
+
174
+ export { PRISMA_BAND_LABEL_W, PRISMA_BOX_KINDS, PRISMA_BOX_PAD_X, PRISMA_BOX_PAD_Y, PRISMA_COLUMNS, PRISMA_COL_GAP, PRISMA_CORRIDOR, PRISMA_COUNT_FONT, PRISMA_EXCL_ARROW_BASE, PRISMA_EXCL_GAP, PRISMA_FLOW_ARROW_BASE, PRISMA_HEADING_FONT, PRISMA_LINE_H, PRISMA_MERGE_ARROW_BASE, PRISMA_MIN_BOX_W, PRISMA_PADDING, PRISMA_PHASES, type PrismaArrow, type PrismaBox, type PrismaBoxKind, type PrismaColumn, type PrismaCount, type PrismaInput, type PrismaIssue, type PrismaIssueCode, type PrismaLayout, type PrismaLayoutBox, type PrismaLayoutElement, type PrismaLayoutOpts, type PrismaPhase, type PrismaRenderOpts, PrismaSvgLabels, type PrismaSvgOpts, PrismaTitleLabels, PrismaValidationError, computePrismaLayout, prismaIssues, prismaLayoutSvg, prismaSvg, validatePrisma };
@@ -0,0 +1,174 @@
1
+ import { c as PrismaTitleLabels, b as PrismaSvgLabels } from '../labels-Br8yjc3C.js';
2
+ export { P as PRISMA_SVG_LABELS_EN, a as PRISMA_TITLE_LABELS_EN } from '../labels-Br8yjc3C.js';
3
+ import { P as Point } from '../geometry-P-XGqGe7.js';
4
+
5
+ /** The three standard PRISMA phases, in display order. */
6
+ declare const PRISMA_PHASES: readonly ["identification", "screening", "included"];
7
+ type PrismaPhase = (typeof PRISMA_PHASES)[number];
8
+ /** Main-column step vs right side-box (exclusion reasons). */
9
+ declare const PRISMA_BOX_KINDS: readonly ["flow", "exclusion"];
10
+ type PrismaBoxKind = (typeof PRISMA_BOX_KINDS)[number];
11
+ /** Single-column default + two-column prior variant. */
12
+ declare const PRISMA_COLUMNS: readonly ["main", "new", "previous"];
13
+ type PrismaColumn = (typeof PRISMA_COLUMNS)[number];
14
+ /**
15
+ * A single count line in a box. `n: null` draws the localized "n = —" token.
16
+ * NEVER inferred or summed — each figure is verbatim as the author declared it.
17
+ */
18
+ interface PrismaCount {
19
+ label: string;
20
+ n: number | null;
21
+ }
22
+ /**
23
+ * A single PRISMA box — a flow step or an exclusion reason side-box.
24
+ *
25
+ * @property id Unique identifier (within the boxes namespace).
26
+ * @property phase Which band the box belongs to.
27
+ * @property kind "flow" = main-column step; "exclusion" = right side-box.
28
+ * @property column Which column within the band. Validation defaults absent → "main".
29
+ * @property rank Declared vertical order within (phase, column), 0-based top→down.
30
+ * This is the AUTHOR's claim, never derived.
31
+ * @property heading Verbatim header text (e.g. "Records identified from:"), or null.
32
+ * @property counts Verbatim count lines (zero allowed).
33
+ * @property title Optional <title> override; defaults to heading + counts.
34
+ */
35
+ interface PrismaBox {
36
+ id: number;
37
+ phase: PrismaPhase;
38
+ kind: PrismaBoxKind;
39
+ column: PrismaColumn;
40
+ rank: number;
41
+ heading: string | null;
42
+ counts: PrismaCount[];
43
+ title?: string;
44
+ }
45
+ /**
46
+ * A declared flow arrow. Direction is determined by geometry (flow→exclusion = horizontal;
47
+ * flow→flow = vertical). NO direction flag — the layout decides from box positions.
48
+ */
49
+ interface PrismaArrow {
50
+ id: number;
51
+ fromId: number;
52
+ toId: number;
53
+ }
54
+ /**
55
+ * The full input for one PRISMA diagram.
56
+ *
57
+ * @property variant "flow" = standard single-column;
58
+ * "flow-with-prior" = two-column (new + previous sources, with merge arrow);
59
+ * "flow-other-methods" = parallel new + other-sources stacks in the main column.
60
+ * @property boxes Declared PRISMA boxes.
61
+ * @property arrows Declared flow arrows.
62
+ */
63
+ interface PrismaInput {
64
+ variant: "flow" | "flow-with-prior" | "flow-other-methods";
65
+ boxes: PrismaBox[];
66
+ arrows: PrismaArrow[];
67
+ }
68
+
69
+ /** Stable machine-readable issue codes (kebab-case; public contract). */
70
+ type PrismaIssueCode = "duplicate-id" | "unknown-arrow-endpoint" | "self-arrow" | "non-finite-count" | "invalid-variant-column" | "arrow-skips-backward";
71
+ interface PrismaIssue {
72
+ code: PrismaIssueCode;
73
+ message: string;
74
+ }
75
+ /** Thrown by computePrismaLayout / prismaSvg on structurally invalid input. */
76
+ declare class PrismaValidationError extends Error {
77
+ readonly issues: readonly PrismaIssue[];
78
+ constructor(issues: readonly PrismaIssue[]);
79
+ }
80
+ /**
81
+ * Computes ALL validation issues for the input, deduplicated and deterministically sorted.
82
+ * Empty input (no boxes AND no arrows) → valid (returns []).
83
+ */
84
+ declare function prismaIssues(input: PrismaInput): readonly PrismaIssue[];
85
+ /** Throws PrismaValidationError (carrying ALL issues) when the input is invalid. */
86
+ declare function validatePrisma(input: PrismaInput): void;
87
+
88
+ declare const PRISMA_PADDING = 32;
89
+ /** Left gutter reserved for rotated band labels (never overlaps boxes). */
90
+ declare const PRISMA_BAND_LABEL_W = 40;
91
+ /** Horizontal gap between two flow columns. */
92
+ declare const PRISMA_COL_GAP = 56;
93
+ /** Vertical corridor between bands. */
94
+ declare const PRISMA_CORRIDOR = 30;
95
+ declare const PRISMA_BOX_PAD_X = 12;
96
+ declare const PRISMA_BOX_PAD_Y = 10;
97
+ declare const PRISMA_LINE_H = 14;
98
+ declare const PRISMA_MIN_BOX_W = 200;
99
+ /** Gap between the right edge of ALL flow columns and the left edge of exclusion boxes. */
100
+ declare const PRISMA_EXCL_GAP = 48;
101
+ declare const PRISMA_HEADING_FONT = 12;
102
+ declare const PRISMA_COUNT_FONT = 10;
103
+ declare const PRISMA_FLOW_ARROW_BASE = 1000000;
104
+ declare const PRISMA_EXCL_ARROW_BASE = 2000000;
105
+ declare const PRISMA_MERGE_ARROW_BASE = 3000000;
106
+ /** A positioned PRISMA box with all metrics needed by the emitter and harness. */
107
+ interface PrismaLayoutBox {
108
+ id: number;
109
+ phase: PrismaPhase;
110
+ kind: "flow" | "exclusion";
111
+ /** Center x. */
112
+ cx: number;
113
+ /** Top y. */
114
+ top: number;
115
+ boxW: number;
116
+ boxH: number;
117
+ rows: {
118
+ lines: string[];
119
+ top: number;
120
+ font: number;
121
+ }[];
122
+ dividerYs: number[];
123
+ heading: string | null;
124
+ countLines: string[];
125
+ title: string;
126
+ }
127
+ /** A routed element (arrow segment polyline). */
128
+ interface PrismaLayoutElement {
129
+ edgeId: number;
130
+ kind: "flow" | "exclusion" | "merge";
131
+ points: Point[];
132
+ title: string;
133
+ headDir: "down" | "right" | "left" | "up";
134
+ }
135
+ /** The positioned PRISMA layout. */
136
+ interface PrismaLayout {
137
+ width: number;
138
+ height: number;
139
+ boxes: PrismaLayoutBox[];
140
+ elements: PrismaLayoutElement[];
141
+ bands: {
142
+ phase: PrismaPhase;
143
+ rowTop: number;
144
+ rowH: number;
145
+ labelX: number;
146
+ centerY: number;
147
+ }[];
148
+ variant: PrismaInput["variant"];
149
+ }
150
+ interface PrismaLayoutOpts {
151
+ labels?: PrismaTitleLabels;
152
+ validate?: boolean;
153
+ }
154
+ declare function computePrismaLayout(input: PrismaInput, opts?: PrismaLayoutOpts): PrismaLayout;
155
+
156
+ interface PrismaSvgOpts {
157
+ svgLabels?: PrismaSvgLabels;
158
+ titleLabels?: PrismaTitleLabels;
159
+ legend?: boolean;
160
+ }
161
+ /**
162
+ * Emits the SVG string for a pre-computed PRISMA layout.
163
+ * All coordinates come from the layout; no geometry is re-derived here.
164
+ */
165
+ declare function prismaLayoutSvg(layout: PrismaLayout, opts?: PrismaSvgOpts): string;
166
+
167
+ type PrismaRenderOpts = PrismaLayoutOpts & PrismaSvgOpts;
168
+ /** Compute layout + emit SVG in one call. Returns both for callers that need the layout. */
169
+ declare function prismaSvg(input: PrismaInput, opts?: PrismaRenderOpts): {
170
+ svg: string;
171
+ layout: PrismaLayout;
172
+ };
173
+
174
+ export { PRISMA_BAND_LABEL_W, PRISMA_BOX_KINDS, PRISMA_BOX_PAD_X, PRISMA_BOX_PAD_Y, PRISMA_COLUMNS, PRISMA_COL_GAP, PRISMA_CORRIDOR, PRISMA_COUNT_FONT, PRISMA_EXCL_ARROW_BASE, PRISMA_EXCL_GAP, PRISMA_FLOW_ARROW_BASE, PRISMA_HEADING_FONT, PRISMA_LINE_H, PRISMA_MERGE_ARROW_BASE, PRISMA_MIN_BOX_W, PRISMA_PADDING, PRISMA_PHASES, type PrismaArrow, type PrismaBox, type PrismaBoxKind, type PrismaColumn, type PrismaCount, type PrismaInput, type PrismaIssue, type PrismaIssueCode, type PrismaLayout, type PrismaLayoutBox, type PrismaLayoutElement, type PrismaLayoutOpts, type PrismaPhase, type PrismaRenderOpts, PrismaSvgLabels, type PrismaSvgOpts, PrismaTitleLabels, PrismaValidationError, computePrismaLayout, prismaIssues, prismaLayoutSvg, prismaSvg, validatePrisma };