schematex 0.2.3 → 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 (41) hide show
  1. package/dist/ai/ai-sdk.cjs +9 -9
  2. package/dist/ai/ai-sdk.js +4 -4
  3. package/dist/ai/index.cjs +12 -12
  4. package/dist/ai/index.js +4 -4
  5. package/dist/browser.cjs +6 -6
  6. package/dist/browser.js +4 -4
  7. package/dist/{chunk-MOU5QRZY.cjs → chunk-DPQYGWCT.cjs} +5 -5
  8. package/dist/{chunk-MOU5QRZY.cjs.map → chunk-DPQYGWCT.cjs.map} +1 -1
  9. package/dist/{chunk-2BM3HJSK.js → chunk-H2OEUBPO.js} +5 -3
  10. package/dist/chunk-H2OEUBPO.js.map +1 -0
  11. package/dist/{chunk-SN7NTZI6.js → chunk-J2LVOWVY.js} +171 -20
  12. package/dist/chunk-J2LVOWVY.js.map +1 -0
  13. package/dist/{chunk-6LZJTAA3.cjs → chunk-MJGDP3CS.cjs} +5 -3
  14. package/dist/chunk-MJGDP3CS.cjs.map +1 -0
  15. package/dist/{chunk-4QP37LD3.js → chunk-MR5HU5WU.js} +3 -3
  16. package/dist/{chunk-4QP37LD3.js.map → chunk-MR5HU5WU.js.map} +1 -1
  17. package/dist/{chunk-QXIGHMH2.cjs → chunk-MSYBSOU2.cjs} +6 -6
  18. package/dist/{chunk-QXIGHMH2.cjs.map → chunk-MSYBSOU2.cjs.map} +1 -1
  19. package/dist/{chunk-Z3DE6S64.cjs → chunk-UAGSCTYI.cjs} +171 -20
  20. package/dist/chunk-UAGSCTYI.cjs.map +1 -0
  21. package/dist/{chunk-S3RBKJM5.js → chunk-VPKCW4PB.js} +4 -4
  22. package/dist/{chunk-S3RBKJM5.js.map → chunk-VPKCW4PB.js.map} +1 -1
  23. package/dist/diagrams/flowchart/index.cjs +7 -7
  24. package/dist/diagrams/flowchart/index.d.cts +1 -1
  25. package/dist/diagrams/flowchart/index.d.ts +1 -1
  26. package/dist/diagrams/flowchart/index.js +1 -1
  27. package/dist/diagrams/genogram/index.cjs +8 -8
  28. package/dist/diagrams/genogram/index.js +1 -1
  29. package/dist/{index-lsSaw3E0.d.cts → index-BTZEka65.d.cts} +10 -1
  30. package/dist/{index-C97K-kuw.d.ts → index-DcU88F9i.d.ts} +10 -1
  31. package/dist/index.cjs +9 -9
  32. package/dist/index.d.cts +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.js +3 -3
  35. package/dist/react.cjs +4 -4
  36. package/dist/react.js +3 -3
  37. package/package.json +1 -1
  38. package/dist/chunk-2BM3HJSK.js.map +0 -1
  39. package/dist/chunk-6LZJTAA3.cjs.map +0 -1
  40. package/dist/chunk-SN7NTZI6.js.map +0 -1
  41. package/dist/chunk-Z3DE6S64.cjs.map +0 -1
@@ -715,13 +715,53 @@ var FC_CONST = {
715
715
  // flow-direction gap between layers
716
716
  dummyWidth: 1,
717
717
  padding: 24,
718
+ /** Latin/digit avg width at 12px font. CJK uses cjkCharWidth instead. */
718
719
  charWidth: 6.8,
719
- // approx font-size 12 proportional width
720
+ /** Full-width glyph width at 12px (CJK ideograph, kana, hangul, fullwidth). */
721
+ cjkCharWidth: 12.5,
720
722
  labelHPad: 16,
721
723
  minNodeWidth: 72,
722
- 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,
723
731
  crossingSweepIters: 24
724
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
+ }
725
765
  function greedyFAS(nodeIds, edges) {
726
766
  const outAdj = /* @__PURE__ */ new Map();
727
767
  const inAdj = /* @__PURE__ */ new Map();
@@ -1040,6 +1080,46 @@ function laneBasedXCoords(layerNodes, pathOf, nodeSpacingX, segments) {
1040
1080
  }
1041
1081
  }
