@diagrammo/dgmo 0.30.0 → 0.31.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.
Files changed (41) hide show
  1. package/README.md +21 -3
  2. package/dist/advanced.cjs +560 -269
  3. package/dist/advanced.d.cts +27 -2
  4. package/dist/advanced.d.ts +27 -2
  5. package/dist/advanced.js +559 -269
  6. package/dist/auto.cjs +558 -270
  7. package/dist/auto.js +93 -93
  8. package/dist/auto.mjs +558 -270
  9. package/dist/cli.cjs +144 -143
  10. package/dist/index.cjs +557 -269
  11. package/dist/index.js +557 -269
  12. package/package.json +1 -1
  13. package/src/advanced.ts +3 -0
  14. package/src/boxes-and-lines/layout-search.ts +214 -0
  15. package/src/boxes-and-lines/layout.ts +4 -0
  16. package/src/boxes-and-lines/parser.ts +78 -0
  17. package/src/boxes-and-lines/renderer.ts +57 -5
  18. package/src/boxes-and-lines/types.ts +9 -0
  19. package/src/c4/renderer.ts +7 -5
  20. package/src/chart-types.ts +2 -2
  21. package/src/class/renderer.ts +4 -2
  22. package/src/cli-banner.ts +107 -0
  23. package/src/cli.ts +13 -0
  24. package/src/colors.ts +22 -0
  25. package/src/er/renderer.ts +4 -2
  26. package/src/graph/flowchart-renderer.ts +4 -2
  27. package/src/graph/state-renderer.ts +4 -2
  28. package/src/infra/renderer.ts +8 -4
  29. package/src/journey-map/parser.ts +15 -1
  30. package/src/journey-map/renderer.ts +1 -1
  31. package/src/kanban/renderer.ts +1 -1
  32. package/src/map/renderer.ts +27 -14
  33. package/src/mindmap/renderer.ts +5 -3
  34. package/src/org/renderer.ts +67 -120
  35. package/src/palettes/color-utils.ts +7 -2
  36. package/src/pert/renderer.ts +13 -8
  37. package/src/raci/renderer.ts +1 -1
  38. package/src/sitemap/renderer.ts +35 -37
  39. package/src/utils/card.ts +183 -0
  40. package/src/utils/tag-groups.ts +10 -10
  41. package/src/utils/visual-conventions.ts +61 -0
package/dist/advanced.js CHANGED
@@ -415,7 +415,7 @@ function resolveColorWithDiagnostic(color, line11, diagnostics, palette) {
415
415
  );
416
416
  return void 0;
417
417
  }
418
- var nord, colorNames, RECOGNIZED_COLOR_NAMES, seriesColors;
418
+ var nord, colorNames, RECOGNIZED_COLOR_NAMES, CATEGORICAL_COLOR_ORDER, seriesColors;
419
419
  var init_colors = __esm({
420
420
  "src/colors.ts"() {
421
421
  "use strict";
@@ -473,6 +473,16 @@ var init_colors = __esm({
473
473
  "black",
474
474
  "white"
475
475
  ]);
476
+ CATEGORICAL_COLOR_ORDER = Object.freeze([
477
+ "red",
478
+ "green",
479
+ "blue",
480
+ "yellow",
481
+ "teal",
482
+ "purple",
483
+ "orange",
484
+ "cyan"
485
+ ]);
476
486
  seriesColors = [
477
487
  nord.nord10,
478
488
  // blue
@@ -1326,11 +1336,7 @@ var init_tag_groups = __esm({
1326
1336
  init_diagnostics();
1327
1337
  init_colors();
1328
1338
  AUTO_TAG_COLOR_SENTINEL = "";
1329
- autoTagColorCycle = Object.freeze(
1330
- RECOGNIZED_COLOR_NAMES.filter(
1331
- (n) => n !== "gray" && n !== "black" && n !== "white"
1332
- )
1333
- );
1339
+ autoTagColorCycle = CATEGORICAL_COLOR_ORDER;
1334
1340
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
1335
1341
  VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
1336
1342
  }
@@ -3120,7 +3126,7 @@ function shapeFill(palette, intent, isDark, opts) {
3120
3126
  }
3121
3127
  function getSeriesColors(palette) {
3122
3128
  const c = palette.colors;
3123
- return [c.blue, c.green, c.yellow, c.orange, c.purple, c.red, c.teal, c.cyan];
3129
+ return CATEGORICAL_COLOR_ORDER.map((name) => c[name]);
3124
3130
  }
3125
3131
  function getSegmentColors(palette, count) {
3126
3132
  if (count <= 0) return [];
@@ -3173,6 +3179,7 @@ var POLITICAL_TINT_BANDS;
3173
3179
  var init_color_utils = __esm({
3174
3180
  "src/palettes/color-utils.ts"() {
3175
3181
  "use strict";
3182
+ init_colors();
3176
3183
  POLITICAL_TINT_BANDS = {
3177
3184
  light: [32, 48, 64, 80],
3178
3185
  dark: [44, 58, 72, 86]
@@ -11493,7 +11500,7 @@ var init_chart_types = __esm({
11493
11500
  },
11494
11501
  {
11495
11502
  id: "map",
11496
- description: "Geographic concept map: highlight/score regions, drop points of interest, connect with routes or edges"
11503
+ description: "Geographic map: a value or count per country, state, or region (choropleth); points of interest; routes. Use when categories are real-world places."
11497
11504
  },
11498
11505
  // ── Tier 3 — Specialized analytical charts ────────────────
11499
11506
  {
@@ -11510,7 +11517,7 @@ var init_chart_types = __esm({
11510
11517
  },
11511
11518
  {
11512
11519
  id: "slope",
11513
- description: "Change between two periods"
11520
+ description: "Change for multiple things between exactly two periods"
11514
11521
  },
11515
11522
  {
11516
11523
  id: "sankey",
@@ -18979,6 +18986,7 @@ function parseBoxesAndLines(content, palette) {
18979
18986
  const nodes = [];
18980
18987
  const edges = [];
18981
18988
  const groups = [];
18989
+ const nodePositions = /* @__PURE__ */ new Map();
18982
18990
  const result = {
18983
18991
  type: "boxes-and-lines",
18984
18992
  title: null,
@@ -19012,6 +19020,8 @@ function parseBoxesAndLines(content, palette) {
19012
19020
  }
19013
19021
  const groupStack = [];
19014
19022
  let contentStarted = false;
19023
+ let inLayoutBlock = false;
19024
+ const LAYOUT_ENTRY_RE = /^(.+?):\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*$/;
19015
19025
  let currentTagGroup = null;
19016
19026
  const metaAliasMap = /* @__PURE__ */ new Map();
19017
19027
  const nameAliasMap = /* @__PURE__ */ new Map();
@@ -19213,6 +19223,42 @@ function parseBoxesAndLines(content, palette) {
19213
19223
  if (currentTagGroup && indent === 0) {
19214
19224
  currentTagGroup = null;
19215
19225
  }
19226
+ if (!inLayoutBlock && indent === 0 && trimmed === "layout") {
19227
+ let isBlock = false;
19228
+ for (let j = i + 1; j < lines.length; j++) {
19229
+ const peek = lines[j];
19230
+ if (!peek.trim()) continue;
19231
+ isBlock = measureIndent2(peek) > 0 && LAYOUT_ENTRY_RE.test(peek.trim());
19232
+ break;
19233
+ }
19234
+ if (isBlock) {
19235
+ flushDescription();
19236
+ closeGroupsToIndent(0);
19237
+ inLayoutBlock = true;
19238
+ continue;
19239
+ }
19240
+ }
19241
+ if (inLayoutBlock) {
19242
+ if (indent > 0) {
19243
+ const lm = trimmed.match(LAYOUT_ENTRY_RE);
19244
+ if (lm) {
19245
+ nodePositions.set(lm[1].trim(), {
19246
+ x: Number(lm[2]),
19247
+ y: Number(lm[3])
19248
+ });
19249
+ } else {
19250
+ result.diagnostics.push(
19251
+ makeDgmoError(
19252
+ lineNum,
19253
+ `Invalid layout entry "${trimmed}" \u2014 expected "<node-id>: <x>, <y>"`,
19254
+ "warning"
19255
+ )
19256
+ );
19257
+ }
19258
+ continue;
19259
+ }
19260
+ inLayoutBlock = false;
19261
+ }
19216
19262
  if (descState !== null) {
19217
19263
  if (indent > descState.indent) {
19218
19264
  if (trimmed.includes("->") || trimmed.includes("<->")) {
@@ -19465,6 +19511,22 @@ function parseBoxesAndLines(content, palette) {
19465
19511
  );
19466
19512
  }
19467
19513
  finalizeAutoTagColors(result.tagGroups);
19514
+ if (nodePositions.size > 0) {
19515
+ const nodeLabelSet = new Set(result.nodes.map((n) => n.label));
19516
+ for (const id of nodePositions.keys()) {
19517
+ if (!nodeLabelSet.has(id)) {
19518
+ pushWarning(0, `layout entry for unknown node "${id}" (ignored)`);
19519
+ }
19520
+ }
19521
+ const unpositioned = result.nodes.filter((n) => !nodePositions.has(n.label)).map((n) => n.label);
19522
+ if (unpositioned.length > 0) {
19523
+ pushWarning(
19524
+ 0,
19525
+ `layout block is partial \u2014 ${unpositioned.length} node(s) without coordinates (${unpositioned.slice(0, 5).join(", ")}${unpositioned.length > 5 ? "\u2026" : ""}); ignoring the block and auto-laying-out`
19526
+ );
19527
+ }
19528
+ result.nodePositions = nodePositions;
19529
+ }
19468
19530
  if (result.tagGroups.length > 0) {
19469
19531
  injectDefaultTagMetadata(result.nodes, result.tagGroups);
19470
19532
  validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
@@ -21565,7 +21627,18 @@ function parseJourneyMap(content, palette) {
21565
21627
  }
21566
21628
  }
21567
21629
  } else {
21568
- personaName = afterKeyword;
21630
+ const colorMatch = afterKeyword.match(/^(.+?)\s+color:\s*(\S+)$/i);
21631
+ if (colorMatch) {
21632
+ personaName = colorMatch[1].trim();
21633
+ personaColor = resolveColorWithDiagnostic(
21634
+ colorMatch[2],
21635
+ lineNumber,
21636
+ result.diagnostics,
21637
+ palette
21638
+ ) ?? void 0;
21639
+ } else {
21640
+ personaName = afterKeyword;
21641
+ }
21569
21642
  }
21570
21643
  if (!personaName) {
21571
21644
  return fail(lineNumber, "persona requires a name");
@@ -24506,6 +24579,63 @@ var init_export_container = __esm({
24506
24579
  }
24507
24580
  });
24508
24581
 
24582
+ // src/utils/card.ts
24583
+ function renderNodeCard(container, opts) {
24584
+ const rect = container.append("rect").attr("x", 0).attr("y", 0).attr("width", opts.width).attr("height", opts.height).attr("rx", opts.rx).attr("fill", opts.fill).attr("stroke", opts.stroke).attr("stroke-width", opts.strokeWidth);
24585
+ if (opts.dashed) {
24586
+ rect.attr("stroke-dasharray", "6 3");
24587
+ }
24588
+ container.append("text").attr("x", opts.width / 2).attr("y", opts.headerHeight / 2 + opts.labelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", opts.labelColor).attr("font-size", opts.labelFontSize).attr("font-weight", "bold").text(opts.label);
24589
+ const meta = opts.meta;
24590
+ if (!meta || meta.rows.length === 0) return;
24591
+ container.append("line").attr("x1", 0).attr("y1", opts.headerHeight).attr("x2", opts.width).attr("y2", opts.headerHeight).attr("stroke", meta.separatorColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
24592
+ const keyX = meta.keyX ?? 10;
24593
+ const maxKeyWidth = Math.max(
24594
+ ...meta.rows.map(([key]) => measureText(`${key}: `, meta.fontSize))
24595
+ );
24596
+ const valueX = keyX + maxKeyWidth;
24597
+ const metaStartY = opts.headerHeight + meta.separatorGap + meta.fontSize;
24598
+ for (let i = 0; i < meta.rows.length; i++) {
24599
+ const [displayKey, value] = meta.rows[i];
24600
+ const rowY = metaStartY + i * meta.lineHeight;
24601
+ container.append("text").attr("x", keyX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(`${displayKey}: `);
24602
+ container.append("text").attr("x", valueX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(value);
24603
+ }
24604
+ }
24605
+ function renderCollapseBar(container, opts) {
24606
+ container.append("clipPath").attr("id", opts.clipId).append("rect").attr("width", opts.width).attr("height", opts.height).attr("rx", opts.rx);
24607
+ container.append("rect").attr("x", opts.inset).attr("y", opts.height - opts.barHeight).attr("width", opts.width - opts.inset * 2).attr("height", opts.barHeight).attr("fill", opts.fill).attr("clip-path", `url(#${opts.clipId})`).attr("class", opts.className);
24608
+ }
24609
+ var init_card = __esm({
24610
+ "src/utils/card.ts"() {
24611
+ "use strict";
24612
+ init_text_measure();
24613
+ }
24614
+ });
24615
+
24616
+ // src/utils/visual-conventions.ts
24617
+ var NODE_STROKE_WIDTH, EDGE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, COLLAPSE_BAR_INSET, HEADER_HEIGHT2, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT2, SEPARATOR_GAP2, COLLAPSE_BAR_HEIGHT, CONTAINER_HEADER_HEIGHT, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2;
24618
+ var init_visual_conventions = __esm({
24619
+ "src/utils/visual-conventions.ts"() {
24620
+ "use strict";
24621
+ NODE_STROKE_WIDTH = 1.5;
24622
+ EDGE_STROKE_WIDTH = 1.5;
24623
+ CARD_RADIUS = 6;
24624
+ CONTAINER_RADIUS = 8;
24625
+ COLLAPSE_BAR_INSET = 0;
24626
+ HEADER_HEIGHT2 = 28;
24627
+ LABEL_FONT_SIZE2 = 13;
24628
+ META_FONT_SIZE2 = 11;
24629
+ META_LINE_HEIGHT2 = 16;
24630
+ SEPARATOR_GAP2 = 6;
24631
+ COLLAPSE_BAR_HEIGHT = 6;
24632
+ CONTAINER_HEADER_HEIGHT = 28;
24633
+ CONTAINER_LABEL_FONT_SIZE = 13;
24634
+ CONTAINER_META_FONT_SIZE = 11;
24635
+ CONTAINER_META_LINE_HEIGHT2 = 16;
24636
+ }
24637
+ });
24638
+
24509
24639
  // src/org/renderer.ts
24510
24640
  var renderer_exports = {};
24511
24641
  __export(renderer_exports, {
@@ -24664,9 +24794,16 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24664
24794
  }
24665
24795
  }
24666
24796
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
24667
- const clipId = `clip-${c.nodeId}`;
24668
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", sContainerRadius);
24669
- cG.append("rect").attr("x", sCollapseBarInset).attr("y", c.height - sCollapseBarHeight).attr("width", c.width - sCollapseBarInset * 2).attr("height", sCollapseBarHeight).attr("fill", containerStroke(palette, colorOff ? void 0 : c.color)).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
24797
+ renderCollapseBar(cG, {
24798
+ width: c.width,
24799
+ height: c.height,
24800
+ barHeight: sCollapseBarHeight,
24801
+ inset: sCollapseBarInset,
24802
+ rx: sContainerRadius,
24803
+ fill: containerStroke(palette, colorOff ? void 0 : c.color),
24804
+ clipId: `clip-${c.nodeId}`,
24805
+ className: "org-collapse-bar"
24806
+ });
24670
24807
  }
24671
24808
  if (!exportDims && c.hasChildren && !rootNodeIds.has(c.nodeId)) {
24672
24809
  const iconSize = 14;
@@ -24717,42 +24854,48 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24717
24854
  solid
24718
24855
  );
24719
24856
  const stroke2 = nodeStroke(palette, colorOff ? void 0 : node.color);
24720
- const rect = nodeG.append("rect").attr("x", 0).attr("y", 0).attr("width", node.width).attr("height", node.height).attr("rx", sCardRadius).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sNodeStrokeWidth);
24721
- if (node.isContainer) {
24722
- rect.attr("stroke-dasharray", "6 3");
24723
- }
24724
24857
  const labelColor = contrastText(
24725
24858
  fill2,
24726
24859
  palette.textOnFillLight,
24727
24860
  palette.textOnFillDark
24728
24861
  );
24729
- nodeG.append("text").attr("x", node.width / 2).attr("y", sHeaderHeight / 2 + sLabelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", sLabelFontSize).attr("font-weight", "bold").text(node.label);
24730
24862
  const metaEntries = Object.entries(node.metadata);
24731
- if (metaEntries.length > 0) {
24732
- nodeG.append("line").attr("x1", 0).attr("y1", sHeaderHeight).attr("x2", node.width).attr("y2", sHeaderHeight).attr("stroke", solid ? labelColor : stroke2).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
24733
- const metaDisplayKeys = metaEntries.map(
24734
- ([k]) => displayNames.get(k) ?? k
24735
- );
24736
- const maxKeyWidth = Math.max(
24737
- ...metaDisplayKeys.map((k) => measureText(`${k}: `, sMetaFontSize))
24738
- );
24739
- const valueX = 10 + maxKeyWidth;
24740
- const metaStartY = sHeaderHeight + sSeparatorGap + sMetaFontSize;
24741
- for (let i = 0; i < metaEntries.length; i++) {
24742
- const [, value] = metaEntries[i];
24743
- const displayKey = metaDisplayKeys[i];
24744
- const rowY = metaStartY + i * sMetaLineHeight;
24745
- nodeG.append("text").attr("x", 10).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(`${displayKey}: `);
24746
- nodeG.append("text").attr("x", valueX).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(value);
24863
+ renderNodeCard(nodeG, {
24864
+ width: node.width,
24865
+ height: node.height,
24866
+ rx: sCardRadius,
24867
+ fill: fill2,
24868
+ stroke: stroke2,
24869
+ strokeWidth: sNodeStrokeWidth,
24870
+ ...node.isContainer && { dashed: true },
24871
+ label: node.label,
24872
+ labelColor,
24873
+ labelFontSize: sLabelFontSize,
24874
+ headerHeight: sHeaderHeight,
24875
+ ...metaEntries.length > 0 && {
24876
+ meta: {
24877
+ rows: metaEntries.map(
24878
+ ([k, value]) => [displayNames.get(k) ?? k, value]
24879
+ ),
24880
+ fontSize: sMetaFontSize,
24881
+ lineHeight: sMetaLineHeight,
24882
+ separatorGap: sSeparatorGap,
24883
+ separatorColor: solid ? labelColor : stroke2,
24884
+ textColor: labelColor
24885
+ }
24747
24886
  }
24748
- }
24887
+ });
24749
24888
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
24750
- const clipId = `clip-${node.id}`;
24751
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", sCardRadius);
24752
- nodeG.append("rect").attr("x", sCollapseBarInset).attr("y", node.height - sCollapseBarHeight).attr("width", node.width - sCollapseBarInset * 2).attr("height", sCollapseBarHeight).attr(
24753
- "fill",
24754
- solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color)
24755
- ).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
24889
+ renderCollapseBar(nodeG, {
24890
+ width: node.width,
24891
+ height: node.height,
24892
+ barHeight: sCollapseBarHeight,
24893
+ inset: sCollapseBarInset,
24894
+ rx: sCardRadius,
24895
+ fill: solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color),
24896
+ clipId: `clip-${node.id}`,
24897
+ className: "org-collapse-bar"
24898
+ });
24756
24899
  }
24757
24900
  if (!exportDims && node.hasChildren && !rootNodeIds.has(node.id)) {
24758
24901
  const iconSize = 14;
@@ -24896,7 +25039,7 @@ function renderOrgForExport(content, theme, palette) {
24896
25039
  return extractExportSvg(container, theme);
24897
25040
  });
24898
25041
  }
24899
- var DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
25042
+ var DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
24900
25043
  var init_renderer = __esm({
24901
25044
  "src/org/renderer.ts"() {
24902
25045
  "use strict";
@@ -24909,27 +25052,14 @@ var init_renderer = __esm({
24909
25052
  init_layout();
24910
25053
  init_legend_constants();
24911
25054
  init_legend_integration();
25055
+ init_card();
24912
25056
  init_text_measure();
24913
25057
  init_legend_layout();
24914
25058
  init_title_constants();
25059
+ init_visual_conventions();
24915
25060
  DIAGRAM_PADDING = 20;
24916
25061
  MAX_SCALE = 3;
24917
25062
  TITLE_HEIGHT = 30;
24918
- LABEL_FONT_SIZE2 = 13;
24919
- META_FONT_SIZE2 = 11;
24920
- META_LINE_HEIGHT2 = 16;
24921
- HEADER_HEIGHT2 = 28;
24922
- SEPARATOR_GAP2 = 6;
24923
- EDGE_STROKE_WIDTH = 1.5;
24924
- NODE_STROKE_WIDTH = 1.5;
24925
- CARD_RADIUS = 6;
24926
- CONTAINER_RADIUS = 8;
24927
- CONTAINER_LABEL_FONT_SIZE = 13;
24928
- CONTAINER_META_FONT_SIZE = 11;
24929
- CONTAINER_META_LINE_HEIGHT2 = 16;
24930
- CONTAINER_HEADER_HEIGHT = 28;
24931
- COLLAPSE_BAR_HEIGHT = 6;
24932
- COLLAPSE_BAR_INSET = 0;
24933
25063
  ANCESTOR_DOT_R = 4;
24934
25064
  ANCESTOR_LABEL_FONT_SIZE = 11;
24935
25065
  ANCESTOR_ROW_HEIGHT = 22;
@@ -25713,21 +25843,21 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25713
25843
  if (width <= 0 || height <= 0) return;
25714
25844
  const ctx = ScaleContext.identity();
25715
25845
  const sDiagramPadding = ctx.aesthetic(DIAGRAM_PADDING2);
25716
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE4);
25717
- const sMetaFontSize = ctx.text(META_FONT_SIZE4);
25718
- const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT4);
25719
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT4);
25720
- const sSeparatorGap = ctx.structural(SEPARATOR_GAP4);
25721
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH2);
25722
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH2);
25846
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE2);
25847
+ const sMetaFontSize = ctx.text(META_FONT_SIZE2);
25848
+ const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT2);
25849
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT2);
25850
+ const sSeparatorGap = ctx.structural(SEPARATOR_GAP2);
25851
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
25852
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
25723
25853
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE);
25724
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE3);
25725
- const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE2);
25726
- const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT4);
25727
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT2);
25854
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
25855
+ const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE);
25856
+ const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT2);
25857
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
25728
25858
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
25729
25859
  const sTitleHeight = ctx.structural(TITLE_HEIGHT2);
25730
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT2);
25860
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
25731
25861
  const sLegendFixedGap = ctx.aesthetic(LEGEND_FIXED_GAP2);
25732
25862
  const hasLegend = layout.legend.length > 0;
25733
25863
  const layoutLegendShift = LEGEND_HEIGHT + LEGEND_GROUP_GAP;
@@ -25818,7 +25948,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25818
25948
  }
25819
25949
  const fill2 = containerFill2(palette, isDark, c.color);
25820
25950
  const stroke2 = containerStroke2(palette, c.color);
25821
- cG.append("rect").attr("x", 0).attr("y", 0).attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS2).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-opacity", 0.35).attr("stroke-width", sNodeStrokeWidth);
25951
+ cG.append("rect").attr("x", 0).attr("y", 0).attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-opacity", 0.35).attr("stroke-width", sNodeStrokeWidth);
25822
25952
  cG.append("text").attr("x", c.width / 2).attr("y", sContainerHeaderHeight / 2 + sContainerLabelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", sContainerLabelFontSize).attr("font-weight", "bold").text(c.label);
25823
25953
  const metaEntries = Object.entries(c.metadata);
25824
25954
  if (metaEntries.length > 0) {
@@ -25843,7 +25973,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25843
25973
  }
25844
25974
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
25845
25975
  const clipId = `clip-${c.nodeId}`;
25846
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS2);
25976
+ cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS);
25847
25977
  cG.append("rect").attr("y", c.height - sCollapseBarHeight).attr("width", c.width).attr("height", sCollapseBarHeight).attr("fill", c.color ?? palette.primary).attr("opacity", 0.5).attr("clip-path", `url(#${clipId})`);
25848
25978
  cG.append("text").attr("x", c.width / 2).attr("y", c.height - sCollapseBarHeight - 6).attr("text-anchor", "middle").attr("fill", palette.textMuted).attr("font-size", sMetaFontSize).text(`+${c.hiddenCount}`);
25849
25979
  }
@@ -25882,13 +26012,23 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25882
26012
  const solid = parsed.options["solid-fill"] === "on";
25883
26013
  const fill2 = nodeFill2(palette, isDark, node.color, solid);
25884
26014
  const stroke2 = nodeStroke2(palette, node.color);
25885
- nodeG.append("rect").attr("x", 0).attr("y", 0).attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS2).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sNodeStrokeWidth);
25886
26015
  const labelColor = contrastText(
25887
26016
  fill2,
25888
26017
  palette.textOnFillLight,
25889
26018
  palette.textOnFillDark
25890
26019
  );
25891
- nodeG.append("text").attr("x", node.width / 2).attr("y", sHeaderHeight / 2 + sLabelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", sLabelFontSize).attr("font-weight", "bold").text(node.label);
26020
+ renderNodeCard(nodeG, {
26021
+ width: node.width,
26022
+ height: node.height,
26023
+ rx: CARD_RADIUS,
26024
+ fill: fill2,
26025
+ stroke: stroke2,
26026
+ strokeWidth: sNodeStrokeWidth,
26027
+ label: node.label,
26028
+ labelColor,
26029
+ labelFontSize: sLabelFontSize,
26030
+ headerHeight: sHeaderHeight
26031
+ });
25892
26032
  const metaEntries = Object.entries(node.metadata);
25893
26033
  if (metaEntries.length > 0) {
25894
26034
  nodeG.append("line").attr("x1", 0).attr("y1", sHeaderHeight).attr("x2", node.width).attr("y2", sHeaderHeight).attr("stroke", solid ? labelColor : stroke2).attr("stroke-opacity", 0.3);
@@ -25923,7 +26063,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25923
26063
  }
25924
26064
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
25925
26065
  const clipId = `clip-${node.id}`;
25926
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS2);
26066
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS);
25927
26067
  nodeG.append("rect").attr("y", node.height - sCollapseBarHeight).attr("width", node.width).attr("height", sCollapseBarHeight).attr("fill", solid ? labelColor : node.color ?? palette.primary).attr("opacity", 0.5).attr("clip-path", `url(#${clipId})`);
