@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/advanced.js CHANGED
@@ -29201,63 +29201,6 @@ function ensureArrowMarkers(defs, colors) {
29201
29201
  ).attr("fill", color);
29202
29202
  }
29203
29203
  }
29204
- function edgePolylineMidpoint(points) {
29205
- if (points.length === 0) return { x: 0, y: 0 };
29206
- if (points.length === 1) return { x: points[0].x, y: points[0].y };
29207
- let total = 0;
29208
- const segLen = [];
29209
- for (let k = 1; k < points.length; k++) {
29210
- const len = Math.hypot(
29211
- points[k].x - points[k - 1].x,
29212
- points[k].y - points[k - 1].y
29213
- );
29214
- segLen.push(len);
29215
- total += len;
29216
- }
29217
- let half = total / 2;
29218
- for (let k = 1; k < points.length; k++) {
29219
- const len = segLen[k - 1];
29220
- if (half <= len || k === points.length - 1) {
29221
- const t = len === 0 ? 0 : Math.min(1, half / len);
29222
- return {
29223
- x: points[k - 1].x + (points[k].x - points[k - 1].x) * t,
29224
- y: points[k - 1].y + (points[k].y - points[k - 1].y) * t
29225
- };
29226
- }
29227
- half -= len;
29228
- }
29229
- const last = points[points.length - 1];
29230
- return { x: last.x, y: last.y };
29231
- }
29232
- function resolveEdgeLabelOverlaps(labels) {
29233
- const MAX_PASSES = 8;
29234
- const PAD = 4;
29235
- for (let pass = 0; pass < MAX_PASSES; pass++) {
29236
- let moved = false;
29237
- for (let i = 0; i < labels.length; i++) {
29238
- for (let j = i + 1; j < labels.length; j++) {
29239
- const a = labels[i];
29240
- const b = labels[j];
29241
- const dx = Math.abs(a.x - b.x);
29242
- const dy = Math.abs(a.y - b.y);
29243
- const overlapX = (a.width + b.width) / 2 + PAD - dx;
29244
- const overlapY = (a.height + b.height) / 2 + PAD - dy;
29245
- if (overlapX > 0 && overlapY > 0) {
29246
- const shift = overlapY / 2 + 1;
29247
- if (a.y < b.y) {
29248
- a.y -= shift;
29249
- b.y += shift;
29250
- } else {
29251
- a.y += shift;
29252
- b.y -= shift;
29253
- }
29254
- moved = true;
29255
- }
29256
- }
29257
- }
29258
- if (!moved) break;
29259
- }
29260
- }
29261
29204
  function renderBoxesAndLines(container, parsed, layout, palette, isDark, options) {
29262
29205
  const {
29263
29206
  onClickItem,
@@ -29464,8 +29407,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29464
29407
  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);
29465
29408
  }
29466
29409
  }
29467
- const labelPositions = [];
29468
- const edgeGroups = /* @__PURE__ */ new Map();
29469
29410
  for (let i = 0; i < layout.edges.length; i++) {
29470
29411
  const le = layout.edges[i];
29471
29412
  const color = edgeColorMap.get(i) ?? palette.textMuted;
@@ -29484,7 +29425,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29484
29425
  const nodeLayout = layoutNodeMap.get(le.source);
29485
29426
  if (nodeLayout) {
29486
29427
  const edgeG2 = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
29487
- edgeGroups.set(i, edgeG2);
29488
29428
  const markerId2 = `bl-arrow-${color.replace("#", "")}`;
29489
29429
  const cx = nodeLayout.x;
29490
29430
  const cy = nodeLayout.y;
@@ -29533,7 +29473,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29533
29473
  }
29534
29474
  if (points.length < 2) continue;
29535
29475
  const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
29536
- edgeGroups.set(i, edgeG);
29537
29476
  const markerId = `bl-arrow-${color.replace("#", "")}`;
29538
29477
  const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
29539
29478
  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})`);
@@ -29541,31 +29480,6 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29541
29480
  const revId = `bl-arrow-rev-${color.replace("#", "")}`;
29542
29481
  path.attr("marker-start", `url(#${revId})`);
29543
29482
  }
29544
- if (le.label && le.points.length > 0) {
29545
- const lw = measureText(le.label, sEdgeLabelFontSize);
29546
- const labelH = sEdgeLabelFontSize + 6;
29547
- const mid = edgePolylineMidpoint(le.points);
29548
- let ly = mid.y;
29549
- if (le.parallelCount > 1 && le.yOffset !== 0) {
29550
- ly += (le.yOffset < 0 ? -labelH : labelH) * 0.5;
29551
- }
29552
- labelPositions.push({
29553
- x: mid.x,
29554
- y: ly,
29555
- width: lw + 8,
29556
- height: labelH,
29557
- idx: i
29558
- });
29559
- }
29560
- }
29561
- resolveEdgeLabelOverlaps(labelPositions);
29562
- for (const lp of labelPositions) {
29563
- const le = layout.edges[lp.idx];
29564
- if (!le.label) continue;
29565
- const edgeG = edgeGroups.get(lp.idx);
29566
- const target = edgeG ?? diagramG;
29567
- 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);
29568
- 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);
29569
29483
  }
29570
29484
  for (const ln of layout.nodes) {
29571
29485
  const node = nodeMap.get(ln.label);
@@ -29616,8 +29530,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29616
29530
  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);
29617
29531
  const desc = node.description;
29618
29532
  if (desc && desc.length > 0 && !hideDescriptions) {
29619
- const MAX_LABEL_LINES3 = 3;
29620
- const fitted = fitLabelToHeader(node.label, ln.width, MAX_LABEL_LINES3);
29533
+ const MAX_LABEL_LINES4 = 3;
29534
+ const fitted = fitLabelToHeader(node.label, ln.width, MAX_LABEL_LINES4);
29621
29535
  const labelLines = fitted.lines;
29622
29536
  const labelLineH = fitted.fontSize * 1.3;
29623
29537
  const labelTotalH = labelLines.length * labelLineH;
@@ -29751,6 +29665,35 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
29751
29665
  }
