@diagrammo/dgmo 0.33.0 → 0.34.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/dist/index.js CHANGED
@@ -29062,63 +29062,6 @@ function ensureArrowMarkers(defs, colors) {
29062
29062
  ).attr("fill", color);
29063
29063
  }
29064
29064
  }
29065
- function edgePolylineMidpoint(points) {
29066
- if (points.length === 0) return { x: 0, y: 0 };
29067
- if (points.length === 1) return { x: points[0].x, y: points[0].y };
29068
- let total = 0;
29069
- const segLen = [];
29070
- for (let k = 1; k < points.length; k++) {
29071
- const len = Math.hypot(
29072
- points[k].x - points[k - 1].x,
29073
- points[k].y - points[k - 1].y
29074
- );
29075
- segLen.push(len);
29076
- total += len;
29077
- }
29078
- let half = total / 2;
29079
- for (let k = 1; k < points.length; k++) {
29080
- const len = segLen[k - 1];
29081
- if (half <= len || k === points.length - 1) {
29082
- const t = len === 0 ? 0 : Math.min(1, half / len);
29083
- return {
29084
- x: points[k - 1].x + (points[k].x - points[k - 1].x) * t,
29085
- y: points[k - 1].y + (points[k].y - points[k - 1].y) * t
29086
- };
29087
- }
29088
- half -= len;
29089
- }
29090
- const last = points[points.length - 1];
29091
- return { x: last.x, y: last.y };
29092
- }
29093
- function resolveEdgeLabelOverlaps(labels) {
29094
- const MAX_PASSES = 8;
29095
- const PAD = 4;
29096
- for (let pass = 0; pass < MAX_PASSES; pass++) {
29097
- let moved = false;
29098
- for (let i = 0; i < labels.length; i++) {
29099
- for (let j = i + 1; j < labels.length; j++) {
29100
- const a = labels[i];
29101
- const b = labels[j];
29102
- const dx = Math.abs(a.x - b.x);
29103
- const dy = Math.abs(a.y - b.y);
29104
- const overlapX = (a.width + b.width) / 2 + PAD - dx;
29105
- const overlapY = (a.height + b.height) / 2 + PAD - dy;
29106
- if (overlapX > 0 && overlapY > 0) {
29107
- const shift = overlapY / 2 + 1;
29108
- if (a.y < b.y) {
29109
- a.y -= shift;
29110
- b.y += shift;
29111
- } else {
29112
- a.y += shift;
29113
- b.y -= shift;
29114
- }
29115
- moved = true;
29116
- }
29117
- }
29118
- }
29119
- if (!moved) break;
29120
- }
29121
- }
29122
29065
  function renderBoxesAndLines(container, parsed, layout, palette, isDark, options) {
29123
29066
  const {
29124
29067
  onClickItem,
@@ -29325,8 +29268,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29325
29268
  groupG.append("text").attr("class", "bl-group-label").attr("x", gx + group.width / 2).attr("y", gy + 18).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sGroupLabelFontSize).attr("font-weight", "600").attr("fill", palette.text).text(group.label);
29326
29269
  }
29327
29270
  }
29328
- const labelPositions = [];
29329
- const edgeGroups = /* @__PURE__ */ new Map();
29330
29271
  for (let i = 0; i < layout.edges.length; i++) {
29331
29272
  const le = layout.edges[i];
29332
29273
  const color = edgeColorMap.get(i) ?? palette.textMuted;
@@ -29345,7 +29286,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29345
29286
  const nodeLayout = layoutNodeMap.get(le.source);
29346
29287
  if (nodeLayout) {
29347
29288
  const edgeG2 = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
29348
- edgeGroups.set(i, edgeG2);
29349
29289
  const markerId2 = `bl-arrow-${color.replace("#", "")}`;
29350
29290
  const cx = nodeLayout.x;
29351
29291
  const cy = nodeLayout.y;
@@ -29394,7 +29334,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29394
29334
  }
29395
29335
  if (points.length < 2) continue;
29396
29336
  const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
29397
- edgeGroups.set(i, edgeG);
29398
29337
  const markerId = `bl-arrow-${color.replace("#", "")}`;
29399
29338
  const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
29400
29339
  const path = edgeG.append("path").attr("class", "bl-edge").attr("d", gen(points) ?? "").attr("fill", "none").attr("stroke", color).attr("stroke-width", sEdgeStrokeWidth).attr("marker-end", `url(#${markerId})`);
@@ -29402,31 +29341,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29402
29341
  const revId = `bl-arrow-rev-${color.replace("#", "")}`;
29403
29342
  path.attr("marker-start", `url(#${revId})`);
29404
29343
  }
29405
- if (le.label && le.points.length > 0) {
29406
- const lw = measureText(le.label, sEdgeLabelFontSize);
29407
- const labelH = sEdgeLabelFontSize + 6;
29408
- const mid = edgePolylineMidpoint(le.points);
29409
- let ly = mid.y;
29410
- if (le.parallelCount > 1 && le.yOffset !== 0) {
29411
- ly += (le.yOffset < 0 ? -labelH : labelH) * 0.5;
29412
- }
29413
- labelPositions.push({
29414
- x: mid.x,
29415
- y: ly,
29416
- width: lw + 8,
29417
- height: labelH,
29418
- idx: i
29419
- });
29420
- }
29421
- }
29422
- resolveEdgeLabelOverlaps(labelPositions);
29423
- for (const lp of labelPositions) {
29424
- const le = layout.edges[lp.idx];
29425
- if (!le.label) continue;
29426
- const edgeG = edgeGroups.get(lp.idx);
29427
- const target = edgeG ?? diagramG;
29428
- target.append("rect").attr("x", lp.x - lp.width / 2).attr("y", lp.y - lp.height / 2).attr("width", lp.width).attr("height", lp.height).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.85);
29429
- target.append("text").attr("x", lp.x).attr("y", lp.y + sEdgeLabelFontSize / 3).attr("text-anchor", "middle").attr("font-size", sEdgeLabelFontSize).attr("fill", palette.textMuted).text(le.label);
29430
29344
  }
29431
29345
  for (const ln of layout.nodes) {
29432
29346
  const node = nodeMap.get(ln.label);
@@ -29477,8 +29391,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29477
29391
  nodeG.append("rect").attr("x", x).attr("y", y).attr("width", ln.width).attr("height", ln.height).attr("rx", NODE_RX).attr("ry", NODE_RX).attr("fill", colors.fill).attr("stroke", colors.stroke).attr("stroke-width", sNodeStrokeWidth);
29478
29392
  const desc = node.description;
29479
29393
  if (desc && desc.length > 0 && !hideDescriptions) {
29480
- const MAX_LABEL_LINES3 = 3;
29481
- const fitted = fitLabelToHeader(node.label, ln.width, MAX_LABEL_LINES3);
29394
+ const MAX_LABEL_LINES4 = 3;
29395
+ const fitted = fitLabelToHeader(node.label, ln.width, MAX_LABEL_LINES4);
29482
29396
  const labelLines = fitted.lines;
29483
29397
  const labelLineH = fitted.fontSize * 1.3;
29484
29398
  const labelTotalH = labelLines.length * labelLineH;
@@ -29612,6 +29526,35 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29612
29526
  }
29613
29527
  }
