schematex 0.2.2 → 0.2.3

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 (163) hide show
  1. package/dist/ai/ai-sdk.cjs +85 -0
  2. package/dist/ai/ai-sdk.cjs.map +1 -0
  3. package/dist/ai/ai-sdk.d.cts +30 -0
  4. package/dist/ai/ai-sdk.d.ts +30 -0
  5. package/dist/ai/ai-sdk.js +83 -0
  6. package/dist/ai/ai-sdk.js.map +1 -0
  7. package/dist/ai/index.cjs +60 -0
  8. package/dist/ai/index.cjs.map +1 -0
  9. package/dist/ai/index.d.cts +155 -0
  10. package/dist/ai/index.d.ts +155 -0
  11. package/dist/ai/index.js +23 -0
  12. package/dist/ai/index.js.map +1 -0
  13. package/dist/browser.cjs +16 -15
  14. package/dist/browser.cjs.map +1 -1
  15. package/dist/browser.js +14 -13
  16. package/dist/browser.js.map +1 -1
  17. package/dist/{chunk-YN467EEQ.js → chunk-2BM3HJSK.js} +544 -100
  18. package/dist/chunk-2BM3HJSK.js.map +1 -0
  19. package/dist/{chunk-ZO77FHBF.cjs → chunk-2JDVJRR3.cjs} +14 -6
  20. package/dist/chunk-2JDVJRR3.cjs.map +1 -0
  21. package/dist/{chunk-QR7VTCI4.cjs → chunk-3YZ6FPQW.cjs} +13 -7
  22. package/dist/chunk-3YZ6FPQW.cjs.map +1 -0
  23. package/dist/{chunk-GEPBET4L.js → chunk-45KP67RR.js} +14 -6
  24. package/dist/chunk-45KP67RR.js.map +1 -0
  25. package/dist/chunk-4QP37LD3.js +1112 -0
  26. package/dist/chunk-4QP37LD3.js.map +1 -0
  27. package/dist/{chunk-LKOBOVNL.cjs → chunk-5AEN2PLB.cjs} +14 -6
  28. package/dist/chunk-5AEN2PLB.cjs.map +1 -0
  29. package/dist/{chunk-Z63XPA2V.cjs → chunk-6LZJTAA3.cjs} +543 -99
  30. package/dist/chunk-6LZJTAA3.cjs.map +1 -0
  31. package/dist/{chunk-7IRT3LOY.cjs → chunk-A5D2IMOX.cjs} +16 -8
  32. package/dist/chunk-A5D2IMOX.cjs.map +1 -0
  33. package/dist/{chunk-XVCAOGFL.cjs → chunk-B37IKTI7.cjs} +221 -44
  34. package/dist/chunk-B37IKTI7.cjs.map +1 -0
  35. package/dist/{chunk-ISACNVFE.cjs → chunk-B6INLQBU.cjs} +15 -9
  36. package/dist/chunk-B6INLQBU.cjs.map +1 -0
  37. package/dist/{chunk-YXIIWLLB.cjs → chunk-COLTVQWR.cjs} +174 -6
  38. package/dist/chunk-COLTVQWR.cjs.map +1 -0
  39. package/dist/chunk-DNZFOCV7.js +796 -0
  40. package/dist/chunk-DNZFOCV7.js.map +1 -0
  41. package/dist/{chunk-XHZ7GXP2.cjs → chunk-E65ITQXV.cjs} +178 -22
  42. package/dist/chunk-E65ITQXV.cjs.map +1 -0
  43. package/dist/{chunk-LCR3KOJV.js → chunk-FCGHV6ZK.js} +16 -8
  44. package/dist/chunk-FCGHV6ZK.js.map +1 -0
  45. package/dist/{chunk-X2BQKXMA.js → chunk-FE6GAUNW.js} +13 -7
  46. package/dist/chunk-FE6GAUNW.js.map +1 -0
  47. package/dist/{chunk-CJ2A3UEQ.js → chunk-LR4X4ZRG.js} +179 -23
  48. package/dist/chunk-LR4X4ZRG.js.map +1 -0
  49. package/dist/{chunk-LXNFVHDT.cjs → chunk-MCFQAUQV.cjs} +21 -13
  50. package/dist/chunk-MCFQAUQV.cjs.map +1 -0
  51. package/dist/chunk-MOU5QRZY.cjs +1121 -0
  52. package/dist/chunk-MOU5QRZY.cjs.map +1 -0
  53. package/dist/{chunk-4KYW63IK.js → chunk-OC22GGQN.js} +222 -45
  54. package/dist/chunk-OC22GGQN.js.map +1 -0
  55. package/dist/{chunk-7HKXU7J2.cjs → chunk-QXIGHMH2.cjs} +65 -38
  56. package/dist/chunk-QXIGHMH2.cjs.map +1 -0
  57. package/dist/{chunk-5UV5VQ7J.js → chunk-RP5UATRA.js} +174 -6
  58. package/dist/chunk-RP5UATRA.js.map +1 -0
  59. package/dist/{chunk-UUPYTUGR.js → chunk-S3RBKJM5.js} +54 -27
  60. package/dist/chunk-S3RBKJM5.js.map +1 -0
  61. package/dist/{chunk-Z3WOHHG3.js → chunk-SN7NTZI6.js} +8 -6
  62. package/dist/chunk-SN7NTZI6.js.map +1 -0
  63. package/dist/{chunk-ZNZIL244.js → chunk-U6L3FAML.js} +15 -9
  64. package/dist/chunk-U6L3FAML.js.map +1 -0
  65. package/dist/{chunk-5SH5NUDW.js → chunk-UGCUNADI.js} +21 -13
  66. package/dist/chunk-UGCUNADI.js.map +1 -0
  67. package/dist/chunk-ULYRO2KY.cjs +800 -0
  68. package/dist/chunk-ULYRO2KY.cjs.map +1 -0
  69. package/dist/{chunk-CXHPP5BL.cjs → chunk-Z3DE6S64.cjs} +8 -6
  70. package/dist/chunk-Z3DE6S64.cjs.map +1 -0
  71. package/dist/{chunk-6YMQSTFF.js → chunk-ZNDIGQJD.js} +14 -6
  72. package/dist/chunk-ZNDIGQJD.js.map +1 -0
  73. package/dist/diagrams/blockdiagram/index.cjs +5 -5
  74. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  75. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  76. package/dist/diagrams/blockdiagram/index.js +1 -1
  77. package/dist/diagrams/circuit/index.d.cts +1 -1
  78. package/dist/diagrams/circuit/index.d.ts +1 -1
  79. package/dist/diagrams/ecomap/index.cjs +7 -6
  80. package/dist/diagrams/ecomap/index.d.cts +2 -2
  81. package/dist/diagrams/ecomap/index.d.ts +2 -2
  82. package/dist/diagrams/ecomap/index.js +2 -1
  83. package/dist/diagrams/entity/index.d.cts +1 -1
  84. package/dist/diagrams/entity/index.d.ts +1 -1
  85. package/dist/diagrams/fishbone/index.cjs +7 -7
  86. package/dist/diagrams/fishbone/index.d.cts +1 -1
  87. package/dist/diagrams/fishbone/index.d.ts +1 -1
  88. package/dist/diagrams/fishbone/index.js +1 -1
  89. package/dist/diagrams/flowchart/index.cjs +7 -7
  90. package/dist/diagrams/flowchart/index.d.cts +2 -2
  91. package/dist/diagrams/flowchart/index.d.ts +2 -2
  92. package/dist/diagrams/flowchart/index.js +1 -1
  93. package/dist/diagrams/genogram/index.cjs +9 -8
  94. package/dist/diagrams/genogram/index.d.cts +1 -1
  95. package/dist/diagrams/genogram/index.d.ts +1 -1
  96. package/dist/diagrams/genogram/index.js +2 -1
  97. package/dist/diagrams/ladder/index.cjs +5 -5
  98. package/dist/diagrams/ladder/index.d.cts +1 -1
  99. package/dist/diagrams/ladder/index.d.ts +1 -1
  100. package/dist/diagrams/ladder/index.js +1 -1
  101. package/dist/diagrams/logic/index.d.cts +1 -1
  102. package/dist/diagrams/logic/index.d.ts +1 -1
  103. package/dist/diagrams/orgchart/index.cjs +6 -6
  104. package/dist/diagrams/orgchart/index.d.cts +5 -2
  105. package/dist/diagrams/orgchart/index.d.ts +5 -2
  106. package/dist/diagrams/orgchart/index.js +1 -1
  107. package/dist/diagrams/pedigree/index.cjs +7 -6
  108. package/dist/diagrams/pedigree/index.d.cts +1 -1
  109. package/dist/diagrams/pedigree/index.d.ts +1 -1
  110. package/dist/diagrams/pedigree/index.js +2 -1
  111. package/dist/diagrams/phylo/index.d.cts +1 -1
  112. package/dist/diagrams/phylo/index.d.ts +1 -1
  113. package/dist/diagrams/sld/index.cjs +5 -5
  114. package/dist/diagrams/sld/index.d.cts +1 -1
  115. package/dist/diagrams/sld/index.d.ts +1 -1
  116. package/dist/diagrams/sld/index.js +1 -1
  117. package/dist/diagrams/sociogram/index.cjs +6 -5
  118. package/dist/diagrams/sociogram/index.d.cts +2 -1
  119. package/dist/diagrams/sociogram/index.d.ts +2 -1
  120. package/dist/diagrams/sociogram/index.js +2 -1
  121. package/dist/diagrams/timing/index.cjs +4 -4
  122. package/dist/diagrams/timing/index.d.cts +1 -1
  123. package/dist/diagrams/timing/index.d.ts +1 -1
  124. package/dist/diagrams/timing/index.js +1 -1
  125. package/dist/diagrams/venn/index.d.cts +1 -1
  126. package/dist/diagrams/venn/index.d.ts +1 -1
  127. package/dist/{index-ga04CTBI.d.ts → index-C97K-kuw.d.ts} +1 -1
  128. package/dist/{index-SSGpCggE.d.cts → index-lsSaw3E0.d.cts} +1 -1
  129. package/dist/index.cjs +28 -27
  130. package/dist/index.d.cts +2 -2
  131. package/dist/index.d.ts +2 -2
  132. package/dist/index.js +13 -12
  133. package/dist/react.cjs +14 -13
  134. package/dist/react.cjs.map +1 -1
  135. package/dist/react.js +13 -12
  136. package/dist/react.js.map +1 -1
  137. package/dist/{types-BcPhMdHd.d.ts → types-C4LnMEcB.d.cts} +58 -4
  138. package/dist/{types-BcPhMdHd.d.cts → types-C4LnMEcB.d.ts} +58 -4
  139. package/package.json +27 -5
  140. package/dist/chunk-4KYW63IK.js.map +0 -1
  141. package/dist/chunk-5SH5NUDW.js.map +0 -1
  142. package/dist/chunk-5UV5VQ7J.js.map +0 -1
  143. package/dist/chunk-6YMQSTFF.js.map +0 -1
  144. package/dist/chunk-7HKXU7J2.cjs.map +0 -1
  145. package/dist/chunk-7IRT3LOY.cjs.map +0 -1
  146. package/dist/chunk-CJ2A3UEQ.js.map +0 -1
  147. package/dist/chunk-CXHPP5BL.cjs.map +0 -1
  148. package/dist/chunk-GEPBET4L.js.map +0 -1
  149. package/dist/chunk-ISACNVFE.cjs.map +0 -1
  150. package/dist/chunk-LCR3KOJV.js.map +0 -1
  151. package/dist/chunk-LKOBOVNL.cjs.map +0 -1
  152. package/dist/chunk-LXNFVHDT.cjs.map +0 -1
  153. package/dist/chunk-QR7VTCI4.cjs.map +0 -1
  154. package/dist/chunk-UUPYTUGR.js.map +0 -1
  155. package/dist/chunk-X2BQKXMA.js.map +0 -1
  156. package/dist/chunk-XHZ7GXP2.cjs.map +0 -1
  157. package/dist/chunk-XVCAOGFL.cjs.map +0 -1
  158. package/dist/chunk-YN467EEQ.js.map +0 -1
  159. package/dist/chunk-YXIIWLLB.cjs.map +0 -1
  160. package/dist/chunk-Z3WOHHG3.js.map +0 -1
  161. package/dist/chunk-Z63XPA2V.cjs.map +0 -1
  162. package/dist/chunk-ZNZIL244.js.map +0 -1
  163. package/dist/chunk-ZO77FHBF.cjs.map +0 -1