25928
26068
  }
25929
26069
  }
@@ -26053,7 +26193,7 @@ async function renderSitemapForExport(content, theme, palette) {
26053
26193
  document.body.removeChild(container);
26054
26194
  return svgHtml;
26055
26195
  }
26056
- var DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, LABEL_FONT_SIZE4, META_FONT_SIZE4, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE3, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
26196
+ var DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
26057
26197
  var init_renderer2 = __esm({
26058
26198
  "src/sitemap/renderer.ts"() {
26059
26199
  "use strict";
@@ -26066,27 +26206,15 @@ var init_renderer2 = __esm({
26066
26206
  init_legend_integration();
26067
26207
  init_legend_layout();
26068
26208
  init_scaling();
26209
+ init_card();
26069
26210
  init_title_constants();
26211
+ init_visual_conventions();
26070
26212
  DIAGRAM_PADDING2 = 20;
26071
26213
  MAX_SCALE2 = 3;
26072
26214
  TITLE_HEIGHT2 = 30;
26073
- LABEL_FONT_SIZE4 = 13;
26074
- META_FONT_SIZE4 = 11;
26075
- META_LINE_HEIGHT4 = 16;
26076
- HEADER_HEIGHT4 = 28;
26077
- SEPARATOR_GAP4 = 6;
26078
- EDGE_STROKE_WIDTH2 = 1.5;
26079
- NODE_STROKE_WIDTH2 = 1.5;
26080
- CARD_RADIUS2 = 6;
26081
- CONTAINER_RADIUS2 = 8;
26082
- CONTAINER_LABEL_FONT_SIZE3 = 13;
26083
- CONTAINER_META_FONT_SIZE2 = 11;
26084
- CONTAINER_META_LINE_HEIGHT4 = 16;
26085
- CONTAINER_HEADER_HEIGHT2 = 28;
26086
26215
  ARROWHEAD_W = 10;
26087
26216
  ARROWHEAD_H = 7;
26088
26217
  EDGE_LABEL_FONT_SIZE = 11;
26089
- COLLAPSE_BAR_HEIGHT2 = 6;
26090
26218
  LEGEND_FIXED_GAP2 = 8;
26091
26219
  lineGenerator = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveBasis);
26092
26220
  lineGeneratorLinear = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveLinear);
@@ -26344,7 +26472,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
26344
26472
  const sCardMetaLineHeight = ctx.structural(CARD_META_LINE_HEIGHT);
26345
26473
  const sCardSeparatorGap = ctx.structural(CARD_SEPARATOR_GAP);
26346
26474
  const sCardGap = ctx.aesthetic(CARD_GAP);
26347
- const sCardRadius = ctx.structural(CARD_RADIUS3);
26475
+ const sCardRadius = ctx.structural(CARD_RADIUS);
26348
26476
  const sCardPaddingX = ctx.aesthetic(CARD_PADDING_X);
26349
26477
  const sCardPaddingY = ctx.aesthetic(CARD_PADDING_Y);
26350
26478
  const sCardStrokeWidth = ctx.structural(CARD_STROKE_WIDTH);
@@ -26724,7 +26852,7 @@ function computeSwimlaneLayout(parsed, buckets, baseLayout, collapsedLanes, coll
26724
26852
  const totalHeight = laneY - sLaneGap + sColumnPadding + sDiagramPadding;
26725
26853
  return { columnXs, lanes, totalWidth, totalHeight, startY };
26726
26854
  }
26727
- function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, isDark, activeTagGroup, collapsedLanes, collapsedColumns, hiddenMetaGroups, sDiagramPadding = DIAGRAM_PADDING3, sTitleHeight = TITLE_HEIGHT3, sLaneHeaderWidth = LANE_HEADER_WIDTH, sColumnGap = COLUMN_GAP, sCollapsedColumnWidth = COLLAPSED_COLUMN_WIDTH, sColumnHeaderHeight = COLUMN_HEADER_HEIGHT, sColumnPadding = COLUMN_PADDING, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardPaddingY = CARD_PADDING_Y, sCardGap = CARD_GAP, sCollapsedLaneHeight = COLLAPSED_LANE_HEIGHT, sLaneGap = LANE_GAP, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT, sColumnHeaderFontSize = COLUMN_HEADER_FONT_SIZE, sColumnRadius = COLUMN_RADIUS, sColumnHeaderRadius = COLUMN_HEADER_RADIUS, sWipFontSize = WIP_FONT_SIZE, sCardRadius = CARD_RADIUS3, sCardPaddingX = CARD_PADDING_X, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE) {
26855
+ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, isDark, activeTagGroup, collapsedLanes, collapsedColumns, hiddenMetaGroups, sDiagramPadding = DIAGRAM_PADDING3, sTitleHeight = TITLE_HEIGHT3, sLaneHeaderWidth = LANE_HEADER_WIDTH, sColumnGap = COLUMN_GAP, sCollapsedColumnWidth = COLLAPSED_COLUMN_WIDTH, sColumnHeaderHeight = COLUMN_HEADER_HEIGHT, sColumnPadding = COLUMN_PADDING, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardPaddingY = CARD_PADDING_Y, sCardGap = CARD_GAP, sCollapsedLaneHeight = COLLAPSED_LANE_HEIGHT, sLaneGap = LANE_GAP, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT, sColumnHeaderFontSize = COLUMN_HEADER_FONT_SIZE, sColumnRadius = COLUMN_RADIUS, sColumnHeaderRadius = COLUMN_HEADER_RADIUS, sWipFontSize = WIP_FONT_SIZE, sCardRadius = CARD_RADIUS, sCardPaddingX = CARD_PADDING_X, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE) {
26728
26856
  const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
26729
26857
  const buckets = bucketCardsBySwimlane(visibleColumns, swimlaneGroup);
26730
26858
  const grid = computeSwimlaneLayout(
@@ -26864,7 +26992,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
26864
26992
  }
26865
26993
  }
26866
26994
  }
26867
- function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palette, isDark, hiddenMetaGroups, solid, sCardRadius = CARD_RADIUS3, sCardPaddingX = CARD_PADDING_X, sCardPaddingY = CARD_PADDING_Y, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT) {
26995
+ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palette, isDark, hiddenMetaGroups, solid, sCardRadius = CARD_RADIUS, sCardPaddingX = CARD_PADDING_X, sCardPaddingY = CARD_PADDING_Y, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT) {
26868
26996
  const card = cardLayout.card;
26869
26997
  const resolvedColor = resolveCardTagColor(card, tagGroups, activeTagGroup);
26870
26998
  const tagMeta = resolveCardTagMeta(card, tagGroups, hiddenMetaGroups);
@@ -26914,7 +27042,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
26914
27042
  }