29614
29528
  }
29529
+ const labelLayer = diagramG.append("g").attr("class", "bl-edge-labels");
29530
+ const labelLineHeight = sEdgeLabelFontSize * 1.3;
29531
+ for (const le of layout.edges) {
29532
+ if (!le.labelLines || le.labelLines.length === 0) continue;
29533
+ if (le.labelX === void 0 || le.labelY === void 0) continue;
29534
+ const lx = le.labelX;
29535
+ const ly = le.labelY;
29536
+ if (hidden.size > 0) {
29537
+ let isHidden = false;
29538
+ for (const [groupKey, hiddenVals] of hidden) {
29539
+ const val = le.metadata[groupKey];
29540
+ if (val && hiddenVals.has(val.toLowerCase())) {
29541
+ isHidden = true;
29542
+ break;
29543
+ }
29544
+ }
29545
+ if (isHidden) continue;
29546
+ }
29547
+ const lw = le.labelWidth ?? 0;
29548
+ const lh = le.labelHeight ?? sEdgeLabelFontSize + 6;
29549
+ const lines = le.labelLines;
29550
+ const labelG = labelLayer.append("g").attr("class", "bl-edge-label").attr("data-line-number", String(le.lineNumber));
29551
+ labelG.append("rect").attr("x", lx - lw / 2).attr("y", ly - lh / 2).attr("width", lw).attr("height", lh).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.72);
29552
+ const text = labelG.append("text").attr("x", lx).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sEdgeLabelFontSize).attr("fill", palette.textMuted);
29553
+ const firstY = ly - (lines.length - 1) / 2 * labelLineHeight + sEdgeLabelFontSize / 3;
29554
+ lines.forEach((line11, k) => {
29555
+ text.append("tspan").attr("x", lx).attr("y", firstY + k * labelLineHeight).text(line11);
29556
+ });
29557
+ }
29615
29558
  const hasDescriptions = parsed.nodes.some(
29616
29559
  (n) => n.description && n.description.length > 0
29617
29560
  );
@@ -29726,6 +29669,222 @@ var init_renderer6 = __esm({
29726
29669
  }
29727
29670
  });
29728
29671
 
