compasso 0.2.0 → 0.4.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.
- package/README.md +126 -7
- package/dist/chunk-F47C6ZEB.js +1041 -0
- package/dist/chunk-F47C6ZEB.js.map +1 -0
- package/dist/chunk-JP4N42AY.js +497 -0
- package/dist/chunk-JP4N42AY.js.map +1 -0
- package/dist/{chunk-P2S7AUOL.js → chunk-LRHHUJFZ.js} +3 -3
- package/dist/{chunk-P2S7AUOL.js.map → chunk-LRHHUJFZ.js.map} +1 -1
- package/dist/{chunk-5B453C4P.js → chunk-O3BT2O42.js} +32 -3
- package/dist/chunk-O3BT2O42.js.map +1 -0
- package/dist/{chunk-EHQMKVDM.js → chunk-Q6DVTCXD.js} +9 -24
- package/dist/chunk-Q6DVTCXD.js.map +1 -0
- package/dist/{chunk-5PGOL2KR.js → chunk-RWPGGWO5.js} +9 -28
- package/dist/chunk-RWPGGWO5.js.map +1 -0
- package/dist/chunk-UJVU7B44.js +764 -0
- package/dist/chunk-UJVU7B44.js.map +1 -0
- package/dist/{chunk-TP3JOOJW.js → chunk-ZBDABVIO.js} +3 -3
- package/dist/{chunk-TP3JOOJW.js.map → chunk-ZBDABVIO.js.map} +1 -1
- package/dist/core/index.cjs +30 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +5 -1
- package/dist/core/index.d.ts +5 -1
- package/dist/core/index.js +1 -1
- package/dist/ecomap/index.cjs +32 -21
- package/dist/ecomap/index.cjs.map +1 -1
- package/dist/ecomap/index.js +2 -2
- package/dist/fault-tree/index.js +2 -2
- package/dist/fishbone/index.js +2 -2
- package/dist/genogram/index.cjs +36 -25
- package/dist/genogram/index.cjs.map +1 -1
- package/dist/genogram/index.d.cts +4 -2
- package/dist/genogram/index.d.ts +4 -2
- package/dist/genogram/index.js +2 -2
- package/dist/index.cjs +2397 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +8 -5
- package/dist/kinship-DqEklrDN.d.ts +51 -0
- package/dist/kinship-Dy_ijjJV.d.cts +51 -0
- package/dist/labels-CBQ_3Ec9.d.cts +123 -0
- package/dist/labels-DNqRkWuI.d.ts +123 -0
- package/dist/labels-RtFw9tX1.d.cts +91 -0
- package/dist/labels-RtFw9tX1.d.ts +91 -0
- package/dist/labels-iZjijjtK.d.cts +64 -0
- package/dist/labels-iZjijjtK.d.ts +64 -0
- package/dist/locales/pt-br.cjs +77 -0
- package/dist/locales/pt-br.cjs.map +1 -1
- package/dist/locales/pt-br.d.cts +12 -2
- package/dist/locales/pt-br.d.ts +12 -2
- package/dist/locales/pt-br.js +72 -1
- package/dist/locales/pt-br.js.map +1 -1
- package/dist/org-chart/index.cjs +853 -0
- package/dist/org-chart/index.cjs.map +1 -0
- package/dist/org-chart/index.d.cts +168 -0
- package/dist/org-chart/index.d.ts +168 -0
- package/dist/org-chart/index.js +4 -0
- package/dist/org-chart/index.js.map +1 -0
- package/dist/pedigree/index.cjs +1151 -0
- package/dist/pedigree/index.cjs.map +1 -0
- package/dist/pedigree/index.d.cts +155 -0
- package/dist/pedigree/index.d.ts +155 -0
- package/dist/pedigree/index.js +4 -0
- package/dist/pedigree/index.js.map +1 -0
- package/dist/phylo/index.cjs +553 -0
- package/dist/phylo/index.cjs.map +1 -0
- package/dist/phylo/index.d.cts +158 -0
- package/dist/phylo/index.d.ts +158 -0
- package/dist/phylo/index.js +4 -0
- package/dist/phylo/index.js.map +1 -0
- package/dist/types-BnMG7TCd.d.cts +66 -0
- package/dist/types-BnMG7TCd.d.ts +66 -0
- package/package.json +42 -3
- package/dist/chunk-5B453C4P.js.map +0 -1
- package/dist/chunk-5PGOL2KR.js.map +0 -1
- package/dist/chunk-EHQMKVDM.js.map +0 -1
- package/dist/kinship-BARO5-qz.d.cts +0 -115
- package/dist/kinship-Bkf87Jhu.d.ts +0 -115
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pedigree/types.ts","../src/pedigree/labels.ts","../src/pedigree/validate.ts","../src/pedigree/layout.ts","../src/pedigree/svg.ts","../src/pedigree/render.ts"],"names":["round","h"],"mappings":"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","file":"chunk-F47C6ZEB.js","sourcesContent":["// 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"]}
|