schematex 0.2.2 → 0.2.4

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-ZO77FHBF.cjs → chunk-2JDVJRR3.cjs} +14 -6
  18. package/dist/chunk-2JDVJRR3.cjs.map +1 -0
  19. package/dist/{chunk-QR7VTCI4.cjs → chunk-3YZ6FPQW.cjs} +13 -7
  20. package/dist/chunk-3YZ6FPQW.cjs.map +1 -0
  21. package/dist/{chunk-GEPBET4L.js → chunk-45KP67RR.js} +14 -6
  22. package/dist/chunk-45KP67RR.js.map +1 -0
  23. package/dist/{chunk-LKOBOVNL.cjs → chunk-5AEN2PLB.cjs} +14 -6
  24. package/dist/chunk-5AEN2PLB.cjs.map +1 -0
  25. package/dist/{chunk-7IRT3LOY.cjs → chunk-A5D2IMOX.cjs} +16 -8
  26. package/dist/chunk-A5D2IMOX.cjs.map +1 -0
  27. package/dist/{chunk-XVCAOGFL.cjs → chunk-B37IKTI7.cjs} +221 -44
  28. package/dist/chunk-B37IKTI7.cjs.map +1 -0
  29. package/dist/{chunk-ISACNVFE.cjs → chunk-B6INLQBU.cjs} +15 -9
  30. package/dist/chunk-B6INLQBU.cjs.map +1 -0
  31. package/dist/{chunk-YXIIWLLB.cjs → chunk-COLTVQWR.cjs} +174 -6
  32. package/dist/chunk-COLTVQWR.cjs.map +1 -0
  33. package/dist/chunk-DNZFOCV7.js +796 -0
  34. package/dist/chunk-DNZFOCV7.js.map +1 -0
  35. package/dist/chunk-DPQYGWCT.cjs +1121 -0
  36. package/dist/chunk-DPQYGWCT.cjs.map +1 -0
  37. package/dist/{chunk-XHZ7GXP2.cjs → chunk-E65ITQXV.cjs} +178 -22
  38. package/dist/chunk-E65ITQXV.cjs.map +1 -0
  39. package/dist/{chunk-LCR3KOJV.js → chunk-FCGHV6ZK.js} +16 -8
  40. package/dist/chunk-FCGHV6ZK.js.map +1 -0
  41. package/dist/{chunk-X2BQKXMA.js → chunk-FE6GAUNW.js} +13 -7
  42. package/dist/chunk-FE6GAUNW.js.map +1 -0
  43. package/dist/{chunk-YN467EEQ.js → chunk-H2OEUBPO.js} +547 -101
  44. package/dist/chunk-H2OEUBPO.js.map +1 -0
  45. package/dist/{chunk-Z3WOHHG3.js → chunk-J2LVOWVY.js} +177 -24
  46. package/dist/chunk-J2LVOWVY.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-Z63XPA2V.cjs → chunk-MJGDP3CS.cjs} +546 -100
  52. package/dist/chunk-MJGDP3CS.cjs.map +1 -0
  53. package/dist/chunk-MR5HU5WU.js +1112 -0
  54. package/dist/chunk-MR5HU5WU.js.map +1 -0
  55. package/dist/{chunk-7HKXU7J2.cjs → chunk-MSYBSOU2.cjs} +65 -38
  56. package/dist/chunk-MSYBSOU2.cjs.map +1 -0
  57. package/dist/{chunk-4KYW63IK.js → chunk-OC22GGQN.js} +222 -45
  58. package/dist/chunk-OC22GGQN.js.map +1 -0
  59. package/dist/{chunk-5UV5VQ7J.js → chunk-RP5UATRA.js} +174 -6
  60. package/dist/chunk-RP5UATRA.js.map +1 -0
  61. package/dist/{chunk-ZNZIL244.js → chunk-U6L3FAML.js} +15 -9
  62. package/dist/chunk-U6L3FAML.js.map +1 -0
  63. package/dist/{chunk-CXHPP5BL.cjs → chunk-UAGSCTYI.cjs} +177 -24
  64. package/dist/chunk-UAGSCTYI.cjs.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-UUPYTUGR.js → chunk-VPKCW4PB.js} +54 -27
  70. package/dist/chunk-VPKCW4PB.js.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-BTZEka65.d.cts} +11 -2
  128. package/dist/{index-SSGpCggE.d.cts → index-DcU88F9i.d.ts} +11 -2
  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
