@zenuml/core 4.3.0 → 4.4.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.
@@ -9723,6 +9723,7 @@ const PARTICIPANT_ICON_WIDTH = 40;
9723
9723
  const LIFELINE_WIDTH = 1;
9724
9724
  const PARTICIPANT_TOP_SPACE_FOR_GROUP = 20;
9725
9725
  const OCCURRENCE_EMPTY_HEIGHT = 24;
9726
+ const DIAGRAM_HEADER_HEIGHT = 24 + 4 * 2 + 1;
9726
9727
 
9727
9728
  var TextType = /* @__PURE__ */ ((TextType2) => {
9728
9729
  TextType2[TextType2["MessageContent"] = 0] = "MessageContent";
@@ -10120,6 +10121,7 @@ const ASYNC_SELF_MESSAGE_HEIGHT = 44;
10120
10121
  const CREATION_MESSAGE_HEIGHT = 40;
10121
10122
  const COMMENT_LINE_HEIGHT = tw(5);
10122
10123
  const FRAGMENT_BORDER_WIDTH = 1;
10124
+ const FRAGMENT_GUARD_HEIGHT = 28;
10123
10125
 
10124
10126
  function getLocalParticipantNames(ctx) {
10125
10127
  if (!ctx) return [];
@@ -10652,7 +10654,7 @@ class FragmentAltVM extends StatementVM {
10652
10654
  let cursor = top + 1 + this.metrics.fragmentHeaderHeight + commentHeight;
10653
10655
  const ifBlock = this.alt?.ifBlock?.();
10654
10656
  if (ifBlock) {
10655
- cursor += 20;
10657
+ cursor += FRAGMENT_GUARD_HEIGHT;
10656
10658
  cursor = this.layoutBlock(
10657
10659
  ifBlock.braceBlock()?.block(),
10658
10660
  leftParticipant,
@@ -10660,7 +10662,7 @@ class FragmentAltVM extends StatementVM {
10660
10662
  );
10661
10663
  }
10662
10664
  this.alt?.elseIfBlock?.()?.forEach((block) => {
10663
- cursor += 20;
10665
+ cursor += FRAGMENT_GUARD_HEIGHT;
10664
10666
  cursor += 8;
10665
10667
  cursor += 1;
10666
10668
  cursor = this.layoutBlock(
@@ -10671,7 +10673,7 @@ class FragmentAltVM extends StatementVM {
10671
10673
  });
10672
10674
  const elseBlock = this.alt?.elseBlock?.()?.braceBlock?.()?.block?.();
10673
10675
  if (elseBlock) {
10674
- cursor += 20;
10676
+ cursor += FRAGMENT_GUARD_HEIGHT;
10675
10677
  cursor += 8;
10676
10678
  cursor += 1;
10677
10679
  cursor = this.layoutBlock(elseBlock, leftParticipant, cursor);
@@ -10706,7 +10708,7 @@ class FragmentSingleBlockVM extends StatementVM {
10706
10708
  const commentHeight = this.measureComment(this.fragment);
10707
10709
  let cursor = top + FRAGMENT_BORDER_WIDTH + this.metrics.fragmentHeaderHeight + commentHeight;
10708
10710
  const hasCondition = Boolean(this.fragment?.parExpr?.()?.condition?.());
10709
- if (hasCondition) cursor += 20;
10711
+ if (hasCondition) cursor += FRAGMENT_GUARD_HEIGHT;
10710
10712
  const block = this.fragment?.braceBlock?.()?.block?.();
10711
10713
  if (block) {
10712
10714
  const fragmentOrigin = this.findLeftParticipant(this.fragment, origin) || origin;
@@ -10954,11 +10956,20 @@ const clearPersistentCache = () => {
10954
10956
  dic = {};
10955
10957
  };
10956
10958
 
10957
- const FONT_FAMILY = "Helvetica, Verdana, serif";
10958
- const FONT_SIZE_PARTICIPANT = "16px";
10959
+ const IBM_PLEX_SANS_FAMILY = "IBM Plex Sans";
10960
+ const DIAGRAM_FONT_STACK = `"${IBM_PLEX_SANS_FAMILY}", Helvetica, Verdana, serif`;
10961
+ const IBM_PLEX_SANS_400_WOFF2_BASE64 = "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";
10962
+ const IBM_PLEX_SANS_400_DATA_URI = `data:font/woff2;base64,${IBM_PLEX_SANS_400_WOFF2_BASE64}`;
10963
+
10964
+ const FONT_FAMILY = DIAGRAM_FONT_STACK;
10965
+ const FONT_SIZE_PARTICIPANT = "14px";
10966
+ const FONT_SIZE_MESSAGE = "15px";
10959
10967
  const FONT_SIZE_FRAGMENT = "14px";
10960
- function getFontSpec() {
10961
- return `${FONT_SIZE_PARTICIPANT} ${FONT_FAMILY}`;
10968
+ function getFontSize(type) {
10969
+ return type === TextType.MessageContent ? FONT_SIZE_MESSAGE : FONT_SIZE_PARTICIPANT;
10970
+ }
10971
+ function getFontSpec(type) {
10972
+ return `${getFontSize(type)} ${FONT_FAMILY}`;
10962
10973
  }
10963
10974
  let canvasCtx = null;
10964
10975
  function setCanvasContext(ctx) {
@@ -10980,18 +10991,21 @@ function getCanvasContext() {
10980
10991
  }
10981
10992
  function WidthProviderOnCanvas(text, type) {
10982
10993
  const measured = text.trim();
10983
- const cacheKey = `WidthProviderOnCanvas_${getFontSpec()}_${measured}_${type}`;
10994
+ const cacheKey = `WidthProviderOnCanvas_${getFontSpec(type)}_${measured}_${type}`;
10984
10995
  const cacheValue = getCache(cacheKey);
10985
10996
  if (cacheValue != null) {
10986
10997
  return cacheValue;
10987
10998
  }
10988
10999
  const ctx = getCanvasContext();
10989
11000
  if (!ctx) {
10990
- const width2 = Math.ceil(measured.length * 16 * 0.6);
11001
+ const width2 = Math.ceil(
11002
+ measured.length * Number.parseFloat(getFontSize(type)) * 0.6
11003
+ );
10991
11004
  setCache(cacheKey, width2);
10992
11005
  return width2;
10993
11006
  }
10994
- ctx.font = getFontSpec();
11007
+ ctx.font = getFontSpec(type);
11008
+ ctx.fontVariantCaps = "normal";
10995
11009
  const width = Math.round(ctx.measureText(measured).width);
10996
11010
  setCache(cacheKey, width, true);
10997
11011
  return width;
@@ -11000,32 +11014,34 @@ const EMOJI_PATTERN = (
11000
11014
  // eslint-disable-next-line no-misleading-character-class
11001
11015
  /[\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}\u{FE00}-\u{FE0F}\u{200D}]/u
11002
11016
  );
11003
- function measureWithSvg(text, fontSize) {
11017
+ function measureWithSvg(text, fontSize, caps = "normal") {
11004
11018
  if (typeof document === "undefined") return null;
11005
11019
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
11006
11020
  svg.setAttribute("style", "position:absolute;left:-9999px;top:-9999px");
11007
11021
  const textEl = document.createElementNS("http://www.w3.org/2000/svg", "text");
11008
11022
  textEl.setAttribute("font-family", FONT_FAMILY);
11009
11023
  textEl.setAttribute("font-size", fontSize);
11024
+ textEl.style.fontVariantCaps = caps;
11025
+ if (typeof textEl.getBBox !== "function") return null;
11010
11026
  textEl.textContent = text;
11011
11027
  svg.appendChild(textEl);
11012
11028
  document.body.appendChild(svg);
11013
11029
  const width = textEl.getBBox().width;
11014
11030
  document.body.removeChild(svg);
11015
- return width;
11031
+ return Number.isFinite(width) && width > 0 ? width : null;
11016
11032
  }
11017
- function measureTextWithFont(text, fontSize) {
11033
+ function measureTextWithFont(text, fontSize, caps = "normal") {
11018
11034
  const measured = text.trim();
11019
11035
  if (!measured) return 0;
11020
11036
  const hasEmoji = EMOJI_PATTERN.test(measured);
11021
11037
  const font = `${fontSize} ${FONT_FAMILY}`;
11022
- const cacheKey = hasEmoji ? `measureTextWithFont_svg_${font}_${measured}` : `measureTextWithFont_${font}_${measured}`;
11038
+ const cacheKey = (hasEmoji ? `measureTextWithFont_svg_${font}_${measured}` : `measureTextWithFont_${font}_${measured}`) + `_${caps}`;
11023
11039
  const cacheValue = getCache(cacheKey);
11024
11040
  if (cacheValue != null) {
11025
11041
  return cacheValue;
11026
11042
  }
11027
- if (hasEmoji) {
11028
- const svgWidth = measureWithSvg(measured, fontSize);
11043
+ if (hasEmoji || caps !== "normal") {
11044
+ const svgWidth = measureWithSvg(measured, fontSize, caps);
11029
11045
  if (svgWidth != null) {
11030
11046
  setCache(cacheKey, svgWidth, true);
11031
11047
  return svgWidth;
@@ -11039,7 +11055,15 @@ function measureTextWithFont(text, fontSize) {
11039
11055
  return width2;
11040
11056
  }
11041
11057
  ctx.font = font;
11042
- const width = ctx.measureText(measured).width;
11058
+ ctx.fontVariantCaps = "normal";
11059
+ const normalWidth = ctx.measureText(measured).width;
11060
+ let width = normalWidth;
11061
+ if (caps !== "normal") {
11062
+ const normalProbe = ctx.measureText("iiii").width;
11063
+ ctx.fontVariantCaps = caps;
11064
+ width = Math.abs(ctx.measureText("iiii").width - normalProbe) > 0.01 ? ctx.measureText(measured).width : Math.max(normalWidth, ctx.measureText(measured.toUpperCase()).width);
11065
+ ctx.fontVariantCaps = "normal";
11066
+ }
11043
11067
  setCache(cacheKey, width, true);
11044
11068
  return width;
11045
11069
  }
@@ -11050,10 +11074,51 @@ function measureSvgParticipantLabelWidth(text) {
11050
11074
  return measureTextWithFont(text, FONT_SIZE_PARTICIPANT);
11051
11075
  }
11052
11076
 
11077
+ const fragmentGuardKeyword = (kind, sourceKeyword) => kind === "alt" || kind === "opt" ? "if" : kind === "loop" ? sourceKeyword ?? "loop" : void 0;
11078
+ const fragmentGuardWidth = (condition, keyword) => Math.ceil(
11079
+ 10 + measureTextWithFont(resolveEmojiInText(condition), "14px") + (keyword ? measureTextWithFont(keyword, "12px", "all-small-caps") + (condition ? 4 : 0) : 0)
11080
+ );
11081
+
11082
+ function longestPath(frame, pathType) {
11083
+ if (!frame.children || frame.children.length === 0) {
11084
+ return 1;
11085
+ }
11086
+ let maxDepth = 0;
11087
+ for (const child of frame.children) {
11088
+ if (pathType === "LEFT" /* LEFT */ && child.left !== frame.left || pathType === "RIGHT" /* RIGHT */ && child.right !== frame.right) {
11089
+ continue;
11090
+ }
11091
+ maxDepth = Math.max(maxDepth, longestPath(child, pathType));
11092
+ }
11093
+ return maxDepth + 1;
11094
+ }
11095
+ const TOP_LEVEL_FRAGMENTS = "top-level-fragments";
11096
+ function topLevelFrame(frames) {
11097
+ if (frames.length === 0) return null;
11098
+ if (frames.length === 1) return frames[0];
11099
+ return { type: TOP_LEVEL_FRAGMENTS, left: "", right: "", children: frames };
11100
+ }
11101
+ function FrameBorder(frame) {
11102
+ if (!frame) {
11103
+ return { left: 0, right: 0 };
11104
+ }
11105
+ if (frame.type === TOP_LEVEL_FRAGMENTS) {
11106
+ const borders = (frame.children ?? []).map(FrameBorder);
11107
+ return {
11108
+ left: Math.max(0, ...borders.map((b) => b.left)),
11109
+ right: Math.max(0, ...borders.map((b) => b.right))
11110
+ };
11111
+ }
11112
+ return {
11113
+ left: FRAGMENT_PADDING_X * longestPath(frame, "LEFT" /* LEFT */),
11114
+ right: FRAGMENT_PADDING_X * longestPath(frame, "RIGHT" /* RIGHT */)
11115
+ };
11116
+ }
11117
+
11053
11118
  const walker = antlr4.tree.ParseTreeWalker.DEFAULT;
11054
11119
  class FrameBuilder extends sequenceParserListener {
11055
11120
  _orderedParticipants;
11056
- frameRoot = null;
11121
+ topLevelFrames = [];
11057
11122
  parents = [];
11058
11123
  constructor(orderedParticipants) {
11059
11124
  super();
@@ -11073,11 +11138,10 @@ class FrameBuilder extends sequenceParserListener {
11073
11138
  right: this.getRight(ctx),
11074
11139
  children: []
11075
11140
  };
11076
- if (!this.frameRoot) {
11077
- this.frameRoot = frame;
11078
- }
11079
11141
  if (this.parents.length > 0) {
11080
11142
  this.parents[this.parents.length - 1].children?.push(frame);
11143
+ } else {
11144
+ this.topLevelFrames.push(frame);
11081
11145
  }
11082
11146
  this.parents.push(frame);
11083
11147
  }
@@ -11137,32 +11201,26 @@ class FrameBuilder extends sequenceParserListener {
11137
11201
  context.children.map((child) => {
11138
11202
  walker.walk(this, child);
11139
11203
  });
11140
- return this.frameRoot;
11204
+ return topLevelFrame(this.topLevelFrames);
11141
11205
  }
11142
11206
  }
11143
11207
 
11144
- function longestPath(frame, pathType) {
11145
- if (!frame.children || frame.children.length === 0) {
11146
- return 1;
11147
- }
11148
- let maxDepth = 0;
11149
- for (const child of frame.children) {
11150
- if (pathType === "LEFT" /* LEFT */ && child.left !== frame.left || pathType === "RIGHT" /* RIGHT */ && child.right !== frame.right) {
11151
- continue;
11152
- }
11153
- maxDepth = Math.max(maxDepth, longestPath(child, pathType));
11154
- }
11155
- return maxDepth + 1;
11156
- }
11157
- function FrameBorder(frame) {
11158
- if (!frame) {
11159
- return { left: 0, right: 0 };
11160
- }
11161
- return {
11162
- left: FRAGMENT_PADDING_X * longestPath(frame, "LEFT" /* LEFT */),
11163
- right: FRAGMENT_PADDING_X * longestPath(frame, "RIGHT" /* RIGHT */)
11208
+ const fragmentHeaderLabel = (kind) => {
11209
+ const labels = {
11210
+ alt: "Alt",
11211
+ loop: "Loop",
11212
+ opt: "Opt",
11213
+ par: "Par",
11214
+ critical: "Critical",
11215
+ section: "Section",
11216
+ tcf: "Try",
11217
+ ref: "Ref"
11164
11218
  };
11165
- }
11219
+ return labels[kind] ?? kind.charAt(0).toUpperCase() + kind.slice(1);
11220
+ };
11221
+ const fragmentHeaderWidth = (label, number) => Math.ceil(
11222
+ 32 + measureTextWithFont(label, "14px", "all-small-caps") * 1.1 + (number ? measureTextWithFont(number, "12px") + 15 : 0)
11223
+ );
11166
11224
 
11167
11225
  function TotalWidth(ctx, coordinates) {
11168
11226
  const allParticipants = coordinates.orderedParticipantNames();
@@ -11369,10 +11427,10 @@ function buildFragmentGeometry(info, coord, coordinates, verticalCoordinates, al
11369
11427
  let fragX;
11370
11428
  if (leftParticipant && rightParticipant) {
11371
11429
  fragWidth = TotalWidth(statNode, coordinates);
11372
- fragX = coordinates.getPosition(leftParticipant) - coordinates.half(leftParticipant);
11430
+ fragX = coordinates.getPosition(leftParticipant) - coordinates.half(leftParticipant) - fragBorder.left;
11373
11431
  } else {
11374
11432
  fragWidth = Math.max(FRAGMENT_MIN_WIDTH, coordinates.getWidth());
11375
- fragX = 0;
11433
+ fragX = -fragBorder.left;
11376
11434
  }
11377
11435
  const sections = [];
11378
11436
  if (info.fragmentSections && info.fragmentSections.length > 1) {
@@ -11388,7 +11446,8 @@ function buildFragmentGeometry(info, coord, coordinates, verticalCoordinates, al
11388
11446
  if (firstStatKey) {
11389
11447
  const innerCoord = verticalCoordinates.getStatementCoordinate(firstStatKey);
11390
11448
  if (innerCoord) {
11391
- sectionY = innerCoord.top - 20 - 8 - 8 - 1;
11449
+ const labelHeight = info.fragmentKind === "alt" ? FRAGMENT_GUARD_HEIGHT : 20;
11450
+ sectionY = innerCoord.top - labelHeight - 8 - 8 - 1;
11392
11451
  }
11393
11452
  }
11394
11453
  }
@@ -11397,11 +11456,14 @@ function buildFragmentGeometry(info, coord, coordinates, verticalCoordinates, al
11397
11456
  const sectionHeight = i < info.fragmentSections.length - 1 ? 0 : coord.top + coord.height - sectionY;
11398
11457
  sections.push({
11399
11458
  label: section.label,
11459
+ guardKeyword: section.guardKeyword,
11400
11460
  y: sectionY,
11401
11461
  height: sectionHeight,
11402
11462
  labelWidth: section.label ? measureSvgFragmentLabelWidth(resolveEmojiInText(section.label)) : void 0,
11403
- innerLabel: /^\[\s*.*\s*\]$/.test(section.label) ? section.label.slice(1, -1).trim() : void 0,
11404
- innerLabelWidth: /^\[\s*.*\s*\]$/.test(section.label) ? measureSvgFragmentLabelWidth(
11463
+ innerLabel: section.condition ?? (/^\[\s*.*\s*\]$/.test(section.label) ? section.label.slice(1, -1).trim() : void 0),
11464
+ innerLabelWidth: section.condition !== void 0 ? measureSvgFragmentLabelWidth(
11465
+ resolveEmojiInText(section.condition)
11466
+ ) : /^\[\s*.*\s*\]$/.test(section.label) ? measureSvgFragmentLabelWidth(
11405
11467
  resolveEmojiInText(section.label.slice(1, -1).trim())
11406
11468
  ) : void 0,
11407
11469
  keyword: (() => {
@@ -11472,7 +11534,9 @@ function buildFragmentGeometry(info, coord, coordinates, verticalCoordinates, al
11472
11534
  return {
11473
11535
  fragment: {
11474
11536
  kind: info.fragmentKind,
11537
+ headerLabel: info.fragmentHeaderLabel,
11475
11538
  label: info.fragmentLabel || "",
11539
+ guardKeyword: info.guardKeyword,
11476
11540
  labelWidth: info.fragmentLabel ? measureSvgFragmentLabelWidth(resolveEmojiInText(info.fragmentLabel)) : void 0,
11477
11541
  x: fragX,
11478
11542
  y: coord.top,
@@ -11688,6 +11752,8 @@ function walkBlock(block, currentOrigin, activeOccurrences, parentNumber, depth,
11688
11752
  hasBlock: false,
11689
11753
  fragmentKind: fragmentInfo.fragmentKind,
11690
11754
  fragmentLabel: fragmentInfo.label,
11755
+ fragmentHeaderLabel: fragmentInfo.headerLabel,
11756
+ guardKeyword: fragmentInfo.guardKeyword,
11691
11757
  fragmentSections: fragmentInfo.sections,
11692
11758
  comment,
11693
11759
  statNode: stat,
@@ -11714,7 +11780,9 @@ function extractFragmentInfo(stat) {
11714
11780
  const label = condition?.getFormattedText?.() || "";
11715
11781
  return {
11716
11782
  fragmentKind: kind,
11783
+ headerLabel: frag.atom?.()?.getFormattedText?.(),
11717
11784
  label,
11785
+ guardKeyword: kind === "loop" ? frag.WHILE?.()?.getText?.() : void 0,
11718
11786
  sections: [{ label, blockNode: frag.braceBlock?.()?.block?.() }]
11719
11787
  };
11720
11788
  }
@@ -11726,6 +11794,8 @@ function extractFragmentInfo(stat) {
11726
11794
  if (ifBlock) {
11727
11795
  sections.push({
11728
11796
  label: "Alt",
11797
+ guardKeyword: "if",
11798
+ condition: ifBlock.parExpr?.()?.condition?.()?.getFormattedText?.() || "",
11729
11799
  blockNode: ifBlock.braceBlock?.()?.block?.()
11730
11800
  });
11731
11801
  }
@@ -11733,14 +11803,17 @@ function extractFragmentInfo(stat) {
11733
11803
  const condition = elseIf.parExpr?.()?.condition?.();
11734
11804
  const label = condition?.getFormattedText?.() || "";
11735
11805
  sections.push({
11736
- label: `[ ${label} ]`,
11806
+ label: `else if ${label}`,
11807
+ guardKeyword: "else if",
11808
+ condition: label,
11737
11809
  blockNode: elseIf.braceBlock?.()?.block?.()
11738
11810
  });
11739
11811
  }
11740
11812
  const elseBlock = alt.elseBlock?.();
11741
11813
  if (elseBlock) {
11742
11814
  sections.push({
11743
- label: "[else]",
11815
+ label: "else",
11816
+ guardKeyword: "else",
11744
11817
  blockNode: elseBlock.braceBlock?.()?.block?.()
11745
11818
  });
11746
11819
  }
@@ -12381,13 +12454,36 @@ function buildGeometry(input) {
12381
12454
  participants,
12382
12455
  measureText
12383
12456
  );
12384
- const { messages, selfCalls, occurrences, creations, fragments, returns, dividers, comments } = buildResult;
12457
+ const {
12458
+ messages,
12459
+ selfCalls,
12460
+ occurrences,
12461
+ creations,
12462
+ fragments,
12463
+ returns,
12464
+ dividers,
12465
+ comments
12466
+ } = buildResult;
12467
+ if (input.enableNumbering === false) {
12468
+ const numberedItems = [
12469
+ ...messages,
12470
+ ...selfCalls,
12471
+ ...fragments,
12472
+ ...returns,
12473
+ ...creations.map((creation) => creation.message)
12474
+ ];
12475
+ for (const numbered of numberedItems) {
12476
+ numbered.number = void 0;
12477
+ }
12478
+ }
12385
12479
  let maxOccBottom = 0;
12386
12480
  let maxOtherY = 0;
12387
- for (const o of occurrences) maxOccBottom = Math.max(maxOccBottom, o.y + o.height);
12481
+ for (const o of occurrences)
12482
+ maxOccBottom = Math.max(maxOccBottom, o.y + o.height);
12388
12483
  for (const m of messages) maxOtherY = Math.max(maxOtherY, m.y);
12389
12484
  for (const s of selfCalls) maxOtherY = Math.max(maxOtherY, s.y + s.height);
12390
- for (const c of creations) maxOtherY = Math.max(maxOtherY, c.message.y + PARTICIPANT_VISUAL_HEIGHT);
12485
+ for (const c of creations)
12486
+ maxOtherY = Math.max(maxOtherY, c.message.y + PARTICIPANT_VISUAL_HEIGHT);
12391
12487
  for (const f of fragments) maxOtherY = Math.max(maxOtherY, f.y + f.height);
12392
12488
  for (const d of dividers) maxOtherY = Math.max(maxOtherY, d.y);
12393
12489
  const diagramHeight = Math.max(
@@ -12397,10 +12493,7 @@ function buildGeometry(input) {
12397
12493
  buildResult.maxReturnBottom
12398
12494
  );
12399
12495
  const lifelineBottom = diagramHeight + PARTICIPANT_VISUAL_HEIGHT - 28;
12400
- const lifelines = buildLifelines(
12401
- participants,
12402
- lifelineBottom
12403
- );
12496
+ const lifelines = buildLifelines(participants, lifelineBottom);
12404
12497
  let diagramWidth = TotalWidth(rootContext, coordinates) - frameBorder.left - frameBorder.right;
12405
12498
  if (measureText) {
12406
12499
  const LABEL_PAD = 10;
@@ -12423,14 +12516,6 @@ function buildGeometry(input) {
12423
12516
  if (rightExtent > diagramWidth) diagramWidth = rightExtent;
12424
12517
  }
12425
12518
  }
12426
- for (const f of fragments) {
12427
- f.x -= frameBorder.left;
12428
- }
12429
- for (const c of comments) {
12430
- if (c.fragmentComment) {
12431
- c.x -= frameBorder.left;
12432
- }
12433
- }
12434
12519
  const nestDepths = /* @__PURE__ */ new Map();
12435
12520
  for (const inner of fragments) {
12436
12521
  let nestDepth = 0;
@@ -12441,7 +12526,6 @@ function buildGeometry(input) {
12441
12526
  }
12442
12527
  }
12443
12528
  nestDepths.set(inner, nestDepth);
12444
- inner.x += nestDepth * FRAGMENT_PADDING_X;
12445
12529
  }
12446
12530
  const contentRightEdge = diagramWidth + frameBorder.right;
12447
12531
  for (const f of fragments) {
@@ -12452,6 +12536,42 @@ function buildGeometry(input) {
12452
12536
  f.width = targetRight - f.x;
12453
12537
  }
12454
12538
  }
12539
+ for (const inner of [...fragments].sort((a, b) => a.height - b.height)) {
12540
+ inner.width = Math.max(
12541
+ inner.width,
12542
+ fragmentHeaderWidth(
12543
+ inner.headerLabel ?? fragmentHeaderLabel(inner.kind),
12544
+ inner.number
12545
+ )
12546
+ );
12547
+ if (inner.label)
12548
+ inner.width = Math.max(
12549
+ inner.width,
12550
+ fragmentGuardWidth(
12551
+ inner.label,
12552
+ fragmentGuardKeyword(inner.kind, inner.guardKeyword)
12553
+ )
12554
+ );
12555
+ for (const section of inner.sections) {
12556
+ if (section.guardKeyword)
12557
+ inner.width = Math.max(
12558
+ inner.width,
12559
+ fragmentGuardWidth(section.innerLabel ?? "", section.guardKeyword)
12560
+ );
12561
+ }
12562
+ for (const outer of fragments) {
12563
+ if (outer.y < inner.y && outer.y + outer.height >= inner.y + inner.height && outer.x <= inner.x) {
12564
+ outer.width = Math.max(
12565
+ outer.width,
12566
+ inner.x + inner.width + FRAGMENT_PADDING_X - outer.x
12567
+ );
12568
+ }
12569
+ }
12570
+ diagramWidth = Math.max(
12571
+ diagramWidth,
12572
+ inner.x + inner.width - frameBorder.right
12573
+ );
12574
+ }
12455
12575
  const groups = buildGroups(participants, diagramHeight);
12456
12576
  return {
12457
12577
  width: diagramWidth,
@@ -12475,13 +12595,13 @@ function buildGeometry(input) {
12475
12595
 
12476
12596
  const ActorSvg = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <path d=\"M15.5489 4.19771C15.5489 5.18773 15.1485 6.13721 14.4358 6.83726C13.7231 7.53731 12.7565 7.93058 11.7486 7.93058C10.7407 7.93058 9.77403 7.53731 9.06133 6.83726C8.34863 6.13721 7.94824 5.18773 7.94824 4.19771C7.94824 3.20768 8.34863 2.25822 9.06133 1.55818C9.77403 0.858126 10.7407 0.464844 11.7486 0.464844C12.7565 0.464844 13.7231 0.858126 14.4358 1.55818C15.1485 2.25822 15.5489 3.20768 15.5489 4.19771Z\" stroke=\"currentColor\"/>\n <path d=\"M6.54883 11.2152L17.2025 11.2073M11.7471 8.06641V19.5806V8.06641ZM11.7471 19.4385L6.79789 23.5738L11.7471 19.4385ZM11.7551 19.4385L17.1864 23.3055L11.7551 19.4385Z\" stroke=\"currentColor\"/>\n </g>\n</svg>\n";
12477
12597
 
12478
- const BoundarySvg = "<svg width=\"101\" height=\"78\" viewBox=\"0 0 101 78\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t<path d=\"M96.3563 39.4479C96.3563 48.4904 92.6755 57.1625 86.1237 63.5566C79.5718 69.9506 70.6856 73.5427 61.4199 73.5427C52.1541 73.5427 43.2679 69.9506 36.7161 63.5566C30.1642 57.1625 26.4834 48.4904 26.4834 39.4479C26.4834 30.147 30.1642 21.2271 36.7161 14.6504C43.2679 8.07366 52.1541 4.37891 61.4199 4.37891C70.6856 4.37891 79.5718 8.07366 86.1237 14.6504C92.6755 21.2271 96.3563 30.147 96.3563 39.4479V39.4479Z\" stroke=\"currentColor\" stroke-width=\"4\"/>\n\t<path d=\"M27.3611 39.4482H3.93945\" stroke=\"currentColor\" stroke-width=\"4\"/>\n\t<path d=\"M4.91504 4.37891V74.5168\" stroke=\"currentColor\" stroke-width=\"4\"/>\n</svg>\n";
12598
+ const BoundarySvg = "<svg width=\"101\" height=\"78\" viewBox=\"0 0 101 78\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t<path d=\"M96.3563 39.4479C96.3563 48.4904 92.6755 57.1625 86.1237 63.5566C79.5718 69.9506 70.6856 73.5427 61.4199 73.5427C52.1541 73.5427 43.2679 69.9506 36.7161 63.5566C30.1642 57.1625 26.4834 48.4904 26.4834 39.4479C26.4834 30.147 30.1642 21.2271 36.7161 14.6504C43.2679 8.07366 52.1541 4.37891 61.4199 4.37891C70.6856 4.37891 79.5718 8.07366 86.1237 14.6504C92.6755 21.2271 96.3563 30.147 96.3563 39.4479V39.4479Z\" stroke=\"currentColor\" stroke-width=\"4.2083\"/>\n\t<path d=\"M27.3611 39.4482H3.93945\" stroke=\"currentColor\" stroke-width=\"4.2083\"/>\n\t<path d=\"M4.91504 4.37891V74.5168\" stroke=\"currentColor\" stroke-width=\"4.2083\"/>\n</svg>\n";
12479
12599
 
12480
- const ControlSvg = "<svg width=\"77\" height=\"86\" viewBox=\"0 0 77 86\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t<g>\n\t\t<path d=\"M74.0149 46.8888C74.0149 51.5755 73.0918 56.2163 71.2983 60.5463C69.5048 64.8762 66.876 68.8105 63.562 72.1245C60.248 75.4385 56.3137 78.0673 51.9838 79.8608C47.6538 81.6543 43.013 82.5774 38.3263 82.5774C33.6396 82.5774 28.9988 81.6543 24.6689 79.8608C20.3389 78.0673 16.4046 75.4385 13.0907 72.1245C9.77666 68.8105 7.14785 64.8762 5.35433 60.5463C3.56081 56.2163 2.6377 51.5755 2.6377 46.8888C2.6377 42.2021 3.56081 37.5613 5.35433 33.2314C7.14785 28.9014 9.77666 24.9671 13.0907 21.6532C16.4046 18.3392 20.3389 15.7104 24.6689 13.9168C28.9988 12.1233 33.6396 11.2002 38.3263 11.2002C43.013 11.2002 47.6538 12.1233 51.9838 13.9168C56.3137 15.7104 60.248 18.3392 63.562 21.6532C66.876 24.9671 69.5048 28.9014 71.2983 33.2314C73.0918 37.5613 74.0149 42.2021 74.0149 46.8888V46.8888Z\" stroke=\"currentColor\" stroke-width=\"4.98203\"/>\n\t\t<path d=\"M47.5352 2.30371L37.5352 11.5001L47.5352 20.6966\" stroke=\"currentColor\" stroke-width=\"6\"/>\n\t</g>\n</svg>\n";
12600
+ const ControlSvg = "<svg width=\"77\" height=\"86\" viewBox=\"0 0 77 86\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t<g>\n\t\t<path d=\"M74.0149 46.8888C74.0149 51.5755 73.0918 56.2163 71.2983 60.5463C69.5048 64.8762 66.876 68.8105 63.562 72.1245C60.248 75.4385 56.3137 78.0673 51.9838 79.8608C47.6538 81.6543 43.013 82.5774 38.3263 82.5774C33.6396 82.5774 28.9988 81.6543 24.6689 79.8608C20.3389 78.0673 16.4046 75.4385 13.0907 72.1245C9.77666 68.8105 7.14785 64.8762 5.35433 60.5463C3.56081 56.2163 2.6377 51.5755 2.6377 46.8888C2.6377 42.2021 3.56081 37.5613 5.35433 33.2314C7.14785 28.9014 9.77666 24.9671 13.0907 21.6532C16.4046 18.3392 20.3389 15.7104 24.6689 13.9168C28.9988 12.1233 33.6396 11.2002 38.3263 11.2002C43.013 11.2002 47.6538 12.1233 51.9838 13.9168C56.3137 15.7104 60.248 18.3392 63.562 21.6532C66.876 24.9671 69.5048 28.9014 71.2983 33.2314C73.0918 37.5613 74.0149 42.2021 74.0149 46.8888V46.8888Z\" stroke=\"currentColor\" stroke-width=\"3.5833\"/>\n\t\t<path d=\"M47.5352 2.30371L37.5352 11.5001L47.5352 20.6966\" stroke=\"currentColor\" stroke-width=\"3.5833\"/>\n\t</g>\n</svg>\n";
12481
12601
 
12482
- const DatabaseSvg = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M12.258 0.001L12.514 0.005L12.769 0.01L13.022 0.018L13.273 0.028L13.522 0.04L13.769 0.055L14.015 0.071L14.257 0.09L14.498 0.11L14.737 0.133L14.973 0.157L15.206 0.184L15.437 0.212L15.666 0.243L15.891 0.275L16.114 0.309L16.334 0.345L16.551 0.383L16.765 0.423L16.976 0.464L17.184 0.507L17.389 0.552L17.59 0.598L17.788 0.646L17.982 0.696L18.173 0.747L18.36 0.8L18.543 0.854L18.723 0.91L18.898 0.967L19.07 1.026L19.238 1.086L19.401 1.147L19.561 1.21L19.716 1.274L19.866 1.34L19.94 1.373L20.013 1.406L20.084 1.44L20.154 1.474L20.223 1.509L20.291 1.544L20.358 1.579L20.424 1.614L20.488 1.65L20.552 1.686L20.614 1.722L20.674 1.758L20.734 1.795L20.792 1.832L20.85 1.869L20.905 1.907L20.96 1.945L21.013 1.983L21.065 2.021L21.116 2.06L21.166 2.099L21.214 2.138L21.261 2.177L21.306 2.217L21.35 2.257L21.393 2.297L21.434 2.337L21.474 2.378L21.513 2.419L21.55 2.46L21.586 2.501L21.62 2.542L21.653 2.584L21.685 2.626L21.715 2.668L21.744 2.71L21.771 2.752L21.797 2.795L21.821 2.838L21.844 2.881L21.865 2.924L21.885 2.967L21.903 3.011L21.92 3.054L21.935 3.098L21.948 3.142L21.96 3.186L21.971 3.231L21.98 3.275L21.987 3.32L21.993 3.365L21.997 3.41L21.999 3.455L22 3.5V20.5L21.999 20.545L21.997 20.59L21.993 20.635L21.987 20.68L21.98 20.725L21.971 20.769L21.96 20.814L21.948 20.858L21.935 20.902L21.92 20.946L21.903 20.989L21.885 21.033L21.865 21.076L21.844 21.119L21.821 21.162L21.797 21.205L21.771 21.248L21.744 21.29L21.715 21.332L21.685 21.374L21.653 21.416L21.62 21.458L21.586 21.499L21.55 21.54L21.513 21.581L21.474 21.622L21.434 21.663L21.393 21.703L21.35 21.743L21.306 21.783L21.261 21.823L21.214 21.862L21.166 21.901L21.116 21.94L21.065 21.979L21.013 22.017L20.96 22.055L20.905 22.093L20.85 22.131L20.792 22.168L20.734 22.205L20.674 22.242L20.614 22.278L20.552 22.314L20.488 22.35L20.424 22.386L20.358 22.421L20.291 22.456L20.223 22.491L20.154 22.526L20.084 22.56L20.013 22.594L19.94 22.627L19.866 22.66L19.716 22.726L19.561 22.79L19.401 22.853L19.238 22.914L19.07 22.974L18.898 23.033L18.723 23.09L18.543 23.146L18.36 23.2L18.173 23.253L17.982 23.304L17.788 23.354L17.59 23.402L17.389 23.448L17.184 23.493L16.976 23.536L16.765 23.577L16.551 23.617L16.334 23.655L16.114 23.691L15.891 23.725L15.666 23.757L15.437 23.788L15.206 23.816L14.973 23.843L14.737 23.867L14.498 23.89L14.257 23.91L14.015 23.929L13.769 23.945L13.522 23.96L13.273 23.972L13.022 23.982L12.769 23.99L12.514 23.995L12.258 23.999L12 24L11.742 23.999L11.486 23.995L11.231 23.99L10.978 23.982L10.727 23.972L10.478 23.96L10.231 23.945L9.986 23.929L9.743 23.91L9.502 23.89L9.264 23.867L9.028 23.843L8.794 23.816L8.563 23.788L8.335 23.757L8.109 23.725L7.886 23.691L7.666 23.655L7.449 23.617L7.235 23.577L7.024 23.536L6.816 23.493L6.612 23.448L6.411 23.402L6.213 23.354L6.018 23.304L5.828 23.253L5.641 23.2L5.457 23.146L5.278 23.09L5.102 23.033L4.93 22.974L4.763 22.914L4.599 22.853L4.44 22.79L4.285 22.726L4.134 22.66L4.06 22.627L3.988 22.594L3.916 22.56L3.846 22.526L3.777 22.491L3.709 22.456L3.642 22.421L3.576 22.386L3.512 22.35L3.449 22.314L3.387 22.278L3.326 22.242L3.266 22.205L3.208 22.168L3.151 22.131L3.095 22.093L3.04 22.055L2.987 22.017L2.935 21.979L2.884 21.94L2.835 21.901L2.786 21.862L2.74 21.823L2.694 21.783L2.65 21.743L2.607 21.703L2.566 21.663L2.526 21.622L2.487 21.581L2.45 21.54L2.414 21.499L2.38 21.458L2.347 21.416L2.315 21.374L2.285 21.332L2.256 21.29L2.229 21.248L2.203 21.205L2.179 21.162L2.156 21.119L2.135 21.076L2.115 21.033L2.097 20.989L2.08 20.946L2.065 20.902L2.052 20.858L2.04 20.814L2.029 20.769L2.02 20.725L2.013 20.68L2.007 20.635L2.003 20.59L2.001 20.545L2 20.5V3.5L2.001 3.455L2.003 3.41L2.007 3.365L2.013 3.32L2.02 3.275L2.029 3.231L2.04 3.186L2.052 3.142L2.065 3.098L2.08 3.054L2.097 3.011L2.115 2.967L2.135 2.924L2.156 2.881L2.179 2.838L2.203 2.795L2.229 2.752L2.256 2.71L2.285 2.668L2.315 2.626L2.347 2.584L2.38 2.542L2.414 2.501L2.45 2.46L2.487 2.419L2.526 2.378L2.566 2.337L2.607 2.297L2.65 2.257L2.694 2.217L2.74 2.177L2.786 2.138L2.835 2.099L2.884 2.06L2.935 2.021L2.987 1.983L3.04 1.945L3.095 1.907L3.151 1.869L3.208 1.832L3.266 1.795L3.326 1.758L3.387 1.722L3.449 1.686L3.512 1.65L3.576 1.614L3.642 1.579L3.709 1.544L3.777 1.509L3.846 1.474L3.916 1.44L3.988 1.406L4.06 1.373L4.134 1.34L4.285 1.274L4.44 1.21L4.599 1.147L4.763 1.086L4.93 1.026L5.102 0.967L5.278 0.91L5.457 0.854L5.641 0.8L5.828 0.747L6.018 0.696L6.213 0.646L6.411 0.598L6.612 0.552L6.816 0.507L7.024 0.464L7.235 0.423L7.449 0.383L7.666 0.345L7.886 0.309L8.109 0.275L8.335 0.243L8.563 0.212L8.794 0.184L9.028 0.157L9.264 0.133L9.502 0.11L9.743 0.09L9.986 0.071L10.231 0.055L10.478 0.04L10.727 0.028L10.978 0.018L11.231 0.01L11.486 0.005L11.742 0.001L12 0L12.258 0.001V0.001ZM3 20.5V20.51L3.001 20.531L3.004 20.552L3.008 20.574L3.013 20.595L3.019 20.617L3.026 20.639L3.035 20.662L3.045 20.684L3.056 20.707L3.068 20.73L3.081 20.753L3.096 20.776L3.112 20.8L3.129 20.823L3.147 20.847L3.166 20.871L3.187 20.895L3.209 20.92L3.232 20.944L3.256 20.969L3.308 21.018L3.364 21.068L3.425 21.119L3.491 21.17L3.561 21.221L3.636 21.272L3.715 21.324L3.799 21.376L3.887 21.428L3.979 21.48L4.076 21.532L4.178 21.583L4.283 21.635L4.393 21.687L4.507 21.738L4.626 21.789L4.749 21.84L4.876 21.89L5.007 21.94L5.142 21.99L5.281 22.038L5.425 22.087L5.572 22.134L5.724 22.181L5.879 22.228L6.039 22.273L6.202 22.318L6.369 22.361L6.54 22.404L6.716 22.445L6.894 22.486L7.077 22.525L7.264 22.564L7.454 22.601L7.648 22.636L7.845 22.671L8.047 22.704L8.251 22.735L8.46 22.765L8.672 22.794L8.888 22.821L9.107 22.846L9.329 22.87L9.555 22.891L9.785 22.911L10.018 22.929L10.254 22.945L10.494 22.96L10.737 22.972L10.983 22.982L11.232 22.99L11.485 22.995L11.741 22.999L12 23L12.26 22.999L12.517 22.995L12.771 22.99L13.021 22.982L13.268 22.971L13.512 22.959L13.753 22.945L13.99 22.929L14.223 22.911L14.454 22.89L14.68 22.869L14.904 22.845L15.124 22.819L15.34 22.792L15.552 22.764L15.762 22.733L15.967 22.702L16.169 22.668L16.367 22.634L16.561 22.598L16.752 22.561L16.939 22.522L17.122 22.482L17.301 22.442L17.476 22.4L17.648 22.357L17.816 22.313L17.979 22.268L18.139 22.222L18.294 22.176L18.446 22.129L18.594 22.081L18.737 22.032L18.876 21.983L19.012 21.933L19.143 21.883L19.269 21.833L19.392 21.782L19.51 21.73L19.624 21.679L19.734 21.627L19.84 21.575L19.941 21.523L20.037 21.471L20.129 21.419L20.217 21.366L20.3 21.315L20.379 21.263L20.453 21.211L20.523 21.16L20.588 21.109L20.648 21.058L20.704 21.008L20.755 20.958L20.778 20.934L20.801 20.909L20.822 20.885L20.842 20.861L20.861 20.837L20.879 20.813L20.896 20.789L20.911 20.766L20.925 20.742L20.938 20.719L20.95 20.696L20.96 20.673L20.97 20.651L20.978 20.629L20.984 20.607L20.99 20.585L20.994 20.563L20.998 20.542L20.999 20.521L21 20.5V16.373L20.923 16.428L20.843 16.481L20.76 16.535L20.675 16.588L20.588 16.64L20.498 16.692L20.405 16.743L20.31 16.793L20.213 16.843L20.113 16.892L20.011 16.941L19.906 16.989L19.8 17.036L19.691 17.083L19.58 17.129L19.466 17.174L19.351 17.219L19.233 17.263L19.113 17.306L18.991 17.348L18.867 17.39L18.741 17.431L18.613 17.471L18.483 17.511L18.351 17.549L18.217 17.587L18.082 17.624L17.944 17.661L17.805 17.696L17.663 17.731L17.52 17.765L17.376 17.798L17.229 17.83L17.081 17.861L16.931 17.891L16.78 17.921L16.627 17.95L16.473 17.977L16.317 18.004L16.159 18.03L16 18.055L15.839 18.079L15.677 18.102L15.514 18.124L15.349 18.145L15.183 18.165L15.016 18.184L14.847 18.202L14.678 18.219L14.507 18.235L14.334 18.25L14.161 18.264L13.986 18.277L13.811 18.289L13.634 18.3L13.456 18.31L13.277 18.318L13.098 18.326L12.917 18.332L12.735 18.337L12.553 18.341L12.369 18.344L12.185 18.346H11.815L11.631 18.344L11.447 18.341L11.265 18.337L11.083 18.332L10.902 18.326L10.723 18.318L10.544 18.31L10.366 18.3L10.19 18.289L10.014 18.277L9.839 18.264L9.666 18.25L9.494 18.235L9.323 18.219L9.153 18.202L8.984 18.184L8.817 18.165L8.651 18.145L8.486 18.124L8.323 18.102L8.161 18.079L8 18.055L7.841 18.03L7.684 18.004L7.528 17.977L7.373 17.95L7.22 17.921L7.069 17.891L6.919 17.861L6.771 17.83L6.625 17.798L6.48 17.765L6.337 17.731L6.196 17.696L6.056 17.661L5.919 17.624L5.783 17.587L5.649 17.549L5.517 17.511L5.387 17.471L5.259 17.431L5.133 17.39L5.009 17.348L4.887 17.306L4.767 17.262L4.65 17.219L4.534 17.174L4.421 17.129L4.309 17.083L4.2 17.036L4.094 16.989L3.989 16.941L3.887 16.892L3.787 16.843L3.69 16.793L3.595 16.743L3.502 16.691L3.412 16.64L3.325 16.588L3.24 16.535L3.157 16.481L3.077 16.427L3 16.373V20.5V20.5ZM3 14.846V14.857L3.001 14.878L3.004 14.899L3.008 14.92L3.013 14.942L3.019 14.964L3.026 14.986L3.035 15.008L3.045 15.03L3.056 15.053L3.068 15.076L3.081 15.099L3.096 15.123L3.112 15.146L3.129 15.17L3.147 15.194L3.166 15.218L3.187 15.242L3.209 15.266L3.232 15.291L3.256 15.315L3.308 15.365L3.364 15.415L3.425 15.465L3.491 15.516L3.561 15.567L3.636 15.619L3.715 15.67L3.799 15.722L3.887 15.774L3.979 15.826L4.076 15.878L4.178 15.93L4.283 15.982L4.393 16.033L4.507 16.084L4.626 16.136L4.749 16.186L4.876 16.237L5.007 16.287L5.142 16.336L5.281 16.385L5.425 16.433L5.572 16.481L5.724 16.528L5.879 16.574L6.039 16.619L6.202 16.664L6.369 16.708L6.54 16.75L6.716 16.792L6.894 16.832L7.077 16.872L7.264 16.91L7.454 16.947L7.648 16.983L7.845 17.017L8.047 17.05L8.251 17.082L8.46 17.112L8.672 17.14L8.888 17.167L9.107 17.192L9.329 17.216L9.555 17.238L9.785 17.258L10.018 17.276L10.254 17.292L10.494 17.306L10.737 17.318L10.983 17.328L11.232 17.336L11.485 17.342L11.741 17.345L12 17.346L12.26 17.345L12.517 17.342L12.771 17.336L13.021 17.328L13.268 17.318L13.512 17.306L13.753 17.291L13.99 17.275L14.223 17.257L14.454 17.237L14.68 17.215L14.904 17.191L15.124 17.166L15.34 17.139L15.552 17.11L15.762 17.08L15.967 17.048L16.169 17.015L16.367 16.98L16.561 16.944L16.752 16.907L16.939 16.868L17.122 16.829L17.301 16.788L17.476 16.746L17.648 16.703L17.816 16.659L17.979 16.614L18.139 16.569L18.294 16.522L18.446 16.475L18.594 16.427L18.737 16.379L18.876 16.329L19.012 16.28L19.143 16.23L19.269 16.179L19.392 16.128L19.51 16.077L19.624 16.025L19.734 15.973L19.84 15.921L19.941 15.869L20.037 15.817L20.129 15.765L20.217 15.713L20.3 15.661L20.379 15.609L20.453 15.558L20.523 15.506L20.588 15.455L20.648 15.405L20.704 15.354L20.755 15.305L20.778 15.28L20.801 15.256L20.822 15.231L20.842 15.207L20.861 15.183L20.879 15.159L20.896 15.135L20.911 15.112L20.925 15.089L20.938 15.065L20.95 15.043L20.96 15.02L20.97 14.997L20.978 14.975L20.984 14.953L20.99 14.931L20.994 14.91L20.998 14.888L20.999 14.867L21 14.846V10.707L20.923 10.761L20.843 10.815L20.76 10.869L20.675 10.921L20.588 10.974L20.498 11.025L20.405 11.076L20.31 11.127L20.213 11.177L20.113 11.226L20.011 11.275L19.906 11.323L19.8 11.37L19.691 11.417L19.58 11.463L19.466 11.508L19.351 11.552L19.233 11.596L19.113 11.64L18.991 11.682L18.867 11.724L18.741 11.765L18.613 11.805L18.483 11.844L18.351 11.883L18.217 11.921L18.082 11.958L17.944 11.994L17.805 12.03L17.663 12.065L17.52 12.098L17.376 12.131L17.229 12.164L17.081 12.195L16.931 12.225L16.78 12.255L16.627 12.283L16.473 12.311L16.317 12.338L16.159 12.364L16 12.389L15.839 12.413L15.677 12.436L15.514 12.458L15.349 12.479L15.183 12.499L15.016 12.518L14.847 12.536L14.678 12.553L14.507 12.569L14.334 12.584L14.161 12.598L13.986 12.611L13.811 12.623L13.634 12.634L13.456 12.643L13.277 12.652L13.098 12.659L12.917 12.666L12.735 12.671L12.553 12.675L12.369 12.678L12.185 12.68H11.815L11.631 12.678L11.447 12.675L11.265 12.671L11.083 12.666L10.902 12.659L10.723 12.652L10.544 12.643L10.366 12.634L10.19 12.623L10.014 12.611L9.839 12.598L9.666 12.584L9.494 12.569L9.323 12.553L9.153 12.536L8.984 12.518L8.817 12.499L8.651 12.479L8.486 12.458L8.323 12.436L8.161 12.413L8 12.389L7.841 12.364L7.684 12.338L7.528 12.311L7.373 12.283L7.22 12.255L7.069 12.225L6.919 12.195L6.771 12.164L6.625 12.131L6.48 12.098L6.337 12.065L6.196 12.03L6.056 11.994L5.919 11.958L5.783 11.921L5.649 11.883L5.517 11.844L5.387 11.805L5.259 11.765L5.133 11.724L5.009 11.682L4.887 11.639L4.767 11.596L4.65 11.552L4.534 11.508L4.421 11.462L4.309 11.416L4.2 11.37L4.094 11.323L3.989 11.275L3.887 11.226L3.787 11.177L3.69 11.127L3.595 11.076L3.502 11.025L3.412 10.974L3.325 10.921L3.24 10.869L3.157 10.815L3.077 10.761L3 10.707V14.846V14.846ZM3 9.18V9.191L3.001 9.211L3.004 9.233L3.008 9.254L3.013 9.276L3.019 9.297L3.026 9.319L3.035 9.342L3.045 9.364L3.056 9.387L3.068 9.41L3.081 9.433L3.096 9.456L3.112 9.48L3.129 9.504L3.147 9.527L3.166 9.551L3.187 9.576L3.209 9.6L3.232 9.624L3.256 9.649L3.308 9.699L3.364 9.749L3.425 9.799L3.491 9.85L3.561 9.901L3.636 9.953L3.715 10.004L3.799 10.056L3.887 10.108L3.979 10.16L4.076 10.212L4.178 10.264L4.283 10.315L4.393 10.367L4.507 10.418L4.626 10.469L4.749 10.52L4.876 10.57L5.007 10.62L5.142 10.67L5.281 10.719L5.425 10.767L5.572 10.815L5.724 10.862L5.879 10.908L6.039 10.953L6.202 10.998L6.369 11.041L6.54 11.084L6.716 11.126L6.894 11.166L7.077 11.206L7.264 11.244L7.454 11.281L7.648 11.317L7.845 11.351L8.047 11.384L8.251 11.416L8.46 11.446L8.672 11.474L8.888 11.501L9.107 11.526L9.329 11.55L9.555 11.571L9.785 11.591L10.018 11.609L10.254 11.626L10.494 11.64L10.737 11.652L10.983 11.662L11.232 11.67L11.485 11.676L11.741 11.679L12 11.68L12.26 11.679L12.517 11.676L12.771 11.67L13.021 11.662L13.268 11.652L13.512 11.639L13.753 11.625L13.99 11.609L14.223 11.591L14.454 11.571L14.68 11.549L14.904 11.525L15.124 11.5L15.34 11.473L15.552 11.444L15.762 11.414L15.967 11.382L16.169 11.349L16.367 11.314L16.561 11.278L16.752 11.241L16.939 11.202L17.122 11.163L17.301 11.122L17.476 11.08L17.648 11.037L17.816 10.993L17.979 10.948L18.139 10.903L18.294 10.856L18.446 10.809L18.594 10.761L18.737 10.712L18.876 10.663L19.012 10.614L19.143 10.563L19.269 10.513L19.392 10.462L19.51 10.41L19.624 10.359L19.734 10.307L19.84 10.255L19.941 10.203L20.037 10.151L20.129 10.099L20.217 10.047L20.3 9.995L20.379 9.943L20.453 9.891L20.523 9.84L20.588 9.789L20.648 9.738L20.704 9.688L20.755 9.639L20.778 9.614L20.801 9.589L20.822 9.565L20.842 9.541L20.861 9.517L20.879 9.493L20.896 9.469L20.911 9.446L20.925 9.422L20.938 9.399L20.95 9.376L20.96 9.354L20.97 9.331L20.978 9.309L20.984 9.287L20.99 9.265L20.994 9.243L20.998 9.222L20.999 9.201L21 9.18V5.027L20.923 5.081L20.843 5.135L20.76 5.188L20.675 5.241L20.588 5.294L20.498 5.345L20.405 5.396L20.31 5.447L20.213 5.497L20.113 5.546L20.011 5.594L19.906 5.642L19.8 5.69L19.691 5.736L19.58 5.782L19.466 5.828L19.351 5.872L19.233 5.916L19.113 5.959L18.991 6.002L18.867 6.044L18.741 6.085L18.613 6.125L18.483 6.164L18.351 6.203L18.217 6.241L18.082 6.278L17.944 6.314L17.805 6.35L17.663 6.384L17.52 6.418L17.376 6.451L17.229 6.483L17.081 6.515L16.931 6.545L16.78 6.575L16.627 6.603L16.473 6.631L16.317 6.658L16.159 6.684L16 6.708L15.839 6.732L15.677 6.755L15.514 6.778L15.349 6.799L15.183 6.819L15.016 6.838L14.847 6.856L14.678 6.873L14.507 6.889L14.334 6.904L14.161 6.918L13.986 6.931L13.811 6.943L13.634 6.953L13.456 6.963L13.277 6.972L13.098 6.979L12.917 6.985L12.735 6.991L12.553 6.995L12.369 6.998L12.185 6.999L12 7L11.815 6.999L11.631 6.998L11.447 6.995L11.265 6.991L11.083 6.985L10.902 6.979L10.723 6.972L10.544 6.963L10.366 6.953L10.19 6.943L10.014 6.931L9.839 6.918L9.666 6.904L9.494 6.889L9.323 6.873L9.153 6.856L8.984 6.838L8.817 6.819L8.651 6.799L8.486 6.778L8.323 6.755L8.161 6.732L8 6.708L7.841 6.684L7.684 6.658L7.528 6.631L7.373 6.603L7.22 6.575L7.069 6.545L6.919 6.515L6.771 6.483L6.625 6.451L6.48 6.418L6.337 6.384L6.196 6.35L6.056 6.314L5.919 6.278L5.783 6.241L5.649 6.203L5.517 6.164L5.387 6.125L5.259 6.084L5.133 6.043L5.009 6.002L4.887 5.959L4.767 5.916L4.65 5.872L4.534 5.828L4.421 5.782L4.309 5.736L4.2 5.69L4.094 5.642L3.989 5.594L3.887 5.546L3.787 5.496L3.69 5.447L3.595 5.396L3.502 5.345L3.412 5.293L3.325 5.241L3.24 5.188L3.157 5.135L3.077 5.081L3 5.027V9.18V9.18ZM11.74 1.001L11.483 1.005L11.229 1.01L10.979 1.018L10.732 1.029L10.488 1.041L10.247 1.055L10.01 1.071L9.777 1.089L9.546 1.11L9.32 1.132L9.096 1.155L8.876 1.181L8.66 1.208L8.448 1.236L8.238 1.267L8.033 1.299L7.831 1.332L7.633 1.366L7.439 1.402L7.248 1.44L7.061 1.478L6.878 1.518L6.699 1.559L6.524 1.601L6.352 1.644L6.184 1.687L6.021 1.732L5.861 1.778L5.706 1.824L5.554 1.872L5.406 1.92L5.263 1.968L5.124 2.017L4.988 2.067L4.857 2.117L4.731 2.168L4.608 2.219L4.49 2.27L4.376 2.322L4.266 2.374L4.16 2.426L4.059 2.478L3.963 2.53L3.871 2.582L3.783 2.634L3.7 2.686L3.621 2.738L3.547 2.789L3.477 2.841L3.412 2.892L3.352 2.942L3.296 2.992L3.245 3.042L3.222 3.067L3.199 3.091L3.178 3.115L3.158 3.14L3.139 3.164L3.121 3.188L3.104 3.211L3.089 3.235L3.075 3.258L3.062 3.281L3.05 3.304L3.04 3.327L3.03 3.349L3.022 3.371L3.016 3.394L3.01 3.415L3.006 3.437L3.002 3.458L3.001 3.479L3 3.5L3.001 3.521L3.002 3.542L3.006 3.563L3.01 3.585L3.016 3.606L3.022 3.629L3.03 3.651L3.04 3.673L3.05 3.696L3.062 3.719L3.075 3.742L3.089 3.765L3.104 3.789L3.121 3.812L3.139 3.836L3.158 3.86L3.178 3.885L3.199 3.909L3.222 3.933L3.245 3.958L3.296 4.008L3.352 4.058L3.412 4.108L3.477 4.159L3.547 4.211L3.621 4.262L3.7 4.314L3.783 4.366L3.871 4.418L3.963 4.47L4.059 4.522L4.16 4.574L4.266 4.626L4.376 4.678L4.49 4.73L4.608 4.781L4.731 4.832L4.857 4.883L4.988 4.933L5.124 4.983L5.263 5.032L5.406 5.08L5.554 5.128L5.706 5.176L5.861 5.222L6.021 5.268L6.184 5.313L6.352 5.356L6.524 5.399L6.699 5.441L6.878 5.482L7.061 5.522L7.248 5.56L7.439 5.598L7.633 5.634L7.831 5.668L8.033 5.701L8.238 5.733L8.448 5.764L8.66 5.792L8.876 5.819L9.096 5.845L9.32 5.868L9.546 5.89L9.777 5.911L10.01 5.929L10.247 5.945L10.488 5.959L10.732 5.971L10.979 5.982L11.229 5.99L11.483 5.995L11.74 5.999L12 6L12.26 5.999L12.517 5.995L12.771 5.99L13.021 5.982L13.268 5.971L13.512 5.959L13.753 5.945L13.99 5.929L14.223 5.911L14.454 5.89L14.68 5.868L14.904 5.845L15.124 5.819L15.34 5.792L15.552 5.764L15.762 5.733L15.967 5.701L16.169 5.668L16.367 5.634L16.561 5.598L16.752 5.56L16.939 5.522L17.122 5.482L17.301 5.441L17.476 5.399L17.648 5.356L17.816 5.313L17.979 5.268L18.139 5.222L18.294 5.176L18.446 5.128L18.594 5.08L18.737 5.032L18.876 4.983L19.012 4.933L19.143 4.883L19.269 4.832L19.392 4.781L19.51 4.73L19.624 4.678L19.734 4.626L19.84 4.574L19.941 4.522L20.037 4.47L20.129 4.418L20.217 4.366L20.3 4.314L20.379 4.262L20.453 4.211L20.523 4.159L20.588 4.108L20.648 4.058L20.704 4.008L20.755 3.958L20.778 3.933L20.801 3.909L20.822 3.885L20.842 3.86L20.861 3.836L20.879 3.812L20.896 3.789L20.911 3.765L20.925 3.742L20.938 3.719L20.95 3.696L20.96 3.673L20.97 3.651L20.978 3.629L20.984 3.606L20.99 3.585L20.994 3.563L20.998 3.542L20.999 3.521L21 3.5L20.999 3.479L20.998 3.458L20.994 3.437L20.99 3.415L20.984 3.394L20.978 3.371L20.97 3.349L20.96 3.327L20.95 3.304L20.938 3.281L20.925 3.258L20.911 3.235L20.896 3.211L20.879 3.188L20.861 3.164L20.842 3.14L20.822 3.115L20.801 3.091L20.778 3.067L20.755 3.042L20.704 2.992L20.648 2.942L20.588 2.892L20.523 2.841L20.453 2.789L20.379 2.738L20.3 2.686L20.217 2.634L20.129 2.582L20.037 2.53L19.941 2.478L19.84 2.426L19.734 2.374L19.624 2.322L19.51 2.27L19.392 2.219L19.269 2.168L19.143 2.117L19.012 2.067L18.876 2.017L18.737 1.968L18.594 1.92L18.446 1.872L18.294 1.824L18.139 1.778L17.979 1.732L17.816 1.687L17.648 1.644L17.476 1.601L17.301 1.559L17.122 1.518L16.939 1.478L16.752 1.44L16.561 1.402L16.367 1.366L16.169 1.332L15.967 1.299L15.762 1.267L15.552 1.236L15.34 1.208L15.124 1.181L14.904 1.155L14.68 1.132L14.454 1.11L14.223 1.089L13.99 1.071L13.753 1.055L13.512 1.041L13.268 1.029L13.021 1.018L12.771 1.01L12.517 1.005L12.26 1.001L12 1L11.74 1.001V1.001Z\" fill=\"currentColor\"/>\n</svg>\n";
12602
+ const DatabaseSvg = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <ellipse cx=\"12\" cy=\"4.5\" rx=\"9.75\" ry=\"2.75\" stroke=\"currentColor\" stroke-width=\"1\"/>\n <path d=\"M2.25 4.5v15a9.75 2.75 0 0 0 19.5 0v-15\" stroke=\"currentColor\" stroke-width=\"1\"/>\n <path d=\"M2.25 9.5a9.75 2.75 0 0 0 19.5 0\" stroke=\"currentColor\" stroke-width=\"1\"/>\n <path d=\"M2.25 14.5a9.75 2.75 0 0 0 19.5 0\" stroke=\"currentColor\" stroke-width=\"1\"/>\n</svg>\n";
12483
12603
 
12484
- const EntitySvg = "<svg width=\"77\" height=\"80\" viewBox=\"0 0 77 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t<g>\n\t\t<path d=\"M74.0149 38.8888C74.0149 43.5755 73.0918 48.2163 71.2983 52.5463C69.5048 56.8762 66.876 60.8105 63.562 64.1245C60.248 67.4385 56.3137 70.0673 51.9838 71.8608C47.6538 73.6543 43.013 74.5774 38.3263 74.5774C33.6396 74.5774 28.9988 73.6543 24.6689 71.8608C20.3389 70.0673 16.4046 67.4385 13.0907 64.1245C9.77666 60.8105 7.14785 56.8762 5.35433 52.5463C3.56081 48.2163 2.6377 43.5755 2.6377 38.8888C2.6377 34.2021 3.56081 29.5613 5.35433 25.2314C7.14785 20.9014 9.77666 16.9671 13.0907 13.6532C16.4046 10.3392 20.3389 7.71035 24.6689 5.91683C28.9988 4.12331 33.6396 3.2002 38.3263 3.2002C43.013 3.2002 47.6538 4.12331 51.9838 5.91683C56.3137 7.71035 60.248 10.3392 63.562 13.6532C66.876 16.9671 69.5048 20.9014 71.2983 25.2314C73.0918 29.5613 74.0149 34.2021 74.0149 38.8888V38.8888Z\" stroke=\"currentColor\" stroke-width=\"4.98203\"/>\n\t\t<path d=\"M2.69922 75.4727L75.6992 75.5154\" stroke=\"currentColor\" stroke-width=\"4\"/>\n\t</g>\n</svg>\n";
12604
+ const EntitySvg = "<svg width=\"77\" height=\"80\" viewBox=\"0 0 77 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t<g>\n\t\t<path d=\"M74.0149 38.8888C74.0149 43.5755 73.0918 48.2163 71.2983 52.5463C69.5048 56.8762 66.876 60.8105 63.562 64.1245C60.248 67.4385 56.3137 70.0673 51.9838 71.8608C47.6538 73.6543 43.013 74.5774 38.3263 74.5774C33.6396 74.5774 28.9988 73.6543 24.6689 71.8608C20.3389 70.0673 16.4046 67.4385 13.0907 64.1245C9.77666 60.8105 7.14785 56.8762 5.35433 52.5463C3.56081 48.2163 2.6377 43.5755 2.6377 38.8888C2.6377 34.2021 3.56081 29.5613 5.35433 25.2314C7.14785 20.9014 9.77666 16.9671 13.0907 13.6532C16.4046 10.3392 20.3389 7.71035 24.6689 5.91683C28.9988 4.12331 33.6396 3.2002 38.3263 3.2002C43.013 3.2002 47.6538 4.12331 51.9838 5.91683C56.3137 7.71035 60.248 10.3392 63.562 13.6532C66.876 16.9671 69.5048 20.9014 71.2983 25.2314C73.0918 29.5613 74.0149 34.2021 74.0149 38.8888V38.8888Z\" stroke=\"currentColor\" stroke-width=\"3.3333\"/>\n\t\t<path d=\"M2.69922 75.4727L75.6992 75.5154\" stroke=\"currentColor\" stroke-width=\"3.3333\"/>\n\t</g>\n</svg>\n";
12485
12605
 
12486
12606
  const Ec2Svg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"48px\" height=\"48px\" viewBox=\"0 0 48 48\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <title>Icon-Resource/Compute/Res_Amazon-EC2_Instance_48</title>\n <g id=\"Icon-Resource/Compute/Res_Amazon-EC2_Instance_48\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path d=\"M9,39 L39,39 L39,9 L9,9 L9,39 Z M46,13 L46,11 L41,11 L41,8 C41,7.448 40.552,7 40,7 L37,7 L37,2 L35,2 L35,7 L31,7 L31,2 L29,2 L29,7 L25,7 L25,2 L23,2 L23,7 L19,7 L19,2 L17,2 L17,7 L13,7 L13,2 L11,2 L11,7 L8,7 C7.447,7 7,7.448 7,8 L7,11 L2,11 L2,13 L7,13 L7,17 L2,17 L2,19 L7,19 L7,23 L2,23 L2,25 L7,25 L7,29 L2,29 L2,31 L7,31 L7,35 L2,35 L2,37 L7,37 L7,40 C7,40.553 7.447,41 8,41 L11,41 L11,46 L13,46 L13,41 L17,41 L17,46 L19,46 L19,41 L23,41 L23,46 L25,46 L25,41 L29,41 L29,46 L31,46 L31,41 L35,41 L35,46 L37,46 L37,41 L40,41 C40.552,41 41,40.553 41,40 L41,37 L46,37 L46,35 L41,35 L41,31 L46,31 L46,29 L41,29 L41,25 L46,25 L46,23 L41,23 L41,19 L46,19 L46,17 L41,17 L41,13 L46,13 Z\" id=\"Amazon-EC2-Instance_Resource-Icon_light-bg\" fill=\"#ED7100\"></path>\n </g>\n</svg>\n";
12487
12607
 
@@ -12550,7 +12670,7 @@ function styleToAttr(style) {
12550
12670
  return Object.entries(style).map(([k, v]) => `${esc(k)}: ${esc(v)}`).join("; ");
12551
12671
  }
12552
12672
 
12553
- const STROKE_WIDTH$1 = 2;
12673
+ const STROKE_WIDTH$1 = 1;
12554
12674
  const HALF_STROKE$1 = STROKE_WIDTH$1 / 2;
12555
12675
  const ICON_SIZE = 24;
12556
12676
  const ICON_MARGIN_RIGHT = 4;
@@ -12558,12 +12678,12 @@ const ICON_PAINT_OFFSET_X = 4;
12558
12678
  const LABEL_PAD_LEFT = 8;
12559
12679
  const LABEL_HORIZONTAL_PADDING = 16;
12560
12680
  const STEREOTYPE_VERTICAL_OFFSET = 8;
12561
- const STEREOTYPE_FONT_SIZE = 16;
12681
+ const STEREOTYPE_FONT_SIZE = 14;
12562
12682
  const BOUNDARY_ICON_VERTICAL_TWEAK = 2.75;
12563
12683
  const PARTICIPANT_TEXT_FILL = "#222";
12564
12684
  function renderParticipant(p) {
12565
12685
  if (p.isStarter) return renderStarterParticipant(p);
12566
- const rx = 3;
12686
+ const rx = 4 - HALF_STROKE$1;
12567
12687
  const x = p.x - p.width / 2 + HALF_STROKE$1;
12568
12688
  const rectY = p.y + HALF_STROKE$1;
12569
12689
  const rectW = p.width - STROKE_WIDTH$1;
@@ -12632,7 +12752,7 @@ function renderStarterParticipant(p) {
12632
12752
  if (!icon) {
12633
12753
  return "";
12634
12754
  }
12635
- const rx = 3;
12755
+ const rx = 4 - HALF_STROKE$1;
12636
12756
  const boxX = p.x - p.width / 2 + HALF_STROKE$1;
12637
12757
  const rectY = p.y + HALF_STROKE$1;
12638
12758
  const rectW = p.width - STROKE_WIDTH$1;
@@ -12672,21 +12792,31 @@ function renderLifeline(l) {
12672
12792
  return `<line x1="${x}" y1="${l.topY}" x2="${x}" y2="${l.bottomY}" class="lifeline" stroke-dasharray="${l.dashed ? "5,5" : "none"}" stroke-dashoffset="${l.dashed ? "5" : "0"}" shape-rendering="crispEdges"/>`;
12673
12793
  }
12674
12794
 
12795
+ function messageNumberWidth(number) {
12796
+ return measureTextWithFont(number, "12px") + 8;
12797
+ }
12798
+ function renderMessageNumber(number, right, baseline) {
12799
+ if (!number) return "";
12800
+ return `<rect x="${right - messageNumberWidth(number)}" y="${baseline - 12}" width="${messageNumberWidth(number)}" height="16" rx="2" class="message-number-bg"/>
12801
+ <text x="${right - 4}" y="${baseline}" text-anchor="end" class="seq-number">${esc(number)}</text>`;
12802
+ }
12803
+
12675
12804
  function renderMessage(m) {
12676
12805
  const isLTR = m.fromX < m.toX;
12677
12806
  const fromX = isLTR ? m.fromX + 1 : m.fromX;
12678
12807
  const toX = isLTR ? m.toX : m.toX + 1;
12679
12808
  const direction = Math.sign(m.toX - m.fromX);
12680
12809
  const labelX = (m.fromX + m.toX) / 2 - direction * 3.5 + 0.5;
12681
- const labelY = m.y - 3.5;
12810
+ const labelY = m.y - 2.5;
12682
12811
  const dashAttr = m.arrowStyle === "dashed" ? ' stroke-dasharray="6,4"' : "";
12683
12812
  const styleAttr = m.style ? ` style="${styleToAttr(m.style)}"` : "";
12684
12813
  const numberX = Math.min(fromX, toX) - 4;
12685
- const numberSvg = m.number ? `<text x="${numberX}" y="${labelY}" text-anchor="end" class="seq-number">${esc(m.number)}</text>` : "";
12686
- const lineY = m.y - 0.5;
12814
+ const numberSvg = renderMessageNumber(m.number, numberX, m.y - 3.5);
12815
+ const headCenterY = m.y - 0.5;
12816
+ const lineY = headCenterY + 0.5;
12687
12817
  return `<g class="message">
12688
12818
  <line x1="${fromX}" y1="${lineY}" x2="${toX}" y2="${lineY}" class="message-line"${dashAttr}/>
12689
- ${renderArrowHead(toX, lineY, m.isReverse, m.arrowStyle)}
12819
+ ${renderArrowHead(toX, headCenterY, m.isReverse, m.arrowStyle)}
12690
12820
  <text x="${labelX}" y="${labelY}" text-anchor="middle" class="message-label"${styleAttr}>${esc(resolveEmojiInText(m.label))}</text>
12691
12821
  ${numberSvg}
12692
12822
  </g>`;
@@ -12697,7 +12827,7 @@ function renderSelfCall(s) {
12697
12827
  const labelX = x1 + 6;
12698
12828
  const labelY = s.y + (isAsync ? 15 : 12);
12699
12829
  const numberY = s.y + 12;
12700
- const numberSvg = s.number ? `<text x="${x1 - 3}" y="${numberY}" text-anchor="end" class="seq-number">${esc(s.number)}</text>` : "";
12830
+ const numberSvg = renderMessageNumber(s.number, x1 - 3, numberY);
12701
12831
  const svgX = x1 + 1;
12702
12832
  const svgY = s.y + (isAsync ? 20 : 14);
12703
12833
  const pathEnd = isAsync ? "L1,15" : "L14,15";
@@ -12706,11 +12836,11 @@ function renderSelfCall(s) {
12706
12836
  const arrowPath = isAsync ? "M1 1.25 L6.15 4.5 L1 7.75" : "M1 1.25 L6.15 4.5 L1 7.75 Z";
12707
12837
  return `<g class="message self-call">
12708
12838
  <svg x="${svgX}" y="${svgY}" width="30" height="24">
12709
- <path d="M0,2 L26,2 Q28,2 28,4 L28,13 Q28,15 26,15 ${pathEnd}" fill="none" stroke="#000" stroke-width="2"/>
12839
+ <path d="M0,2 L26,2 Q28,2 28,4 L28,13 Q28,15 26,15 ${pathEnd}" fill="none" stroke="#000" stroke-width="1"/>
12710
12840
  <g transform="translate(${arrowTx}, 10)">
12711
12841
  <svg height="10" width="7" viewBox="0 0 7 9">
12712
12842
  <g transform="scale(-1, 1) translate(-7, 0)">
12713
- <path d="${arrowPath}" stroke="#000" stroke-linecap="round" fill="${arrowFill}" stroke-width="2"/>
12843
+ <path d="${arrowPath}" stroke="#000" stroke-linecap="round" fill="${arrowFill}" stroke-width="1"/>
12714
12844
  </g>
12715
12845
  </svg>
12716
12846
  </g>
@@ -12728,96 +12858,125 @@ function renderArrowHead(tipX, tipY, pointsLeft, style) {
12728
12858
  const rtlTransform = pointsLeft ? ' transform="scale(-1, 1) translate(-7, 0)"' : "";
12729
12859
  return `<svg x="${svgX}" y="${svgY}" width="7" height="10" viewBox="0 0 7 9" overflow="visible" class="arrow-head${isFilled ? "" : " arrow-open"}">
12730
12860
  <g${rtlTransform}>
12731
- <path d="${pathD}" stroke="#000" stroke-linecap="round" stroke-width="2" fill="${fillAttr}"/>
12861
+ <path d="${pathD}" transform="translate(1 0.5)" stroke="#000" stroke-linecap="round" stroke-width="1" fill="${fillAttr}"/>
12732
12862
  </g>
12733
12863
  </svg>`;
12734
12864
  }
12735
12865
 
12736
12866
  function renderOccurrence(o) {
12737
- const strokeHalf = 1;
12867
+ const strokeHalf = 0.5;
12738
12868
  const rx = o.x + strokeHalf;
12739
- return `<rect x="${rx}" y="${o.y + strokeHalf}" width="${o.width - strokeHalf * 2}" height="${o.height - strokeHalf * 2}" rx="1" class="occurrence" data-participant="${esc(o.participantName)}"/>`;
12869
+ return `<rect x="${rx}" y="${o.y + strokeHalf}" width="${o.width - strokeHalf * 2}" height="${o.height - strokeHalf * 2}" rx="1.5" class="occurrence" data-participant="${esc(o.participantName)}"/>`;
12740
12870
  }
12741
12871
 
12742
12872
  const HEADER_HEIGHT = DEFAULT_LAYOUT_METRICS.fragmentHeaderHeight;
12743
- const BRACKET_WIDTH = 3.89;
12873
+ const SMALL_CAPS_OPTICAL_LIFT = 1.5;
12874
+ const NUMBER_OPTICAL_LIFT = 0.5;
12744
12875
  const TEXT_PAD_X = 4;
12876
+ const NUMBER_PAD_X = 4;
12745
12877
  const STROKE_WIDTH = 1;
12746
12878
  const HALF_STROKE = STROKE_WIDTH / 2;
12747
12879
  function renderFragment(f) {
12748
12880
  const parts = [];
12881
+ const kindLabel = f.headerLabel ?? fragmentHeaderLabel(f.kind);
12882
+ const width = Math.max(f.width, fragmentHeaderWidth(kindLabel, f.number));
12749
12883
  parts.push(
12750
- `<rect x="${f.x + HALF_STROKE}" y="${f.y + HALF_STROKE}" width="${f.width - STROKE_WIDTH}" height="${f.height - STROKE_WIDTH}" rx="4" class="fragment-border"/>`
12884
+ `<rect x="${f.x + HALF_STROKE}" y="${f.y + HALF_STROKE}" width="${width - STROKE_WIDTH}" height="${f.height - STROKE_WIDTH}" rx="${4 - HALF_STROKE}" class="fragment-border"/>`
12751
12885
  );
12752
12886
  const headerX = f.x + 1;
12753
12887
  const headerY = f.headerY;
12754
- const headerW = f.width - 2;
12888
+ const headerW = width - 2;
12755
12889
  parts.push(
12756
- `<rect x="${headerX}" y="${headerY}" width="${headerW}" height="${HEADER_HEIGHT}" class="fragment-header"/>`
12890
+ `<rect x="${headerX}" y="${headerY}" width="${headerW}" height="${HEADER_HEIGHT}" class="fragment-header"${f.kind === "opt" ? "" : ' style="clip-path: inset(0 round 4px 4px 0 0)"'}/>`
12757
12891
  );
12758
- const iconX = headerX + 4;
12892
+ const numberWidth = f.number ? Math.ceil(measureTextWithFont(f.number, "12px") * 64) / 64 : 0;
12893
+ const numberInset = f.number ? numberWidth + 14 : 0;
12894
+ const titleY = headerY + HEADER_HEIGHT / 2 - 0.5;
12895
+ if (f.number) {
12896
+ const numberBoxX = headerX + 4;
12897
+ const numberX = numberBoxX + NUMBER_PAD_X;
12898
+ parts.push(
12899
+ `<rect x="${numberBoxX}" y="${headerY + (HEADER_HEIGHT - 1 - 16) / 2}" width="${numberWidth + NUMBER_PAD_X * 2}" height="16" rx="2" class="fragment-number-bg"/>`,
12900
+ `<text x="${numberX}" y="${titleY - NUMBER_OPTICAL_LIFT}" dominant-baseline="central" class="seq-number">${esc(f.number)}</text>`
12901
+ );
12902
+ }
12903
+ const iconX = headerX + 4 + numberInset;
12759
12904
  const iconY = headerY;
12760
12905
  parts.push(getFragmentIcon(f.kind, iconX, iconY));
12761
- const kindLabel = getKindLabel(f.kind);
12762
- const labelX = headerX + 26;
12906
+ const labelX = headerX + 26 + numberInset;
12907
+ const labelY = titleY - SMALL_CAPS_OPTICAL_LIFT;
12763
12908
  parts.push(
12764
- `<text x="${labelX}" y="${headerY + HEADER_HEIGHT / 2 - 0.5}" dominant-baseline="central" class="fragment-label">${esc(kindLabel)}</text>`
12909
+ `<text x="${labelX}" y="${labelY}" dominant-baseline="central" class="fragment-label">${esc(kindLabel)}</text>`
12765
12910
  );
12766
- if (f.number) {
12911
+ if (f.label) {
12767
12912
  parts.push(
12768
- `<text x="${f.x - 3}" y="${headerY + HEADER_HEIGHT / 2 - 4.5}" text-anchor="end" dominant-baseline="central" class="seq-number">${esc(f.number)}</text>`
12913
+ renderGuardRow(
12914
+ headerX,
12915
+ headerY + HEADER_HEIGHT,
12916
+ f.label,
12917
+ fragmentGuardKeyword(f.kind, f.guardKeyword)
12918
+ )
12769
12919
  );
12770
12920
  }
12771
- if (f.label) {
12772
- const condY = headerY + HEADER_HEIGHT + 15;
12773
- parts.push(renderBracketedLabel(headerX, condY, f.label, f.labelWidth, "fragment-condition"));
12774
- }
12775
12921
  if (f.sections.length > 1) {
12776
12922
  for (let i = 1; i < f.sections.length; i++) {
12777
12923
  const section = f.sections[i];
12778
12924
  const lineY = section.y;
12779
12925
  const separatorY = lineY + HALF_STROKE;
12780
12926
  const sepX1 = f.x + 1 + (section.contentInsetLeft ?? 0);
12781
- const sepX2 = f.x + f.width - 1;
12927
+ const sepX2 = f.x + width - 1;
12782
12928
  parts.push(
12783
12929
  `<line x1="${sepX1}" y1="${separatorY}" x2="${sepX2}" y2="${separatorY}" class="fragment-separator"/>`
12784
12930
  );
12785
12931
  if (section.label) {
12786
- const labelY = lineY + 16;
12932
+ if (f.kind === "alt") {
12933
+ parts.push(
12934
+ renderGuardRow(
12935
+ f.x + 1,
12936
+ lineY + 1,
12937
+ section.innerLabel ?? "",
12938
+ section.guardKeyword
12939
+ )
12940
+ );
12941
+ continue;
12942
+ }
12943
+ const labelY2 = lineY + 16;
12787
12944
  const isFinally = section.label.startsWith("finally");
12788
12945
  const isBracketed = !!section.innerLabel && section.label !== "[else]";
12789
12946
  if (isBracketed) {
12790
12947
  const labelX2 = f.x + 1;
12791
- parts.push(
12792
- renderBracketedLabel(labelX2, labelY, section.innerLabel, section.innerLabelWidth, "fragment-section-label")
12793
- );
12948
+ parts.push(renderGuardRow(labelX2, lineY + 1, section.innerLabel));
12794
12949
  continue;
12795
12950
  }
12796
12951
  const spaceIdx = section.label.indexOf(" ");
12797
12952
  if (spaceIdx > 0 && !isFinally) {
12798
12953
  const keyword = section.keyword || section.label.substring(0, spaceIdx);
12799
12954
  const condition = section.detail || section.label.substring(spaceIdx + 1);
12800
- const keywordWidth = section.keywordWidth ?? keyword.length * 7;
12955
+ const keywordWidth = measureTextWithFont(
12956
+ keyword,
12957
+ "14px",
12958
+ "all-small-caps"
12959
+ );
12801
12960
  const keywordX = f.x + 5;
12802
12961
  const conditionX = keywordX + keywordWidth + TEXT_PAD_X * 2;
12803
- const bgWidth = (section.keywordWidth ?? keyword.length * 7) + (section.detailWidth ?? condition.length * 7) + TEXT_PAD_X * 4;
12962
+ const bgWidth = keywordWidth + (section.detailWidth ?? condition.length * 7) + TEXT_PAD_X * 4;
12804
12963
  parts.push(
12805
- `<g opacity="0.65"><rect x="${keywordX - TEXT_PAD_X}" y="${lineY + 1}" width="${bgWidth}" height="20" fill="#fff"/><text x="${keywordX}" y="${labelY}" class="fragment-section-label" fill="#222">${esc(keyword)}</text><text x="${conditionX}" y="${labelY}" class="fragment-section-label" fill="#222">${esc(condition)}</text></g>`
12964
+ `<g opacity="0.65"><rect x="${keywordX - TEXT_PAD_X}" y="${lineY + 1}" width="${bgWidth}" height="20" fill="#fff"/><text x="${keywordX}" y="${labelY2}" class="fragment-section-label fragment-section-keyword" fill="#222">${esc(keyword)}</text><text x="${conditionX}" y="${labelY2}" class="fragment-section-label" fill="#222">${esc(condition)}</text></g>`
12806
12965
  );
12807
12966
  } else {
12808
12967
  const finallyX = f.x + 5;
12809
- const finallyY = labelY;
12968
+ const finallyY = labelY2;
12810
12969
  if (section.label === "[else]") {
12811
12970
  parts.push(
12812
- `<text x="${finallyX}" y="${finallyY}" class="fragment-section-label">${esc(section.label)}</text>`
12971
+ `<text x="${finallyX}" y="${finallyY}" class="fragment-section-label fragment-section-keyword">${esc(section.label)}</text>`
12813
12972
  );
12814
12973
  continue;
12815
12974
  }
12816
- const bgWidth = (section.labelWidth ?? section.label.length * 7) + TEXT_PAD_X * 2;
12975
+ const bgWidth = (isFinally ? measureTextWithFont(section.label, "14px", "all-small-caps") : section.labelWidth ?? section.label.length * 7) + TEXT_PAD_X * 2;
12817
12976
  const bgY = lineY + 1;
12818
12977
  const bgHeight = 20;
12819
12978
  parts.push(
12820
- `<g opacity="0.65"><rect x="${finallyX - TEXT_PAD_X}" y="${bgY}" width="${bgWidth}" height="${bgHeight}" fill="#fff"/><text x="${finallyX}" y="${finallyY}" class="fragment-section-label">${esc(section.label)}</text></g>`
12979
+ `<g opacity="0.65"><rect x="${finallyX - TEXT_PAD_X}" y="${bgY}" width="${bgWidth}" height="${bgHeight}" fill="#fff"/><text x="${finallyX}" y="${finallyY}" class="fragment-section-label fragment-section-keyword">${esc(section.label)}</text></g>`
12821
12980
  );
12822
12981
  }
12823
12982
  }
@@ -12827,33 +12986,11 @@ function renderFragment(f) {
12827
12986
  ${parts.join("\n ")}
12828
12987
  </g>`;
12829
12988
  }
12830
- function renderBracketedLabel(x, y, innerText, innerWidth, cls = "fragment-condition") {
12831
- const measuredInnerWidth = innerWidth ?? innerText.length * 7;
12832
- const innerX = x + BRACKET_WIDTH + TEXT_PAD_X;
12833
- const closeX = innerX + measuredInnerWidth + TEXT_PAD_X;
12834
- return `<g><text x="${x}" y="${y}" class="${cls}">[</text><text x="${innerX}" y="${y}" class="${cls}" opacity="0.65">${esc(resolveEmojiInText(innerText))}</text><text x="${closeX}" y="${y}" class="${cls}">]</text></g>`;
12835
- }
12836
- function getKindLabel(kind) {
12837
- switch (kind) {
12838
- case "alt":
12839
- return "Alt";
12840
- case "loop":
12841
- return "Loop";
12842
- case "opt":
12843
- return "Opt";
12844
- case "par":
12845
- return "Par";
12846
- case "critical":
12847
- return "Critical";
12848
- case "section":
12849
- return "Section";
12850
- case "tcf":
12851
- return "Try";
12852
- case "ref":
12853
- return "Ref";
12854
- default:
12855
- return kind.charAt(0).toUpperCase() + kind.slice(1);
12856
- }
12989
+ function renderGuardRow(x, rowY, innerText, keyword) {
12990
+ const baseline = rowY + 19;
12991
+ const textX = x + 4;
12992
+ const conditionX = textX + (keyword ? measureTextWithFont(keyword, "12px", "all-small-caps") + 4 : 0);
12993
+ return `<g class="guard-row">` + (keyword ? `<text x="${textX}" y="${baseline}" class="guard-keyword">${esc(keyword)}</text>` : "") + (innerText ? `<text x="${conditionX}" y="${baseline}" class="fragment-condition" opacity="0.65">${esc(resolveEmojiInText(innerText))}</text>` : "") + `</g>`;
12857
12994
  }
12858
12995
  function getFragmentIcon(kind, x, y) {
12859
12996
  const w = 20;
@@ -12879,7 +13016,7 @@ function getFragmentIcon(kind, x, y) {
12879
13016
  <path d="M12 15V15.5" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
12880
13017
  </svg>`;
12881
13018
  case "tcf":
12882
- return `<svg x="${x}" y="${y}" width="${w}" height="${h}" viewBox="0 0 76 76" fill="#000" stroke="none">
13019
+ return `<svg x="${x}" y="${y}" width="${w}" height="${h}" viewBox="0 3 76 76" fill="#000" stroke="none">
12883
13020
  <path d="M 26,22.0001L 27,21.9998L 27,27L 26.0001,27.0003C 23.2386,27.0003 21.0001,29.2389 21.0001,32.0003L 21,46.0002C 21,48.7616 23.2386,51.0002 25.9999,51.0002L 27,51.0002L 27,47L 33.75,53.5L 27,60L 27,56L 26,56C 20.4771,56 16,51.5229 16,46L 16,32.0001C 16,26.4773 20.4771,22.0001 26,22.0001 Z M 33,27L 59,27L 59,32L 33,32L 33,27 Z M 36,35L 59,35L 59,40L 36,40L 36,35 Z M 33,43L 59,43L 59,48L 33,48L 33,43 Z"/>
12884
13021
  </svg>`;
12885
13022
  case "ref":
@@ -12937,7 +13074,7 @@ function renderOpenArrow(tipX, tipY, pointsLeft) {
12937
13074
  const x1 = tipX + dir * w;
12938
13075
  const y1 = tipY - halfH;
12939
13076
  const y2 = tipY + halfH;
12940
- return `<polyline points="${x1},${y1} ${tipX},${tipY} ${x1},${y2}" fill="none" stroke-linecap="round" class="arrow-head arrow-open"/>`;
13077
+ return `<polyline points="${x1},${y1} ${tipX},${tipY} ${x1},${y2}" transform="translate(${pointsLeft ? -1 : 1} 0)" fill="none" stroke-linecap="round" class="arrow-head arrow-open"/>`;
12941
13078
  }
12942
13079
 
12943
13080
  function renderReturn(r) {
@@ -12947,8 +13084,9 @@ function renderReturn(r) {
12947
13084
  const minX = Math.min(r.fromX, r.toX);
12948
13085
  const ARROW_PADDING_HALF = 3.5;
12949
13086
  const labelX = minX + Math.abs(r.toX - r.fromX) / 2 + (r.isReverse ? ARROW_PADDING_HALF : -ARROW_PADDING_HALF);
12950
- const lineY = Math.floor(r.y);
12951
- const labelY = lineY - 3;
13087
+ const snappedY = Math.floor(r.y);
13088
+ const lineY = snappedY + 0.5;
13089
+ const labelY = snappedY - 3;
12952
13090
  const arrowTipX = r.toX;
12953
13091
  const w = 5.15;
12954
13092
  const halfH = 3.25;
@@ -12957,10 +13095,10 @@ function renderReturn(r) {
12957
13095
  const ay1 = lineY - halfH;
12958
13096
  const ay2 = lineY + halfH;
12959
13097
  const numberX = Math.min(r.fromX, r.toX) - 4;
12960
- const numberSvg = r.number ? `<text x="${numberX}" y="${labelY}" text-anchor="end" class="seq-number">${esc(r.number)}</text>` : "";
13098
+ const numberSvg = renderMessageNumber(r.number, numberX, labelY);
12961
13099
  return `<g class="return">
12962
13100
  <line x1="${r.fromX}" y1="${lineY}" x2="${r.toX}" y2="${lineY}" class="return-line"/>
12963
- <polyline points="${ax1},${ay1} ${arrowTipX},${lineY} ${ax1},${ay2}" fill="none" stroke-linecap="round" class="return-arrow"/>
13101
+ <polyline points="${ax1},${ay1} ${arrowTipX},${lineY} ${ax1},${ay2}" transform="translate(${dir} 0)" fill="none" stroke-linecap="round" class="return-arrow"/>
12964
13102
  <text x="${labelX}" y="${labelY}" text-anchor="middle" class="return-label">${esc(resolveEmojiInText(r.label))}</text>
12965
13103
  ${numberSvg}
12966
13104
  </g>`;
@@ -13100,7 +13238,6 @@ function renderGroup(g) {
13100
13238
  </g>`;
13101
13239
  }
13102
13240
 
13103
- const HELVETICA = "Helvetica, Verdana, serif";
13104
13241
  const DEFAULT_PALETTE = {
13105
13242
  frameBorder: "#666",
13106
13243
  frameBg: "#ffffff",
@@ -13118,7 +13255,7 @@ const DEFAULT_PALETTE = {
13118
13255
  fragmentText: "#000",
13119
13256
  fragmentSeparator: "#e5e7eb",
13120
13257
  commentText: "#333",
13121
- fontFamily: HELVETICA
13258
+ fontFamily: DIAGRAM_FONT_STACK
13122
13259
  };
13123
13260
  const THEME_PALETTES = {
13124
13261
  "theme-default": DEFAULT_PALETTE,
@@ -13144,7 +13281,7 @@ const THEME_PALETTES = {
13144
13281
  fragmentText: "#368eff",
13145
13282
  fragmentSeparator: "#e5e9f0",
13146
13283
  commentText: "#353748",
13147
- fontFamily: HELVETICA
13284
+ fontFamily: DIAGRAM_FONT_STACK
13148
13285
  },
13149
13286
  // src/assets/tailwind.css `.theme-clean-dark`.
13150
13287
  "theme-clean-dark": {
@@ -13164,7 +13301,7 @@ const THEME_PALETTES = {
13164
13301
  fragmentText: "#cecfd2",
13165
13302
  fragmentSeparator: "#cecfd2",
13166
13303
  commentText: "#cecfd2",
13167
- fontFamily: HELVETICA
13304
+ fontFamily: DIAGRAM_FONT_STACK
13168
13305
  },
13169
13306
  // src/assets/tailwind.css `.theme-neon`. The DOM theme also swaps in the
13170
13307
  // MS Sans Serif webfont (`.zenuml .theme-neon`); the SVG names it first and
@@ -13187,7 +13324,7 @@ const THEME_PALETTES = {
13187
13324
  fragmentText: "#8ffc5b",
13188
13325
  fragmentSeparator: "#60ff33",
13189
13326
  commentText: "#8ffc5b",
13190
- fontFamily: `"MS Sans Serif", ${HELVETICA}`
13327
+ fontFamily: `"MS Sans Serif", ${DIAGRAM_FONT_STACK}`
13191
13328
  }
13192
13329
  };
13193
13330
  function resolvePalette(theme) {
@@ -13198,43 +13335,48 @@ function resolvePalette(theme) {
13198
13335
  }
13199
13336
  function buildThemeStyles(p) {
13200
13337
  return `
13338
+ @font-face { font-family: "${IBM_PLEX_SANS_FAMILY}"; font-weight: 400; font-style: normal; src: url(${IBM_PLEX_SANS_400_DATA_URI}) format("woff2"); }
13201
13339
  .frame-border-outer { fill: ${p.frameBorder}; }
13202
13340
  .frame-border-inner { fill: ${p.frameBg}; }
13203
13341
  .frame-header-bg { fill: ${p.frameBg}; }
13204
13342
  .frame-header-line { stroke: ${p.frameBorder}; stroke-width: 1; shape-rendering: crispEdges; }
13205
- .frame-title { font-family: ${p.fontFamily}; font-size: 16px; font-weight: 600; fill: ${p.titleText}; }
13206
- .participant-box { fill: ${p.participantBg}; stroke: ${p.participantBorder}; stroke-width: 2; }
13207
- .participant-label { font-family: ${p.fontFamily}; font-size: 16px; fill: ${p.participantText}; }
13343
+ .frame-title { font-family: ${p.fontFamily}; font-size: 14px; font-weight: 400; fill: ${p.titleText}; }
13344
+ .participant-box { fill: ${p.participantBg}; stroke: ${p.participantBorder}; stroke-width: 1; }
13345
+ .participant-label { font-family: ${p.fontFamily}; font-size: 14px; fill: ${p.participantText}; }
13208
13346
  .participant-icon { color: ${p.participantText}; }
13209
13347
  .participant-icon [fill="currentColor"]:not([stroke]) { stroke: ${p.participantBorder}; stroke-width: 1; }
13210
13348
  .lifeline { stroke: ${p.participantBorder}; stroke-width: 1; }
13211
- .message-line { stroke: ${p.messageArrow}; stroke-width: 2; shape-rendering: crispEdges; }
13212
- .message-label { font-family: ${p.fontFamily}; font-size: 14px; fill: ${p.messageText}; }
13213
- .arrow-head { fill: ${p.messageArrow}; stroke: ${p.messageArrow}; stroke-width: 2; }
13349
+ .message-line { stroke: ${p.messageArrow}; stroke-width: 1; shape-rendering: crispEdges; }
13350
+ .message-label { font-family: ${p.fontFamily}; font-size: 15px; fill: ${p.messageText}; }
13351
+ .arrow-head { fill: ${p.messageArrow}; stroke: ${p.messageArrow}; stroke-width: 1; }
13214
13352
  .arrow-open { fill: none; }
13215
- .occurrence { fill: ${p.occurrenceBg}; stroke: ${p.occurrenceBorder}; stroke-width: 2; shape-rendering: crispEdges; }
13216
- .fragment-border { fill: none; stroke: ${p.fragmentBorder}; stroke-width: 1; shape-rendering: crispEdges; }
13353
+ .occurrence { fill: ${p.occurrenceBg}; stroke: ${p.occurrenceBorder}; stroke-width: 1; shape-rendering: crispEdges; }
13354
+ .fragment-border { fill: none; stroke: ${p.fragmentBorder}; stroke-width: 1; }
13217
13355
  .fragment-header { fill: ${p.fragmentHeaderBg}; fill-opacity: ${p.fragmentHeaderOpacity}; stroke: none; shape-rendering: crispEdges; }
13218
- .fragment-label { font-family: ${p.fontFamily}; font-size: 14px; font-weight: 600; fill: ${p.fragmentText}; }
13356
+ .fragment-number-bg { fill: #6b7280; fill-opacity: 0.1; stroke: none; }
13357
+ .message-number-bg { fill: #6b7280; fill-opacity: 0.1; stroke: none; }
13358
+ .fragment-label { font-family: ${p.fontFamily}; font-size: 14px; font-weight: 400; font-variant-caps: all-small-caps; fill: ${p.fragmentText}; }
13219
13359
  .fragment-condition { font-family: ${p.fontFamily}; font-size: 14px; fill: ${p.fragmentText}; }
13220
13360
  .fragment-separator { stroke: ${p.fragmentSeparator}; stroke-width: 1; shape-rendering: crispEdges; }
13361
+ .fragment-section-keyword { font-variant-caps: all-small-caps; }
13221
13362
  .fragment-section-label { font-family: ${p.fontFamily}; font-size: 14px; fill: ${p.fragmentText}; }
13222
- .return-line { stroke: ${p.messageArrow}; stroke-width: 2; stroke-dasharray: 6,4; shape-rendering: crispEdges; }
13223
- .return-arrow { stroke: ${p.messageArrow}; stroke-width: 2; fill: none; }
13224
- .return-label { font-family: ${p.fontFamily}; font-size: 14px; fill: ${p.messageText}; }
13363
+ .return-line { stroke: ${p.messageArrow}; stroke-width: 1; stroke-dasharray: 6,4; shape-rendering: crispEdges; }
13364
+ .return-arrow { stroke: ${p.messageArrow}; stroke-width: 1; fill: none; }
13365
+ .return-label { font-family: ${p.fontFamily}; font-size: 15px; fill: ${p.messageText}; }
13225
13366
  .return-icon { fill: ${p.messageText}; }
13226
13367
  .divider-line { stroke: #aaaa33; stroke-width: 1; }
13227
13368
  .divider-bg { fill: #fff5ad; stroke: #aaaa33; stroke-width: 1; }
13228
13369
  .divider-label { font-family: ${p.fontFamily}; font-size: 14px; fill: #333; }
13229
13370
  .comment-text { font-family: ${p.fontFamily}; font-size: 14px; fill: ${p.commentText}; opacity: 0.5; }
13230
- .seq-number { font-family: ${p.fontFamily}; font-size: 12px; font-weight: 100; fill: #6b7280; }
13371
+ .guard-keyword { font-family: ${p.fontFamily}; font-size: 12px; font-weight: 400; font-variant-caps: all-small-caps; fill: #6b7280; }
13372
+ .seq-number { font-family: ${p.fontFamily}; font-size: 12px; font-weight: 400; fill: #6b7280; }
13231
13373
  .group-outline { fill: none; stroke: ${p.participantBorder}; }
13232
13374
  .group-title-bg { fill: ${p.frameBg}; stroke: none; }
13233
13375
  .group-title-text { font-family: ${p.fontFamily}; font-size: 13px; font-weight: 400; fill: ${p.participantText}; }
13234
13376
  `;
13235
13377
  }
13236
13378
 
13237
- const FRAME_HEADER_HEIGHT = 28;
13379
+ const FRAME_VIEWPORT_HEADER_ALLOWANCE = 28;
13238
13380
  const FRAME_BORDER_RADIUS = 4;
13239
13381
  function renderToSvg(code, options) {
13240
13382
  const rootContext = RootContext(code);
@@ -13258,14 +13400,41 @@ function renderToSvg(code, options) {
13258
13400
  coordinates,
13259
13401
  verticalCoordinates,
13260
13402
  title,
13261
- measureText: WidthProviderOnCanvas
13403
+ measureText: WidthProviderOnCanvas,
13404
+ enableNumbering: options?.enableNumbering
13262
13405
  });
13263
13406
  return { ...composeSvg(geometry, options), geometry };
13264
13407
  }
13265
13408
  function composeSvg(g, options) {
13266
13409
  const padding = 10;
13267
- const headerH = FRAME_HEADER_HEIGHT;
13268
- const contentLeftMargin = 1 + padding + g.frameBorderLeft;
13410
+ const headerH = FRAME_VIEWPORT_HEADER_ALLOWANCE;
13411
+ let contentLeftMargin = 1 + padding + g.frameBorderLeft;
13412
+ let numberLeft = 0;
13413
+ for (const message of [
13414
+ ...g.messages,
13415
+ ...g.creations.map((creation) => creation.message)
13416
+ ]) {
13417
+ if (!message.number) continue;
13418
+ numberLeft = Math.min(
13419
+ numberLeft,
13420
+ Math.min(message.fromX, message.toX) + 1 - 4 - messageNumberWidth(message.number)
13421
+ );
13422
+ }
13423
+ for (const call of g.selfCalls) {
13424
+ if (call.number)
13425
+ numberLeft = Math.min(
13426
+ numberLeft,
13427
+ call.x - 3 - messageNumberWidth(call.number)
13428
+ );
13429
+ }
13430
+ for (const returned of g.returns) {
13431
+ if (returned.number && !returned.isSelf)
13432
+ numberLeft = Math.min(
13433
+ numberLeft,
13434
+ Math.min(returned.fromX, returned.toX) - 4 - messageNumberWidth(returned.number)
13435
+ );
13436
+ }
13437
+ contentLeftMargin += Math.max(0, padding - contentLeftMargin - numberLeft);
13269
13438
  const viewWidth = g.width + contentLeftMargin + padding + g.frameBorderRight + 1;
13270
13439
  const viewHeight = g.height + padding * 2 + headerH - 1;
13271
13440
  const parts = [];
@@ -13315,8 +13484,7 @@ function composeSvg(g, options) {
13315
13484
  `<rect class="frame-border-outer" x="0" y="0" width="${viewWidth}" height="${viewHeight}" rx="${r}" fill="#666"/>`,
13316
13485
  `<rect class="frame-border-inner" x="1" y="1" width="${viewWidth - 2}" height="${viewHeight - 2}" rx="${Math.max(0, r - 1)}" fill="#fff"/>`
13317
13486
  ].join("\n");
13318
- const contentPaddingTop = 6;
13319
- const headerLineY = headerH + contentPaddingTop;
13487
+ const headerLineY = 1 + DIAGRAM_HEADER_HEIGHT;
13320
13488
  const headerLineDrawY = headerLineY - 0.5;
13321
13489
  const headerLineSvg = `<line class="frame-header-line" x1="1" y1="${headerLineDrawY}" x2="${viewWidth - 1}" y2="${headerLineDrawY}"/>`;
13322
13490
  const titleSvg = g.title ? `<text x="5" y="${headerLineDrawY / 2}" dominant-baseline="central" class="frame-title">${esc(g.title)}</text>` : "";
@@ -13800,7 +13968,11 @@ async function renderMarkdownFile(inputArg, args, config) {
13800
13968
  async function main() {
13801
13969
  if (!globalThis.OffscreenCanvas && typeof document === "undefined") {
13802
13970
  try {
13803
- const { createCanvas } = await import('@napi-rs/canvas');
13971
+ const { createCanvas, GlobalFonts } = await import('@napi-rs/canvas');
13972
+ GlobalFonts.register(
13973
+ Buffer.from(IBM_PLEX_SANS_400_WOFF2_BASE64, "base64"),
13974
+ IBM_PLEX_SANS_FAMILY
13975
+ );
13804
13976
  setCanvasContext(createCanvas(1, 1).getContext("2d"));
13805
13977
  } catch {
13806
13978
  }