1042
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
+ }
1043
1123
  const lanesPerLayer = layerNodes.map(
1044
1124
  (layer) => {
1045
1125
  const m = /* @__PURE__ */ new Map();
@@ -1114,22 +1194,52 @@ function laneBasedXCoords(layerNodes, pathOf, nodeSpacingX, segments) {
1114
1194
  }
1115
1195
  return result;
1116
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
+ }
1117
1223
  function layoutFlowchart(ast) {
1118
1224
  const dir = ast.direction;
1119
1225
  const isHorizontalDir = dir === "LR" || dir === "RL";
1120
1226
  const sizeOf = (n) => {
1227
+ const rawTextW = measureLabelWidth(n.label);
1121
1228
  const labelW = Math.min(
1122
1229
  FC_CONST.maxLabelWidth,
1123
- Math.ceil(n.label.length * FC_CONST.charWidth) + FC_CONST.labelHPad * 2
1230
+ Math.ceil(rawTextW) + FC_CONST.labelHPad * 2
1124
1231
  );
1125
1232
  let shapeW = Math.max(FC_CONST.minNodeWidth, labelW);
1126
1233
  let shapeH = FC_CONST.nodeHeight;
1127
1234
  if (n.shape === "diamond") {
1128
- shapeW = Math.max(shapeW, labelW * 1.25);
1235
+ shapeW = Math.max(shapeW, labelW * 1.4);
1129
1236
  shapeH = Math.max(shapeH, 52);
1130
1237
  }
1131
- if (n.shape === "parallelogram" || n.shape === "parallelogram-alt" || n.shape === "trapezoid" || n.shape === "trapezoid-alt") {
1132
- 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;
1133
1243
  }
1134
1244
  if (n.shape === "stadium" || n.shape === "round") {
1135
1245
  shapeW = Math.max(shapeW, shapeH + 20);
@@ -1140,7 +1250,10 @@ function layoutFlowchart(ast) {
1140
1250
  shapeH = side;
1141
1251
  }
1142
1252
  if (n.shape === "hexagon") {
1143
- shapeW = Math.max(shapeW, labelW + 44);
1253
+ shapeW = Math.max(shapeW, labelW + 48);
1254
+ }
1255
+ if (n.shape === "asymmetric") {
1256
+ shapeW += 24;
1144
1257
  }
1145
1258
  if (n.shape === "cylinder") {
1146
1259
  shapeH = Math.max(shapeH, 52);
@@ -1277,8 +1390,9 @@ function layoutFlowchart(ast) {
1277
1390
  const layerNodes = ordered.map(
1278
1391
  (layer) => layer.map((id) => lnodes.get(id))
1279
1392
  );
1393
+ const useLane = ast.subgraphs.length > 0 && hasOverlappingTopLevelClusters(ast, layerMap, sgParent);
1280
1394
  let xMap;
1281
- if (ast.subgraphs.length > 0) {
1395
+ if (useLane) {
1282
1396
  xMap = laneBasedXCoords(
1283
1397
  layerNodes,
1284
1398
  pathOf,
@@ -1292,7 +1406,6 @@ function layoutFlowchart(ast) {
1292
1406
  xMap = bkXCoords(bkLayers, segments, FC_CONST.nodeSpacingX);
1293
1407
  }
1294
1408
  const isHorizontal = dir === "LR" || dir === "RL";
1295
- const layerGap = FC_CONST.layerSpacingY;
1296
1409
  const layerHeights = layerNodes.map((layer) => {
1297
1410
  let maxH = 0;
1298
1411
  for (const n of layer) {
@@ -1302,17 +1415,56 @@ function layoutFlowchart(ast) {
1302
1415
  return maxH > 0 ? maxH : FC_CONST.nodeHeight;
1303
1416
  });
1304
1417
  const hasClusters = ast.subgraphs.length > 0;
1305
- const CLUSTER_OVERHEAD_TITLE = hasClusters ? 44 : 0;
1306
- 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;
1307
1420
  const extraTopPad = isHorizontal ? CLUSTER_OVERHEAD_SIDE : CLUSTER_OVERHEAD_TITLE;
1308
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
+ };
1309
1460
  const layerCenterY = [];
1310
1461
  {
1311
1462
  let y = FC_CONST.padding + extraTopPad;
1312
1463
  for (let li = 0; li < layerHeights.length; li++) {
1313
1464
  y += layerHeights[li] / 2;
1314
1465
  layerCenterY.push(y);
1315
- y += layerHeights[li] / 2 + layerGap;
1466
+ y += layerHeights[li] / 2;
1467
+ if (li < layerHeights.length - 1) y += layerGapAt(li);
1316
1468
  }
1317
1469
  }
1318
1470
  let minX = Infinity;
@@ -1456,8 +1608,7 @@ function layoutFlowchart(ast) {
1456
1608
  }
1457
1609
  return 0;
1458
1610
  }
1459
- const CLUSTER_PAD = 24;
1460
- const CLUSTER_TITLE_H = 20;
1611
+ const { pad: CLUSTER_PAD, titleH: CLUSTER_TITLE_H } = CLUSTER_GEO;
1461
1612
  const clusters = ast.subgraphs.map((sg) => {
1462
1613
  const memberIds = collectDescendantNodeIds(sg.id);
1463
1614
  const members = outNodes.filter((n) => memberIds.includes(n.node.id));
@@ -1558,23 +1709,23 @@ function shapeSVG(shape, w, h) {
1558
1709
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node sx-fc-node-diamond" });
1559
1710
  }
1560
1711
  case "parallelogram": {
1561
- const slant = 20;
1712
+ const slant = SHAPE_SLANT.parallelogram;
1562
1713
  const points = `${slant},0 ${w},0 ${w - slant},${h} 0,${h}`;
1563
1714
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1564
1715
  }
1565
1716
  // ── M2 additional shapes ────────────────────────────────────
1566
1717
  case "parallelogram-alt": {
1567
- const slant = 20;
1718
+ const slant = SHAPE_SLANT.parallelogram;
1568
1719
  const points = `0,0 ${w - slant},0 ${w},${h} ${slant},${h}`;
1569
1720
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1570
1721
  }
1571
1722
  case "trapezoid": {
1572
- const slant = 16;
1723
+ const slant = SHAPE_SLANT.trapezoid;
1573
1724
  const points = `0,0 ${w},0 ${w - slant},${h} ${slant},${h}`;
1574
1725
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1575
1726
  }
1576
1727
  case "trapezoid-alt": {
1577
- const slant = 16;
1728
+ const slant = SHAPE_SLANT.trapezoid;
1578
1729
  const points = `${slant},0 ${w - slant},0 ${w},${h} 0,${h}`;
1579
1730
  return chunkHDKDQAEQ_cjs.polygon({ points, class: "sx-fc-node" });
1580
1731
  }
@@ -1878,5 +2029,5 @@ exports.layoutFlowchart = layoutFlowchart;
1878
2029
  exports.parseFlowchart = parseFlowchart;
1879
2030
  exports.renderFlowchart = renderFlowchart;
1880
2031
  exports.renderFlowchartAST = renderFlowchartAST;
1881
- //# sourceMappingURL=chunk-Z3DE6S64.cjs.map
1882
- //# sourceMappingURL=chunk-Z3DE6S64.cjs.map
2032
+ //# sourceMappingURL=chunk-UAGSCTYI.cjs.map
2033
+ //# sourceMappingURL=chunk-UAGSCTYI.cjs.map