@@ -1,5 +1,6 @@
1
+ import { parseLegendDirective, applyLegendOverrides, renderLegend } from './chunk-DNZFOCV7.js';
1
2
  import { resolveGenogramTheme, STROKE_WIDTH, cssCustomProperties } from './chunk-2VNMKOUO.js';
2
- import { title, text, group, el, rect, pattern, path, circle, defs, polygon, line, desc, svgRoot } from './chunk-KLJEK547.js';
3
+ import { title, text, group, pattern, path, circle, el, defs, polygon, rect, line, desc, svgRoot } from './chunk-KLJEK547.js';
3
4
 
4
5
  // src/diagrams/genogram/parser.ts
5
6
  var ParseError = class extends Error {
@@ -108,6 +109,7 @@ function parseGenogram(text2) {
108
109
  const individualsMap = /* @__PURE__ */ new Map();
109
110
  const relationships = [];
110
111
  const childSpecialProps = /* @__PURE__ */ new Map();
112
+ const legendOverrides = {};
111
113
  skipBlankAndComments(state);
112
114
  while (state.currentLine < state.lines.length) {
113
115
  skipBlankAndComments(state);
@@ -118,6 +120,10 @@ function parseGenogram(text2) {
118
120
  state.currentLine++;
119
121
  continue;
120
122
  }
123
+ if (parseLegendDirective(trimmed, legendOverrides)) {
124
+ state.currentLine++;
125
+ continue;
126
+ }
121
127
  const emotionalMatch = detectEmotionalOp(trimmed);
122
128
  if (emotionalMatch) {
123
129
  const { leftId, emotionalType, rightId: emRightId, directional, label: emLabel } = emotionalMatch;
@@ -243,11 +249,13 @@ function parseGenogram(text2) {
243
249
  });
244
250
  }
245
251
  }
252
+ const hasLegendOverrides = Object.keys(legendOverrides).length > 0 && Object.values(legendOverrides).some((v) => v !== void 0);
246
253
  return {
247
254
  type: "genogram",
248
255
  individuals: Array.from(individualsMap.values()),
249
256
  relationships,
250
- metadata: Object.keys(metadata).length > 0 ? metadata : void 0
257
+ metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
258
+ legendOverrides: hasLegendOverrides ? legendOverrides : void 0
251
259
  };
252
260
  }