26915
27043
  }
26916
27044
  }
26917
- var DIAGRAM_PADDING3, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_RADIUS3, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT3, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, COLLAPSED_COLUMN_WIDTH, COLLAPSED_LANE_HEIGHT, LANE_HEADER_WIDTH, LANE_GAP;
27045
+ var DIAGRAM_PADDING3, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT3, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, COLLAPSED_COLUMN_WIDTH, COLLAPSED_LANE_HEIGHT, LANE_HEADER_WIDTH, LANE_GAP;
26918
27046
  var init_renderer3 = __esm({
26919
27047
  "src/kanban/renderer.ts"() {
26920
27048
  "use strict";
@@ -26928,6 +27056,7 @@ var init_renderer3 = __esm({
26928
27056
  init_legend_integration();
26929
27057
  init_scaling();
26930
27058
  init_text_measure();
27059
+ init_visual_conventions();
26931
27060
  init_title_constants();
26932
27061
  DIAGRAM_PADDING3 = 20;
26933
27062
  COLUMN_GAP = 16;
@@ -26938,7 +27067,6 @@ var init_renderer3 = __esm({
26938
27067
  CARD_META_LINE_HEIGHT = 14;
26939
27068
  CARD_SEPARATOR_GAP = 4;
26940
27069
  CARD_GAP = 8;
26941
- CARD_RADIUS3 = 6;
26942
27070
  CARD_PADDING_X = 10;
26943
27071
  CARD_PADDING_Y = 6;
26944
27072
  CARD_STROKE_WIDTH = 1.5;
@@ -27241,8 +27369,8 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
27241
27369
  const sClassFontSize = ctx.text(CLASS_FONT_SIZE2);
27242
27370
  const sMemberFontSize = ctx.text(MEMBER_FONT_SIZE2);
27243
27371
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE2);
27244
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH3);
27245
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH3);
27372
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
27373
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
27246
27374
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT2);
27247
27375
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y2);
27248
27376
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X);
@@ -27501,7 +27629,7 @@ function renderClassDiagramForExport(content, theme, palette) {
27501
27629
  return extractExportSvg(container, theme);
27502
27630
  });
27503
27631
  }
27504
- var DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE2, MEMBER_FONT_SIZE2, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, CLASS_TYPE_MAP, CLASS_TYPE_ORDER, LEGEND_GROUP_NAME, lineGenerator2;
27632
+ var DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE2, MEMBER_FONT_SIZE2, EDGE_LABEL_FONT_SIZE2, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, CLASS_TYPE_MAP, CLASS_TYPE_ORDER, LEGEND_GROUP_NAME, lineGenerator2;
27505
27633
  var init_renderer4 = __esm({
27506
27634
  "src/class/renderer.ts"() {
27507
27635
  "use strict";
@@ -27516,13 +27644,12 @@ var init_renderer4 = __esm({
27516
27644
  init_scaling();
27517
27645
  init_text_measure();
27518
27646
  init_note_box();
27647
+ init_visual_conventions();
27519
27648
  DIAGRAM_PADDING4 = 20;
27520
27649
  MAX_SCALE3 = 3;
27521
27650
  CLASS_FONT_SIZE2 = 13;
27522
27651
  MEMBER_FONT_SIZE2 = 11;
27523
27652
  EDGE_LABEL_FONT_SIZE2 = 11;
27524
- EDGE_STROKE_WIDTH3 = 1.5;
27525
- NODE_STROKE_WIDTH3 = 1.5;
27526
27653
  MEMBER_LINE_HEIGHT2 = 18;
27527
27654
  COMPARTMENT_PADDING_Y2 = 8;
27528
27655
  MEMBER_PADDING_X = 10;
@@ -28018,7 +28145,7 @@ function constraintIcon(constraint) {
28018
28145
  return "\u25CB";
28019
28146
  }
28020
28147
  }
28021
- function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH4) {
28148
+ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH) {
28022
28149
  const dx = point.x - prevPoint.x;
28023
28150
  const dy = point.y - prevPoint.y;
28024
28151
  const len = Math.sqrt(dx * dx + dy * dy);
@@ -28078,8 +28205,8 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
28078
28205
  const sTableFontSize = ctx.text(TABLE_FONT_SIZE2);
28079
28206
  const sColumnFontSize = ctx.text(COLUMN_FONT_SIZE2);
28080
28207
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE4);
28081
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH4);
28082
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH4);
28208
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
28209
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
28083
28210
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT4);
28084
28211
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y4);
28085
28212
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X2);
@@ -28357,7 +28484,7 @@ function renderERDiagramForExport(content, theme, palette) {
28357
28484
  document.body.removeChild(container);
28358
28485
  }
28359
28486
  }
28360
- var DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COLUMN_FONT_SIZE2, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH4, NODE_STROKE_WIDTH4, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator3;
28487
+ var DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COLUMN_FONT_SIZE2, EDGE_LABEL_FONT_SIZE4, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator3;
28361
28488
  var init_renderer5 = __esm({
28362
28489
  "src/er/renderer.ts"() {
28363
28490
  "use strict";
@@ -28374,13 +28501,12 @@ var init_renderer5 = __esm({
28374
28501
  init_parser9();
28375
28502
  init_layout4();
28376
28503
  init_classify();
28504
+ init_visual_conventions();
28377
28505
  DIAGRAM_PADDING5 = 20;
28378
28506
  MAX_SCALE4 = 3;
28379
28507
  TABLE_FONT_SIZE2 = 13;
28380
28508
  COLUMN_FONT_SIZE2 = 11;
28381
28509
  EDGE_LABEL_FONT_SIZE4 = 11;
28382
- EDGE_STROKE_WIDTH4 = 1.5;
28383
- NODE_STROKE_WIDTH4 = 1.5;
28384
28510
  MEMBER_LINE_HEIGHT4 = 18;
28385
28511
  COMPARTMENT_PADDING_Y4 = 8;
28386
28512
  MEMBER_PADDING_X2 = 10;
@@ -28610,9 +28736,9 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28610
28736
  const sDiagramPadding = sctx.aesthetic(DIAGRAM_PADDING6);
28611
28737
  const sMinNodeFontSize = sctx.text(MIN_NODE_FONT_SIZE);
28612
28738
  const sEdgeLabelFontSize = sctx.text(EDGE_LABEL_FONT_SIZE5);
28613
- const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH5);
28614
- const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH5);
28615
- const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT3);
28739
+ const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH);
28740
+ const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH);
28741
+ const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT2);
28616
28742
  const sDescFontSize = sctx.text(DESC_FONT_SIZE);
28617
28743
  const sGroupLabelFontSize = sctx.text(GROUP_LABEL_FONT_SIZE);
28618
28744
  const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
@@ -28704,8 +28830,32 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28704
28830
  const scaleX = width / (contentW + sDiagramPadding * 2);
28705
28831
  const scaleY = height / (contentH + sDiagramPadding * 2);
28706
28832
  const scale = Math.min(scaleX, scaleY, 3);
28707
- const offsetX = (width - contentW * scale) / 2;
28708
- const offsetY = sDiagramPadding + titleOffset + legendH;
28833
+ let centerShiftX = 0;
28834
+ let centerShiftY = 0;
28835
+ if (parsed.nodePositions && parsed.nodePositions.size > 0) {
28836
+ let bMinX = Infinity, bMinY = Infinity, bMaxX = -Infinity, bMaxY = -Infinity;
28837
+ const accB = (x, y) => {
28838
+ if (x < bMinX) bMinX = x;
28839
+ if (x > bMaxX) bMaxX = x;
28840
+ if (y < bMinY) bMinY = y;
28841
+ if (y > bMaxY) bMaxY = y;
28842
+ };
28843
+ for (const n of layout.nodes) {
28844
+ accB(n.x - n.width / 2, n.y - n.height / 2);
28845
+ accB(n.x + n.width / 2, n.y + n.height / 2);
28846
+ }
28847
+ for (const g of layout.groups) {
28848
+ accB(g.x - g.width / 2, g.y - g.height / 2);
28849
+ accB(g.x + g.width / 2, g.y + g.height / 2);
28850
+ }
28851
+ for (const e of layout.edges) for (const p of e.points) accB(p.x, p.y);
28852
+ if (Number.isFinite(bMinX)) {
28853
+ centerShiftX = (layout.width - bMaxX - bMinX) / 2;
28854
+ centerShiftY = (layout.height - bMaxY - bMinY) / 2;
28855
+ }
28856
+ }
28857
+ const offsetX = (width - contentW * scale) / 2 + centerShiftX * scale;
28858
+ const offsetY = sDiagramPadding + titleOffset + legendH + centerShiftY * scale;
28709
28859
  const svg = d3Selection11.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").style("font-family", FONT_FAMILY).style("background", palette.bg);