29752
29666
  }
29753
29667
  }
29668
+ const labelLayer = diagramG.append("g").attr("class", "bl-edge-labels");
29669
+ const labelLineHeight = sEdgeLabelFontSize * 1.3;
29670
+ for (const le of layout.edges) {
29671
+ if (!le.labelLines || le.labelLines.length === 0) continue;
29672
+ if (le.labelX === void 0 || le.labelY === void 0) continue;
29673
+ const lx = le.labelX;
29674
+ const ly = le.labelY;
29675
+ if (hidden.size > 0) {
29676
+ let isHidden = false;
29677
+ for (const [groupKey2, hiddenVals] of hidden) {
29678
+ const val = le.metadata[groupKey2];
29679
+ if (val && hiddenVals.has(val.toLowerCase())) {
29680
+ isHidden = true;
29681
+ break;
29682
+ }
29683
+ }
29684
+ if (isHidden) continue;
29685
+ }
29686
+ const lw = le.labelWidth ?? 0;
29687
+ const lh = le.labelHeight ?? sEdgeLabelFontSize + 6;
29688
+ const lines = le.labelLines;
29689
+ const labelG = labelLayer.append("g").attr("class", "bl-edge-label").attr("data-line-number", String(le.lineNumber));
29690
+ 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);
29691
+ 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);
29692
+ const firstY = ly - (lines.length - 1) / 2 * labelLineHeight + sEdgeLabelFontSize / 3;
29693
+ lines.forEach((line11, k) => {
29694
+ text.append("tspan").attr("x", lx).attr("y", firstY + k * labelLineHeight).text(line11);
29695
+ });
29696
+ }
29754
29697
  const hasDescriptions = parsed.nodes.some(
29755
29698
  (n) => n.description && n.description.length > 0
29756
29699
  );
@@ -29865,6 +29808,222 @@ var init_renderer6 = __esm({
29865
29808
  }
29866
29809
  });
29867
29810
 