29672
+ // src/boxes-and-lines/label-placement.ts
29673
+ function measureEdgeLabel(label, fontSize = EDGE_LABEL_FONT_SIZE6, maxWidth = LABEL_MAX_WIDTH) {
29674
+ let lines = wrapTextToWidth(label, fontSize, maxWidth, { hardBreak: true });
29675
+ if (lines.length > MAX_LABEL_LINES) {
29676
+ const kept = lines.slice(0, MAX_LABEL_LINES - 1);
29677
+ const rest = lines.slice(MAX_LABEL_LINES - 1).join(" ");
29678
+ kept.push(truncateText(rest, fontSize, maxWidth));
29679
+ lines = kept;
29680
+ }
29681
+ let textW = 0;
29682
+ for (const ln of lines) {
29683
+ const w = measureText(ln, fontSize);
29684
+ if (w > textW) textW = w;
29685
+ }
29686
+ return {
29687
+ lines,
29688
+ width: textW + 2 * H_PAD,
29689
+ height: lines.length * fontSize * LABEL_LINE_HEIGHT + 2 * V_PAD
29690
+ };
29691
+ }
29692
+ function edgePolylineMidpoint(points) {
29693
+ return pointAtArcFraction(points, 0.5).p;
29694
+ }
29695
+ function pointAtArcFraction(points, t) {
29696
+ if (points.length === 0) return { p: { x: 0, y: 0 }, nx: 0, ny: 1 };
29697
+ if (points.length === 1)
29698
+ return { p: { x: points[0].x, y: points[0].y }, nx: 0, ny: 1 };
29699
+ const segLen = [];
29700
+ let total = 0;
29701
+ for (let k = 1; k < points.length; k++) {
29702
+ const len = Math.hypot(
29703
+ points[k].x - points[k - 1].x,
29704
+ points[k].y - points[k - 1].y
29705
+ );
29706
+ segLen.push(len);
29707
+ total += len;
29708
+ }
29709
+ let want = total * Math.max(0, Math.min(1, t));
29710
+ for (let k = 1; k < points.length; k++) {
29711
+ const len = segLen[k - 1];
29712
+ if (want <= len || k === points.length - 1) {
29713
+ const f = len === 0 ? 0 : Math.min(1, want / len);
29714
+ const ax = points[k - 1].x;
29715
+ const ay = points[k - 1].y;
29716
+ const bx = points[k].x;
29717
+ const by = points[k].y;
29718
+ const dx = bx - ax;
29719
+ const dy = by - ay;
29720
+ const dlen = Math.hypot(dx, dy) || 1;
29721
+ return {
29722
+ p: { x: ax + dx * f, y: ay + dy * f },
29723
+ nx: -dy / dlen,
29724
+ ny: dx / dlen
29725
+ };
29726
+ }
29727
+ want -= len;
29728
+ }
29729
+ const last = points[points.length - 1];
29730
+ return { p: { x: last.x, y: last.y }, nx: 0, ny: 1 };
29731
+ }
29732
+ function rectFromCenter(cx, cy, w, h) {
29733
+ return {
29734
+ minX: cx - w / 2,
29735
+ minY: cy - h / 2,
29736
+ maxX: cx + w / 2,
29737
+ maxY: cy + h / 2
29738
+ };
29739
+ }
29740
+ function overlapsAny(cx, cy, w, h, obstacles, pad2) {
29741
+ const minX = cx - w / 2 - pad2;
29742
+ const minY = cy - h / 2 - pad2;
29743
+ const maxX = cx + w / 2 + pad2;
29744
+ const maxY = cy + h / 2 + pad2;
29745
+ for (const o of obstacles) {
29746
+ if (minX < o.maxX && maxX > o.minX && minY < o.maxY && maxY > o.minY)
29747
+ return true;
29748
+ }
29749
+ return false;
29750
+ }
29751
+ function slideFractions() {
29752
+ const out = [0.5];
29753
+ for (let k = 1; k <= SLIDE_SAMPLES; k++) {
29754
+ const off = k * 0.08;
29755
+ if (0.5 - off >= 0.12) out.push(0.5 - off);
29756
+ if (0.5 + off <= 0.88) out.push(0.5 + off);
29757
+ }
29758
+ return out;
29759
+ }
29760
+ function findClearPosition(w, h, points, obstacles) {
29761
+ const ts = slideFractions();
29762
+ for (const t of ts) {
29763
+ const { p } = pointAtArcFraction(points, t);
29764
+ if (!overlapsAny(p.x, p.y, w, h, obstacles, BOX_CLEAR_PAD)) return p;
29765
+ }
29766
+ for (let mag = PERP_STEP; mag <= PERP_MAX; mag += PERP_STEP) {
29767
+ for (const t of ts) {
29768
+ const { p, nx, ny } = pointAtArcFraction(points, t);
29769
+ for (const sign of [-1, 1]) {
29770
+ const x = p.x + nx * mag * sign;
29771
+ const y = p.y + ny * mag * sign;
29772
+ if (!overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD)) return { x, y };
29773
+ }
29774
+ }
29775
+ }
29776
+ return null;
29777
+ }
29778
+ function resolveLabelOverlaps(boxes) {
29779
+ const MAX_PASSES = 8;
29780
+ const PAD = 4;
29781
+ for (let pass = 0; pass < MAX_PASSES; pass++) {
29782
+ let moved = false;
29783
+ for (let i = 0; i < boxes.length; i++) {
29784
+ for (let j = i + 1; j < boxes.length; j++) {
29785
+ const a = boxes[i];
29786
+ const b = boxes[j];
29787
+ const dx = Math.abs(a.cx - b.cx);
29788
+ const dy = Math.abs(a.cy - b.cy);
29789
+ const overlapX = (a.w + b.w) / 2 + PAD - dx;
29790
+ const overlapY = (a.h + b.h) / 2 + PAD - dy;
29791
+ if (overlapX > 0 && overlapY > 0) {
29792
+ const shift = overlapY / 2 + 1;
29793
+ if (a.cy < b.cy) {
29794
+ a.cy -= shift;
29795
+ b.cy += shift;
29796
+ } else {
29797
+ a.cy += shift;
29798
+ b.cy -= shift;
29799
+ }
29800
+ moved = true;
29801
+ }
29802
+ }
29803
+ }
29804
+ if (!moved) break;
29805
+ }
29806
+ }
29807
+ function placeEdgeLabels(layout, opts) {
29808
+ const fontSize = opts?.fontSize ?? EDGE_LABEL_FONT_SIZE6;
29809
+ const maxWidth = opts?.maxWidth ?? LABEL_MAX_WIDTH;
29810
+ const obstacles = [];
29811
+ for (const n of layout.nodes)
29812
+ obstacles.push(rectFromCenter(n.x, n.y, n.width, n.height));
29813
+ for (const g of layout.groups)
29814
+ if (g.collapsed)
29815
+ obstacles.push(rectFromCenter(g.x, g.y, g.width, g.height));
29816
+ const boxes = [];
29817
+ layout.edges.forEach((e, idx) => {
29818
+ if (!e.label || e.points.length < 2) return;
29819
+ const m = measureEdgeLabel(e.label, fontSize, maxWidth);
29820
+ const mid = edgePolylineMidpoint(e.points);
29821
+ let cy = mid.y;
29822
+ if (e.parallelCount > 1 && e.yOffset !== 0)
29823
+ cy += (e.yOffset < 0 ? -1 : 1) * (m.height / 2);
29824
+ boxes.push({
29825
+ edgeIdx: idx,
29826
+ cx: mid.x,
29827
+ cy,
29828
+ w: m.width,
29829
+ h: m.height,
29830
+ lines: m.lines,
29831
+ resolved: true
29832
+ });
29833
+ });
29834
+ for (const box of boxes) {
29835
+ if (!overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
29836
+ continue;
29837
+ const e = layout.edges[box.edgeIdx];
29838
+ const clear = findClearPosition(box.w, box.h, e.points, obstacles);
29839
+ if (clear) {
29840
+ box.cx = clear.x;
29841
+ box.cy = clear.y;
29842
+ } else {
29843
+ box.resolved = false;
29844
+ }
29845
+ }
29846
+ resolveLabelOverlaps(boxes);
29847
+ for (const box of boxes) {
29848
+ if (overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
29849
+ box.resolved = false;
29850
+ }
29851
+ const boxByIdx = /* @__PURE__ */ new Map();
29852
+ for (const b of boxes) boxByIdx.set(b.edgeIdx, b);
29853
+ const edges = layout.edges.map((e, idx) => {
29854
+ const b = boxByIdx.get(idx);
29855
+ if (!b) return e;
29856
+ return {
29857
+ ...e,
29858
+ labelX: b.cx,
29859
+ labelY: b.cy,
29860
+ labelWidth: b.w,
29861
+ labelHeight: b.h,
29862
+ labelLines: b.lines
29863
+ };
29864
+ });
29865
+ return {
29866
+ layout: { ...layout, edges },
29867
+ unresolved: boxes.filter((b) => !b.resolved).map((b) => b.edgeIdx)
29868
+ };
29869
+ }
29870
+ var EDGE_LABEL_FONT_SIZE6, LABEL_MAX_WIDTH, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, H_PAD, V_PAD, BOX_CLEAR_PAD, PERP_STEP, PERP_MAX, SLIDE_SAMPLES;
29871
+ var init_label_placement = __esm({
29872
+ "src/boxes-and-lines/label-placement.ts"() {
29873
+ "use strict";
29874
+ init_text_measure();
29875
+ EDGE_LABEL_FONT_SIZE6 = 11;
29876
+ LABEL_MAX_WIDTH = 160;
29877
+ MAX_LABEL_LINES = 3;
29878
+ LABEL_LINE_HEIGHT = 1.3;
29879
+ H_PAD = 6;
29880
+ V_PAD = 3;
29881
+ BOX_CLEAR_PAD = 4;
29882
+ PERP_STEP = 8;
29883
+ PERP_MAX = 40;
29884
+ SLIDE_SAMPLES = 9;
29885
+ }
29886
+ });
29887
+
29729
29888
  // src/boxes-and-lines/layout-layered.ts
29730
29889
  function rng(s) {
29731
29890
  return () => {
@@ -31515,6 +31674,7 @@ function edgeLength(layout) {
31515
31674
  }
31516
31675
  async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
31517
31676
  const hideDescriptions = opts?.hideDescriptions ?? false;
31677
+ const reserveEdgeLabels = opts?.reserveEdgeLabels ?? false;
31518
31678
  const onProgress = opts?.onProgress;
31519
31679
  const tick = onProgress ? () => new Promise((r) => setTimeout(r)) : () => void 0;
31520
31680
  const collapsedGroupLabels = /* @__PURE__ */ new Set();
@@ -31807,8 +31967,14 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
31807
31967
  for (const e of ord(parsed.edges)) {
31808
31968
  const s = srcRep(e.source);
31809
31969
  const t = tgtRep(e.target);
31810
- if (s !== t && g.hasNode(s) && g.hasNode(t))
31811
- g.setEdge(s, t, {}, edgeKey(e));
31970
+ if (s !== t && g.hasNode(s) && g.hasNode(t)) {
31971
+ let edgeLabel = {};
31972
+ if (reserveEdgeLabels && e.label) {
31973
+ const m = measureEdgeLabel(e.label, EDGE_LABEL_FONT_SIZE6);
31974
+ edgeLabel = { width: m.width, height: m.height, labelpos: "c" };
31975
+ }
31976
+ g.setEdge(s, t, edgeLabel, edgeKey(e));
31977
+ }
31812
31978
  }
31813
31979
  dagre4.layout(g);
31814
31980
  const nodes = parsed.nodes.map((n2) => {
@@ -32037,6 +32203,7 @@ var init_layout_search = __esm({
32037
32203
  init_layout5();
32038
32204
  init_layout_layered();
32039
32205
  init_layout_grouped();
32206
+ init_label_placement();
32040
32207
  DEFAULT_LAMBDA = 4;
32041
32208
  ESCALATE_THRESHOLD = 4;
32042
32209
  ESCALATE_MAX_N = 45;
@@ -32095,9 +32262,9 @@ function estimateLabelLines(label, nodeWidth = NODE_WIDTH) {
32095
32262
  current = word;
32096
32263
  }
32097
32264
  }
32098
- if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
32265
+ if (lines <= MAX_LABEL_LINES2) return Math.min(lines, MAX_LABEL_LINES2);
32099
32266
  }
32100
- return MAX_LABEL_LINES;
32267
+ return MAX_LABEL_LINES2;
32101
32268
  }
32102
32269
  function computeNodeSize(node, reserveValueRow) {
32103
32270
  if (!node.description || node.description.length === 0) {
@@ -32105,7 +32272,7 @@ function computeNodeSize(node, reserveValueRow) {
32105
32272
  }
32106
32273
  const w = DESC_NODE_WIDTH;
32107
32274
  const labelLines = estimateLabelLines(node.label, w);
32108
- const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
32275
+ const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT2 + LABEL_PAD;
32109
32276
  const maxTextWidth = w - 24;
32110
32277
  let totalRenderedLines = 0;
32111
32278
  for (const line11 of node.description) {
@@ -32129,7 +32296,7 @@ function computeNodeSize(node, reserveValueRow) {
32129
32296
  }
32130
32297
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
32131
32298
  const { layoutBoxesAndLinesSearch: layoutBoxesAndLinesSearch2 } = await Promise.resolve().then(() => (init_layout_search(), layout_search_exports));
32132
- const searched = await layoutBoxesAndLinesSearch2(parsed, collapseInfo, {
32299
+ const searchOpts = {
32133
32300
  ...layoutOptions?.hideDescriptions !== void 0 && {
32134
32301
  hideDescriptions: layoutOptions.hideDescriptions
32135
32302
  },
@@ -32139,12 +32306,23 @@ async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
32139
32306
  ...layoutOptions?.onProgress !== void 0 && {
32140
32307
  onProgress: layoutOptions.onProgress
32141
32308
  }
32142
- });
32143
- return attachNotes(
32144
- applyParallelEdgeOffsets(searched),
32309
+ };
32310
+ const searched = await layoutBoxesAndLinesSearch2(
32145
32311
  parsed,
32146
- layoutOptions?.collapsedNotes
32147
- );
32312
+ collapseInfo,
32313
+ searchOpts
32314
+ );
32315
+ let placed = placeEdgeLabels(applyParallelEdgeOffsets(searched));
32316
+ if (placed.unresolved.length > 0) {
32317
+ const relaid = await layoutBoxesAndLinesSearch2(parsed, collapseInfo, {
32318
+ ...searchOpts,
32319
+ reserveEdgeLabels: true
32320
+ });
32321
+ const relaidPlaced = placeEdgeLabels(applyParallelEdgeOffsets(relaid));
32322
+ if (relaidPlaced.unresolved.length < placed.unresolved.length)
32323
+ placed = relaidPlaced;
32324
+ }
32325
+ return attachNotes(placed.layout, parsed, layoutOptions?.collapsedNotes);
32148
32326
  }
32149
32327
  function attachNotes(layout, parsed, collapsedNotes) {
32150
32328
  const notesSuppressed = parsed.options?.["no-notes"] === "on";
@@ -32212,6 +32390,7 @@ function attachNotes(layout, parsed, collapsedNotes) {
32212
32390
  points: e.points.map((pt) => ({ x: pt.x + shiftX, y: pt.y + shiftY })),
32213
32391
  ...e.labelX !== void 0 && { labelX: e.labelX + shiftX },
32214
32392
  ...e.labelY !== void 0 && { labelY: e.labelY + shiftY }
32393
+ // labelWidth/labelHeight/labelLines are shift-invariant — carried via spread.
32215
32394
  })) : layout.edges;
32216
32395
  const finalGroups = shifted ? layout.groups.map((grp) => ({
32217
32396
  ...grp,
@@ -32256,11 +32435,12 @@ function applyParallelEdgeOffsets(layout) {
32256
32435
  }))
32257
32436
  };
32258
32437
  }
32259
- var MARGIN5, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP4, MAX_DESC_LINES2, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD, VALUE_ROW_FONT, VALUE_ROW_H;
32438
+ var MARGIN5, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP4, MAX_DESC_LINES2, MAX_LABEL_LINES2, LABEL_LINE_HEIGHT2, LABEL_PAD, VALUE_ROW_FONT, VALUE_ROW_H;
32260
32439
  var init_layout5 = __esm({
32261
32440
  "src/boxes-and-lines/layout.ts"() {
32262
32441
  "use strict";
32263
32442
  init_text_measure();
32443
+ init_label_placement();
32264
32444
  init_notes();
32265
32445
  MARGIN5 = 40;
32266
32446
  MAX_PARALLEL_EDGES = 5;
@@ -32274,8 +32454,8 @@ var init_layout5 = __esm({
32274
32454
  DESC_PADDING = 8;
32275
32455
  SEPARATOR_GAP4 = 4;
32276
32456
  MAX_DESC_LINES2 = 6;
32277
- MAX_LABEL_LINES = 3;
32278
- LABEL_LINE_HEIGHT = 1.3;
32457
+ MAX_LABEL_LINES2 = 3;
32458
+ LABEL_LINE_HEIGHT2 = 1.3;
32279
32459
  LABEL_PAD = 12;
32280
32460
  VALUE_ROW_FONT = 11;
32281
32461
  VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
@@ -32294,7 +32474,7 @@ function tokenize(text) {
32294
32474
  return tokens;
32295
32475
  }
32296
32476
  function tryWrap(tokens, maxWidth, fontSize, maxLines) {
32297
- const availWidth = maxWidth - H_PAD;
32477
+ const availWidth = maxWidth - H_PAD2;
32298
32478
  const lines = [];
32299
32479
  let currentLine = "";
32300
32480
  for (const token of tokens) {
@@ -32319,7 +32499,7 @@ function tryWrap(tokens, maxWidth, fontSize, maxLines) {
32319
32499
  return lines;
32320
32500
  }
32321
32501
  function truncateLastLine(lines, maxWidth, fontSize) {
32322
- const availWidth = maxWidth - H_PAD;
32502
+ const availWidth = maxWidth - H_PAD2;
32323
32503
  const result = [...lines];
32324
32504
  const last = result[result.length - 1];
32325
32505
  if (measureText(last, fontSize) > availWidth) {
@@ -32327,7 +32507,7 @@ function truncateLastLine(lines, maxWidth, fontSize) {
32327
32507
  }
32328
32508
  return result;
32329
32509
  }
32330
- function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABEL_LINES2) {
32510
+ function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABEL_LINES3) {
32331
32511
  if (!text) return { lines: [""], fontSize: baseFontSize };
32332
32512
  const tokens = tokenize(text);
32333
32513
  for (let fs = baseFontSize; fs >= minFontSize; fs--) {
@@ -32342,7 +32522,7 @@ function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABE
32342
32522
  if (allLines.length > maxLines) {
32343
32523
  const last = truncated[truncated.length - 1];
32344
32524
  if (!last.endsWith("\u2026")) {
32345
- const availWidth = maxWidth - H_PAD;
32525
+ const availWidth = maxWidth - H_PAD2;
32346
32526
  if (measureText(last + "\u2026", minFontSize) > availWidth) {
32347
32527
  truncated[truncated.length - 1] = truncateText(
32348
32528
  last,
@@ -32369,7 +32549,7 @@ function computeNodeText(label, description, depth, nodeWidth, hideDescriptions)
32369
32549
  nodeWidth,
32370
32550
  baseFontSize,
32371
32551
  MIN_FONT_SIZE,
32372
- MAX_LABEL_LINES2
32552
+ MAX_LABEL_LINES3
32373
32553
  );
32374
32554
  const descLines = [];
32375
32555
  let descFontSize = DESC_FONT_SIZE3;
@@ -32397,14 +32577,14 @@ function computeNodeText(label, description, depth, nodeWidth, hideDescriptions)
32397
32577
  descFontSize
32398
32578
  };
32399
32579
  }
32400
- var H_PAD, MAX_LABEL_LINES2, MAX_DESC_LINES3, ROOT_FONT_SIZE, MIN_FONT_SIZE, FONT_STEP, DESC_FONT_SIZE3;
32580
+ var H_PAD2, MAX_LABEL_LINES3, MAX_DESC_LINES3, ROOT_FONT_SIZE, MIN_FONT_SIZE, FONT_STEP, DESC_FONT_SIZE3;
32401
32581
  var init_text_wrap = __esm({
32402
32582
  "src/mindmap/text-wrap.ts"() {
32403
32583
  "use strict";
32404
32584
  init_description_helpers();
32405
32585
  init_text_measure();
32406
- H_PAD = 16;
32407
- MAX_LABEL_LINES2 = 3;
32586
+ H_PAD2 = 16;
32587
+ MAX_LABEL_LINES3 = 3;
32408
32588
  MAX_DESC_LINES3 = 2;
32409
32589
  ROOT_FONT_SIZE = 17;
32410
32590
  MIN_FONT_SIZE = 9;
@@ -32791,7 +32971,7 @@ function nodeHeightS(node, hideDescriptions, sc) {
32791
32971
  hideDescriptions
32792
32972
  );
32793
32973
  const labelLineCount = text.labelLines.length;
32794
- const labelH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT : LABEL_LINE_HEIGHT2 * labelLineCount;
32974
+ const labelH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT : LABEL_LINE_HEIGHT3 * labelLineCount;
32795
32975
  let h = labelH + NODE_V_PAD;
32796
32976
  if (text.descLines.length > 0) {
32797
32977
  h += DESC_LINE_HEIGHT3 * text.descLines.length + 4;
@@ -32811,7 +32991,7 @@ function populateDepthCache(roots) {
32811
32991
  };
32812
32992
  walk(roots, 0);
32813
32993
  }
32814
- var ROOT_WIDTH, DEPTH1_WIDTH, LEAF_WIDTH, SINGLE_LABEL_HEIGHT, LABEL_LINE_HEIGHT2, DESC_LINE_HEIGHT3, NODE_V_PAD, H_GAP2, V_GAP2, MARGIN6, MULTI_ROOT_GAP, nodeDepthCache;
32994
+ var ROOT_WIDTH, DEPTH1_WIDTH, LEAF_WIDTH, SINGLE_LABEL_HEIGHT, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT3, NODE_V_PAD, H_GAP2, V_GAP2, MARGIN6, MULTI_ROOT_GAP, nodeDepthCache;
32815
32995
  var init_layout6 = __esm({
32816
32996
  "src/mindmap/layout.ts"() {
32817
32997
  "use strict";
@@ -32822,7 +33002,7 @@ var init_layout6 = __esm({
32822
33002
  DEPTH1_WIDTH = 150;
32823
33003
  LEAF_WIDTH = 120;
32824
33004
  SINGLE_LABEL_HEIGHT = 28;
32825
- LABEL_LINE_HEIGHT2 = 18;
33005
+ LABEL_LINE_HEIGHT3 = 18;
32826
33006
  DESC_LINE_HEIGHT3 = 14;
32827
33007
  NODE_V_PAD = 10;
32828
33008
  H_GAP2 = 40;
@@ -33114,18 +33294,18 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
33114
33294
  descFontSize
33115
33295
  } = textLayout;
33116
33296
  const labelLineCount = labelLines.length;
33117
- const labelZoneH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT2 : LABEL_LINE_HEIGHT3 * labelLineCount;
33297
+ const labelZoneH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT2 : LABEL_LINE_HEIGHT4 * labelLineCount;
33118
33298
  const labelZoneHeight = showDesc ? labelZoneH : node.height;
33119
33299
  const centerX = node.x + node.width / 2;
33120
33300
  if (labelLineCount <= 1) {
33121
33301
  const labelY = node.y + labelZoneHeight / 2 + fontSize * 0.35;
33122
33302
  nodeG.append("text").attr("x", centerX).attr("y", labelY).attr("text-anchor", "middle").attr("font-size", fontSize).attr("font-weight", isRoot ? "bold" : "normal").attr("fill", onFillText).text(labelLines[0]);
33123
33303
  } else {
33124
- const blockH = LABEL_LINE_HEIGHT3 * (labelLineCount - 1);
33304
+ const blockH = LABEL_LINE_HEIGHT4 * (labelLineCount - 1);
33125
33305
  const firstBaselineY = node.y + labelZoneHeight / 2 - blockH / 2 + fontSize * 0.35;
33126
33306
  const textEl = nodeG.append("text").attr("x", centerX).attr("text-anchor", "middle").attr("font-size", fontSize).attr("font-weight", isRoot ? "bold" : "normal").attr("fill", onFillText);
33127
33307
  for (let i = 0; i < labelLines.length; i++) {
33128
- textEl.append("tspan").attr("x", centerX).attr("y", firstBaselineY + i * LABEL_LINE_HEIGHT3).text(labelLines[i]);
33308
+ textEl.append("tspan").attr("x", centerX).attr("y", firstBaselineY + i * LABEL_LINE_HEIGHT4).text(labelLines[i]);
33129
33309
  }
33130
33310
  }
33131
33311
  if (labelLines.length > 1 || labelLines[0] !== node.label) {
@@ -33200,7 +33380,7 @@ function renderMindmapForExport(content, theme, palette) {
33200
33380
  return extractExportSvg(container, theme);
33201
33381
  });
33202
33382
  }
33203
- var DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
33383
+ var DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT4, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
33204
33384
  var init_renderer7 = __esm({
33205
33385
  "src/mindmap/renderer.ts"() {
33206
33386
  "use strict";
@@ -33222,7 +33402,7 @@ var init_renderer7 = __esm({
33222
33402
  DIAGRAM_PADDING7 = 20;
33223
33403
  TITLE_HEIGHT4 = 30;
33224
33404
  SINGLE_LABEL_HEIGHT2 = 28;
33225
- LABEL_LINE_HEIGHT3 = 18;
33405
+ LABEL_LINE_HEIGHT4 = 18;
33226
33406
  DESC_LINE_HEIGHT4 = 14;
33227
33407
  NODE_RADIUS = 6;
33228
33408
  ROOT_STROKE_WIDTH = 2.5;
@@ -35891,7 +36071,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
35891
36071
  const labelText = edge.label ?? "";
35892
36072
  const techText = edge.technology ? `[${edge.technology}]` : "";
35893
36073
  const textW = Math.max(
35894
- measureText(labelText, EDGE_LABEL_FONT_SIZE6),
36074
+ measureText(labelText, EDGE_LABEL_FONT_SIZE7),
35895
36075
  measureText(techText, TECH_FONT_SIZE)
35896
36076
  );
35897
36077
  const bgW = textW + 12;
@@ -35902,7 +36082,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
35902
36082
  textY = midPt.y - 4;
35903
36083
  }
35904
36084
  if (labelText) {
35905
- edgeG.append("text").attr("x", midPt.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", edgeColor3).attr("font-size", EDGE_LABEL_FONT_SIZE6).attr("class", "c4-edge-label").text(labelText);
36085
+ edgeG.append("text").attr("x", midPt.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", edgeColor3).attr("font-size", EDGE_LABEL_FONT_SIZE7).attr("class", "c4-edge-label").text(labelText);
35906
36086
  }
35907
36087
  if (techText) {
35908
36088
  edgeG.append("text").attr("x", midPt.x).attr("y", labelText ? textY + 18 : textY + 4).attr("text-anchor", "middle").attr("fill", edgeColor3).attr("font-size", TECH_FONT_SIZE).attr("font-style", "italic").attr("class", "c4-edge-tech").text(techText);
@@ -36086,7 +36266,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
36086
36266
  const labelText = edge.label ?? "";
36087
36267
  const techText = edge.technology ? `[${edge.technology}]` : "";
36088
36268
  const textW = Math.max(
36089
- measureText(labelText, EDGE_LABEL_FONT_SIZE6),
36269
+ measureText(labelText, EDGE_LABEL_FONT_SIZE7),
36090
36270
  measureText(techText, TECH_FONT_SIZE)
36091
36271
  );
36092
36272
  const bgW = textW + 12;
@@ -36104,7 +36284,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
36104
36284
  });
36105
36285
  }
36106
36286
  }
36107
- placeEdgeLabels(pendingLabels, edges, obstacleRects);
36287
+ placeEdgeLabels2(pendingLabels, edges, obstacleRects);
36108
36288
  for (const lbl of pendingLabels) {
36109
36289
  lbl.edgeG.append("rect").attr("x", lbl.x - lbl.bgW / 2).attr("y", lbl.y - lbl.bgH / 2).attr("width", lbl.bgW).attr("height", lbl.bgH).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.9).attr("class", "c4-edge-label-bg");
36110
36290
  let textY = lbl.y;
@@ -36112,7 +36292,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
36112
36292
  textY = lbl.y - 4;
36113
36293
  }
36114
36294
  if (lbl.labelText) {
36115
- lbl.edgeG.append("text").attr("x", lbl.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", lbl.edgeColor).attr("font-size", EDGE_LABEL_FONT_SIZE6).attr("class", "c4-edge-label").text(lbl.labelText);
36295
+ lbl.edgeG.append("text").attr("x", lbl.x).attr("y", textY + 4).attr("text-anchor", "middle").attr("fill", lbl.edgeColor).attr("font-size", EDGE_LABEL_FONT_SIZE7).attr("class", "c4-edge-label").text(lbl.labelText);
36116
36296
  }
36117
36297
  if (lbl.techText) {
36118
36298
  lbl.edgeG.append("text").attr("x", lbl.x).attr("y", lbl.labelText ? textY + 18 : textY + 4).attr("text-anchor", "middle").attr("fill", lbl.edgeColor).attr("font-size", TECH_FONT_SIZE).attr("font-style", "italic").attr("class", "c4-edge-tech").text(lbl.techText);
@@ -36193,7 +36373,7 @@ function tangentAt(points, t) {
36193
36373
  }
36194
36374
  return { x: 0, y: 1 };
36195
36375
  }
36196
- function placeEdgeLabels(labels, edges, obstacleRects) {
36376
+ function placeEdgeLabels2(labels, edges, obstacleRects) {
36197
36377
  if (labels.length === 0) return;
36198
36378
  const allPaths = edges.map((e) => e.points);
36199
36379
  const placedRects = [];
@@ -36731,7 +36911,7 @@ function renderC4DeploymentForExport(content, theme, palette) {
36731
36911
  document.body.removeChild(el);
36732
36912
  }
36733
36913
  }
36734
- var DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE6, TECH_FONT_SIZE, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, BOUNDARY_LABEL_FONT_SIZE, BOUNDARY_STROKE_WIDTH, BOUNDARY_RADIUS, DRILL_BAR_HEIGHT, CYLINDER_RY, PERSON_HEAD_R, PERSON_ARM_SPAN, PERSON_LEG_SPAN, PERSON_ICON_W, PERSON_SW, lineGenerator4;
36914
+ var DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE7, TECH_FONT_SIZE, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, BOUNDARY_LABEL_FONT_SIZE, BOUNDARY_STROKE_WIDTH, BOUNDARY_RADIUS, DRILL_BAR_HEIGHT, CYLINDER_RY, PERSON_HEAD_R, PERSON_ARM_SPAN, PERSON_LEG_SPAN, PERSON_ICON_W, PERSON_SW, lineGenerator4;
36735
36915
  var init_renderer9 = __esm({
36736
36916
  "src/c4/renderer.ts"() {
36737
36917
  "use strict";
@@ -36754,7 +36934,7 @@ var init_renderer9 = __esm({
36754
36934
  NAME_FONT_SIZE2 = 14;
36755
36935
  DESC_FONT_SIZE5 = 11;
36756
36936
  DESC_LINE_HEIGHT6 = 16;
36757
- EDGE_LABEL_FONT_SIZE6 = 11;
36937
+ EDGE_LABEL_FONT_SIZE7 = 11;
36758
36938
  TECH_FONT_SIZE = 10;
36759
36939
  CARD_H_PAD4 = 20;
36760
36940
  CARD_V_PAD4 = 14;
@@ -37379,7 +37559,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
37379
37559
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
37380
37560
  const sTitleY = ctx.structural(TITLE_Y);
37381
37561
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
37382
- const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE7);
37562
+ const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE8);
37383
37563
  const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
37384
37564
  const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
37385
37565
  const sArrowheadW = ctx.structural(ARROWHEAD_W3);
@@ -37605,7 +37785,7 @@ function renderFlowchartForExport(content, theme, palette) {
37605
37785
  document.body.removeChild(container);
37606
37786
  }
37607
37787
  }
37608
- var DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
37788
+ var DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE8, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
37609
37789
  var init_flowchart_renderer = __esm({
37610
37790
  "src/graph/flowchart-renderer.ts"() {
37611
37791
  "use strict";
@@ -37624,7 +37804,7 @@ var init_flowchart_renderer = __esm({
37624
37804
  DIAGRAM_PADDING9 = 20;
37625
37805
  MAX_SCALE6 = 3;
37626
37806
  NODE_FONT_SIZE2 = 13;
37627
- EDGE_LABEL_FONT_SIZE7 = 11;
37807
+ EDGE_LABEL_FONT_SIZE8 = 11;
37628
37808
  ARROWHEAD_W3 = 10;
37629
37809
  ARROWHEAD_H3 = 7;
37630
37810
  IO_SKEW = 15;
@@ -39059,7 +39239,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
39059
39239
  const midIdx = Math.floor(edge.points.length / 2);
39060
39240
  const midPt = edge.points[midIdx];
39061
39241
  if (midPt) {
39062
- const halfWidth = (measureText(edge.label, EDGE_LABEL_FONT_SIZE8) + 8) / 2;
39242
+ const halfWidth = (measureText(edge.label, EDGE_LABEL_FONT_SIZE9) + 8) / 2;
39063
39243
  if (midPt.x - halfWidth < minX) minX = midPt.x - halfWidth;
39064
39244
  if (midPt.x + halfWidth > maxX) maxX = midPt.x + halfWidth;
39065
39245
  }
@@ -39093,7 +39273,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
39093
39273
  height: totalHeight
39094
39274
  };
39095
39275
  }
39096
- var MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT5, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT3, NODE_FONT_SIZE3, META_FONT_SIZE5, EDGE_LABEL_FONT_SIZE8, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP2;
39276
+ var MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT5, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT3, NODE_FONT_SIZE3, META_FONT_SIZE5, EDGE_LABEL_FONT_SIZE9, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP2;
39097
39277
  var init_layout10 = __esm({
39098
39278
  "src/infra/layout.ts"() {
39099
39279
  "use strict";
@@ -39107,7 +39287,7 @@ var init_layout10 = __esm({
39107
39287
  COLLAPSE_BAR_HEIGHT3 = 6;
39108
39288
  NODE_FONT_SIZE3 = 13;
39109
39289
  META_FONT_SIZE5 = 10;
39110
- EDGE_LABEL_FONT_SIZE8 = 11;
39290
+ EDGE_LABEL_FONT_SIZE9 = 11;
39111
39291
  PADDING_X3 = 24;
39112
39292
  GROUP_PADDING2 = 20;
39113
39293
  GROUP_HEADER_HEIGHT = 24;
@@ -39214,7 +39394,7 @@ function buildScaledConstants(ctx) {
39214
39394
  sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
39215
39395
  sMetaFontSize: ctx.text(META_FONT_SIZE6),
39216
39396
  sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
39217
- sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE9),
39397
+ sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE10),
39218
39398
  sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
39219
39399
  sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
39220
39400
  sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
@@ -39943,7 +40123,7 @@ function renderEdgeLabels(svg, edges, nodes, groups, palette, _isDark, animate,
39943
40123
  if (!midPt) continue;
39944
40124
  const labelText = edge.label;
39945
40125
  const g = svg.append("g").attr("class", animate ? "infra-edge-label" : "");
39946
- const textWidth = measureText(labelText, EDGE_LABEL_FONT_SIZE9) + 8;
40126
+ const textWidth = measureText(labelText, EDGE_LABEL_FONT_SIZE10) + 8;
39947
40127
  g.append("rect").attr("x", midPt.x - textWidth / 2).attr("y", midPt.y - 8).attr("width", textWidth).attr("height", 16).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.9);
39948
40128
  g.append("text").attr("x", midPt.x).attr("y", midPt.y + 4).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sc.sEdgeLabelFontSize).attr("fill", palette.textMuted).text(labelText);
39949
40129
  if (animate) {
@@ -40553,7 +40733,7 @@ function parseAndLayoutInfra(content) {
40553
40733
  const layout = layoutInfra(computed);
40554
40734
  return { parsed, computed, layout };
40555
40735
  }
40556
- var NODE_FONT_SIZE4, META_FONT_SIZE6, META_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE9, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, PROP_DISPLAY, DESC_MAX_CHARS, DESC_MAX_WIDTH, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
40736
+ var NODE_FONT_SIZE4, META_FONT_SIZE6, META_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, PROP_DISPLAY, DESC_MAX_CHARS, DESC_MAX_WIDTH, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
40557
40737
  var init_renderer10 = __esm({
40558
40738
  "src/infra/renderer.ts"() {
40559
40739
  "use strict";
@@ -40577,7 +40757,7 @@ var init_renderer10 = __esm({
40577
40757
  NODE_FONT_SIZE4 = 13;
40578
40758
  META_FONT_SIZE6 = 10;
40579
40759
  META_LINE_HEIGHT6 = 14;
40580
- EDGE_LABEL_FONT_SIZE9 = 11;
40760
+ EDGE_LABEL_FONT_SIZE10 = 11;
40581
40761
  GROUP_LABEL_FONT_SIZE2 = 14;
40582
40762
  NODE_BORDER_RADIUS = 8;
40583
40763
  OVERLOAD_STROKE_WIDTH = 3;
@@ -46966,7 +47146,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
46966
47146
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
46967
47147
  const sTitleY = ctx.structural(TITLE_Y);
46968
47148
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
46969
- const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE10);
47149
+ const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE11);
46970
47150
  const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
46971
47151
  const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
46972
47152
  const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
@@ -47246,7 +47426,7 @@ function renderStateForExport(content, theme, palette) {
47246
47426
  document.body.removeChild(container);
47247
47427
  }
47248
47428
  }
47249
- var DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE3, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
47429
+ var DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE11, GROUP_LABEL_FONT_SIZE3, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
47250
47430
  var init_state_renderer = __esm({
47251
47431
  "src/graph/state-renderer.ts"() {
47252
47432
  "use strict";
@@ -47265,7 +47445,7 @@ var init_state_renderer = __esm({
47265
47445
  DIAGRAM_PADDING12 = 20;
47266
47446
  MAX_SCALE7 = 3;
47267
47447
  NODE_FONT_SIZE6 = 13;
47268
- EDGE_LABEL_FONT_SIZE10 = 11;
47448
+ EDGE_LABEL_FONT_SIZE11 = 11;
47269
47449
  GROUP_LABEL_FONT_SIZE3 = 11;
47270
47450
  ARROWHEAD_W5 = 10;
47271
47451
  ARROWHEAD_H5 = 7;
@@ -50087,10 +50267,10 @@ function renderedDescNodeHeight(numLines, scale) {
50087
50267
  return headerH + textBlockH + bottomPad;
50088
50268
  }
50089
50269
  function wrapEdgeLabelText(label, description, maxWidth = EDGE_LABEL_MAX_WIDTH) {
50090
- const labelLines = label ? wrapTextToWidth(label, EDGE_LABEL_FONT_SIZE11, maxWidth) : [];
50270
+ const labelLines = label ? wrapTextToWidth(label, EDGE_LABEL_FONT_SIZE12, maxWidth) : [];
50091
50271
  const descLines = [];
50092
50272
  for (const d of description) {
50093
- descLines.push(...wrapTextToWidth(d, EDGE_LABEL_FONT_SIZE11, maxWidth));
50273
+ descLines.push(...wrapTextToWidth(d, EDGE_LABEL_FONT_SIZE12, maxWidth));
50094
50274
  }
50095
50275
  return { labelLines, descLines };
50096
50276
  }
@@ -50228,9 +50408,9 @@ function computeEdgePaths(layoutNodes, parsed, cx, cy, radius, isClockwise) {
50228
50408
  const lineCount = labelLines.length + descLines.length;
50229
50409
  let labelPxW = 0;
50230
50410
  for (const l of labelLines)
50231
- labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE11));
50411
+ labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE12));
50232
50412
  for (const l of descLines)
50233
- labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE11));
50413
+ labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE12));
50234
50414
  const { labelX, labelY, labelAngle } = computeEdgeLabelPosition(
50235
50415
  midAngle,
50236
50416
  radius,
@@ -50332,9 +50512,9 @@ function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isC
50332
50512
  );
50333
50513
  let textWidth = 0;
50334
50514
  for (const l of labelLines)
50335
- textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE11));
50515
+ textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE12));
50336
50516
  for (const l of descLines)
50337
- textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE11));
50517
+ textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE12));
50338
50518
  if (textWidth === 0) continue;
50339
50519
  const normAngle = (le.labelAngle % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI);
50340
50520
  const isRight = normAngle < Math.PI * 0.4 || normAngle > Math.PI * 1.6;
@@ -50408,7 +50588,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
50408
50588
  const midAngle = srcExitAngle + dir * visibleSweep / 2;
50409
50589
  return { path, midAngle };
50410
50590
  }
50411
- var MIN_ARC_ANGLE, LABEL_FONT_SIZE4, CIRCLE_LABEL_FONT_SIZE, DESC_FONT_SIZE6, EDGE_LABEL_FONT_SIZE11, MIN_NODE_WIDTH4, MAX_NODE_WIDTH3, DESC_MIN_WIDTH, DESC_WIDTH_STEP, DESC_TARGET_RATIO, PLAIN_NODE_HEIGHT, HEADER_HEIGHT4, DESC_LINE_HEIGHT7, DESC_PAD_Y, NODE_PAD_X, MIN_CIRCLE_RADIUS, CIRCLE_PAD, RENDERER_DESC_FONT, RENDERER_DESC_FONT_MIN, RENDERER_DESC_LINE_H, RENDERER_DESC_LINE_H_MIN, EDGE_LABEL_MAX_WIDTH;
50591
+ var MIN_ARC_ANGLE, LABEL_FONT_SIZE4, CIRCLE_LABEL_FONT_SIZE, DESC_FONT_SIZE6, EDGE_LABEL_FONT_SIZE12, MIN_NODE_WIDTH4, MAX_NODE_WIDTH3, DESC_MIN_WIDTH, DESC_WIDTH_STEP, DESC_TARGET_RATIO, PLAIN_NODE_HEIGHT, HEADER_HEIGHT4, DESC_LINE_HEIGHT7, DESC_PAD_Y, NODE_PAD_X, MIN_CIRCLE_RADIUS, CIRCLE_PAD, RENDERER_DESC_FONT, RENDERER_DESC_FONT_MIN, RENDERER_DESC_LINE_H, RENDERER_DESC_LINE_H_MIN, EDGE_LABEL_MAX_WIDTH;
50412
50592
  var init_layout14 = __esm({
50413
50593
  "src/cycle/layout.ts"() {
50414
50594
  "use strict";
@@ -50419,7 +50599,7 @@ var init_layout14 = __esm({
50419
50599
  LABEL_FONT_SIZE4 = 13;
50420
50600
  CIRCLE_LABEL_FONT_SIZE = 16;
50421
50601
  DESC_FONT_SIZE6 = 11;
50422
- EDGE_LABEL_FONT_SIZE11 = 11;
50602
+ EDGE_LABEL_FONT_SIZE12 = 11;
50423
50603
  MIN_NODE_WIDTH4 = 70;
50424
50604
  MAX_NODE_WIDTH3 = 260;
50425
50605
  DESC_MIN_WIDTH = 140;
@@ -50565,7 +50745,7 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
50565
50745
  const scaledNodeFont = Math.max(6, Math.round(NODE_FONT_SIZE7 * layout.scale));
50566
50746
  const scaledEdgeLabelFont = Math.max(
50567
50747
  6,
50568
- Math.round(EDGE_LABEL_FONT_SIZE12 * layout.scale)
50748
+ Math.round(EDGE_LABEL_FONT_SIZE13 * layout.scale)
50569
50749
  );
50570
50750
  const CIRCLE_LABEL_FONT_SIZE2 = 16;
50571
50751
  const scaledCircleLabelFont = Math.max(
@@ -50728,7 +50908,7 @@ function ensureArrowMarker(defs, color, strokeWidth) {
50728
50908
  const mh = Math.max(1.5, mw * 0.5);
50729
50909
  defs.append("marker").attr("id", id).attr("viewBox", `0 0 ${mw} ${mh}`).attr("refX", mw * 0.1).attr("refY", mh / 2).attr("markerWidth", mw).attr("markerHeight", mh).attr("orient", "auto").append("polygon").attr("points", `0,0 ${mw},${mh / 2} 0,${mh}`).attr("fill", color);
50730
50910
  }
50731
- var NODE_FONT_SIZE7, DESC_FONT_SIZE7, EDGE_LABEL_FONT_SIZE12, DESC_LINE_HEIGHT8, TITLE_AREA_HEIGHT;
50911
+ var NODE_FONT_SIZE7, DESC_FONT_SIZE7, EDGE_LABEL_FONT_SIZE13, DESC_LINE_HEIGHT8, TITLE_AREA_HEIGHT;
50732
50912
  var init_renderer15 = __esm({
50733
50913
  "src/cycle/renderer.ts"() {
50734
50914
  "use strict";
@@ -50745,7 +50925,7 @@ var init_renderer15 = __esm({
50745
50925
  init_text_measure();
50746
50926
  NODE_FONT_SIZE7 = 13;
50747
50927
  DESC_FONT_SIZE7 = 11;
50748
- EDGE_LABEL_FONT_SIZE12 = 11;
50928
+ EDGE_LABEL_FONT_SIZE13 = 11;
50749
50929
  DESC_LINE_HEIGHT8 = 15;
50750
50930
  TITLE_AREA_HEIGHT = 50;
50751
50931
  }