28710
28860
  if (sctx.isBelowFloor) {
28711
28861
  svg.attr("width", "100%");
@@ -28841,7 +28991,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28841
28991
  const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
28842
28992
  edgeGroups.set(i, edgeG);
28843
28993
  const markerId = `bl-arrow-${color.replace("#", "")}`;
28844
- const gen = parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28994
+ const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28845
28995
  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})`);
28846
28996
  if (le.bidirectional) {
28847
28997
  const revId = `bl-arrow-rev-${color.replace("#", "")}`;
@@ -29122,7 +29272,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
29122
29272
  }
29123
29273
  });
29124
29274
  }
29125
- var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE5, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB;
29275
+ var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE5, NODE_RX, COLLAPSE_BAR_HEIGHT2, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB, lineGeneratorStraight;
29126
29276
  var init_renderer6 = __esm({
29127
29277
  "src/boxes-and-lines/renderer.ts"() {
29128
29278
  "use strict";
@@ -29138,14 +29288,13 @@ var init_renderer6 = __esm({
29138
29288
  init_wrapped_desc();
29139
29289
  init_scaling();
29140
29290
  init_text_measure();
29291
+ init_visual_conventions();
29141
29292
  DIAGRAM_PADDING6 = 20;
29142
29293
  NODE_FONT_SIZE = 11;
29143
29294
  MIN_NODE_FONT_SIZE = 9;
29144
29295
  EDGE_LABEL_FONT_SIZE5 = 11;
29145
- EDGE_STROKE_WIDTH5 = 1.5;
29146
- NODE_STROKE_WIDTH5 = 1.5;
29147
29296
  NODE_RX = 8;
29148
- COLLAPSE_BAR_HEIGHT3 = 4;
29297
+ COLLAPSE_BAR_HEIGHT2 = 4;
29149
29298
  ARROWHEAD_W2 = 5;
29150
29299
  ARROWHEAD_H2 = 4;
29151
29300
  DESC_FONT_SIZE = 10;
@@ -29159,6 +29308,7 @@ var init_renderer6 = __esm({
29159
29308
  VALUE_FONT_SIZE = 11;
29160
29309
  lineGeneratorLR = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29161
29310
  lineGeneratorTB = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29311
+ lineGeneratorStraight = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveLinear);
29162
29312
  }
29163
29313
  });
29164
29314
 
@@ -30348,6 +30498,156 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30348
30498
  return { x: rect.x + dx * s, y: rect.y + dy * s };
30349
30499
  };
30350
30500
  const isInsideRect = (p, rect) => Math.abs(p.x - rect.x) <= rect.w / 2 && Math.abs(p.y - rect.y) <= rect.h / 2;
30501
+ const pinned = parsed.nodePositions;
30502
+ const groupLabelSet = new Set(parsed.groups.map((g) => g.label));
30503
+ const groupsAreFlat = parsed.groups.every(
30504
+ (g) => !g.parentGroup && !g.children.some((c) => groupLabelSet.has(c))
30505
+ );
30506
+ const allOriginalGroupLabels = new Set(
30507
+ (collapseInfo?.originalGroups ?? parsed.groups).map((g) => g.label)
30508
+ );
30509
+ const collapsedAreFlatPinned = collapsedGroupLabels.size === 0 || pinned !== void 0 && collapseInfo !== void 0 && [...collapsedGroupLabels].every((label) => {
30510
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30511
+ if (!og || og.parentGroup) return false;
30512
+ return og.children.every(
30513
+ (c) => pinned.has(c) && !allOriginalGroupLabels.has(c)
30514
+ );
30515
+ });
30516
+ const allPinned = pinned !== void 0 && (parsed.nodes.length > 0 || collapsedGroupLabels.size > 0) && parsed.nodes.every((n2) => pinned.has(n2.label)) && groupsAreFlat && collapsedAreFlatPinned;
30517
+ function placePinned(pins) {
30518
+ const collapsedPosByGid = /* @__PURE__ */ new Map();
30519
+ const collapsedBoxes = [];
30520
+ if (collapseInfo)
30521
+ for (const label of collapsedGroupLabels) {
30522
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30523
+ if (!og) continue;
30524
+ let cx0 = Infinity, cy0 = Infinity, cx1 = -Infinity, cy1 = -Infinity;
30525
+ for (const c of og.children) {
30526
+ const p = pins.get(c);
30527
+ if (!p) continue;
30528
+ cx0 = Math.min(cx0, p.x);
30529
+ cx1 = Math.max(cx1, p.x);
30530
+ cy0 = Math.min(cy0, p.y);
30531
+ cy1 = Math.max(cy1, p.y);
30532
+ }
30533
+ if (!Number.isFinite(cx0)) continue;
30534
+ const cx = (cx0 + cx1) / 2;
30535
+ const cy = (cy0 + cy1) / 2;
30536
+ collapsedPosByGid.set(`__group_${label}`, { x: cx, y: cy });
30537
+ collapsedBoxes.push({
30538
+ label,
30539
+ lineNumber: og.lineNumber,
30540
+ childCount: collapseInfo.collapsedChildCounts.get(label) ?? og.children.length,
30541
+ x: cx,
30542
+ y: cy
30543
+ });
30544
+ }
30545
+ const posOf = (label) => pins.get(label) ?? collapsedPosByGid.get(label);
30546
+ const rectOf = (label) => {
30547
+ const p = posOf(label);
30548
+ const s = sizes.get(label) ?? { width: NODE_WIDTH, height: NODE_HEIGHT };
30549
+ return { x: p.x, y: p.y, w: s.width, h: s.height };
30550
+ };
30551
+ const nodes = parsed.nodes.map((n2) => {
30552
+ const r = rectOf(n2.label);
30553
+ return { label: n2.label, x: r.x, y: r.y, width: r.w, height: r.h };
30554
+ });
30555
+ const edges = parsed.edges.flatMap((e) => {
30556
+ const sp = posOf(e.source);
30557
+ const tp = posOf(e.target);
30558
+ if (!sp || !tp) return [];
30559
+ const srcRect = rectOf(e.source);
30560
+ const tgtRect = rectOf(e.target);
30561
+ const p0 = rectBorderPoint(srcRect, tp);
30562
+ const p1 = rectBorderPoint(tgtRect, sp);
30563
+ return [
30564
+ {
30565
+ source: e.source,
30566
+ target: e.target,
30567
+ ...e.label !== void 0 && { label: e.label },
30568
+ bidirectional: e.bidirectional,
30569
+ lineNumber: e.lineNumber,
30570
+ points: [p0, p1],
30571
+ yOffset: 0,
30572
+ parallelCount: 1,
30573
+ metadata: e.metadata,
30574
+ straight: true
30575
+ }
30576
+ ];
30577
+ });
30578
+ const GROUP_PAD = 16;
30579
+ const nodeByLabel = new Map(nodes.map((n2) => [n2.label, n2]));
30580
+ const groups = [];
30581
+ for (const grp of parsed.groups) {
30582
+ let gx0 = Infinity, gy0 = Infinity, gx1 = -Infinity, gy1 = -Infinity;
30583
+ for (const c of grp.children) {
30584
+ const n2 = nodeByLabel.get(c);
30585
+ if (!n2) continue;
30586
+ gx0 = Math.min(gx0, n2.x - n2.width / 2);
30587
+ gx1 = Math.max(gx1, n2.x + n2.width / 2);
30588
+ gy0 = Math.min(gy0, n2.y - n2.height / 2);
30589
+ gy1 = Math.max(gy1, n2.y + n2.height / 2);
30590
+ }
30591
+ if (!Number.isFinite(gx0)) continue;
30592
+ const x0 = gx0 - GROUP_PAD;
30593
+ const x1 = gx1 + GROUP_PAD;
30594
+ const y0 = gy0 - GROUP_LABEL_ZONE2;
30595
+ const y1 = gy1 + GROUP_PAD;
30596
+ groups.push({
30597
+ label: grp.label,
30598
+ lineNumber: grp.lineNumber,
30599
+ x: (x0 + x1) / 2,
30600
+ y: (y0 + y1) / 2,
30601
+ width: x1 - x0,
30602
+ height: y1 - y0,
30603
+ collapsed: false,
30604
+ childCount: grp.children.length
30605
+ });
30606
+ }
30607
+ for (const cb of collapsedBoxes) {
30608
+ groups.push({
30609
+ label: cb.label,
30610
+ lineNumber: cb.lineNumber,
30611
+ x: cb.x,
30612
+ y: cb.y,
30613
+ width: NODE_WIDTH,
30614
+ height: NODE_HEIGHT,
30615
+ collapsed: true,
30616
+ childCount: cb.childCount
30617
+ });
30618
+ }
30619
+ const M = 40;
30620
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
30621
+ const acc = (x, y) => {
30622
+ if (x < minX) minX = x;
30623
+ if (x > maxX) maxX = x;
30624
+ if (y < minY) minY = y;
30625
+ if (y > maxY) maxY = y;
30626
+ };
30627
+ for (const n2 of nodes) {
30628
+ acc(n2.x - n2.width / 2, n2.y - n2.height / 2);
30629
+ acc(n2.x + n2.width / 2, n2.y + n2.height / 2);
30630
+ }
30631
+ for (const e of edges) for (const p of e.points) acc(p.x, p.y);
30632
+ for (const gr of groups) {
30633
+ acc(gr.x - gr.width / 2, gr.y - gr.height / 2);
30634
+ acc(gr.x + gr.width / 2, gr.y + gr.height / 2);
30635
+ }
30636
+ const TOL = 2;
30637
+ const sx = minX < M - TOL ? M - minX : 0;
30638
+ const sy = minY < M - TOL ? M - minY : 0;
30639
+ const shifted = sx !== 0 || sy !== 0;
30640
+ return {
30641
+ nodes: shifted ? nodes.map((n2) => ({ ...n2, x: n2.x + sx, y: n2.y + sy })) : nodes,
30642
+ edges: shifted ? edges.map((e) => ({
30643
+ ...e,
30644
+ points: e.points.map((p) => ({ x: p.x + sx, y: p.y + sy }))
30645
+ })) : edges,
30646
+ groups: shifted ? groups.map((gr) => ({ ...gr, x: gr.x + sx, y: gr.y + sy })) : groups,
30647
+ width: maxX + sx + M,
30648
+ height: maxY + sy + M
30649
+ };
30650
+ }
30351
30651
  function place(cfg) {
30352
30652
  const r = cfg.seed === void 0 ? null : rng2(cfg.seed + 1);
30353
30653
  const ord = (a) => r ? shuffle(a, r) : a.slice();
@@ -30486,6 +30786,7 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30486
30786
  height: gg.height ?? 600
30487
30787
  };
30488
30788
  }
30789
+ if (allPinned) return placePinned(pinned);
30489
30790
  const n = parsed.nodes.length;
30490
30791
  const seedCount = opts?.seeds ?? (n <= 12 ? 80 : n <= 22 ? 40 : n <= 35 ? 22 : 10);
30491
30792
  const REFINE_K = opts?.refineK ?? 6;
@@ -30680,7 +30981,7 @@ function computeNodeSize(node, reserveValueRow) {
30680
30981
  }
30681
30982
  totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
30682
30983
  const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
30683
- const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30984
+ const totalHeight = labelHeight + SEPARATOR_GAP4 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30684
30985
  return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
30685
30986
  }
30686
30987
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
@@ -30809,7 +31110,7 @@ function applyParallelEdgeOffsets(layout) {
30809
31110
  }))
30810
31111
  };
30811
31112
  }
30812
- var MARGIN4, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES2, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD, VALUE_ROW_FONT, VALUE_ROW_H;
31113
+ var MARGIN4, 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;
30813
31114
  var init_layout5 = __esm({
30814
31115
  "src/boxes-and-lines/layout.ts"() {
30815
31116
  "use strict";
@@ -30825,13 +31126,13 @@ var init_layout5 = __esm({
30825
31126
  DESC_FONT_SIZE2 = 10;
30826
31127
  DESC_LINE_HEIGHT2 = 1.4;
30827
31128
  DESC_PADDING = 8;
30828
- SEPARATOR_GAP5 = 4;
31129
+ SEPARATOR_GAP4 = 4;
30829
31130
  MAX_DESC_LINES2 = 6;
30830
31131
  MAX_LABEL_LINES = 3;
30831
31132
  LABEL_LINE_HEIGHT = 1.3;
30832
31133
  LABEL_PAD = 12;
30833
31134
  VALUE_ROW_FONT = 11;
30834
- VALUE_ROW_H = SEPARATOR_GAP5 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
31135
+ VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
30835
31136
  }
30836
31137
  });
30837
31138
 
@@ -31593,11 +31894,11 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31593
31894
  });
31594
31895
  }
31595
31896
  for (const edge of renderLayout.edges) {
31596
- mainG.append("path").attr("class", "mindmap-edge").attr("d", edge.path).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", EDGE_STROKE_WIDTH6).attr("stroke-opacity", 0.5);
31897
+ mainG.append("path").attr("class", "mindmap-edge").attr("d", edge.path).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", EDGE_STROKE_WIDTH).attr("stroke-opacity", 0.5);
31597
31898
  }
31598
31899
  for (const node of renderLayout.nodes) {
31599
31900
  const isRoot = node.radius === 0 && renderLayout.nodes.indexOf(node) === 0;
31600
- const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH6;
31901
+ const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH;
31601
31902
  const effectiveColor = options?.colorByDepth ? depthColor(node.depth, palette) : node.color;
31602
31903
  const fill2 = nodeFill4(
31603
31904
  palette,
@@ -31680,7 +31981,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31680
31981
  const clipId = `collapse-clip-${node.id}`;
31681
31982
  const defs = mainG.append("defs");
31682
31983
  defs.append("clipPath").attr("id", clipId).append("rect").attr("x", node.x).attr("y", node.y).attr("width", node.width).attr("height", node.height).attr("rx", NODE_RADIUS).attr("ry", NODE_RADIUS);
31683
- nodeG.append("rect").attr("class", "collapse-bar").attr("x", node.x).attr("y", node.y + node.height - COLLAPSE_BAR_HEIGHT4).attr("width", node.width).attr("height", COLLAPSE_BAR_HEIGHT4).attr("fill", stroke2).attr("clip-path", `url(#${clipId})`);
31984
+ nodeG.append("rect").attr("class", "collapse-bar").attr("x", node.x).attr("y", node.y + node.height - COLLAPSE_BAR_HEIGHT).attr("width", node.width).attr("height", COLLAPSE_BAR_HEIGHT).attr("fill", stroke2).attr("clip-path", `url(#${clipId})`);
31684
31985
  }
31685
31986
  if (onClickItem) {
31686
31987
  nodeG.style("cursor", "pointer").on("click", (event) => {
@@ -31728,7 +32029,7 @@ function renderMindmapForExport(content, theme, palette) {
31728
32029
  return extractExportSvg(container, theme);
31729
32030
  });
31730
32031
  }
31731
- var DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, NODE_STROKE_WIDTH6, EDGE_STROKE_WIDTH6, COLLAPSE_BAR_HEIGHT4, DEPTH_COLOR_KEYS;
32032
+ var DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
31732
32033
  var init_renderer7 = __esm({
31733
32034
  "src/mindmap/renderer.ts"() {
31734
32035
  "use strict";
@@ -31745,6 +32046,7 @@ var init_renderer7 = __esm({
31745
32046
  init_legend_layout();
31746
32047
  init_title_constants();
31747
32048
  init_scaling();
32049
+ init_visual_conventions();
31748
32050
  DIAGRAM_PADDING7 = 20;
31749
32051
  TITLE_HEIGHT4 = 30;
31750
32052
  SINGLE_LABEL_HEIGHT2 = 28;
@@ -31752,9 +32054,6 @@ var init_renderer7 = __esm({
31752
32054
  DESC_LINE_HEIGHT4 = 14;
31753
32055
  NODE_RADIUS = 6;
31754
32056
  ROOT_STROKE_WIDTH = 2.5;
31755
- NODE_STROKE_WIDTH6 = 1.5;
31756
- EDGE_STROKE_WIDTH6 = 1.5;
31757
- COLLAPSE_BAR_HEIGHT4 = 6;
31758
32057
  DEPTH_COLOR_KEYS = [
31759
32058
  "red",
31760
32059
  "orange",
@@ -32983,10 +33282,10 @@ function computeC4NodeDimensions(el, options) {
32983
33282
  const metaEntries = collectCardMetadata(el.metadata);
32984
33283
  if (metaEntries.length > 0) {
32985
33284
  height2 += DIVIDER_GAP;
32986
- height2 += metaEntries.length * META_LINE_HEIGHT5;
33285
+ height2 += metaEntries.length * META_LINE_HEIGHT4;
32987
33286
  const maxMetaWidth = Math.max(
32988
33287
  ...metaEntries.map(
32989
- (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE5) + CARD_H_PAD3 * 2
33288
+ (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE4) + CARD_H_PAD3 * 2
32990
33289
  )
32991
33290
  );
32992
33291
  if (maxMetaWidth > width) width = Math.min(MAX_NODE_WIDTH, maxMetaWidth);
@@ -34263,7 +34562,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
34263
34562
  height: totalHeight
34264
34563
  };
34265
34564
  }
34266
- var gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT5, META_FONT_SIZE5, MARGIN6, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
34565
+ var gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT4, META_FONT_SIZE4, MARGIN6, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
34267
34566
  var init_layout8 = __esm({
34268
34567
  "src/c4/layout.ts"() {
34269
34568
  "use strict";
@@ -34281,8 +34580,8 @@ var init_layout8 = __esm({
34281
34580
  DESC_FONT_SIZE4 = 11;
34282
34581
  CARD_V_PAD3 = 14;
34283
34582
  CARD_H_PAD3 = 20;
34284
- META_LINE_HEIGHT5 = 16;
34285
- META_FONT_SIZE5 = 11;
34583
+ META_LINE_HEIGHT4 = 16;
34584
+ META_FONT_SIZE4 = 11;
34286
34585
  MARGIN6 = 40;
34287
34586
  BOUNDARY_PAD = 40;
34288
34587
  GROUP_BOUNDARY_PAD = 24;
@@ -34405,7 +34704,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34405
34704
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34406
34705
  const pathD = lineGenerator4(edge.points);
34407
34706
  if (pathD) {
34408
- const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH7).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34707
+ const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34409
34708
  if (dashed) {
34410
34709
  pathEl.attr("stroke-dasharray", "6 3");
34411
34710
  }
@@ -34471,7 +34770,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34471
34770
  palette.textOnFillLight,
34472
34771
  palette.textOnFillDark
34473
34772
  );
34474
- nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4).attr("ry", CARD_RADIUS4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34773
+ nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS).attr("ry", CARD_RADIUS).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34475
34774
  let yPos = -h / 2 + CARD_V_PAD4;
34476
34775
  const typeLabel = `\xAB${node.type}\xBB`;
34477
34776
  nodeG.append("text").attr("x", 0).attr("y", yPos + TYPE_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", TYPE_FONT_SIZE).attr("font-style", "italic").text(typeLabel);
@@ -34515,7 +34814,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34515
34814
  }
34516
34815
  if (node.drillable) {
34517
34816
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
34518
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4);
34817
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS);
34519
34818
  nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", solid ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
34520
34819
  }
34521
34820
  }
@@ -34575,14 +34874,14 @@ function drawCylinderCard(nodeG, w, h, fill2, stroke2, dashed) {
34575
34874
  `A ${w / 2} ${ry} 0 0 1 ${-w / 2} ${h / 2 - ry}`,
34576
34875
  "Z"
34577
34876
  ].join(" ");
34578
- const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34877
+ const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34579
34878
  if (dashed) {
34580
34879
  el.attr("stroke-dasharray", "6 3");
34581
34880
  }
34582
- nodeG.append("ellipse").attr("cx", 0).attr("cy", -h / 2 + ry).attr("rx", w / 2).attr("ry", ry).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34881
+ nodeG.append("ellipse").attr("cx", 0).attr("cy", -h / 2 + ry).attr("rx", w / 2).attr("ry", ry).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34583
34882
  }
34584
34883
  function drawCardRect(nodeG, w, h, fill2, stroke2, dashed) {
34585
- const el = nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4).attr("ry", CARD_RADIUS4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34884
+ const el = nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS).attr("ry", CARD_RADIUS).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34586
34885
  if (dashed) {
34587
34886
  el.attr("stroke-dasharray", "6 3");
34588
34887
  }
@@ -34602,7 +34901,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
34602
34901
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34603
34902
  const pathD = lineGenerator4(edge.points);
34604
34903
  if (pathD) {
34605
- const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH7).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34904
+ const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34606
34905
  if (dashed) {
34607
34906
  pathEl.attr("stroke-dasharray", "6 3");
34608
34907
  }
@@ -35097,13 +35396,13 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35097
35396
  nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD4 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD4 / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
35098
35397
  yPos += DIVIDER_GAP2;
35099
35398
  const maxKeyWidth = Math.max(
35100
- ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE6))
35399
+ ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE2))
35101
35400
  );
35102
35401
  const valueX = -w / 2 + CARD_H_PAD4 + maxKeyWidth;
35103
35402
  for (const entry of metaEntries) {
35104
- nodeG.append("text").attr("x", -w / 2 + CARD_H_PAD4).attr("y", yPos + META_FONT_SIZE6 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE6).text(`${entry.key}:`);
35105
- nodeG.append("text").attr("x", valueX).attr("y", yPos + META_FONT_SIZE6 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE6).text(entry.value);
35106
- yPos += META_LINE_HEIGHT6;
35403
+ nodeG.append("text").attr("x", -w / 2 + CARD_H_PAD4).attr("y", yPos + META_FONT_SIZE2 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE2).text(`${entry.key}:`);
35404
+ nodeG.append("text").attr("x", valueX).attr("y", yPos + META_FONT_SIZE2 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE2).text(entry.value);
35405
+ yPos += META_LINE_HEIGHT2;
35107
35406
  }
35108
35407
  }
35109
35408
  } else {
@@ -35130,7 +35429,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35130
35429
  }
35131
35430
  if (node.drillable) {
35132
35431
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
35133
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4);
35432
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS);
35134
35433
  nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", solid ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
35135
35434
  }