29811
+ // src/boxes-and-lines/label-placement.ts
29812
+ function measureEdgeLabel(label, fontSize = EDGE_LABEL_FONT_SIZE6, maxWidth = LABEL_MAX_WIDTH) {
29813
+ let lines = wrapTextToWidth(label, fontSize, maxWidth, { hardBreak: true });
29814
+ if (lines.length > MAX_LABEL_LINES) {
29815
+ const kept = lines.slice(0, MAX_LABEL_LINES - 1);
29816
+ const rest = lines.slice(MAX_LABEL_LINES - 1).join(" ");
29817
+ kept.push(truncateText(rest, fontSize, maxWidth));
29818
+ lines = kept;
29819
+ }
29820
+ let textW = 0;
29821
+ for (const ln of lines) {
29822
+ const w = measureText(ln, fontSize);
29823
+ if (w > textW) textW = w;
29824
+ }
29825
+ return {
29826
+ lines,
29827
+ width: textW + 2 * H_PAD,
29828
+ height: lines.length * fontSize * LABEL_LINE_HEIGHT + 2 * V_PAD
29829
+ };
29830
+ }
29831
+ function edgePolylineMidpoint(points) {
29832
+ return pointAtArcFraction(points, 0.5).p;
29833
+ }
29834
+ function pointAtArcFraction(points, t) {
29835
+ if (points.length === 0) return { p: { x: 0, y: 0 }, nx: 0, ny: 1 };
29836
+ if (points.length === 1)
29837
+ return { p: { x: points[0].x, y: points[0].y }, nx: 0, ny: 1 };
29838
+ const segLen = [];
29839
+ let total = 0;
29840
+ for (let k = 1; k < points.length; k++) {
29841
+ const len = Math.hypot(
29842
+ points[k].x - points[k - 1].x,
29843
+ points[k].y - points[k - 1].y
29844
+ );
29845
+ segLen.push(len);
29846
+ total += len;
29847
+ }
29848
+ let want = total * Math.max(0, Math.min(1, t));
29849
+ for (let k = 1; k < points.length; k++) {
29850
+ const len = segLen[k - 1];
29851
+ if (want <= len || k === points.length - 1) {
29852
+ const f = len === 0 ? 0 : Math.min(1, want / len);
29853
+ const ax = points[k - 1].x;
29854
+ const ay = points[k - 1].y;
29855
+ const bx = points[k].x;
29856
+ const by = points[k].y;
29857
+ const dx = bx - ax;
29858
+ const dy = by - ay;
29859
+ const dlen = Math.hypot(dx, dy) || 1;
29860
+ return {
29861
+ p: { x: ax + dx * f, y: ay + dy * f },
29862
+ nx: -dy / dlen,
29863
+ ny: dx / dlen
29864
+ };
29865
+ }
29866
+ want -= len;
29867
+ }
29868
+ const last = points[points.length - 1];
29869
+ return { p: { x: last.x, y: last.y }, nx: 0, ny: 1 };
29870
+ }
29871
+ function rectFromCenter(cx, cy, w, h) {
29872
+ return {
29873
+ minX: cx - w / 2,
29874
+ minY: cy - h / 2,
29875
+ maxX: cx + w / 2,
29876
+ maxY: cy + h / 2
29877
+ };
29878
+ }
29879
+ function overlapsAny(cx, cy, w, h, obstacles, pad2) {
29880
+ const minX = cx - w / 2 - pad2;
29881
+ const minY = cy - h / 2 - pad2;
29882
+ const maxX = cx + w / 2 + pad2;
29883
+ const maxY = cy + h / 2 + pad2;
29884
+ for (const o of obstacles) {
29885
+ if (minX < o.maxX && maxX > o.minX && minY < o.maxY && maxY > o.minY)
29886
+ return true;
29887
+ }
29888
+ return false;
29889
+ }
29890
+ function slideFractions() {
29891
+ const out = [0.5];
29892
+ for (let k = 1; k <= SLIDE_SAMPLES; k++) {
29893
+ const off = k * 0.08;
29894
+ if (0.5 - off >= 0.12) out.push(0.5 - off);
29895
+ if (0.5 + off <= 0.88) out.push(0.5 + off);
29896
+ }
29897
+ return out;
29898
+ }
29899
+ function findClearPosition(w, h, points, obstacles) {
29900
+ const ts = slideFractions();
29901
+ for (const t of ts) {
29902
+ const { p } = pointAtArcFraction(points, t);
29903
+ if (!overlapsAny(p.x, p.y, w, h, obstacles, BOX_CLEAR_PAD)) return p;
29904
+ }
29905
+ for (let mag = PERP_STEP; mag <= PERP_MAX; mag += PERP_STEP) {
29906
+ for (const t of ts) {
29907
+ const { p, nx, ny } = pointAtArcFraction(points, t);
29908
+ for (const sign of [-1, 1]) {
29909
+ const x = p.x + nx * mag * sign;
29910
+ const y = p.y + ny * mag * sign;
29911
+ if (!overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD)) return { x, y };
29912
+ }
29913
+ }
29914
+ }
29915
+ return null;
29916
+ }
29917
+ function resolveLabelOverlaps(boxes) {
29918
+ const MAX_PASSES = 8;
29919
+ const PAD = 4;
29920
+ for (let pass = 0; pass < MAX_PASSES; pass++) {
29921
+ let moved = false;
29922
+ for (let i = 0; i < boxes.length; i++) {
29923
+ for (let j = i + 1; j < boxes.length; j++) {
29924
+ const a = boxes[i];
29925
+ const b = boxes[j];
29926
+ const dx = Math.abs(a.cx - b.cx);
29927
+ const dy = Math.abs(a.cy - b.cy);
29928
+ const overlapX = (a.w + b.w) / 2 + PAD - dx;
29929
+ const overlapY = (a.h + b.h) / 2 + PAD - dy;
29930
+ if (overlapX > 0 && overlapY > 0) {
29931
+ const shift = overlapY / 2 + 1;
29932
+ if (a.cy < b.cy) {
29933
+ a.cy -= shift;
29934
+ b.cy += shift;
29935
+ } else {
29936
+ a.cy += shift;
29937
+ b.cy -= shift;
29938
+ }
29939
+ moved = true;
29940
+ }
29941
+ }
29942
+ }
29943
+ if (!moved) break;
29944
+ }
29945
+ }
29946
+ function placeEdgeLabels(layout, opts) {
29947
+ const fontSize = opts?.fontSize ?? EDGE_LABEL_FONT_SIZE6;
29948
+ const maxWidth = opts?.maxWidth ?? LABEL_MAX_WIDTH;
29949
+ const obstacles = [];
29950
+ for (const n of layout.nodes)
29951
+ obstacles.push(rectFromCenter(n.x, n.y, n.width, n.height));
29952
+ for (const g of layout.groups)
29953
+ if (g.collapsed)
29954
+ obstacles.push(rectFromCenter(g.x, g.y, g.width, g.height));
29955
+ const boxes = [];
29956
+ layout.edges.forEach((e, idx) => {
29957
+ if (!e.label || e.points.length < 2) return;
29958
+ const m = measureEdgeLabel(e.label, fontSize, maxWidth);
29959
+ const mid = edgePolylineMidpoint(e.points);
29960
+ let cy = mid.y;
29961
+ if (e.parallelCount > 1 && e.yOffset !== 0)
29962
+ cy += (e.yOffset < 0 ? -1 : 1) * (m.height / 2);
29963
+ boxes.push({
29964
+ edgeIdx: idx,
29965
+ cx: mid.x,
29966
+ cy,
29967
+ w: m.width,
29968
+ h: m.height,
29969
+ lines: m.lines,
29970
+ resolved: true
29971
+ });
29972
+ });
29973
+ for (const box of boxes) {
29974
+ if (!overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
29975
+ continue;
29976
+ const e = layout.edges[box.edgeIdx];
29977
+ const clear = findClearPosition(box.w, box.h, e.points, obstacles);
29978
+ if (clear) {
29979
+ box.cx = clear.x;
29980
+ box.cy = clear.y;
29981
+ } else {
29982
+ box.resolved = false;
29983
+ }
29984
+ }
29985
+ resolveLabelOverlaps(boxes);
29986
+ for (const box of boxes) {
29987
+ if (overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
29988
+ box.resolved = false;
29989
+ }
29990
+ const boxByIdx = /* @__PURE__ */ new Map();
29991
+ for (const b of boxes) boxByIdx.set(b.edgeIdx, b);
29992
+ const edges = layout.edges.map((e, idx) => {
29993
+ const b = boxByIdx.get(idx);
29994
+ if (!b) return e;
29995
+ return {
29996
+ ...e,
29997
+ labelX: b.cx,
29998
+ labelY: b.cy,
29999
+ labelWidth: b.w,
30000
+ labelHeight: b.h,
30001
+ labelLines: b.lines
30002
+ };
30003
+ });
30004
+ return {
30005
+ layout: { ...layout, edges },
30006
+ unresolved: boxes.filter((b) => !b.resolved).map((b) => b.edgeIdx)
30007
+ };
30008
+ }
30009
+ 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;
30010
+ var init_label_placement = __esm({
30011
+ "src/boxes-and-lines/label-placement.ts"() {
30012
+ "use strict";
30013
+ init_text_measure();
30014
+ EDGE_LABEL_FONT_SIZE6 = 11;
30015
+ LABEL_MAX_WIDTH = 160;
30016
+ MAX_LABEL_LINES = 3;
30017
+ LABEL_LINE_HEIGHT = 1.3;
30018
+ H_PAD = 6;
30019
+ V_PAD = 3;
30020
+ BOX_CLEAR_PAD = 4;
30021
+ PERP_STEP = 8;
30022
+ PERP_MAX = 40;
30023
+ SLIDE_SAMPLES = 9;
30024
+ }
30025
+ });
30026
+
29868
30027
  // src/boxes-and-lines/layout-layered.ts
29869
30028
  function rng(s) {
29870
30029
  return () => {
@@ -31654,6 +31813,7 @@ function edgeLength(layout) {
31654
31813
  }
31655
31814
  async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
31656
31815
  const hideDescriptions = opts?.hideDescriptions ?? false;
31816
+ const reserveEdgeLabels = opts?.reserveEdgeLabels ?? false;
31657
31817
  const onProgress = opts?.onProgress;
31658
31818
  const tick = onProgress ? () => new Promise((r) => setTimeout(r)) : () => void 0;
31659
31819
  const collapsedGroupLabels = /* @__PURE__ */ new Set();
@@ -31946,8 +32106,14 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
31946
32106
  for (const e of ord(parsed.edges)) {
31947
32107
  const s = srcRep(e.source);
31948
32108
  const t = tgtRep(e.target);
31949
- if (s !== t && g.hasNode(s) && g.hasNode(t))
31950
- g.setEdge(s, t, {}, edgeKey(e));
32109
+ if (s !== t && g.hasNode(s) && g.hasNode(t)) {
32110
+ let edgeLabel = {};
32111
+ if (reserveEdgeLabels && e.label) {
32112
+ const m = measureEdgeLabel(e.label, EDGE_LABEL_FONT_SIZE6);
32113
+ edgeLabel = { width: m.width, height: m.height, labelpos: "c" };
32114
+ }
32115
+ g.setEdge(s, t, edgeLabel, edgeKey(e));
32116
+ }
31951
32117
  }
31952
32118
  dagre4.layout(g);
31953
32119
  const nodes = parsed.nodes.map((n2) => {
@@ -32176,6 +32342,7 @@ var init_layout_search = __esm({
32176
32342
  init_layout5();
32177
32343
  init_layout_layered();
32178
32344
  init_layout_grouped();
32345
+ init_label_placement();
32179
32346
  DEFAULT_LAMBDA = 4;
32180
32347
  ESCALATE_THRESHOLD = 4;
32181
32348
  ESCALATE_MAX_N = 45;
@@ -32234,9 +32401,9 @@ function estimateLabelLines(label, nodeWidth = NODE_WIDTH) {
32234
32401
  current = word;
32235
32402
  }
32236
32403
  }
32237
- if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
32404
+ if (lines <= MAX_LABEL_LINES2) return Math.min(lines, MAX_LABEL_LINES2);
32238
32405
  }
32239
- return MAX_LABEL_LINES;
32406
+ return MAX_LABEL_LINES2;
32240
32407
  }
32241
32408
  function computeNodeSize(node, reserveValueRow) {
32242
32409
  if (!node.description || node.description.length === 0) {
@@ -32244,7 +32411,7 @@ function computeNodeSize(node, reserveValueRow) {
32244
32411
  }
32245
32412
  const w = DESC_NODE_WIDTH;
32246
32413
  const labelLines = estimateLabelLines(node.label, w);
32247
- const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
32414
+ const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT2 + LABEL_PAD;
32248
32415
  const maxTextWidth = w - 24;
32249
32416
  let totalRenderedLines = 0;
32250
32417
  for (const line11 of node.description) {
@@ -32268,7 +32435,7 @@ function computeNodeSize(node, reserveValueRow) {
32268
32435
  }
32269
32436
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
32270
32437
  const { layoutBoxesAndLinesSearch: layoutBoxesAndLinesSearch2 } = await Promise.resolve().then(() => (init_layout_search(), layout_search_exports));
32271
- const searched = await layoutBoxesAndLinesSearch2(parsed, collapseInfo, {
32438
+ const searchOpts = {
32272
32439
  ...layoutOptions?.hideDescriptions !== void 0 && {
32273
32440
  hideDescriptions: layoutOptions.hideDescriptions
32274
32441
  },
@@ -32278,12 +32445,23 @@ async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
32278
32445
  ...layoutOptions?.onProgress !== void 0 && {
32279
32446
  onProgress: layoutOptions.onProgress
32280
32447
  }
32281
- });
32282
- return attachNotes(
32283
- applyParallelEdgeOffsets(searched),
32448
+ };
32449
+ const searched = await layoutBoxesAndLinesSearch2(
32284
32450
  parsed,
32285
- layoutOptions?.collapsedNotes
32451
+ collapseInfo,
32452
+ searchOpts
32286
32453
  );
32454
+ let placed = placeEdgeLabels(applyParallelEdgeOffsets(searched));
32455
+ if (placed.unresolved.length > 0) {
32456
+ const relaid = await layoutBoxesAndLinesSearch2(parsed, collapseInfo, {
32457
+ ...searchOpts,
32458
+ reserveEdgeLabels: true
32459
+ });
32460
+ const relaidPlaced = placeEdgeLabels(applyParallelEdgeOffsets(relaid));
32461
+ if (relaidPlaced.unresolved.length < placed.unresolved.length)
32462
+ placed = relaidPlaced;
32463
+ }
32464
+ return attachNotes(placed.layout, parsed, layoutOptions?.collapsedNotes);
32287
32465
  }
32288
32466
  function attachNotes(layout, parsed, collapsedNotes) {
32289
32467
  const notesSuppressed = parsed.options?.["no-notes"] === "on";
@@ -32351,6 +32529,7 @@ function attachNotes(layout, parsed, collapsedNotes) {
32351
32529
  points: e.points.map((pt) => ({ x: pt.x + shiftX, y: pt.y + shiftY })),
32352
32530
  ...e.labelX !== void 0 && { labelX: e.labelX + shiftX },
32353
32531
  ...e.labelY !== void 0 && { labelY: e.labelY + shiftY }
32532
+ // labelWidth/labelHeight/labelLines are shift-invariant — carried via spread.
32354
32533
  })) : layout.edges;
32355
32534
  const finalGroups = shifted ? layout.groups.map((grp) => ({
32356
32535
  ...grp,
@@ -32395,11 +32574,12 @@ function applyParallelEdgeOffsets(layout) {
32395
32574
  }))
32396
32575
  };
32397
32576
  }
32398
- 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;
32577
+ 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;
32399
32578
  var init_layout5 = __esm({
32400
32579
  "src/boxes-and-lines/layout.ts"() {
32401
32580
  "use strict";
32402
32581
  init_text_measure();
32582
+ init_label_placement();
32403
32583
  init_notes();
32404
32584
  MARGIN5 = 40;
32405
32585
  MAX_PARALLEL_EDGES = 5;
@@ -32413,8 +32593,8 @@ var init_layout5 = __esm({
32413
32593
  DESC_PADDING = 8;
32414
32594
  SEPARATOR_GAP4 = 4;
32415
32595
  MAX_DESC_LINES2 = 6;
32416
- MAX_LABEL_LINES = 3;
32417
- LABEL_LINE_HEIGHT = 1.3;
32596
+ MAX_LABEL_LINES2 = 3;
32597
+ LABEL_LINE_HEIGHT2 = 1.3;
32418
32598
  LABEL_PAD = 12;
32419
32599
  VALUE_ROW_FONT = 11;
32420
32600
  VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
@@ -32433,7 +32613,7 @@ function tokenize(text) {
32433
32613
  return tokens;
32434
32614
  }
32435
32615
  function tryWrap(tokens, maxWidth, fontSize, maxLines) {
32436
- const availWidth = maxWidth - H_PAD;
32616
+ const availWidth = maxWidth - H_PAD2;
32437
32617
  const lines = [];
32438
32618
  let currentLine = "";
32439
32619
  for (const token of tokens) {
@@ -32458,7 +32638,7 @@ function tryWrap(tokens, maxWidth, fontSize, maxLines) {
32458
32638
  return lines;
32459
32639
  }
32460
32640
  function truncateLastLine(lines, maxWidth, fontSize) {
32461
- const availWidth = maxWidth - H_PAD;
32641
+ const availWidth = maxWidth - H_PAD2;
32462
32642
  const result = [...lines];
32463
32643
  const last = result[result.length - 1];
32464
32644
  if (measureText(last, fontSize) > availWidth) {
@@ -32466,7 +32646,7 @@ function truncateLastLine(lines, maxWidth, fontSize) {
32466
32646
  }
32467
32647
  return result;
32468
32648
  }
32469
- function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABEL_LINES2) {
32649
+ function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABEL_LINES3) {
32470
32650
  if (!text) return { lines: [""], fontSize: baseFontSize };
32471
32651
  const tokens = tokenize(text);
32472
32652
  for (let fs = baseFontSize; fs >= minFontSize; fs--) {
@@ -32481,7 +32661,7 @@ function wrapText(text, maxWidth, baseFontSize, minFontSize, maxLines = MAX_LABE
32481
32661
  if (allLines.length > maxLines) {
32482
32662
  const last = truncated[truncated.length - 1];
32483
32663
  if (!last.endsWith("\u2026")) {
32484
- const availWidth = maxWidth - H_PAD;
32664
+ const availWidth = maxWidth - H_PAD2;
32485
32665
  if (measureText(last + "\u2026", minFontSize) > availWidth) {
32486
32666
  truncated[truncated.length - 1] = truncateText(
32487
32667
  last,
@@ -32508,7 +32688,7 @@ function computeNodeText(label, description, depth, nodeWidth, hideDescriptions)
32508
32688
  nodeWidth,
32509
32689
  baseFontSize,
32510
32690
  MIN_FONT_SIZE,
32511
- MAX_LABEL_LINES2
32691
+ MAX_LABEL_LINES3
32512
32692
  );
32513
32693
  const descLines = [];
32514
32694
  let descFontSize = DESC_FONT_SIZE3;
@@ -32536,14 +32716,14 @@ function computeNodeText(label, description, depth, nodeWidth, hideDescriptions)
32536
32716
  descFontSize
32537
32717
  };
32538
32718
  }
32539
- var H_PAD, MAX_LABEL_LINES2, MAX_DESC_LINES3, ROOT_FONT_SIZE, MIN_FONT_SIZE, FONT_STEP, DESC_FONT_SIZE3;
32719
+ var H_PAD2, MAX_LABEL_LINES3, MAX_DESC_LINES3, ROOT_FONT_SIZE, MIN_FONT_SIZE, FONT_STEP, DESC_FONT_SIZE3;
32540
32720
  var init_text_wrap = __esm({
32541
32721
  "src/mindmap/text-wrap.ts"() {
32542
32722
  "use strict";
32543
32723
  init_description_helpers();
32544
32724
  init_text_measure();
32545
- H_PAD = 16;
32546
- MAX_LABEL_LINES2 = 3;
32725
+ H_PAD2 = 16;
32726
+ MAX_LABEL_LINES3 = 3;
32547
32727
  MAX_DESC_LINES3 = 2;
32548
32728
  ROOT_FONT_SIZE = 17;
32549
32729
  MIN_FONT_SIZE = 9;
@@ -32930,7 +33110,7 @@ function nodeHeightS(node, hideDescriptions, sc) {
32930
33110
  hideDescriptions
32931
33111
  );
32932
33112
  const labelLineCount = text.labelLines.length;
32933
- const labelH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT : LABEL_LINE_HEIGHT2 * labelLineCount;
33113
+ const labelH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT : LABEL_LINE_HEIGHT3 * labelLineCount;
32934
33114
  let h = labelH + NODE_V_PAD;
32935
33115
  if (text.descLines.length > 0) {
32936
33116
  h += DESC_LINE_HEIGHT3 * text.descLines.length + 4;
@@ -32950,7 +33130,7 @@ function populateDepthCache(roots) {
32950
33130
  };
32951
33131
  walk(roots, 0);
32952
33132
  }
32953
- 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;
33133
+ 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;
32954
33134
  var init_layout6 = __esm({
32955
33135
  "src/mindmap/layout.ts"() {
32956
33136
  "use strict";
@@ -32961,7 +33141,7 @@ var init_layout6 = __esm({
32961
33141
  DEPTH1_WIDTH = 150;
32962
33142
  LEAF_WIDTH = 120;
32963
33143
  SINGLE_LABEL_HEIGHT = 28;
32964
- LABEL_LINE_HEIGHT2 = 18;
33144
+ LABEL_LINE_HEIGHT3 = 18;
32965
33145
  DESC_LINE_HEIGHT3 = 14;
32966
33146
  NODE_V_PAD = 10;
32967
33147
  H_GAP2 = 40;
@@ -33253,18 +33433,18 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
33253
33433
  descFontSize
33254
33434
  } = textLayout;
33255
33435
  const labelLineCount = labelLines.length;
33256
- const labelZoneH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT2 : LABEL_LINE_HEIGHT3 * labelLineCount;
33436
+ const labelZoneH = labelLineCount <= 1 ? SINGLE_LABEL_HEIGHT2 : LABEL_LINE_HEIGHT4 * labelLineCount;
33257
33437
  const labelZoneHeight = showDesc ? labelZoneH : node.height;
33258
33438
  const centerX = node.x + node.width / 2;
33259
33439
  if (labelLineCount <= 1) {
33260
33440
  const labelY = node.y + labelZoneHeight / 2 + fontSize * 0.35;
33261
33441
  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]);
33262
33442
  } else {
33263
- const blockH = LABEL_LINE_HEIGHT3 * (labelLineCount - 1);
33443
+ const blockH = LABEL_LINE_HEIGHT4 * (labelLineCount - 1);
33264
33444
  const firstBaselineY = node.y + labelZoneHeight / 2 - blockH / 2 + fontSize * 0.35;
33265
33445
  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);
33266
33446
  for (let i = 0; i < labelLines.length; i++) {
33267
- textEl.append("tspan").attr("x", centerX).attr("y", firstBaselineY + i * LABEL_LINE_HEIGHT3).text(labelLines[i]);
33447
+ textEl.append("tspan").attr("x", centerX).attr("y", firstBaselineY + i * LABEL_LINE_HEIGHT4).text(labelLines[i]);
33268
33448
  }
33269
33449
  }
33270
33450
  if (labelLines.length > 1 || labelLines[0] !== node.label) {
@@ -33339,7 +33519,7 @@ function renderMindmapForExport(content, theme, palette) {
33339
33519
  return extractExportSvg(container, theme);
33340
33520
  });
33341
33521
  }
33342
- var DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
33522
+ var DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT4, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
33343
33523
  var init_renderer7 = __esm({
33344
33524
  "src/mindmap/renderer.ts"() {
33345
33525
  "use strict";
@@ -33361,7 +33541,7 @@ var init_renderer7 = __esm({
33361
33541
  DIAGRAM_PADDING7 = 20;
33362
33542
  TITLE_HEIGHT4 = 30;
33363
33543
  SINGLE_LABEL_HEIGHT2 = 28;
33364
- LABEL_LINE_HEIGHT3 = 18;
33544
+ LABEL_LINE_HEIGHT4 = 18;
33365
33545
  DESC_LINE_HEIGHT4 = 14;
33366
33546
  NODE_RADIUS = 6;
33367
33547
  ROOT_STROKE_WIDTH = 2.5;
@@ -36030,7 +36210,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
36030
36210
  const labelText = edge.label ?? "";
36031
36211
  const techText = edge.technology ? `[${edge.technology}]` : "";
36032
36212
  const textW = Math.max(
36033
- measureText(labelText, EDGE_LABEL_FONT_SIZE6),
36213
+ measureText(labelText, EDGE_LABEL_FONT_SIZE7),
36034
36214
  measureText(techText, TECH_FONT_SIZE)
36035
36215
  );
36036
36216
  const bgW = textW + 12;
@@ -36041,7 +36221,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
36041
36221
  textY = midPt.y - 4;
36042
36222
  }
36043
36223
  if (labelText) {
36044
- 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);
36224
+ 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);
36045
36225
  }
36046
36226
  if (techText) {
36047
36227
  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);
@@ -36225,7 +36405,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
36225
36405
  const labelText = edge.label ?? "";
36226
36406
  const techText = edge.technology ? `[${edge.technology}]` : "";
36227
36407
  const textW = Math.max(
36228
- measureText(labelText, EDGE_LABEL_FONT_SIZE6),
36408
+ measureText(labelText, EDGE_LABEL_FONT_SIZE7),
36229
36409
  measureText(techText, TECH_FONT_SIZE)
36230
36410
  );
36231
36411
  const bgW = textW + 12;
@@ -36243,7 +36423,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
36243
36423
  });
36244
36424
  }
36245
36425
  }
36246
- placeEdgeLabels(pendingLabels, edges, obstacleRects);
36426
+ placeEdgeLabels2(pendingLabels, edges, obstacleRects);
36247
36427
  for (const lbl of pendingLabels) {
36248
36428
  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");
36249
36429
  let textY = lbl.y;
@@ -36251,7 +36431,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
36251
36431
  textY = lbl.y - 4;
36252
36432
  }
36253
36433
  if (lbl.labelText) {
36254
- 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);
36434
+ 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);
36255
36435
  }
36256
36436
  if (lbl.techText) {
36257
36437
  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);
@@ -36332,7 +36512,7 @@ function tangentAt(points, t) {
36332
36512
  }
36333
36513
  return { x: 0, y: 1 };
36334
36514
  }
36335
- function placeEdgeLabels(labels, edges, obstacleRects) {
36515
+ function placeEdgeLabels2(labels, edges, obstacleRects) {
36336
36516
  if (labels.length === 0) return;
36337
36517
  const allPaths = edges.map((e) => e.points);
36338
36518
  const placedRects = [];
@@ -36870,7 +37050,7 @@ function renderC4DeploymentForExport(content, theme, palette) {
36870
37050
  document.body.removeChild(el);
36871
37051
  }
36872
37052
  }
36873
- 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;
37053
+ 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;
36874
37054
  var init_renderer9 = __esm({
36875
37055
  "src/c4/renderer.ts"() {
36876
37056
  "use strict";
@@ -36893,7 +37073,7 @@ var init_renderer9 = __esm({
36893
37073
  NAME_FONT_SIZE2 = 14;
36894
37074
  DESC_FONT_SIZE5 = 11;
36895
37075
  DESC_LINE_HEIGHT6 = 16;
36896
- EDGE_LABEL_FONT_SIZE6 = 11;
37076
+ EDGE_LABEL_FONT_SIZE7 = 11;
36897
37077
  TECH_FONT_SIZE = 10;
36898
37078
  CARD_H_PAD4 = 20;
36899
37079
  CARD_V_PAD4 = 14;
@@ -37518,7 +37698,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
37518
37698
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
37519
37699
  const sTitleY = ctx.structural(TITLE_Y);
37520
37700
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
37521
- const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE7);
37701
+ const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE8);
37522
37702
  const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
37523
37703
  const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
37524
37704
  const sArrowheadW = ctx.structural(ARROWHEAD_W3);
@@ -37744,7 +37924,7 @@ function renderFlowchartForExport(content, theme, palette) {
37744
37924
  document.body.removeChild(container);
37745
37925
  }
37746
37926
  }
37747
- var DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
37927
+ var DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE8, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
37748
37928
  var init_flowchart_renderer = __esm({
37749
37929
  "src/graph/flowchart-renderer.ts"() {
37750
37930
  "use strict";
@@ -37763,7 +37943,7 @@ var init_flowchart_renderer = __esm({
37763
37943
  DIAGRAM_PADDING9 = 20;
37764
37944
  MAX_SCALE6 = 3;
37765
37945
  NODE_FONT_SIZE2 = 13;
37766
- EDGE_LABEL_FONT_SIZE7 = 11;
37946
+ EDGE_LABEL_FONT_SIZE8 = 11;
37767
37947
  ARROWHEAD_W3 = 10;
37768
37948
  ARROWHEAD_H3 = 7;
37769
37949
  IO_SKEW = 15;
@@ -39198,7 +39378,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
39198
39378
  const midIdx = Math.floor(edge.points.length / 2);
39199
39379
  const midPt = edge.points[midIdx];
39200
39380
  if (midPt) {
39201
- const halfWidth = (measureText(edge.label, EDGE_LABEL_FONT_SIZE8) + 8) / 2;
39381
+ const halfWidth = (measureText(edge.label, EDGE_LABEL_FONT_SIZE9) + 8) / 2;
39202
39382
  if (midPt.x - halfWidth < minX) minX = midPt.x - halfWidth;
39203
39383
  if (midPt.x + halfWidth > maxX) maxX = midPt.x + halfWidth;
39204
39384
  }
@@ -39232,7 +39412,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
39232
39412
  height: totalHeight
39233
39413
  };
39234
39414
  }
39235
- 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;
39415
+ 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;
39236
39416
  var init_layout10 = __esm({
39237
39417
  "src/infra/layout.ts"() {
39238
39418
  "use strict";
@@ -39246,7 +39426,7 @@ var init_layout10 = __esm({
39246
39426
  COLLAPSE_BAR_HEIGHT3 = 6;
39247
39427
  NODE_FONT_SIZE3 = 13;
39248
39428
  META_FONT_SIZE5 = 10;
39249
- EDGE_LABEL_FONT_SIZE8 = 11;
39429
+ EDGE_LABEL_FONT_SIZE9 = 11;
39250
39430
  PADDING_X3 = 24;
39251
39431
  GROUP_PADDING2 = 20;
39252
39432
  GROUP_HEADER_HEIGHT = 24;
@@ -39353,7 +39533,7 @@ function buildScaledConstants(ctx) {
39353
39533
  sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
39354
39534
  sMetaFontSize: ctx.text(META_FONT_SIZE6),
39355
39535
  sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
39356
- sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE9),
39536
+ sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE10),
39357
39537
  sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
39358
39538
  sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
39359
39539
  sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
@@ -40082,7 +40262,7 @@ function renderEdgeLabels(svg, edges, nodes, groups, palette, _isDark, animate,
40082
40262
  if (!midPt) continue;
40083
40263
  const labelText = edge.label;
40084
40264
  const g = svg.append("g").attr("class", animate ? "infra-edge-label" : "");
40085
- const textWidth = measureText(labelText, EDGE_LABEL_FONT_SIZE9) + 8;
40265
+ const textWidth = measureText(labelText, EDGE_LABEL_FONT_SIZE10) + 8;
40086
40266
  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);
40087
40267
  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);
40088
40268
  if (animate) {
@@ -40692,7 +40872,7 @@ function parseAndLayoutInfra(content) {
40692
40872
  const layout = layoutInfra(computed);
40693
40873
  return { parsed, computed, layout };
40694
40874
  }
40695
- 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;
40875
+ 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;
40696
40876
  var init_renderer10 = __esm({
40697
40877
  "src/infra/renderer.ts"() {
40698
40878
  "use strict";
@@ -40716,7 +40896,7 @@ var init_renderer10 = __esm({
40716
40896
  NODE_FONT_SIZE4 = 13;
40717
40897
  META_FONT_SIZE6 = 10;
40718
40898
  META_LINE_HEIGHT6 = 14;
40719
- EDGE_LABEL_FONT_SIZE9 = 11;
40899
+ EDGE_LABEL_FONT_SIZE10 = 11;
40720
40900
  GROUP_LABEL_FONT_SIZE2 = 14;
40721
40901
  NODE_BORDER_RADIUS = 8;
40722
40902
  OVERLOAD_STROKE_WIDTH = 3;
@@ -47108,7 +47288,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
47108
47288
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
47109
47289
  const sTitleY = ctx.structural(TITLE_Y);
47110
47290
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
47111
- const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE10);
47291
+ const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE11);
47112
47292
  const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
47113
47293
  const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
47114
47294
  const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
@@ -47388,7 +47568,7 @@ function renderStateForExport(content, theme, palette) {
47388
47568
  document.body.removeChild(container);
47389
47569
  }
47390
47570
  }
47391
- 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;
47571
+ 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;
47392
47572
  var init_state_renderer = __esm({
47393
47573
  "src/graph/state-renderer.ts"() {
47394
47574
  "use strict";
@@ -47407,7 +47587,7 @@ var init_state_renderer = __esm({
47407
47587
  DIAGRAM_PADDING12 = 20;
47408
47588
  MAX_SCALE7 = 3;
47409
47589
  NODE_FONT_SIZE6 = 13;
47410
- EDGE_LABEL_FONT_SIZE10 = 11;
47590
+ EDGE_LABEL_FONT_SIZE11 = 11;
47411
47591
  GROUP_LABEL_FONT_SIZE3 = 11;
47412
47592
  ARROWHEAD_W5 = 10;
47413
47593
  ARROWHEAD_H5 = 7;
@@ -50449,10 +50629,10 @@ function renderedDescNodeHeight(numLines, scale) {
50449
50629
  return headerH + textBlockH + bottomPad;
50450
50630
  }
50451
50631
  function wrapEdgeLabelText(label, description, maxWidth = EDGE_LABEL_MAX_WIDTH) {
50452
- const labelLines = label ? wrapTextToWidth(label, EDGE_LABEL_FONT_SIZE11, maxWidth) : [];
50632
+ const labelLines = label ? wrapTextToWidth(label, EDGE_LABEL_FONT_SIZE12, maxWidth) : [];
50453
50633
  const descLines = [];
50454
50634
  for (const d of description) {
50455
- descLines.push(...wrapTextToWidth(d, EDGE_LABEL_FONT_SIZE11, maxWidth));
50635
+ descLines.push(...wrapTextToWidth(d, EDGE_LABEL_FONT_SIZE12, maxWidth));
50456
50636
  }
50457
50637
  return { labelLines, descLines };
50458
50638
  }
@@ -50590,9 +50770,9 @@ function computeEdgePaths(layoutNodes, parsed, cx, cy, radius, isClockwise) {
50590
50770
  const lineCount = labelLines.length + descLines.length;
50591
50771
  let labelPxW = 0;
50592
50772
  for (const l of labelLines)
50593
- labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE11));
50773
+ labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE12));
50594
50774
  for (const l of descLines)
50595
- labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE11));
50775
+ labelPxW = Math.max(labelPxW, measureText(l, EDGE_LABEL_FONT_SIZE12));
50596
50776
  const { labelX, labelY, labelAngle } = computeEdgeLabelPosition(
50597
50777
  midAngle,
50598
50778
  radius,
@@ -50694,9 +50874,9 @@ function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isC
50694
50874
  );
50695
50875
  let textWidth = 0;
50696
50876
  for (const l of labelLines)
50697
- textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE11));
50877
+ textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE12));
50698
50878
  for (const l of descLines)
50699
- textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE11));
50879
+ textWidth = Math.max(textWidth, measureText(l, EDGE_LABEL_FONT_SIZE12));
50700
50880
  if (textWidth === 0) continue;
50701
50881
  const normAngle = (le.labelAngle % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI);
50702
50882
  const isRight = normAngle < Math.PI * 0.4 || normAngle > Math.PI * 1.6;
@@ -50770,7 +50950,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
50770
50950
  const midAngle = srcExitAngle + dir * visibleSweep / 2;
50771
50951
  return { path, midAngle };
50772
50952
  }
50773
- 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;
50953
+ 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;
50774
50954
  var init_layout14 = __esm({
50775
50955
  "src/cycle/layout.ts"() {
50776
50956
  "use strict";
@@ -50781,7 +50961,7 @@ var init_layout14 = __esm({
50781
50961
  LABEL_FONT_SIZE4 = 13;
50782
50962
  CIRCLE_LABEL_FONT_SIZE = 16;
50783
50963
  DESC_FONT_SIZE6 = 11;
50784
- EDGE_LABEL_FONT_SIZE11 = 11;
50964
+ EDGE_LABEL_FONT_SIZE12 = 11;
50785
50965
  MIN_NODE_WIDTH4 = 70;
50786
50966
  MAX_NODE_WIDTH3 = 260;
50787
50967
  DESC_MIN_WIDTH = 140;
@@ -50927,7 +51107,7 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
50927
51107
  const scaledNodeFont = Math.max(6, Math.round(NODE_FONT_SIZE7 * layout.scale));
50928
51108
  const scaledEdgeLabelFont = Math.max(
50929
51109
  6,
50930
- Math.round(EDGE_LABEL_FONT_SIZE12 * layout.scale)
51110
+ Math.round(EDGE_LABEL_FONT_SIZE13 * layout.scale)
50931
51111
  );
50932
51112
  const CIRCLE_LABEL_FONT_SIZE2 = 16;
50933
51113
  const scaledCircleLabelFont = Math.max(
@@ -51090,7 +51270,7 @@ function ensureArrowMarker(defs, color, strokeWidth) {
51090
51270
  const mh = Math.max(1.5, mw * 0.5);
51091
51271
  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);
51092
51272
  }
51093
- var NODE_FONT_SIZE7, DESC_FONT_SIZE7, EDGE_LABEL_FONT_SIZE12, DESC_LINE_HEIGHT8, TITLE_AREA_HEIGHT;
51273
+ var NODE_FONT_SIZE7, DESC_FONT_SIZE7, EDGE_LABEL_FONT_SIZE13, DESC_LINE_HEIGHT8, TITLE_AREA_HEIGHT;
51094
51274
  var init_renderer15 = __esm({
51095
51275
  "src/cycle/renderer.ts"() {
51096
51276
  "use strict";
@@ -51107,7 +51287,7 @@ var init_renderer15 = __esm({
51107
51287
  init_text_measure();
51108
51288
  NODE_FONT_SIZE7 = 13;
51109
51289
  DESC_FONT_SIZE7 = 11;
51110
- EDGE_LABEL_FONT_SIZE12 = 11;
51290
+ EDGE_LABEL_FONT_SIZE13 = 11;
51111
51291
  DESC_LINE_HEIGHT8 = 15;
51112
51292
  TITLE_AREA_HEIGHT = 50;
51113
51293
  }