@@ -5,14 +5,16 @@ var chunkHDKDQAEQ_cjs = require('./chunk-HDKDQAEQ.cjs');
5
5
 
6
6
  // src/diagrams/flowchart/parser.ts
7
7
  var FlowchartParseError = class extends Error {
8
- constructor(message, line2, col) {
9
- super(`[line ${line2}:${col}] ${message}`);
8
+ constructor(message, line2, column, source) {
9
+ super(`[line ${line2}:${column}] ${message}`);
10
10
  this.line = line2;
11
- this.col = col;
11
+ this.column = column;
12
+ this.source = source;
12
13
  this.name = "FlowchartParseError";
13
14
  }
14
15
  line;
15
- col;
16
+ column;
17
+ source;
16
18
  };
17
19
  var DIRECTIONS = /* @__PURE__ */ new Set(["TB", "TD", "BT", "LR", "RL"]);
18
20
  function parseShapeSuffix(line2, pos) {
@@ -713,13 +715,53 @@ var FC_CONST = {
713
715
  // flow-direction gap between layers
714
716
  dummyWidth: 1,
715
717
  padding: 24,
718
+ /** Latin/digit avg width at 12px font. CJK uses cjkCharWidth instead. */
716
719
  charWidth: 6.8,
717
- // approx font-size 12 proportional width
720
+ /** Full-width glyph width at 12px (CJK ideograph, kana, hangul, fullwidth). */
721
+ cjkCharWidth: 12.5,
718
722
  labelHPad: 16,
719
723
  minNodeWidth: 72,
720
- maxLabelWidth: 220,
724
+ /**
725
+ * Cap on per-line label width. Until line-wrapping lands, this clamp is
726
+ * a soft contract: nodes never grow past this, and any overflow becomes
727
+ * the caller's problem. Set generously so common CJK sentences (≤30
728
+ * full-width chars) still fit without truncation or text overflow.
729
+ */
730
+ maxLabelWidth: 420,
721
731
  crossingSweepIters: 24
722
732
  };
733
+ var SHAPE_SLANT = {
734
+ parallelogram: 20,
735
+ trapezoid: 16
736
+ };
737
+ var CLUSTER_GEO = {
738
+ pad: 24,
739
+ titleH: 20,
740
+ /** Extra visible separation between two sequential cluster bboxes. */
741
+ gap: 12
742
+ };
743
+ function isFullWidth(code) {
744
+ if (code >= 12288 && code <= 12351) return true;
745
+ if (code >= 12352 && code <= 12447) return true;
746
+ if (code >= 12448 && code <= 12543) return true;
747
+ if (code >= 13312 && code <= 19903) return true;
748
+ if (code >= 19968 && code <= 40959) return true;
749
+ if (code >= 44032 && code <= 55215) return true;
750
+ if (code >= 63744 && code <= 64255) return true;
751
+ if (code >= 65280 && code <= 65376) return true;
752
+ if (code >= 65504 && code <= 65510) return true;
753
+ if (code >= 131072 && code <= 196607) return true;
754
+ return false;
755
+ }
756
+ function measureLabelWidth(label) {
757
+ let w = 0;
758
+ for (const ch of label) {
759
+ const code = ch.codePointAt(0) ?? 0;
760
+ if (isFullWidth(code)) w += FC_CONST.cjkCharWidth;
761
+ else w += FC_CONST.charWidth;
762
+ }
763
+ return w;
764
+ }
723
765
  function greedyFAS(nodeIds, edges) {
724
766
  const outAdj = /* @__PURE__ */ new Map();
725
767
  const inAdj = /* @__PURE__ */ new Map();
@@ -1038,6 +1080,46 @@ function laneBasedXCoords(layerNodes, pathOf, nodeSpacingX, segments) {
1038
1080
  }
1039
1081
  }
1040
1082
  }
1083
+ const clusterLanes = laneOrder.filter((l) => l !== null);
1084
+ if (clusterLanes.length >= 2 && laneOrder.includes(null)) {
1085
+ const tmpPartition = layerNodes.map(
1086
+ (layer) => {
1087
+ const m = /* @__PURE__ */ new Map();
1088
+ for (const n of layer) {
1089
+ if (n.isDummy) continue;
1090
+ const lane = laneOf(n.id);
1091
+ if (!m.has(lane)) m.set(lane, []);
1092
+ m.get(lane).push(n);
1093
+ }
1094
+ return m;
1095
+ }
1096
+ );
1097
+ const clusterOccupiedLayers = /* @__PURE__ */ new Set();
1098
+ for (let li = 0; li < tmpPartition.length; li++) {
1099
+ for (const lane of clusterLanes) {
1100
+ if ((tmpPartition[li].get(lane) ?? []).length > 0) {
1101
+ clusterOccupiedLayers.add(li);
1102
+ }
1103
+ }
1104
+ }
1105
+ let nullIsBoundary = true;
1106
+ for (let li = 0; li < tmpPartition.length; li++) {
1107
+ const nm = tmpPartition[li].get(null) ?? [];
1108
+ if (nm.length > 0 && clusterOccupiedLayers.has(li)) {
1109
+ nullIsBoundary = false;
1110
+ break;
1111
+ }
1112
+ }
1113
+ if (nullIsBoundary) {
1114
+ const mid = Math.floor(clusterLanes.length / 2);
1115
+ laneOrder.length = 0;
1116
+ laneOrder.push(
1117
+ ...clusterLanes.slice(0, mid),
1118
+ null,
1119
+ ...clusterLanes.slice(mid)
1120
+ );
1121
+ }
1122
+ }
1041
1123
  const lanesPerLayer = layerNodes.map(
1042
1124
  (layer) => {
1043
1125
  const m = /* @__PURE__ */ new Map();
@@ -1112,22 +1194,52 @@ function laneBasedXCoords(layerNodes, pathOf, nodeSpacingX, segments) {
1112
1194
  }
1113
1195
  return result;
1114
1196
  }
1197
+ function hasOverlappingTopLevelClusters(ast, layerMap, sgParent) {
1198
+ const topLevel = ast.subgraphs.filter((sg) => !sgParent.get(sg.id));
1199
+ if (topLevel.length < 2) return false;
1200
+ const collect = (sgId) => {
1201
+ const sg = ast.subgraphs.find((s) => s.id === sgId);
1202
+ if (!sg) return [];
1203
+ const ids = [...sg.children];
1204
+ for (const childSgId of sg.subgraphs) ids.push(...collect(childSgId));
1205
+ return ids;
1206
+ };
1207
+ const ranges = topLevel.map((sg) => {
1208
+ const ids = collect(sg.id);
1209
+ if (ids.length === 0) return { min: 0, max: -1 };
1210
+ const layers = ids.map((id) => layerMap.get(id) ?? 0);
1211
+ return { min: Math.min(...layers), max: Math.max(...layers) };
1212
+ });
1213
+ for (let i = 0; i < ranges.length; i++) {
1214
+ for (let j = i + 1; j < ranges.length; j++) {
1215
+ const a = ranges[i];
1216
+ const b = ranges[j];
1217
+ if (a.max < a.min || b.max < b.min) continue;
1218
+ if (a.min <= b.max && b.min <= a.max) return true;
1219
+ }
1220
+ }
1221
+ return false;
1222
+ }
1115
1223
  function layoutFlowchart(ast) {
1116
1224
  const dir = ast.direction;
1117
1225
  const isHorizontalDir = dir === "LR" || dir === "RL";
1118
1226
  const sizeOf = (n) => {
1227
+ const rawTextW = measureLabelWidth(n.label);
1119
1228
  const labelW = Math.min(
1120
1229
  FC_CONST.maxLabelWidth,
1121
- Math.ceil(n.label.length * FC_CONST.charWidth) + FC_CONST.labelHPad * 2
1230
+ Math.ceil(rawTextW) + FC_CONST.labelHPad * 2
1122
1231
  );
1123
1232
  let shapeW = Math.max(FC_CONST.minNodeWidth, labelW);
1124
1233
  let shapeH = FC_CONST.nodeHeight;
1125
1234
  if (n.shape === "diamond") {
1126
- shapeW = Math.max(shapeW, labelW * 1.25);
1235
+ shapeW = Math.max(shapeW, labelW * 1.4);
1127
1236
  shapeH = Math.max(shapeH, 52);
1128
1237
  }
1129
- if (n.shape === "parallelogram" || n.shape === "parallelogram-alt" || n.shape === "trapezoid" || n.shape === "trapezoid-alt") {
1130
- shapeW += 20;
1238
+ if (n.shape === "parallelogram" || n.shape === "parallelogram-alt") {
1239
+ shapeW += 2 * SHAPE_SLANT.parallelogram + 8;
1240
+ }
1241
+ if (n.shape === "trapezoid" || n.shape === "trapezoid-alt") {
1242
+ shapeW += 2 * SHAPE_SLANT.trapezoid + 8;
1131
1243
  }
1132
1244
  if (n.shape === "stadium" || n.shape === "round") {
1133
1245
  shapeW = Math.max(shapeW, shapeH + 20);
@@ -1138,7 +1250,10 @@ function layoutFlowchart(ast) {
1138
1250
  shapeH = side;
1139
1251
  }
1140
1252
  if (n.shape === "hexagon") {
1141
- shapeW = Math.max(shapeW, labelW + 44);
1253
+ shapeW = Math.max(shapeW, labelW + 48);
1254
+ }
1255
+ if (n.shape === "asymmetric") {
1256
+ shapeW += 24;
1142
1257
  }
1143
1258
  if (n.shape === "cylinder") {
1144
1259
  shapeH = Math.max(shapeH, 52);
@@ -1275,8 +1390,9 @@ function layoutFlowchart(ast) {
1275
1390
  const layerNodes = ordered.map(
1276
1391
  (layer) => layer.map((id) => lnodes.get(id))
1277
1392
  );
1393
+ const useLane = ast.subgraphs.length > 0 && hasOverlappingTopLevelClusters(ast, layerMap, sgParent);
1278
1394
  let xMap;
1279
- if (ast.subgraphs.length > 0) {
1395
+ if (useLane) {
1280
1396
  xMap = laneBasedXCoords(
1281
1397
  layerNodes,
1282
1398
  pathOf,
@@ -1290,7 +1406,6 @@ function layoutFlowchart(ast) {
1290
1406
  xMap = bkXCoords(bkLayers, segments, FC_CONST.nodeSpacingX);
1291
1407
  }
1292
1408
  const isHorizontal = dir === "LR" || dir === "RL";
1293
- const layerGap = FC_CONST.layerSpacingY;
1294
1409
  const layerHeights = layerNodes.map((layer) => {
1295
1410
  let maxH = 0;
1296
1411
  for (const n of layer) {
@@ -1300,17 +1415,56 @@ function layoutFlowchart(ast) {
1300
1415
  return maxH > 0 ? maxH : FC_CONST.nodeHeight;
1301
1416
  });
1302
1417
  const hasClusters = ast.subgraphs.length > 0;
1303
- const CLUSTER_OVERHEAD_TITLE = hasClusters ? 44 : 0;
1304
- const CLUSTER_OVERHEAD_SIDE = hasClusters ? 24 : 0;
1418
+ const CLUSTER_OVERHEAD_TITLE = hasClusters ? CLUSTER_GEO.pad + CLUSTER_GEO.titleH : 0;
1419
+ const CLUSTER_OVERHEAD_SIDE = hasClusters ? CLUSTER_GEO.pad : 0;
1305
1420
  const extraTopPad = isHorizontal ? CLUSTER_OVERHEAD_SIDE : CLUSTER_OVERHEAD_TITLE;
1306
1421
  const extraLeftPad = isHorizontal ? CLUSTER_OVERHEAD_TITLE : CLUSTER_OVERHEAD_SIDE;
1422
+ const topLevelOf = (sgId) => {
1423
+ let cur = sgId;
1424
+ let safety = 32;
1425
+ while (safety-- > 0) {
1426
+ const p = sgParent.get(cur);
1427
+ if (!p) return cur;
1428
+ cur = p;
1429
+ }
1430
+ return cur;
1431
+ };
1432
+ const clustersAtLayer = layerNodes.map(() => /* @__PURE__ */ new Set());
1433
+ for (let li = 0; li < layerNodes.length; li++) {
1434
+ for (const n of layerNodes[li]) {
1435
+ if (n.isDummy) continue;
1436
+ const parent = parentOf.get(n.id);
1437
+ if (!parent) continue;
1438
+ clustersAtLayer[li].add(topLevelOf(parent));
1439
+ }
1440
+ }
1441
+ const layerGapAt = (li) => {
1442
+ const a = clustersAtLayer[li] ?? /* @__PURE__ */ new Set();
1443
+ const b = clustersAtLayer[li + 1] ?? /* @__PURE__ */ new Set();
1444
+ let hasExit = false;
1445
+ for (const c of a) if (!b.has(c)) {
1446
+ hasExit = true;
1447
+ break;
1448
+ }
1449
+ let hasEntry = false;
1450
+ for (const c of b) if (!a.has(c)) {
1451
+ hasEntry = true;
1452
+ break;
1453
+ }
1454
+ let required = 0;
1455
+ if (hasExit) required += CLUSTER_GEO.pad;
1456
+ if (hasEntry) required += CLUSTER_GEO.pad + CLUSTER_GEO.titleH;
1457
+ if (hasExit && hasEntry) required += CLUSTER_GEO.gap;
1458
+ return Math.max(FC_CONST.layerSpacingY, required);
1459
+ };
1307
1460
  const layerCenterY = [];
1308
1461
  {
1309
1462
  let y = FC_CONST.padding + extraTopPad;
1310
1463
  for (let li = 0; li < layerHeights.length; li++) {
1311
1464
  y += layerHeights[li] / 2;
1312
1465
  layerCenterY.push(y);
1313
- y += layerHeights[li] / 2 + layerGap;
1466
+ y += layerHeights[li] / 2;
1467
+ if (li < layerHeights.length - 1) y += layerGapAt(li);
1314
1468
  }
1315
1469
  }
1316
1470
  let minX = Infinity;
@@ -1454,8 +1608,7 @@ function layoutFlowchart(ast) {
1454
1608
  }
1455
1609
  return 0;
1456
1610
  }
1457
- const CLUSTER_PAD = 24;
1458
- const CLUSTER_TITLE_H = 20;
1611
+ const { pad: CLUSTER_PAD, titleH: CLUSTER_TITLE_H } = CLUSTER_GEO;
1459
1612
  const clusters = ast.subgraphs.map((sg) => {
1460
1613
  const memberIds = collectDescendantNodeIds(sg.id);
1461
1614
  const members = outNodes.filter((n) => memberIds.includes(n.node.id));
@@ -1556,23 +1709,23 @@ function shapeSVG(shape, w, h) {
1556
1709
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node sx-fc-node-diamond" });
1557
1710
  }
1558
1711
  case "parallelogram": {
1559
- const slant = 20;
1712
+ const slant = SHAPE_SLANT.parallelogram;
1560
1713
  const points = `${slant},0 ${w},0 ${w - slant},${h} 0,${h}`;
1561
1714
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1562
1715
  }
1563
1716
  // ── M2 additional shapes ────────────────────────────────────
1564
1717
  case "parallelogram-alt": {
1565
- const slant = 20;
1718
+ const slant = SHAPE_SLANT.parallelogram;
1566
1719
  const points = `0,0 ${w - slant},0 ${w},${h} ${slant},${h}`;
1567
1720
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1568
1721
  }
1569
1722
  case "trapezoid": {
1570
- const slant = 16;
1723
+ const slant = SHAPE_SLANT.trapezoid;
1571
1724
  const points = `0,0 ${w},0 ${w - slant},${h} ${slant},${h}`;
1572
1725
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1573
1726
  }
1574
1727
  case "trapezoid-alt": {
1575
- const slant = 16;
1728
+ const slant = SHAPE_SLANT.trapezoid;
1576
1729
  const points = `${slant},0 ${w - slant},0 ${w},${h} 0,${h}`;
1577
1730
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1578
1731
  }
@@ -1876,5 +2029,5 @@ exports.layoutFlowchart = layoutFlowchart;
1876
2029
  exports.parseFlowchart = parseFlowchart;
1877
2030
  exports.renderFlowchart = renderFlowchart;
1878
2031
  exports.renderFlowchartAST = renderFlowchartAST;
1879
- //# sourceMappingURL=chunk-CXHPP5BL.cjs.map
1880
- //# sourceMappingURL=chunk-CXHPP5BL.cjs.map
2032
+ //# sourceMappingURL=chunk-UAGSCTYI.cjs.map
2033
+ //# sourceMappingURL=chunk-UAGSCTYI.cjs.map