35136
35435
  }
@@ -35259,7 +35558,7 @@ function renderC4DeploymentForExport(content, theme, palette) {
35259
35558
  document.body.removeChild(el);
35260
35559
  }
35261
35560
  }
35262
- 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, EDGE_STROKE_WIDTH7, NODE_STROKE_WIDTH7, CARD_RADIUS4, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, META_FONT_SIZE6, META_LINE_HEIGHT6, 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;
35561
+ 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;
35263
35562
  var init_renderer9 = __esm({
35264
35563
  "src/c4/renderer.ts"() {
35265
35564
  "use strict";
@@ -35273,6 +35572,7 @@ var init_renderer9 = __esm({
35273
35572
  init_legend_constants();
35274
35573
  init_legend_integration();
35275
35574
  init_title_constants();
35575
+ init_visual_conventions();
35276
35576
  DIAGRAM_PADDING8 = 20;
35277
35577
  MAX_SCALE5 = 3;
35278
35578
  TITLE_HEIGHT6 = 30;
@@ -35282,16 +35582,11 @@ var init_renderer9 = __esm({
35282
35582
  DESC_LINE_HEIGHT6 = 16;
35283
35583
  EDGE_LABEL_FONT_SIZE6 = 11;
35284
35584
  TECH_FONT_SIZE = 10;
35285
- EDGE_STROKE_WIDTH7 = 1.5;
35286
- NODE_STROKE_WIDTH7 = 1.5;
35287
- CARD_RADIUS4 = 6;
35288
35585
  CARD_H_PAD4 = 20;
35289
35586
  CARD_V_PAD4 = 14;
35290
35587
  TYPE_LABEL_HEIGHT2 = 18;
35291
35588
  DIVIDER_GAP2 = 6;
35292
35589
  NAME_HEIGHT2 = 20;
35293
- META_FONT_SIZE6 = 11;
35294
- META_LINE_HEIGHT6 = 16;
35295
35590
  BOUNDARY_LABEL_FONT_SIZE = 12;
35296
35591
  BOUNDARY_STROKE_WIDTH = 1.5;
35297
35592
  BOUNDARY_RADIUS = 8;
@@ -35696,7 +35991,7 @@ function nodeFill6(palette, isDark, shape, nodeColor2, isEndTerminal, colorOff,
35696
35991
  function nodeStroke6(palette, shape, nodeColor2, isEndTerminal, colorOff) {
35697
35992
  return nodeColor2 ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
35698
35993
  }
35699
- function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35994
+ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35700
35995
  const w = node.width;
35701
35996
  const h = node.height;
35702
35997
  const rx = h / 2;
@@ -35708,7 +36003,7 @@ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeS
35708
36003
  nodeStroke6(palette, node.shape, node.color, isEnd, colorOff)
35709
36004
  ).attr("stroke-width", sNodeStrokeWidth);
35710
36005
  }
35711
- function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
36006
+ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35712
36007
  const w = node.width;
35713
36008
  const h = node.height;
35714
36009
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr(
@@ -35727,7 +36022,7 @@ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWid
35727
36022
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35728
36023
  ).attr("stroke-width", sNodeStrokeWidth);
35729
36024
  }
35730
- function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
36025
+ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35731
36026
  const w = node.width / 2;
35732
36027
  const h = node.height / 2;
35733
36028
  const points = [`${0},${-h}`, `${w},${0}`, `${0},${h}`, `${-w},${0}`].join(
@@ -35749,7 +36044,7 @@ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35749
36044
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35750
36045
  ).attr("stroke-width", sNodeStrokeWidth);
35751
36046
  }
35752
- function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW) {
36047
+ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW) {
35753
36048
  const w = node.width / 2;
35754
36049
  const h = node.height / 2;
35755
36050
  const sk = sIoSkew;
@@ -35775,7 +36070,7 @@ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth =
35775
36070
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35776
36071
  ).attr("stroke-width", sNodeStrokeWidth);
35777
36072
  }
35778
- function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sSubroutineInset = SUBROUTINE_INSET) {
36073
+ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sSubroutineInset = SUBROUTINE_INSET) {
35779
36074
  const w = node.width;
35780
36075
  const h = node.height;
35781
36076
  const s = nodeStroke6(palette, node.shape, node.color, void 0, colorOff);
@@ -35793,7 +36088,7 @@ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStroke
35793
36088
  g.append("line").attr("x1", -w / 2 + sSubroutineInset).attr("y1", -h / 2).attr("x2", -w / 2 + sSubroutineInset).attr("y2", h / 2).attr("stroke", innerStroke).attr("stroke-width", sNodeStrokeWidth);
35794
36089
  g.append("line").attr("x1", w / 2 - sSubroutineInset).attr("y1", -h / 2).attr("x2", w / 2 - sSubroutineInset).attr("y2", h / 2).attr("stroke", innerStroke).attr("stroke-width", sNodeStrokeWidth);
35795
36090
  }
35796
- function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36091
+ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35797
36092
  const w = node.width;
35798
36093
  const h = node.height;
35799
36094
  const waveH = sDocWaveHeight;
@@ -35824,7 +36119,7 @@ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35824
36119
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35825
36120
  ).attr("stroke-width", sNodeStrokeWidth);
35826
36121
  }
35827
- function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36122
+ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35828
36123
  switch (node.shape) {
35829
36124
  case "terminal":
35830
36125
  renderTerminal(
@@ -35911,8 +36206,8 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
35911
36206
  const sTitleY = ctx.structural(TITLE_Y);
35912
36207
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
35913
36208
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE7);
35914
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH8);
35915
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH8);
36209
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
36210
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
35916
36211
  const sArrowheadW = ctx.structural(ARROWHEAD_W3);
35917
36212
  const sArrowheadH = ctx.structural(ARROWHEAD_H3);
35918
36213
  const sIoSkew = ctx.structural(IO_SKEW);
@@ -36136,7 +36431,7 @@ function renderFlowchartForExport(content, theme, palette) {
36136
36431
  document.body.removeChild(container);
36137
36432
  }
36138
36433
  }
36139
- var DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, EDGE_STROKE_WIDTH8, NODE_STROKE_WIDTH8, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
36434
+ var DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
36140
36435
  var init_flowchart_renderer = __esm({
36141
36436
  "src/graph/flowchart-renderer.ts"() {
36142
36437
  "use strict";
@@ -36151,12 +36446,11 @@ var init_flowchart_renderer = __esm({
36151
36446
  init_scaling();
36152
36447
  init_text_measure();
36153
36448
  init_note_box();
36449
+ init_visual_conventions();
36154
36450
  DIAGRAM_PADDING9 = 20;
36155
36451
  MAX_SCALE6 = 3;
36156
36452
  NODE_FONT_SIZE2 = 13;
36157
36453
  EDGE_LABEL_FONT_SIZE7 = 11;
36158
- EDGE_STROKE_WIDTH8 = 1.5;
36159
- NODE_STROKE_WIDTH8 = 1.5;
36160
36454
  ARROWHEAD_W3 = 10;
36161
36455
  ARROWHEAD_H3 = 7;
36162
36456
  IO_SKEW = 15;
@@ -37141,7 +37435,7 @@ function hasRoles(node) {
37141
37435
  }
37142
37436
  function computeNodeWidth2(node, expanded, options) {
37143
37437
  const badgeVal = node.computedConcurrentInvocations === 0 && node.computedInstances > 1 ? node.computedInstances : 0;
37144
- const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE7) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37438
+ const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE5) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37145
37439
  const labelWidth2 = measureText(node.label, NODE_FONT_SIZE3) + badgeWidth + PADDING_X3;
37146
37440
  const allKeys = [];
37147
37441
  if (node.computedRps > 0) allKeys.push("RPS");
@@ -37188,7 +37482,7 @@ function computeNodeWidth2(node, expanded, options) {
37188
37482
  }
37189
37483
  if (allKeys.length === 0) return Math.max(MIN_NODE_WIDTH2, labelWidth2);
37190
37484
  const keyColWidth = Math.max(
37191
- ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE7))
37485
+ ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE5))
37192
37486
  );
37193
37487
  let maxRowWidth = 0;
37194
37488
  if (node.computedRps > 0) {
@@ -37201,7 +37495,7 @@ function computeNodeWidth2(node, expanded, options) {
37201
37495
  const rpsVal = effectiveCap > 0 && !node.isEdge ? `${formatRpsShort(node.computedRps)} / ${formatRpsShort(effectiveCap)}` : formatRps(node.computedRps);
37202
37496
  maxRowWidth = Math.max(
37203
37497
  maxRowWidth,
37204
- keyColWidth + measureText(rpsVal, META_FONT_SIZE7)
37498
+ keyColWidth + measureText(rpsVal, META_FONT_SIZE5)
37205
37499
  );
37206
37500
  }
37207
37501
  if (expanded) {
@@ -37218,7 +37512,7 @@ function computeNodeWidth2(node, expanded, options) {
37218
37512
  const valStr = p.key === "max-rps" || p.key === "ratelimit-rps" ? formatRpsShort(numVal) : p.key === "latency-ms" || p.key === "cb-latency-threshold-ms" || p.key === "duration-ms" || p.key === "cold-start-ms" ? formatMs(numVal) : PCT_KEYS.includes(p.key) ? `${numVal}%` : String(p.value);
37219
37513
  maxRowWidth = Math.max(
37220
37514
  maxRowWidth,
37221
- keyColWidth + measureText(valStr, META_FONT_SIZE7)
37515
+ keyColWidth + measureText(valStr, META_FONT_SIZE5)
37222
37516
  );
37223
37517
  }
37224
37518
  }
@@ -37229,7 +37523,7 @@ function computeNodeWidth2(node, expanded, options) {
37229
37523
  if (ms > 0) {
37230
37524
  maxRowWidth = Math.max(
37231
37525
  maxRowWidth,
37232
- keyColWidth + measureText(formatMs(ms), META_FONT_SIZE7)
37526
+ keyColWidth + measureText(formatMs(ms), META_FONT_SIZE5)
37233
37527
  );
37234
37528
  }
37235
37529
  }
@@ -37240,37 +37534,37 @@ function computeNodeWidth2(node, expanded, options) {
37240
37534
  const combinedVal = `${formatMs(perc.p90)} / ${formatMs(threshold)}`;
37241
37535
  maxRowWidth = Math.max(
37242
37536
  maxRowWidth,
37243
- keyColWidth + measureText(combinedVal, META_FONT_SIZE7)
37537
+ keyColWidth + measureText(combinedVal, META_FONT_SIZE5)
37244
37538
  );
37245
37539
  }
37246
37540
  }
37247
37541
  if (node.computedUptime < 1) {
37248
37542
  maxRowWidth = Math.max(
37249
37543
  maxRowWidth,
37250
- keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE7)
37544
+ keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE5)
37251
37545
  );
37252
37546
  }
37253
37547
  if (node.computedAvailability < 1) {
37254
37548
  maxRowWidth = Math.max(
37255
37549
  maxRowWidth,
37256
- keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE7)
37550
+ keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE5)
37257
37551
  );
37258
37552
  }
37259
37553
  if (node.computedCbState === "open") {
37260
37554
  maxRowWidth = Math.max(
37261
37555
  maxRowWidth,
37262
- measureText("CB: OPEN", META_FONT_SIZE7) + 8
37556
+ measureText("CB: OPEN", META_FONT_SIZE5) + 8
37263
37557
  );
37264
37558
  }
37265
37559
  }
37266
- const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE7;
37560
+ const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE5;
37267
37561
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
37268
37562
  let descWidth = 0;
37269
37563
  for (const dl of descLines) {
37270
- const truncated = truncateText(dl, META_FONT_SIZE7, DESC_MAX_WIDTH2);
37564
+ const truncated = truncateText(dl, META_FONT_SIZE5, DESC_MAX_WIDTH2);
37271
37565
  descWidth = Math.max(
37272
37566
  descWidth,
37273
- measureText(truncated, META_FONT_SIZE7) + PADDING_X3
37567
+ measureText(truncated, META_FONT_SIZE5) + PADDING_X3
37274
37568
  );
37275
37569
  }
37276
37570
  return Math.max(MIN_NODE_WIDTH2, labelWidth2, maxRowWidth + 20, descWidth);
@@ -37280,17 +37574,17 @@ function computeNodeHeight2(node, expanded, options) {
37280
37574
  const computedCount = countComputedRows(node, expanded);
37281
37575
  const hasRps = node.computedRps > 0;
37282
37576
  const descLineCount = expanded && node.description && !node.isEdge ? node.description.length : 0;
37283
- const descH = descLineCount * META_LINE_HEIGHT7;
37577
+ const descH = descLineCount * META_LINE_HEIGHT5;
37284
37578
  if (propCount === 0 && computedCount === 0 && !hasRps)
37285
37579
  return NODE_HEADER_HEIGHT + descH + NODE_PAD_BOTTOM;
37286
37580
  let h = NODE_HEADER_HEIGHT + descH + NODE_SEPARATOR_GAP;
37287
37581
  const computedSectionCount = (hasRps ? 1 : 0) + computedCount;
37288
- h += computedSectionCount * META_LINE_HEIGHT7;
37582
+ h += computedSectionCount * META_LINE_HEIGHT5;
37289
37583
  if (computedSectionCount > 0 && propCount > 0) h += NODE_SEPARATOR_GAP;
37290
- h += propCount * META_LINE_HEIGHT7;
37584
+ h += propCount * META_LINE_HEIGHT5;
37291
37585
  if (hasRoles(node)) h += ROLE_DOT_ROW;
37292
37586
  h += NODE_PAD_BOTTOM;
37293
- if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT5;
37587
+ if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT3;
37294
37588
  return h;
37295
37589
  }