253
261
  function currentLineText(state) {
@@ -1148,96 +1156,30 @@ function getRequiredDefs(individuals, includeArrowMarker = false) {
1148
1156
  }
1149
1157
  }
1150
1158
  const children = [];
1151
- if (neededFills.has("half-left")) {
1152
- children.push(
1153
- el("clipPath", { id: "schematex-genogram-clip-half-left-rect" }, [
1154
- rect({ x: "0", y: "0", width: "50%", height: "100%" })
1155
- ]),
1156
- el("clipPath", { id: "schematex-genogram-clip-half-left-circle" }, [
1157
- rect({ x: "-50", y: "-50", width: "50", height: "100" })
1158
- ])
1159
- );
1160
- }
1161
- if (neededFills.has("half-right")) {
1162
- children.push(
1163
- el("clipPath", { id: "schematex-genogram-clip-half-right-rect" }, [
1164
- rect({ x: "50%", y: "0", width: "50%", height: "100%" })
1165
- ]),
1166
- el("clipPath", { id: "schematex-genogram-clip-half-right-circle" }, [
1167
- rect({ x: "0", y: "-50", width: "50", height: "100" })
1168
- ])
1169
- );
1170
- }
1171
- if (neededFills.has("half-bottom")) {
1172
- children.push(
1173
- el("clipPath", { id: "schematex-genogram-clip-half-bottom-rect" }, [
1174
- rect({ x: "0", y: "50%", width: "100%", height: "50%" })
1175
- ]),
1176
- el("clipPath", { id: "schematex-genogram-clip-half-bottom-circle" }, [
1177
- rect({ x: "-50", y: "0", width: "100", height: "50" })
1178
- ])
1179
- );
1180
- }
1181
- if (neededFills.has("quarter")) {
1182
- children.push(
1183
- el("clipPath", { id: "schematex-genogram-clip-quarter-rect" }, [
1184
- rect({ x: "0", y: "0", width: "50%", height: "50%" })
1185
- ]),
1186
- el("clipPath", { id: "schematex-genogram-clip-quarter-circle" }, [
1187
- rect({ x: "-50", y: "-50", width: "50", height: "50" })
1188
- ])
1189
- );
1190
- }
1191
- if (neededFills.has("half-top")) {
1192
- children.push(
1193
- el("clipPath", { id: "schematex-genogram-clip-half-top-rect" }, [
1194
- rect({ x: "0", y: "0", width: "100%", height: "50%" })
1195
- ]),
1196
- el("clipPath", { id: "schematex-genogram-clip-half-top-circle" }, [
1197
- rect({ x: "-50", y: "-50", width: "100", height: "50" })
1198
- ])
1199
- );
1200
- }
1201
- if (neededFills.has("quad-tl")) {
1202
- children.push(
1203
- el("clipPath", { id: "schematex-genogram-clip-quad-tl-rect" }, [
1204
- rect({ x: "0", y: "0", width: "50%", height: "50%" })
1205
- ]),
1206
- el("clipPath", { id: "schematex-genogram-clip-quad-tl-circle" }, [
1207
- rect({ x: "-50", y: "-50", width: "50", height: "50" })
1208
- ])
1209
- );
1210
- }
1211
- if (neededFills.has("quad-tr")) {
1212
- children.push(
1213
- el("clipPath", { id: "schematex-genogram-clip-quad-tr-rect" }, [
1214
- rect({ x: "50%", y: "0", width: "50%", height: "50%" })
1215
- ]),
1216
- el("clipPath", { id: "schematex-genogram-clip-quad-tr-circle" }, [
1217
- rect({ x: "0", y: "-50", width: "50", height: "50" })
1218
- ])
1219
- );
1220
- }
1221
- if (neededFills.has("quad-bl")) {
1222
- children.push(
1223
- el("clipPath", { id: "schematex-genogram-clip-quad-bl-rect" }, [
1224
- rect({ x: "0", y: "50%", width: "50%", height: "50%" })
1225
- ]),
1226
- el("clipPath", { id: "schematex-genogram-clip-quad-bl-circle" }, [
1227
- rect({ x: "-50", y: "0", width: "50", height: "50" })
1228
- ])
1229
- );
1230
- }
1231
- if (neededFills.has("quad-br")) {
1159
+ function quadClips(suffix, x, y, w, h) {
1160
+ const r = rect({ x, y, width: w, height: h });
1232
1161
  children.push(
1233
- el("clipPath", { id: "schematex-genogram-clip-quad-br-rect" }, [
1234
- rect({ x: "50%", y: "50%", width: "50%", height: "50%" })
1235
- ]),
1236
- el("clipPath", { id: "schematex-genogram-clip-quad-br-circle" }, [
1237
- rect({ x: "0", y: "0", width: "50", height: "50" })
1238
- ])
1162
+ el(
1163
+ "clipPath",
1164
+ { id: `schematex-genogram-clip-${suffix}-rect`, clipPathUnits: "objectBoundingBox" },
1165
+ [r]
1166
+ ),
1167
+ el(
1168
+ "clipPath",
1169
+ { id: `schematex-genogram-clip-${suffix}-circle`, clipPathUnits: "objectBoundingBox" },
1170
+ [r]
1171
+ )
1239
1172
  );
1240
1173
  }
1174
+ if (neededFills.has("half-left")) quadClips("half-left", 0, 0, 0.5, 1);
1175
+ if (neededFills.has("half-right")) quadClips("half-right", 0.5, 0, 0.5, 1);
1176
+ if (neededFills.has("half-top")) quadClips("half-top", 0, 0, 1, 0.5);
1177
+ if (neededFills.has("half-bottom")) quadClips("half-bottom", 0, 0.5, 1, 0.5);
1178
+ if (neededFills.has("quarter")) quadClips("quarter", 0, 0, 0.5, 0.5);
1179
+ if (neededFills.has("quad-tl")) quadClips("quad-tl", 0, 0, 0.5, 0.5);
1180
+ if (neededFills.has("quad-tr")) quadClips("quad-tr", 0.5, 0, 0.5, 0.5);
1181
+ if (neededFills.has("quad-bl")) quadClips("quad-bl", 0, 0.5, 0.5, 0.5);
1182
+ if (neededFills.has("quad-br")) quadClips("quad-br", 0.5, 0.5, 0.5, 0.5);
1241
1183
  if (neededFills.has("striped")) {
1242
1184
  children.push(
1243
1185
  pattern(
@@ -1418,6 +1360,469 @@ function conditionFillElement(sex, half, cond) {
1418
1360
  }
1419
1361
  }
1420
1362
 
1363
+ // src/diagrams/genogram/legend.ts
1364
+ var EMOTIONAL_TYPES2 = /* @__PURE__ */ new Set([
1365
+ "harmony",
1366
+ "close",
1367
+ "bestfriends",
1368
+ "love",
1369
+ "inlove",
1370
+ "friendship",
1371
+ "hostile",
1372
+ "conflict",
1373
+ "enmity",
1374
+ "distant-hostile",
1375
+ "cutoff",
1376
+ "close-hostile",
1377
+ "fused",
1378
+ "fused-hostile",
1379
+ "distant",
1380
+ "normal",
1381
+ "nevermet",
1382
+ "abuse",
1383
+ "physical-abuse",
1384
+ "emotional-abuse",
1385
+ "sexual-abuse",
1386
+ "neglect",
1387
+ "manipulative",
1388
+ "controlling",
1389
+ "jealous",
1390
+ "focused",
1391
+ "focused-neg",
1392
+ "distrust",
1393
+ "admirer",
1394
+ "limerence"
1395
+ ]);
1396
+ var STRUCTURAL_TYPES = /* @__PURE__ */ new Set([
1397
+ "married",
1398
+ "divorced",
1399
+ "separated",
1400
+ "engaged",
1401
+ "cohabiting",
1402
+ "domestic-partnership",
1403
+ "consanguineous",
1404
+ "parent-child",
1405
+ "adopted",
1406
+ "foster",
1407
+ "twin-identical",
1408
+ "twin-fraternal"
1409
+ ]);
1410
+ var HERITAGE_PALETTE = [
1411
+ "#2563eb",
1412
+ "#059669",
1413
+ "#d97706",
1414
+ "#dc2626",
1415
+ "#7c3aed",
1416
+ "#0891b2",
1417
+ "#ca8a04",
1418
+ "#db2777"
1419
+ ];
1420
+ var SECTIONS = [
1421
+ { id: "symbols", title: "Symbols" },
1422
+ { id: "structural", title: "Structural" },
1423
+ { id: "relationships", title: "Relationships" },
1424
+ { id: "conditions", title: "Conditions" },
1425
+ { id: "heritage", title: "Heritage" },
1426
+ { id: "markers", title: "Markers" }
1427
+ ];
1428
+ function buildGenogramLegend(ast, theme) {
1429
+ const items = [];
1430
+ items.push(...buildSymbolItems(ast.individuals, theme));
1431
+ items.push(...buildStructuralItems(ast.relationships, theme));
1432
+ items.push(...buildRelationshipItems(ast.relationships));
1433
+ items.push(...buildConditionItems(ast.individuals));
1434
+ items.push(...buildHeritageItems(ast.individuals));
1435
+ items.push(...buildMarkerItems(ast.individuals, theme));
1436
+ return {
1437
+ mode: "auto",
1438
+ title: "Legend",
1439
+ position: "bottom-inline",
1440
+ columns: 1,
1441
+ sections: SECTIONS,
1442
+ items
1443
+ };
1444
+ }
1445
+ var OBVIOUS_SEX = /* @__PURE__ */ new Set(["male", "female"]);
1446
+ function buildSymbolItems(individuals, theme) {
1447
+ const items = [];
1448
+ const sexUsed = /* @__PURE__ */ new Set();
1449
+ const statusUsed = /* @__PURE__ */ new Set();
1450
+ for (const ind of individuals) {
1451
+ sexUsed.add(ind.sex);
1452
+ if (ind.status && ind.status !== "alive") statusUsed.add(ind.status);
1453
+ }
1454
+ const sexOrder = [
1455
+ "unknown",
1456
+ "other",
1457
+ "nonbinary",
1458
+ "intersex"
1459
+ ];
1460
+ for (const s of sexOrder) {
1461
+ if (!sexUsed.has(s)) continue;
1462
+ if (OBVIOUS_SEX.has(s)) continue;
1463
+ items.push({
1464
+ key: `sex.${s}`,
1465
+ label: sexLabel(s),
1466
+ kind: "shape",
1467
+ shape: sexShape(s),
1468
+ fill: theme ? sexFill(s, theme) : void 0,
1469
+ color: theme?.stroke,
1470
+ section: "symbols"
1471
+ });
1472
+ }
1473
+ const statusOrder = [
1474
+ "deceased",
1475
+ "stillborn",
1476
+ "miscarriage",
1477
+ "abortion",
1478
+ "pregnancy",
1479
+ "sab",
1480
+ "tab",
1481
+ "ectopic"
1482
+ ];
1483
+ for (const st of statusOrder) {
1484
+ if (!statusUsed.has(st)) continue;
1485
+ items.push({
1486
+ key: `status.${st}`,
1487
+ label: statusLabel(st),
1488
+ kind: "marker",
1489
+ marker: statusMarker(st),
1490
+ color: theme?.deceasedMark,
1491
+ section: "symbols"
1492
+ });
1493
+ }
1494
+ return items;
1495
+ }
1496
+ function sexFill(s, theme) {
1497
+ switch (s) {
1498
+ case "male":
1499
+ return theme.maleFill;
1500
+ case "female":
1501
+ return theme.femaleFill;
1502
+ default:
1503
+ return theme.unknownFill;
1504
+ }
1505
+ }
1506
+ function sexShape(s) {
1507
+ switch (s) {
1508
+ case "male":
1509
+ return "square";
1510
+ case "female":
1511
+ return "circle";
1512
+ case "unknown":
1513
+ return "diamond";
1514
+ case "other":
1515
+ case "nonbinary":
1516
+ return "diamond";
1517
+ case "intersex":
1518
+ return "diamond";
1519
+ default:
1520
+ return "square";
1521
+ }
1522
+ }
1523
+ function sexLabel(s) {
1524
+ switch (s) {
1525
+ case "male":
1526
+ return "Male";
1527
+ case "female":
1528
+ return "Female";
1529
+ case "unknown":
1530
+ return "Unknown";
1531
+ case "other":
1532
+ return "Other";
1533
+ case "nonbinary":
1534
+ return "Non-binary";
1535
+ case "intersex":
1536
+ return "Intersex";
1537
+ default:
1538
+ return s;
1539
+ }
1540
+ }
1541
+ function statusMarker(s) {
1542
+ switch (s) {
1543
+ case "deceased":
1544
+ case "stillborn":
1545
+ return "X";
1546
+ case "miscarriage":
1547
+ case "sab":
1548
+ case "tab":
1549
+ case "abortion":
1550
+ case "ectopic":
1551
+ return "slash";
1552
+ default:
1553
+ return "dot";
1554
+ }
1555
+ }
1556
+ function statusLabel(s) {
1557
+ switch (s) {
1558
+ case "deceased":
1559
+ return "Deceased";
1560
+ case "stillborn":
1561
+ return "Stillborn";
1562
+ case "miscarriage":
1563
+ return "Miscarriage";
1564
+ case "abortion":
1565
+ return "Abortion";
1566
+ case "pregnancy":
1567
+ return "Pregnancy";
1568
+ case "sab":
1569
+ return "Spontaneous abortion";
1570
+ case "tab":
1571
+ return "Therapeutic abortion";
1572
+ case "ectopic":
1573
+ return "Ectopic pregnancy";
1574
+ default:
1575
+ return s;
1576
+ }
1577
+ }
1578
+ var OBVIOUS_STRUCTURAL = /* @__PURE__ */ new Set([
1579
+ "married",
1580
+ // single horizontal line — universal McGoldrick
1581
+ "parent-child"
1582
+ // single vertical line — universal
1583
+ ]);
1584
+ function buildStructuralItems(rels, theme) {
1585
+ const used = /* @__PURE__ */ new Set();
1586
+ for (const r of rels) {
1587
+ if (STRUCTURAL_TYPES.has(r.type)) used.add(r.type);
1588
+ }
1589
+ const order = [
1590
+ "divorced",
1591
+ "separated",
1592
+ "engaged",
1593
+ "cohabiting",
1594
+ "domestic-partnership",
1595
+ "consanguineous",
1596
+ "adopted",
1597
+ "foster",
1598
+ "twin-identical",
1599
+ "twin-fraternal"
1600
+ ];
1601
+ const items = [];
1602
+ for (const t of order) {
1603
+ if (!used.has(t)) continue;
1604
+ if (OBVIOUS_STRUCTURAL.has(t)) continue;
1605
+ items.push(structuralItem(t, theme));
1606
+ }
1607
+ return items;
1608
+ }
1609
+ function structuralItem(t, theme) {
1610
+ const base = {
1611
+ key: t,
1612
+ label: humanize(t),
1613
+ kind: "line",
1614
+ color: theme?.stroke,
1615
+ section: "structural",
1616
+ pattern: "solid"
1617
+ };
1618
+ switch (t) {
1619
+ case "divorced":
1620
+ return { ...base, kind: "edge", marker: "X", pattern: "solid" };
1621
+ case "separated":
1622
+ return { ...base, kind: "edge", marker: "slash", pattern: "solid" };
1623
+ case "engaged":
1624
+ case "cohabiting":
1625
+ case "adopted":
1626
+ case "foster":
1627
+ return { ...base, pattern: "dashed" };
1628
+ case "consanguineous":
1629
+ return { ...base, pattern: "double" };
1630
+ case "twin-identical":
1631
+ case "twin-fraternal":
1632
+ return { ...base, pattern: "solid" };
1633
+ default:
1634
+ return base;
1635
+ }
1636
+ }
1637
+ function buildRelationshipItems(rels) {
1638
+ const used = /* @__PURE__ */ new Set();
1639
+ for (const r of rels) {
1640
+ if (EMOTIONAL_TYPES2.has(r.type)) used.add(r.type);
1641
+ }
1642
+ const order = [
1643
+ "harmony",
1644
+ "close",
1645
+ "bestfriends",
1646
+ "love",
1647
+ "inlove",
1648
+ "friendship",
1649
+ "hostile",
1650
+ "conflict",
1651
+ "enmity",
1652
+ "distant-hostile",
1653
+ "cutoff",
1654
+ "close-hostile",
1655
+ "fused",
1656
+ "fused-hostile",
1657
+ "distant",
1658
+ "normal",
1659
+ "nevermet",
1660
+ "abuse",
1661
+ "physical-abuse",
1662
+ "emotional-abuse",
1663
+ "sexual-abuse",
1664
+ "neglect",
1665
+ "manipulative",
1666
+ "controlling",
1667
+ "jealous",
1668
+ "focused",
1669
+ "focused-neg",
1670
+ "distrust",
1671
+ "admirer",
1672
+ "limerence"
1673
+ ];
1674
+ const items = [];
1675
+ for (const t of order) {
1676
+ if (!used.has(t)) continue;
1677
+ items.push({
1678
+ key: t,
1679
+ label: humanize(t),
1680
+ kind: "line",
1681
+ color: emotionalColor(t),
1682
+ pattern: emotionalPattern(t),
1683
+ strokeWidth: emotionalStrokeWidth(t),
1684
+ section: "relationships"
1685
+ });
1686
+ }
1687
+ return items;
1688
+ }
1689
+ function emotionalColor(t) {
1690
+ if (["harmony", "close", "bestfriends", "love", "inlove", "friendship"].includes(t)) return "#4caf50";
1691
+ if (["hostile", "conflict", "enmity", "distant-hostile", "cutoff"].includes(t)) return "#e53935";
1692
+ if (["close-hostile", "fused", "fused-hostile"].includes(t)) return "#9c27b0";
1693
+ if (["distant", "normal", "nevermet"].includes(t)) return "#9e9e9e";
1694
+ if (["abuse", "physical-abuse", "emotional-abuse", "sexual-abuse", "neglect"].includes(t)) return "#b71c1c";
1695
+ if (["manipulative", "controlling", "jealous"].includes(t)) return "#e65100";
1696
+ return "#1565c0";
1697
+ }
1698
+ function emotionalPattern(t) {
1699
+ if (["hostile", "conflict", "enmity", "distant-hostile", "close-hostile", "fused-hostile"].includes(t)) return "zigzag";
1700
+ if (["distant", "nevermet"].includes(t)) return "dashed";
1701
+ if (t === "cutoff") return "broken";
1702
+ return "solid";
1703
+ }
1704
+ function emotionalStrokeWidth(t) {
1705
+ if (["fused", "fused-hostile", "bestfriends"].includes(t)) return 4;
1706
+ if (["close", "close-hostile", "love", "inlove"].includes(t)) return 3;
1707
+ return 2;
1708
+ }
1709
+ function buildConditionItems(individuals) {
1710
+ const seen = /* @__PURE__ */ new Map();
1711
+ for (const ind of individuals) {
1712
+ if (!ind.conditions) continue;
1713
+ for (const c of ind.conditions) {
1714
+ if (seen.has(c.label)) continue;
1715
+ const color = c.color ?? defaultCategoryColor(c.category);
1716
+ const isFull = c.fill === "full";
1717
+ seen.set(c.label, {
1718
+ key: c.label,
1719
+ label: humanize(c.label),
1720
+ kind: isFull ? "fill" : "fill-pattern",
1721
+ color,
1722
+ shape: isFull ? void 0 : c.fill,
1723
+ section: "conditions"
1724
+ });
1725
+ }
1726
+ }
1727
+ return Array.from(seen.values());
1728
+ }
1729
+ function defaultCategoryColor(cat) {
1730
+ if (!cat) return "#9ca3af";
1731
+ const map = {
1732
+ cardiovascular: "#dc2626",
1733
+ cancer: "#a21caf",
1734
+ diabetes: "#d97706",
1735
+ "mental-health": "#2563eb",
1736
+ depression: "#1d4ed8",
1737
+ anxiety: "#0ea5e9",
1738
+ bipolar: "#6366f1",
1739
+ ptsd: "#475569",
1740
+ "substance-alcohol": "#92400e",
1741
+ "substance-drugs": "#7c2d12",
1742
+ "substance-tobacco": "#854d0e",
1743
+ neurological: "#7e22ce",
1744
+ respiratory: "#0891b2",
1745
+ autoimmune: "#be185d",
1746
+ genetic: "#0f766e",
1747
+ reproductive: "#db2777",
1748
+ "eating-disorder": "#9333ea",
1749
+ "learning-developmental": "#0369a1",
1750
+ kidney: "#b45309",
1751
+ "liver-gi": "#ca8a04",
1752
+ obesity: "#ea580c",
1753
+ other: "#9ca3af"
1754
+ };
1755
+ return map[cat] ?? "#9ca3af";
1756
+ }
1757
+ function buildHeritageItems(individuals) {
1758
+ const all = /* @__PURE__ */ new Set();
1759
+ for (const ind of individuals) {
1760
+ if (!ind.heritage) continue;
1761
+ for (const h of ind.heritage) all.add(h);
1762
+ }
1763
+ const ordered = Array.from(all).sort();
1764
+ return ordered.map((id, i) => ({
1765
+ key: id,
1766
+ label: humanize(id),
1767
+ kind: "fill",
1768
+ color: HERITAGE_PALETTE[i % HERITAGE_PALETTE.length],
1769
+ section: "heritage"
1770
+ }));
1771
+ }
1772
+ function buildMarkerItems(individuals, theme) {
1773
+ const used = /* @__PURE__ */ new Set();
1774
+ for (const ind of individuals) {
1775
+ if (!ind.markers) continue;
1776
+ for (const m of ind.markers) used.add(m);
1777
+ }
1778
+ const order = [
1779
+ "proband",
1780
+ "consultand",
1781
+ "evaluated",
1782
+ "index-person",
1783
+ "transgender",
1784
+ "no-children",
1785
+ "infertile"
1786
+ ];
1787
+ const items = [];
1788
+ for (const m of order) {
1789
+ if (!used.has(m)) continue;
1790
+ items.push(markerItem(m, theme));
1791
+ }
1792
+ return items;
1793
+ }
1794
+ function markerItem(m, theme) {
1795
+ switch (m) {
1796
+ case "proband":
1797
+ return { key: `marker.${m}`, label: "Proband (P)", kind: "marker", marker: "P", section: "markers" };
1798
+ case "consultand":
1799
+ return { key: `marker.${m}`, label: "Consultand (C)", kind: "marker", marker: "C", section: "markers" };
1800
+ case "evaluated":
1801
+ return { key: `marker.${m}`, label: "Evaluated (E)", kind: "marker", marker: "E", section: "markers" };
1802
+ case "index-person":
1803
+ return {
1804
+ key: `marker.${m}`,
1805
+ label: "Index person (focal subject)",
1806
+ kind: "shape",
1807
+ shape: "concentric-square",
1808
+ fill: "#fef3c7",
1809
+ color: theme?.stroke,
1810
+ section: "markers"
1811
+ };
1812
+ case "transgender":
1813
+ return { key: `marker.${m}`, label: "Transgender", kind: "marker", marker: "star", section: "markers" };
1814
+ case "no-children":
1815
+ return { key: `marker.${m}`, label: "No children (by choice)", kind: "marker", marker: "slash", section: "markers" };
1816
+ case "infertile":
1817
+ return { key: `marker.${m}`, label: "Infertile", kind: "marker", marker: "X", section: "markers" };
1818
+ default:
1819
+ return { key: `marker.${m}`, label: humanize(m), kind: "marker", marker: "dot", section: "markers" };
1820
+ }
1821
+ }
1822
+ function humanize(s) {
1823
+ return s.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
1824
+ }
1825
+
1421
1826
  // src/diagrams/genogram/renderer.ts
1422
1827
  function renderGenogram(layout, config, ast) {
1423
1828
  const hasDirectional = layout.edges.some((e) => e.relationship.directional);
@@ -1444,8 +1849,9 @@ function renderGenogram(layout, config, ast) {
1444
1849
  defsStr,
1445
1850
  styleStr
1446
1851
  ];
1852
+ const chartContent = [];
1447
1853
  if (chartTitle) {
1448
- layers.push(
1854
+ chartContent.push(
1449
1855
  text(
1450
1856
  {
1451
1857
  x: layout.width / 2,
@@ -1460,17 +1866,54 @@ function renderGenogram(layout, config, ast) {
1460
1866
  )
1461
1867
  );
1462
1868
  }
1463
- const contentGroup = group(
1464
- { transform: titleHeight > 0 ? `translate(0, ${titleHeight})` : void 0 },
1465
- [edgeLayers, emotionalLayer, ...nodeLayers, labelLayer, edgeLabelLayer]
1869
+ chartContent.push(
1870
+ group(
1871
+ { transform: titleHeight > 0 ? `translate(0, ${titleHeight})` : void 0 },
1872
+ [edgeLayers, emotionalLayer, ...nodeLayers, labelLayer, edgeLabelLayer]
1873
+ )
1874
+ );
1875
+ let finalWidth = layout.width;
1876
+ let finalHeight = totalHeight;
1877
+ let legendSvg = "";
1878
+ if (ast) {
1879
+ const themeBase = resolveGenogramTheme(config.theme);
1880
+ const autoSpec = buildGenogramLegend(ast, themeBase);
1881
+ const finalSpec = applyLegendOverrides(autoSpec, ast.legendOverrides);
1882
+ if (finalSpec.mode === "on" && finalSpec.items.length > 0) {
1883
+ const { svg, bbox: lb } = renderLegend(
1884
+ finalSpec,
1885
+ {
1886
+ canvasWidth: layout.width,
1887
+ canvasHeight: totalHeight,
1888
+ padding: 16,
1889
+ titleHeight
1890
+ },
1891
+ themeBase,
1892
+ { fontFamily: config.fontFamily, fontSize: config.fontSize }
1893
+ );
1894
+ if (svg) {
1895
+ legendSvg = svg;
1896
+ const overflowX = lb.x + lb.w + 8;
1897
+ const overflowY = lb.y + lb.h + 8;
1898
+ if (overflowX > finalWidth) finalWidth = overflowX;
1899
+ if (overflowY > finalHeight) finalHeight = overflowY;
1900
+ }
1901
+ }
1902
+ }
1903
+ const chartXOffset = Math.max(0, (finalWidth - layout.width) / 2);
1904
+ layers.push(
1905
+ group(
1906
+ { transform: chartXOffset > 0 ? `translate(${chartXOffset}, 0)` : void 0 },
1907
+ chartContent
1908
+ )
1466
1909
  );
1467
- layers.push(contentGroup);
1910
+ if (legendSvg) layers.push(legendSvg);
1468
1911
  return svgRoot(
1469
1912
  {
1470
- viewBox: `0 0 ${layout.width} ${totalHeight}`,
1913
+ viewBox: `0 0 ${finalWidth} ${finalHeight}`,
1471
1914
  class: "schematex-diagram schematex-genogram",
1472
- width: layout.width,
1473
- height: totalHeight
1915
+ width: finalWidth,
1916
+ height: finalHeight
1474
1917
  },
1475
1918
  layers
1476
1919
  );
@@ -1491,7 +1934,8 @@ function buildStyles(config) {
1491
1934
  .schematex-genogram-edge-divorced .schematex-genogram-divorce-mark { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; }
1492
1935
  .schematex-genogram-edge-separated .schematex-genogram-separation-mark { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; }
1493
1936
  .schematex-genogram-deceased-mark { stroke: ${t.deceasedMark}; stroke-width: ${STROKE_WIDTH.normal}; stroke-linecap: round; }
1494
- .schematex-genogram-condition-fill { fill: ${t.conditionFill}; }
1937
+ /* Inline fill on each .schematex-genogram-condition-fill element comes from cond.color. The CSS only sets a default for elements that did not receive an inline fill attribute. */
1938
+ .schematex-genogram-condition-fill:not([fill]) { fill: ${t.conditionFill}; }
1495
1939
  .schematex-genogram-age { font-family: ${config.fontFamily}; fill: ${t.text}; pointer-events: none; }
1496
1940
  .schematex-genogram-title { fill: ${t.text}; }
1497
1941
  .schematex-genogram-edge-label { font-family: ${config.fontFamily}; fill: ${t.text}; }
@@ -1792,5 +2236,5 @@ var genogram = {
1792
2236
  };
1793
2237
 
1794
2238
  export { ParseError, genogram, getRequiredDefs, layoutGenogram, parseGenogram, renderGenogram, renderIndividualSymbol };
1795
- //# sourceMappingURL=chunk-YN467EEQ.js.map
1796
- //# sourceMappingURL=chunk-YN467EEQ.js.map
2239
+ //# sourceMappingURL=chunk-2BM3HJSK.js.map
2240
+ //# sourceMappingURL=chunk-2BM3HJSK.js.map