37296
37590
  function formatRps(rps) {
@@ -37625,20 +37919,20 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
37625
37919
  height: totalHeight
37626
37920
  };
37627
37921
  }
37628
- var MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT7, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT5, NODE_FONT_SIZE3, META_FONT_SIZE7, EDGE_LABEL_FONT_SIZE8, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
37922
+ 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_GAP;
37629
37923
  var init_layout10 = __esm({
37630
37924
  "src/infra/layout.ts"() {
37631
37925
  "use strict";
37632
37926
  init_text_measure();
37633
37927
  MIN_NODE_WIDTH2 = 140;
37634
37928
  NODE_HEADER_HEIGHT = 28;
37635
- META_LINE_HEIGHT7 = 14;
37929
+ META_LINE_HEIGHT5 = 14;
37636
37930
  NODE_SEPARATOR_GAP = 4;
37637
37931
  NODE_PAD_BOTTOM = 10;
37638
37932
  ROLE_DOT_ROW = 12;
37639
- COLLAPSE_BAR_HEIGHT5 = 6;
37933
+ COLLAPSE_BAR_HEIGHT3 = 6;
37640
37934
  NODE_FONT_SIZE3 = 13;
37641
- META_FONT_SIZE7 = 10;
37935
+ META_FONT_SIZE5 = 10;
37642
37936
  EDGE_LABEL_FONT_SIZE8 = 11;
37643
37937
  PADDING_X3 = 24;
37644
37938
  GROUP_PADDING2 = 20;
@@ -37744,19 +38038,19 @@ import * as d3Shape8 from "d3-shape";
37744
38038
  function buildScaledConstants(ctx) {
37745
38039
  return {
37746
38040
  sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
37747
- sMetaFontSize: ctx.text(META_FONT_SIZE8),
37748
- sMetaLineHeight: ctx.structural(META_LINE_HEIGHT8),
38041
+ sMetaFontSize: ctx.text(META_FONT_SIZE6),
38042
+ sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
37749
38043
  sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE9),
37750
38044
  sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
37751
38045
  sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
37752
- sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH9),
37753
- sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH9),
38046
+ sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
38047
+ sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH),
37754
38048
  sOverloadStrokeWidth: ctx.structural(OVERLOAD_STROKE_WIDTH),
37755
38049
  sRoleDotRadius: ctx.structural(ROLE_DOT_RADIUS),
37756
38050
  sNodeSeparatorGap: ctx.structural(NODE_SEPARATOR_GAP2),
37757
38051
  sNodePadBottom: ctx.structural(NODE_PAD_BOTTOM2),
37758
- sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT6),
37759
- sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET2),
38052
+ sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT),
38053
+ sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET),
37760
38054
  sParticleR: ctx.structural(PARTICLE_R),
37761
38055
  sRejectParticleR: ctx.structural(PARTICLE_R),
37762
38056
  sRejectDropDistance: ctx.structural(REJECT_DROP_DISTANCE),
@@ -38080,7 +38374,7 @@ function isWarning(node) {
38080
38374
  return cap > 0 && node.computedRps / cap > 0.7;
38081
38375
  }
38082
38376
  function truncateDesc(text) {
38083
- return truncateText(text, META_FONT_SIZE8, DESC_MAX_WIDTH);
38377
+ return truncateText(text, META_FONT_SIZE6, DESC_MAX_WIDTH);
38084
38378
  }
38085
38379
  function sloLatencyColor(p90, slo) {
38086
38380
  const t = slo.latencyP90 ?? 0;
@@ -38559,7 +38853,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38559
38853
  if (!isNodeCollapsed) {
38560
38854
  const expanded = expandedNodeIds?.has(node.id) ?? false;
38561
38855
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
38562
- const descH = descLines.length * META_LINE_HEIGHT8;
38856
+ const descH = descLines.length * META_LINE_HEIGHT6;
38563
38857
  for (let di = 0; di < descLines.length; di++) {
38564
38858
  const rawLine = descLines[di];
38565
38859
  const processed = preprocessDescriptionLine(rawLine);
@@ -38567,7 +38861,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38567
38861
  const isTruncated = descTruncated !== processed;
38568
38862
  const textEl = g.append("text").attr("x", node.x).attr(
38569
38863
  "y",
38570
- y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT8 + META_LINE_HEIGHT8 / 2 + sc.sMetaFontSize * 0.35
38864
+ y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT6 + META_LINE_HEIGHT6 / 2 + sc.sMetaFontSize * 0.35
38571
38865
  ).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sc.sMetaFontSize).attr("fill", textFill);
38572
38866
  renderInlineText(textEl, descTruncated, palette, sc.sMetaFontSize);
38573
38867
  if (isTruncated) textEl.append("title").text(rawLine);
@@ -39085,7 +39379,7 @@ function parseAndLayoutInfra(content) {
39085
39379
  const layout = layoutInfra(computed);
39086
39380
  return { parsed, computed, layout };
39087
39381
  }
39088
- var NODE_FONT_SIZE4, META_FONT_SIZE8, META_LINE_HEIGHT8, EDGE_LABEL_FONT_SIZE9, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, EDGE_STROKE_WIDTH9, NODE_STROKE_WIDTH9, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, COLLAPSE_BAR_HEIGHT6, COLLAPSE_BAR_INSET2, 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;
39382
+ 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;
39089
39383
  var init_renderer10 = __esm({
39090
39384
  "src/infra/renderer.ts"() {
39091
39385
  "use strict";
@@ -39104,21 +39398,18 @@ var init_renderer10 = __esm({
39104
39398
  init_legend_layout();
39105
39399
  init_title_constants();
39106
39400
  init_scaling();
39401
+ init_visual_conventions();
39107
39402
  NODE_FONT_SIZE4 = 13;
39108
- META_FONT_SIZE8 = 10;
39109
- META_LINE_HEIGHT8 = 14;
39403
+ META_FONT_SIZE6 = 10;
39404
+ META_LINE_HEIGHT6 = 14;
39110
39405
  EDGE_LABEL_FONT_SIZE9 = 11;
39111
39406
  GROUP_LABEL_FONT_SIZE2 = 14;
39112
39407
  NODE_BORDER_RADIUS = 8;
39113
- EDGE_STROKE_WIDTH9 = 1.5;
39114
- NODE_STROKE_WIDTH9 = 1.5;
39115
39408
  OVERLOAD_STROKE_WIDTH = 3;
39116
39409
  ROLE_DOT_RADIUS = 3;
39117
39410
  NODE_HEADER_HEIGHT2 = 28;
39118
39411
  NODE_SEPARATOR_GAP2 = 4;
39119
39412
  NODE_PAD_BOTTOM2 = 10;
39120
- COLLAPSE_BAR_HEIGHT6 = 6;
39121
- COLLAPSE_BAR_INSET2 = 0;
39122
39413
  LEGEND_FIXED_GAP3 = 16;
39123
39414
  SPEED_BADGE_H_PAD = 5;
39124
39415
  SPEED_BADGE_V_PAD = 3;
@@ -39157,7 +39448,7 @@ var init_renderer10 = __esm({
39157
39448
  partitions: "partitions"
39158
39449
  };
39159
39450
  DESC_MAX_CHARS = 120;
39160
- DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE8;
39451
+ DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE6;
39161
39452
  RPS_FORMAT_KEYS = /* @__PURE__ */ new Set(["max-rps", "ratelimit-rps"]);
39162
39453
  MS_FORMAT_KEYS = /* @__PURE__ */ new Set([
39163
39454
  "latency-ms",
@@ -40949,18 +41240,18 @@ function renderPert(container, resolved, layout, palette, isDark, options = {})
40949
41240
  const sLegendPillHeight = ctx.structural(LEGEND_PILL_HEIGHT);
40950
41241
  const sLegendBlockHeight = showTagLegend ? sLegendTopGap + sLegendPillHeight + sLegendBottomGap : 0;
40951
41242
  const sNodeRadius = ctx.structural(NODE_RADIUS2);
40952
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH10);
41243
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
40953
41244
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE5);
40954
41245
  const sNodeCellFontSize = ctx.text(NODE_CELL_FONT_SIZE2);
40955
41246
  const sNodeTopRowHeight = ctx.structural(NODE_TOP_ROW_HEIGHT);
40956
41247
  const sNodeBottomRowHeight = ctx.structural(NODE_BOTTOM_ROW_HEIGHT);
40957
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH10);
41248
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
40958
41249
  const sArrowheadW = ctx.structural(ARROWHEAD_W4);
40959
41250
  const sArrowheadH = ctx.structural(ARROWHEAD_H4);
40960
- const sContainerRadius = ctx.structural(CONTAINER_RADIUS3);
40961
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE4);
40962
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT3);
40963
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT7);
41251
+ const sContainerRadius = ctx.structural(CONTAINER_RADIUS);
41252
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
41253
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
41254
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
40964
41255
  const sPinIconW = ctx.structural(PIN_ICON_W);
40965
41256
  const sPinIconH = ctx.structural(PIN_ICON_H);
40966
41257
  const scaledWidth = layout.width + sDiagramPad * 2;
@@ -41527,7 +41818,7 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41527
41818
  palette.textOnFillDark
41528
41819
  );
41529
41820
  const sNR = sc.nodeRadius ?? NODE_RADIUS2;
41530
- const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT7;
41821
+ const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT;
41531
41822
  drawTextbookCard(g, {
41532
41823
  width: grp.width,
41533
41824
  height: grp.height,
@@ -41561,10 +41852,10 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41561
41852
  g.append("rect").attr("class", "pert-collapse-bar").attr("x", grp.x).attr("y", grp.y + grp.height - sCBH).attr("width", grp.width).attr("height", sCBH).attr("fill", cardBaseColor).attr("clip-path", `url(#${clipId})`);
41562
41853
  continue;
41563
41854
  }
41564
- const sCR = sc.containerRadius ?? CONTAINER_RADIUS3;
41565
- const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE4;
41566
- const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT3;
41567
- const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH10;
41855
+ const sCR = sc.containerRadius ?? CONTAINER_RADIUS;
41856
+ const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE;
41857
+ const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT;
41858
+ const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH;
41568
41859
  g.append("rect").attr("x", grp.x).attr("y", grp.y).attr("width", grp.width).attr("height", grp.height).attr("rx", sCR).attr("ry", sCR).attr("fill", containerFill3).attr("stroke", containerStroke3).attr("stroke-opacity", 0.35).attr("stroke-width", sNSW);
41569
41860
  g.append("text").attr("x", grp.x + grp.width / 2).attr("y", grp.y + sCHH / 2 + sCLFS / 2 - 2).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("fill", palette.text).attr("font-size", sCLFS).attr("font-weight", "bold").text(label);
41570
41861
  }
@@ -41617,7 +41908,7 @@ function renderEdges2(root, resolved, layout, palette, collapsedSet, sc = {}) {
41617
41908
  }
41618
41909
  const path = lineGenerator6(e.points);
41619
41910
  if (!path) continue;
41620
- const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH10;
41911
+ const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH;
41621
41912
  const sELFS = sc.edgeLabelFontSize ?? 10;
41622
41913
  layer.append("path").attr("class", "pert-edge").attr("d", path).attr("fill", "none").attr("stroke", bandColor(band, palette, palette.textMuted)).attr("stroke-width", sESW).attr("marker-end", `url(#${bandArrow(band)})`).attr("data-source", e.source).attr("data-target", e.target).attr("data-critical", String(isCritical)).attr("data-critical-path", String(isCritical)).attr("data-criticality-band", band ?? "");
41623
41914
  const parsedEdge = edgeByKey.get(`${e.source}->${e.target}`);
@@ -41799,7 +42090,7 @@ function computeDurationEmphasis(activities) {
41799
42090
  function drawTextbookCard(g, a) {
41800
42091
  const { width: w, height: h, x, y } = a;
41801
42092
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41802
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42093
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41803
42094
  const sTRH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41804
42095
  const sBRH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41805
42096
  const sNFS = a.sNodeFontSize ?? NODE_FONT_SIZE5;
@@ -41898,7 +42189,7 @@ function drawTextbookCard(g, a) {
41898
42189
  function drawMilestonePill(g, a) {
41899
42190
  const { width: w, height: h, x, y } = a;
41900
42191
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41901
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42192
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41902
42193
  const topRowH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41903
42194
  const botRowH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41904
42195
  const sNCFS = a.sNodeCellFontSize ?? NODE_CELL_FONT_SIZE2;
@@ -42031,7 +42322,7 @@ function renderCaptionBlock(svg, bullets, args) {
42031
42322
  palette.textOnFillDark
42032
42323
  );
42033
42324
  const block = svg.append("g").attr("class", "pert-caption-block").attr("data-pert-caption", "");
42034
- block.append("rect").attr("class", "pert-caption-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH10);
42325
+ block.append("rect").attr("class", "pert-caption-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH);
42035
42326
  block.append("text").attr("class", "pert-caption-header").attr("x", x + width / 2).attr("y", y + CAPTION_BOX_PADDING_Y + CAPTION_FONT_SIZE).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", CAPTION_FONT_SIZE).attr("font-weight", "700").text("Summary");
42036
42327
  const textX = x + CAPTION_BOX_PADDING_X;
42037
42328
  const firstBaselineY = y + CAPTION_BOX_PADDING_Y + CAPTION_HEADER_BAND_HEIGHT + CAPTION_FONT_SIZE;
@@ -42148,7 +42439,7 @@ function renderTornadoBlock(svg, rows, args) {
42148
42439
  palette.textOnFillDark
42149
42440
  );
42150
42441
  const block = svg.append("g").attr("class", "pert-tornado-block").attr("data-pert-tornado", "");
42151
- block.append("rect").attr("class", "pert-tornado-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH10);
42442
+ block.append("rect").attr("class", "pert-tornado-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH);
42152
42443
  block.append("text").attr("class", "pert-tornado-header").attr("x", x + width / 2).attr("y", y + CAPTION_BOX_PADDING_Y + CAPTION_FONT_SIZE).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", CAPTION_FONT_SIZE).attr("font-weight", "700").text("Activity Risk");
42153
42444
  const fmt = (v) => {
42154
42445
  const r = Math.round(v * 100) / 100;
@@ -42304,7 +42595,7 @@ function renderScurveBlock(svg, data, args) {
42304
42595
  palette.textOnFillDark
42305
42596
  );
42306
42597
  const block = svg.append("g").attr("class", "pert-scurve-block").attr("data-pert-scurve", "");
42307
- block.append("rect").attr("class", "pert-scurve-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH10);
42598
+ block.append("rect").attr("class", "pert-scurve-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH);
42308
42599
  const hasTitle = typeof title === "string" && title.length > 0;
42309
42600
  if (hasTitle) {
42310
42601
  const titleText = title.replace(/\.$/, "");
@@ -42488,7 +42779,7 @@ function formatScurveDate(iso) {
42488
42779
  if (month < 0 || month > 11 || isNaN(day)) return iso;
42489
42780
  return `${SCURVE_MONTH_NAMES[month]} ${day}`;
42490
42781
  }
42491
- var DIAGRAM_PADDING11, NODE_FONT_SIZE5, NODE_CELL_FONT_SIZE2, NODE_RADIUS2, NODE_STROKE_WIDTH10, NODE_TOP_ROW_HEIGHT, NODE_BOTTOM_ROW_HEIGHT, EDGE_STROKE_WIDTH10, ARROWHEAD_W4, ARROWHEAD_H4, CONTAINER_RADIUS3, CONTAINER_LABEL_FONT_SIZE4, CONTAINER_HEADER_HEIGHT3, COLLAPSE_BAR_HEIGHT7, DURATION_FADE_OPACITY, PIN_ICON_W, PIN_ICON_H, LEGEND_PILL_HEIGHT, LEGEND_TOP_GAP, LEGEND_BOTTOM_GAP, FIELD_LEGEND_HEADER_BAND_HEIGHT, FIELD_LEGEND_CELL_VPAD, FIELD_LEGEND_LABEL_FONT_SIZE, FIELD_LEGEND_DESC_FONT_SIZE, FIELD_LEGEND_DESC_LINE_HEIGHT, FIELD_LEGEND_LABEL_DESC_GAP, FIELD_LEGEND_CELLS, lineGenerator6, FIELD_LEGEND_MIN_W, SUB_BULLET_INDENT, CAPTION_HEADER_BAND_HEIGHT, TORNADO_TOP_N, TORNADO_ROW_HEIGHT, TORNADO_NAME_COL_W, TORNADO_BAR_FONT_SIZE, TORNADO_BAR_HEIGHT, SUMMARY_MIN_W, SUMMARY_MAX_W, ANALYSIS_GAP, COL1_VSTACK_GAP, TORNADO_MIN_W, SCURVE_MIN_W, SCURVE_BOX_HEIGHT, SCURVE_PLOT_PADDING_X, SCURVE_PLOT_PADDING_RIGHT, SCURVE_PLOT_PADDING_BOTTOM, SCURVE_TICK_FONT_SIZE, SCURVE_PERCENTILE_RADIUS, DAYS_PER_UNIT, SCURVE_MONTH_NAMES, UNIT_TO_DAYS_LOCAL2;
42782
+ var DIAGRAM_PADDING11, NODE_FONT_SIZE5, NODE_CELL_FONT_SIZE2, NODE_RADIUS2, NODE_TOP_ROW_HEIGHT, NODE_BOTTOM_ROW_HEIGHT, ARROWHEAD_W4, ARROWHEAD_H4, DURATION_FADE_OPACITY, PIN_ICON_W, PIN_ICON_H, LEGEND_PILL_HEIGHT, LEGEND_TOP_GAP, LEGEND_BOTTOM_GAP, FIELD_LEGEND_HEADER_BAND_HEIGHT, FIELD_LEGEND_CELL_VPAD, FIELD_LEGEND_LABEL_FONT_SIZE, FIELD_LEGEND_DESC_FONT_SIZE, FIELD_LEGEND_DESC_LINE_HEIGHT, FIELD_LEGEND_LABEL_DESC_GAP, FIELD_LEGEND_CELLS, lineGenerator6, FIELD_LEGEND_MIN_W, SUB_BULLET_INDENT, CAPTION_HEADER_BAND_HEIGHT, TORNADO_TOP_N, TORNADO_ROW_HEIGHT, TORNADO_NAME_COL_W, TORNADO_BAR_FONT_SIZE, TORNADO_BAR_HEIGHT, SUMMARY_MIN_W, SUMMARY_MAX_W, ANALYSIS_GAP, COL1_VSTACK_GAP, TORNADO_MIN_W, SCURVE_MIN_W, SCURVE_BOX_HEIGHT, SCURVE_PLOT_PADDING_X, SCURVE_PLOT_PADDING_RIGHT, SCURVE_PLOT_PADDING_BOTTOM, SCURVE_TICK_FONT_SIZE, SCURVE_PERCENTILE_RADIUS, DAYS_PER_UNIT, SCURVE_MONTH_NAMES, UNIT_TO_DAYS_LOCAL2;
42492
42783
  var init_renderer11 = __esm({
42493
42784
  "src/pert/renderer.ts"() {
42494
42785
  "use strict";
@@ -42504,20 +42795,15 @@ var init_renderer11 = __esm({
42504
42795
  init_analyzer();
42505
42796
  init_layout11();
42506
42797
  init_internal();
42798
+ init_visual_conventions();
42507
42799
  DIAGRAM_PADDING11 = 20;
42508
42800
  NODE_FONT_SIZE5 = 13;
42509
42801
  NODE_CELL_FONT_SIZE2 = 11;
42510
42802
  NODE_RADIUS2 = 6;
42511
- NODE_STROKE_WIDTH10 = 1.5;
42512
42803
  NODE_TOP_ROW_HEIGHT = 26;
42513
42804
  NODE_BOTTOM_ROW_HEIGHT = 26;
42514
- EDGE_STROKE_WIDTH10 = 1.5;
42515
42805
  ARROWHEAD_W4 = 10;
42516
42806
  ARROWHEAD_H4 = 7;
42517
- CONTAINER_RADIUS3 = 8;
42518
- CONTAINER_LABEL_FONT_SIZE4 = 13;
42519
- CONTAINER_HEADER_HEIGHT3 = 28;
42520
- COLLAPSE_BAR_HEIGHT7 = 6;
42521
42807
  DURATION_FADE_OPACITY = 0.55;
42522
42808
  PIN_ICON_W = 13;
42523
42809
  PIN_ICON_H = 13;
@@ -45509,8 +45795,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
45509
45795
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
45510
45796
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE10);
45511
45797
  const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
45512
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH11);
45513
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH11);
45798
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
45799
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
45514
45800
  const sArrowheadW = ctx.structural(ARROWHEAD_W5);
45515
45801
  const sArrowheadH = ctx.structural(ARROWHEAD_H5);
45516
45802
  const sPseudostateRadius = ctx.structural(PSEUDOSTATE_RADIUS);
@@ -45787,7 +46073,7 @@ function renderStateForExport(content, theme, palette) {
45787
46073
  document.body.removeChild(container);
45788
46074
  }
45789
46075
  }
45790
- var DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE3, EDGE_STROKE_WIDTH11, NODE_STROKE_WIDTH11, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
46076
+ 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;
45791
46077
  var init_state_renderer = __esm({
45792
46078
  "src/graph/state-renderer.ts"() {
45793
46079
  "use strict";
@@ -45802,13 +46088,12 @@ var init_state_renderer = __esm({
45802
46088
  init_scaling();
45803
46089
  init_text_measure();
45804
46090
  init_note_box();
46091
+ init_visual_conventions();
45805
46092
  DIAGRAM_PADDING12 = 20;
45806
46093
  MAX_SCALE7 = 3;
45807
46094
  NODE_FONT_SIZE6 = 13;
45808
46095
  EDGE_LABEL_FONT_SIZE10 = 11;
45809
46096
  GROUP_LABEL_FONT_SIZE3 = 11;
45810
- EDGE_STROKE_WIDTH11 = 1.5;
45811
- NODE_STROKE_WIDTH11 = 1.5;
45812
46097
  ARROWHEAD_W5 = 10;
45813
46098
  ARROWHEAD_H5 = 7;
45814
46099
  PSEUDOSTATE_RADIUS = 10;
@@ -47743,14 +48028,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47743
48028
  const panelY = PADDING2;
47744
48029
  const textX = panelX + CARD_PADDING_X3;
47745
48030
  const clipId = "persona-clip";
47746
- defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5);
48031
+ defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS);
47747
48032
  const personaFill = shapeFill(palette, personaColor, isDark, { solid });
47748
48033
  const onPersonaText = contrastText(
47749
48034
  personaFill,
47750
48035
  palette.textOnFillLight,
47751
48036
  palette.textOnFillDark
47752
48037
  );
47753
- personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5).attr("fill", personaFill);
48038
+ personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", personaFill);
47754
48039
  if (descLines.length > 0) {
47755
48040
  personaG.append("line").attr("x1", panelX + 1).attr("x2", panelX + panelWidth - silhouetteZone).attr("y1", panelY + titleRowH).attr("y2", panelY + titleRowH).attr("stroke", solid ? onPersonaText : personaColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
47756
48041
  }
@@ -47758,7 +48043,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47758
48043
  const silY = panelY + panelHeight / 2 - 6;
47759
48044
  const silClip = personaG.append("g").attr("clip-path", `url(#${clipId})`);
47760
48045
  renderPersonaSilhouette(silClip, silX, silY, personaColor, palette, 1.2);
47761
- personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5).attr("fill", "none").attr("stroke", personaColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48046
+ personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", "none").attr("stroke", personaColor).attr("stroke-width", CARD_STROKE_WIDTH2);
47762
48047
  personaG.append("text").attr("x", textX).attr("y", panelY + CARD_PADDING_Y3 + FONT_SIZE_STEP).attr("font-size", FONT_SIZE_STEP).attr("font-weight", "500").attr("fill", onPersonaText).text(parsed.persona.name);
47763
48048
  for (let li = 0; li < descLines.length; li++) {
47764
48049
  const lineEl = personaG.append("text").attr("x", textX).attr("y", panelY + titleRowH + descLineH * (li + 1)).attr("font-size", FONT_SIZE_META).attr("fill", onPersonaText);
@@ -47998,7 +48283,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47998
48283
  { solid }
47999
48284
  );
48000
48285
  const rowStroke = stepColor ?? palette.textMuted;
48001
- itemG.append("rect").attr("x", listX).attr("y", itemY).attr("width", cardW).attr("height", COLLAPSED_CARD_H).attr("rx", CARD_RADIUS5).attr("fill", rowFill).attr("stroke", rowStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
48286
+ itemG.append("rect").attr("x", listX).attr("y", itemY).attr("width", cardW).attr("height", COLLAPSED_CARD_H).attr("rx", CARD_RADIUS).attr("fill", rowFill).attr("stroke", rowStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
48002
48287
  const faceCx = listX + CARD_PADDING_X3 + COLLAPSED_FACE_R;
48003
48288
  const faceCy = itemY + COLLAPSED_CARD_H / 2;
48004
48289
  if (step.score !== void 0) {
@@ -48161,7 +48446,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
48161
48446
  const scoreColor = scoreToColor(score, palette);
48162
48447
  const tintedBg = mix(scoreColor, palette.surface, 20);
48163
48448
  const g = overlayG.append("g").attr("class", "journey-thought-hover");
48164
- g.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", CARD_RADIUS5).attr("fill", tintedBg).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48449
+ g.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", CARD_RADIUS).attr("fill", tintedBg).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48165
48450
  g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy - FACE_RADIUS - 1).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48166
48451
  const centerX = bx + bw / 2;
48167
48452
  for (let i = 0; i < lines.length; i++) {
@@ -48318,7 +48603,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48318
48603
  palette.textOnFillLight,
48319
48604
  palette.textOnFillDark
48320
48605
  );
48321
- stepG.append("rect").attr("x", cx).attr("y", cy).attr("width", sl.width).attr("height", sl.height).attr("rx", CARD_RADIUS5).attr("fill", cardFill).attr("stroke", cardStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
48606
+ stepG.append("rect").attr("x", cx).attr("y", cy).attr("width", sl.width).attr("height", sl.height).attr("rx", CARD_RADIUS).attr("fill", cardFill).attr("stroke", cardStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
48322
48607
  const titleMaxW = sl.width - CARD_PADDING_X3 * 2;
48323
48608
  const titleLines = wrapTextToWidth(sl.step.title, FONT_SIZE_STEP, titleMaxW);
48324
48609
  for (let i = 0; i < titleLines.length; i++) {
@@ -48377,7 +48662,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48377
48662
  const stripFill = shapeFill(palette, stripColor, isDark, {
48378
48663
  ...solid !== void 0 && { solid }
48379
48664
  });
48380
- stepG.append("rect").attr("x", cx).attr("y", stripY).attr("width", sl.width).attr("height", TAG_STRIP_HEIGHT).attr("rx", CARD_RADIUS5).attr("fill", stripFill).attr("stroke", stripColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48665
+ stepG.append("rect").attr("x", cx).attr("y", stripY).attr("width", sl.width).attr("height", TAG_STRIP_HEIGHT).attr("rx", CARD_RADIUS).attr("fill", stripFill).attr("stroke", stripColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48381
48666
  const stripTextColor = contrastText(
48382
48667
  stripFill,
48383
48668
  palette.textOnFillLight,
@@ -48493,7 +48778,7 @@ function renderJourneyMapForExport(content, theme, palette) {
48493
48778
  }
48494
48779
  return svgEl.outerHTML;
48495
48780
  }
48496
- var DIAGRAM_PADDING13, PADDING2, CARD_RADIUS5, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
48781
+ var DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
48497
48782
  var init_renderer14 = __esm({
48498
48783
  "src/journey-map/renderer.ts"() {
48499
48784
  "use strict";
@@ -48506,9 +48791,9 @@ var init_renderer14 = __esm({
48506
48791
  init_tag_groups();
48507
48792
  init_scaling();
48508
48793
  init_text_measure();
48794
+ init_visual_conventions();
48509
48795
  DIAGRAM_PADDING13 = 20;
48510
48796
  PADDING2 = DIAGRAM_PADDING13;
48511
- CARD_RADIUS5 = 6;
48512
48797
  CARD_PADDING_X3 = 10;
48513
48798
  CARD_PADDING_Y3 = 6;
48514
48799
  CARD_HEADER_HEIGHT3 = 24;
@@ -48585,7 +48870,7 @@ function computeCycleLayout(parsed, options) {
48585
48870
  const hasDesc = !hideDescriptions && node.description.length > 0;
48586
48871
  const labelWidth2 = Math.max(
48587
48872
  MIN_NODE_WIDTH4,
48588
- measureText(node.label, LABEL_FONT_SIZE5) + NODE_PAD_X * 2
48873
+ measureText(node.label, LABEL_FONT_SIZE4) + NODE_PAD_X * 2
48589
48874
  );
48590
48875
  if (circleNodes) {
48591
48876
  return computeCircleNodeDims(node, hasDesc);
@@ -48802,7 +49087,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48802
49087
  let bestScore = Infinity;
48803
49088
  for (let w = minW; w <= MAX_NODE_WIDTH3; w += DESC_WIDTH_STEP) {
48804
49089
  const wrapped2 = wrapDescForWidth(description, w);
48805
- const h = HEADER_HEIGHT5 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
49090
+ const h = HEADER_HEIGHT4 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48806
49091
  const ratio = w / h;
48807
49092
  const score = Math.abs(Math.log(ratio / DESC_TARGET_RATIO));
48808
49093
  if (score < bestScore) {
@@ -48814,7 +49099,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48814
49099
  const wrapped = wrapDescForWidth(description, minW);
48815
49100
  return {
48816
49101
  width: minW,
48817
- height: HEADER_HEIGHT5 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
49102
+ height: HEADER_HEIGHT4 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48818
49103
  wrappedDesc: wrapped
48819
49104
  };
48820
49105
  }
@@ -48827,7 +49112,7 @@ function wrapDescForWidth(description, nodeWidth) {
48827
49112
  );
48828
49113
  }
48829
49114
  function renderedDescNodeHeight(numLines, scale) {
48830
- const headerH = HEADER_HEIGHT5 * scale;
49115
+ const headerH = HEADER_HEIGHT4 * scale;
48831
49116
  const descFont = Math.max(
48832
49117
  RENDERER_DESC_FONT_MIN,
48833
49118
  Math.round(RENDERER_DESC_FONT * scale)
@@ -49162,7 +49447,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
49162
49447
  const midAngle = srcExitAngle + dir * visibleSweep / 2;
49163
49448
  return { path, midAngle };
49164
49449
  }
49165
- var MIN_ARC_ANGLE, LABEL_FONT_SIZE5, 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_HEIGHT5, 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;
49450
+ 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;
49166
49451
  var init_layout14 = __esm({
49167
49452
  "src/cycle/layout.ts"() {
49168
49453
  "use strict";
@@ -49170,7 +49455,7 @@ var init_layout14 = __esm({
49170
49455
  init_wrapped_desc();
49171
49456
  init_text_measure();
49172
49457
  MIN_ARC_ANGLE = 15 * Math.PI / 180;
49173
- LABEL_FONT_SIZE5 = 13;
49458
+ LABEL_FONT_SIZE4 = 13;
49174
49459
  CIRCLE_LABEL_FONT_SIZE = 16;
49175
49460
  DESC_FONT_SIZE6 = 11;
49176
49461
  EDGE_LABEL_FONT_SIZE11 = 11;
@@ -49180,7 +49465,7 @@ var init_layout14 = __esm({
49180
49465
  DESC_WIDTH_STEP = 20;
49181
49466
  DESC_TARGET_RATIO = 1.6;
49182
49467
  PLAIN_NODE_HEIGHT = 50;
49183
- HEADER_HEIGHT5 = 36;
49468
+ HEADER_HEIGHT4 = 36;
49184
49469
  DESC_LINE_HEIGHT7 = 16;
49185
49470
  DESC_PAD_Y = 14;
49186
49471
  NODE_PAD_X = 20;
@@ -53287,6 +53572,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53287
53572
  const svg = d3Selection23.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY).style("background", layout.background);
53288
53573
  svg.append("rect").attr("width", width).attr("height", height).attr("fill", layout.background);
53289
53574
  const defs = svg.append("defs");
53575
+ const uid = mapInstanceCounter++;
53576
+ const nid = (base) => `${base}__m${uid}`;
53290
53577
  const arrowSize = (w) => Math.min(15, 7 + w * 0.95);
53291
53578
  const haloColor = palette.bg;
53292
53579
  const gRegions = svg.append("g").attr("class", "dgmo-map-regions");
@@ -53319,8 +53606,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53319
53606
  for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
53320
53607
  if (layout.relief.length && layout.reliefHatch) {
53321
53608
  const h = layout.reliefHatch;
53322
- const rangeClipId = "dgmo-relief-clip";
53323
- const landClipId = "dgmo-relief-land";
53609
+ const rangeClipId = nid("dgmo-relief-clip");
53610
+ const landClipId = nid("dgmo-relief-land");
53324
53611
  const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
53325
53612
  for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
53326
53613
  const landClip = defs.append("clipPath").attr("id", landClipId);
@@ -53333,7 +53620,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53333
53620
  }
53334
53621
  if (layout.coastlineStyle) {
53335
53622
  const cs = layout.coastlineStyle;
53336
- const maskId = "dgmo-map-water-mask";
53623
+ const maskId = nid("dgmo-map-water-mask");
53337
53624
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53338
53625
  mask.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white");
53339
53626
  const landD = layout.regions.filter((r) => r.id !== "lake").map((r) => r.d).join(" ");
@@ -53351,7 +53638,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53351
53638
  appendWaterLines(
53352
53639
  gWater,
53353
53640
  defs,
53354
- "dgmo-map-coast",
53641
+ nid("dgmo-map-coast"),
53355
53642
  // Pass the canvas frame so edges collinear with it (the antimeridian on a
53356
53643
  // world map, regional clipExtent cuts) don't get ringed as fake coast —
53357
53644
  // land runs cleanly to the render-area edge.
@@ -53388,7 +53675,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53388
53675
  (l) => l.poiId !== void 0 && !l.hidden
53389
53676
  );
53390
53677
  if (poiLabels.length) {
53391
- const patchBlurId = "dgmo-map-label-patch-blur";
53678
+ const patchBlurId = nid("dgmo-map-label-patch-blur");
53392
53679
  defs.append("filter").attr("id", patchBlurId).attr("x", "-50%").attr("y", "-50%").attr("width", "200%").attr("height", "200%").append("feGaussianBlur").attr("in", "SourceGraphic").attr("stdDeviation", 2.5);
53393
53680
  const PAD = 8;
53394
53681
  const buildPatch = (labels, maskId, decoCluster) => {
@@ -53433,7 +53720,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53433
53720
  if (clusterUi) {
53434
53721
  buildPatch(
53435
53722
  poiLabels.filter((l) => l.clusterMember === void 0),
53436
- "dgmo-map-label-patch"
53723
+ nid("dgmo-map-label-patch")
53437
53724
  );
53438
53725
  const byCluster = /* @__PURE__ */ new Map();
53439
53726
  for (const l of poiLabels) {
@@ -53444,9 +53731,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53444
53731
  }
53445
53732
  let ci = 0;
53446
53733
  for (const [cid, labs] of byCluster)
53447
- buildPatch(labs, `dgmo-map-label-patch-c${ci++}`, cid);
53734
+ buildPatch(labs, nid(`dgmo-map-label-patch-c${ci++}`), cid);
53448
53735
  } else {
53449
- buildPatch(poiLabels, "dgmo-map-label-patch");
53736
+ buildPatch(poiLabels, nid("dgmo-map-label-patch"));
53450
53737
  }
53451
53738
  }
53452
53739
  if (layout.insets.length) {
@@ -53455,7 +53742,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53455
53742
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
53456
53743
  insetG.append("path").attr("d", d).attr("fill", layout.background).attr("stroke", mix(palette.text, palette.bg, 55)).attr("stroke-width", 1).attr("stroke-linejoin", "round");
53457
53744
  if (box.contextLand) {
53458
- const clipId = `dgmo-map-inset-clip-${bi}`;
53745
+ const clipId = nid(`dgmo-map-inset-clip-${bi}`);
53459
53746
  defs.append("clipPath").attr("id", clipId).append("path").attr("d", d);
53460
53747
  insetG.append("path").attr("d", box.contextLand.d).attr("fill", box.contextLand.fill).attr("clip-path", `url(#${clipId})`);
53461
53748
  }
@@ -53463,7 +53750,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53463
53750
  for (const r of layout.insetRegions) drawRegion(insetG, r, 0.5);
53464
53751
  if (layout.coastlineStyle) {
53465
53752
  const cs = layout.coastlineStyle;
53466
- const maskId = "dgmo-map-inset-water-mask";
53753
+ const maskId = nid("dgmo-map-inset-water-mask");
53467
53754
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53468
53755
  const reach = Math.max(0, ...cs.lines.map((l) => l.d + l.thickness));
53469
53756
  for (const box of layout.insets) {
@@ -53472,7 +53759,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53472
53759
  }
53473
53760
  layout.insets.forEach((box, bi) => {
53474
53761
  if (box.contextLand)
53475
- mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#dgmo-map-inset-clip-${bi})`);
53762
+ mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#${nid(`dgmo-map-inset-clip-${bi}`)})`);
53476
53763
  });
53477
53764
  for (const r of layout.insetRegions)
53478
53765
  if (r.id !== "lake")
@@ -53480,7 +53767,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53480
53767
  for (const r of layout.insetRegions)
53481
53768
  if (r.id === "lake")
53482
53769
  mask.append("path").attr("d", r.d).attr("fill", "white");
53483
- const clipId = "dgmo-map-inset-water-clip";
53770
+ const clipId = nid("dgmo-map-inset-water-clip");
53484
53771
  const clip = defs.append("clipPath").attr("id", clipId);
53485
53772
  for (const box of layout.insets) {
53486
53773
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
@@ -53490,7 +53777,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53490
53777
  appendWaterLines(
53491
53778
  gInsetWater,
53492
53779
  defs,
53493
- "dgmo-map-inset-coast",
53780
+ nid("dgmo-map-inset-coast"),
53494
53781
  coastlineOuterRings(layout.insetRegions, cs.minExtent),
53495
53782
  cs,
53496
53783
  layout.background
@@ -53519,7 +53806,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53519
53806
  }
53520
53807
  wireSync(p, leg.lineNumber);
53521
53808
  if (leg.arrow) {
53522
- const id = `dgmo-map-arrow-${i}`;
53809
+ const id = nid(`dgmo-map-arrow-${i}`);
53523
53810
  const s = arrowSize(leg.width);
53524
53811
  defs.append("marker").attr("id", id).attr("viewBox", "0 0 10 10").attr("refX", 10).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", s).attr("markerHeight", s).attr("orient", "auto-start-reverse").append("path").attr("d", "M0,0L10,5L0,10z").attr("fill", leg.color);
53525
53812
  p.attr("marker-end", `url(#${id})`);
@@ -53715,7 +54002,7 @@ function emitText(g, x, y, text, anchor, color, halo, withHalo, fontSize, italic
53715
54002
  }
53716
54003
  return t;
53717
54004
  }
53718
- var LABEL_FONT;
54005
+ var LABEL_FONT, mapInstanceCounter;
53719
54006
  var init_renderer16 = __esm({
53720
54007
  "src/map/renderer.ts"() {
53721
54008
  "use strict";
@@ -53727,6 +54014,7 @@ var init_renderer16 = __esm({
53727
54014
  init_legend_band();
53728
54015
  init_layout15();
53729
54016
  LABEL_FONT = 11;
54017
+ mapInstanceCounter = 0;
53730
54018
  }
53731
54019
  });
53732
54020
 
@@ -54658,7 +54946,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54658
54946
  const sHMargin = ctx.aesthetic(H_MARGIN);
54659
54947
  const sVMargin = ctx.aesthetic(V_MARGIN3);
54660
54948
  const sTitleAreaHeight = ctx.structural(TITLE_AREA_HEIGHT4);
54661
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT6);
54949
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT5);
54662
54950
  const sRowHeight = ctx.structural(ROW_HEIGHT);
54663
54951
  const sPhaseHeight = ctx.structural(PHASE_HEIGHT);
54664
54952
  const sTaskLabelMin = ctx.structural(TASK_LABEL_MIN);
@@ -54683,7 +54971,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54683
54971
  const sLegendLetterFont = ctx.text(LEGEND_LETTER_FONT);
54684
54972
  const sViolationLineHeight = ctx.structural(VIOLATION_LINE_HEIGHT);
54685
54973
  const sStackTopGap = ctx.structural(STACK_TOP_GAP);
54686
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH12);
54974
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
54687
54975
  const sNodeRadius = ctx.structural(NODE_RADIUS3);
54688
54976
  const innerWidth = Math.max(0, width - 2 * sHMargin);
54689
54977
  let roleColW = Math.max(
@@ -55229,7 +55517,7 @@ function parseQuotedSegments(message) {
55229
55517
  out.push({ text: message.slice(last), bold: false });
55230
55518
  return out;
55231
55519
  }
55232
- var MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT6, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT2, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_STROKE_WIDTH12, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
55520
+ var MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT5, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT2, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
55233
55521
  var init_renderer19 = __esm({
55234
55522
  "src/raci/renderer.ts"() {
55235
55523
  "use strict";
@@ -55240,6 +55528,7 @@ var init_renderer19 = __esm({
55240
55528
  init_variants();
55241
55529
  init_scaling();
55242
55530
  init_text_measure();
55531
+ init_visual_conventions();
55243
55532
  MARKER_LABELS = {
55244
55533
  raci: { R: "Responsible", A: "Accountable", C: "Consulted", I: "Informed" },
55245
55534
  rasci: {
@@ -55261,7 +55550,7 @@ var init_renderer19 = __esm({
55261
55550
  TITLE_LEGEND_GAP = 16;
55262
55551
  LEGEND_LABEL_FONT = 12;
55263
55552
  LEGEND_LETTER_FONT = 14;
55264
- HEADER_HEIGHT6 = 36;
55553
+ HEADER_HEIGHT5 = 36;
55265
55554
  ROW_HEIGHT = 36;
55266
55555
  PHASE_HEIGHT = 40;
55267
55556
  TASK_LABEL_MIN = 200;
@@ -55281,7 +55570,6 @@ var init_renderer19 = __esm({
55281
55570
  ROLE_HEADER_FONT = 12;
55282
55571
  PHASE_FONT = 13;
55283
55572
  TINT_PCT = 25;
55284
- NODE_STROKE_WIDTH12 = 1.5;
55285
55573
  NODE_RADIUS3 = 6;
55286
55574
  AUTO_ACCENTS = [
55287
55575
  "blue",
@@ -55882,11 +56170,11 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55882
56170
  const lines = splitParticipantLabel(
55883
56171
  p.label,
55884
56172
  labelTextWidth(PARTICIPANT_BOX_WIDTH),
55885
- LABEL_FONT_SIZE6
56173
+ LABEL_FONT_SIZE5
55886
56174
  );
55887
56175
  if (lines.length === 0) continue;
55888
56176
  const widest = Math.max(
55889
- ...lines.map((l) => measureText(l, LABEL_FONT_SIZE6))
56177
+ ...lines.map((l) => measureText(l, LABEL_FONT_SIZE5))
55890
56178
  );
55891
56179
  const labelWidth2 = widest + 10;
55892
56180
  uniformBoxWidth = Math.max(uniformBoxWidth, labelWidth2);
@@ -55920,7 +56208,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55920
56208
  const sSelfCallWidth = ctx.structural(SELF_CALL_WIDTH);
55921
56209
  const sNoteTextWidthMax = sNoteMaxW - sNotePadH * 2 - sNoteFold;
55922
56210
  const sNoteLaneMax = sGap - sActivationWidth - sNoteGap;
55923
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE6);
56211
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE5);
55924
56212
  const sLabelTextWidth = labelTextWidth(sBoxW);
55925
56213
  const participantIndexMap = /* @__PURE__ */ new Map();
55926
56214
  participants.forEach((p, i) => participantIndexMap.set(p.id, i));
@@ -57057,7 +57345,7 @@ function buildNoteMessageMap(elements) {
57057
57345
  walk(elements);
57058
57346
  return map;
57059
57347
  }
57060
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE6) {
57348
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
57061
57349
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
57062
57350
  if (tagAttr) {
57063
57351
  g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
@@ -57105,7 +57393,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
57105
57393
  });
57106
57394
  }
57107
57395
  }
57108
- var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE6, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE2, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
57396
+ var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE2, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
57109
57397
  var init_renderer20 = __esm({
57110
57398
  "src/sequence/renderer.ts"() {
57111
57399
  "use strict";
@@ -57125,7 +57413,7 @@ var init_renderer20 = __esm({
57125
57413
  PARTICIPANT_GAP = 160;
57126
57414
  PARTICIPANT_BOX_WIDTH = 120;
57127
57415
  PARTICIPANT_BOX_HEIGHT = 50;
57128
- LABEL_FONT_SIZE6 = 13;
57416
+ LABEL_FONT_SIZE5 = 13;
57129
57417
  TOP_MARGIN = 20;
57130
57418
  TITLE_HEIGHT8 = 30;
57131
57419
  PARTICIPANT_Y_OFFSET = 10;
@@ -62052,6 +62340,7 @@ init_renderer4();
62052
62340
  init_parser9();
62053
62341
  init_layout4();
62054
62342
  init_renderer5();
62343
+ init_tag_groups();
62055
62344
  init_inline_markdown();
62056
62345
  init_name_normalize();
62057
62346
  init_parser10();
@@ -63553,6 +63842,7 @@ export {
63553
63842
  applyGroupOrdering,
63554
63843
  applyPositionOverrides,
63555
63844
  atlasPalette,
63845
+ autoTagColorCycle,
63556
63846
  blueprintPalette,
63557
63847
  buildExtendedChartOption,
63558
63848
  buildNoteMessageMap,