@diagrammo/dgmo 0.93.0 → 0.95.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 (122) hide show
  1. package/dist/advanced.d.ts +98 -21
  2. package/dist/advanced.js +79 -61
  3. package/dist/block.d.ts +6 -0
  4. package/dist/block.js +23 -20
  5. package/dist/chart-meta.js +9 -9
  6. package/dist/{charts-d3-ERYYVGP6.js → charts-d3-SZV2SFTM.js} +2 -2
  7. package/dist/{chunk-J6AEKIRQ.js → chunk-2I4UQG7W.js} +1 -1
  8. package/dist/{chunk-LDDDKWL6.js → chunk-2J2CWWWK.js} +1 -1
  9. package/dist/{chunk-QDRCWVV3.js → chunk-4EX4OKGZ.js} +71 -8
  10. package/dist/{chunk-A5WIAMCT.js → chunk-4UVCTLRH.js} +1 -1
  11. package/dist/{chunk-KCMGIYPO.js → chunk-5XBYLYYI.js} +1 -1
  12. package/dist/{chunk-XUTR7GNT.js → chunk-62GLKE6Q.js} +68 -29
  13. package/dist/{chunk-D6PVMUCX.js → chunk-67N26CER.js} +4 -4
  14. package/dist/{chunk-IIV4SMJL.js → chunk-6EFCOES2.js} +370 -285
  15. package/dist/{chunk-TNV4F5WA.js → chunk-7IALGIOI.js} +2 -2
  16. package/dist/{chunk-MB2SQF7N.js → chunk-7WEYXYLC.js} +1 -1
  17. package/dist/{chunk-4RY5D5RE.js → chunk-AM42TLSZ.js} +98 -93
  18. package/dist/{chunk-J43OCO22.js → chunk-BCV2VJTM.js} +2 -2
  19. package/dist/{chunk-7OWK5K5C.js → chunk-BH2SF4TT.js} +2 -2
  20. package/dist/{chunk-UVX3IYXF.js → chunk-BTP2BMWN.js} +4 -4
  21. package/dist/{chunk-MUJVNSEW.js → chunk-C6G36F5S.js} +1 -1
  22. package/dist/{chunk-ZTLMEBAC.js → chunk-E7F76M3U.js} +208 -26
  23. package/dist/{chunk-AUS7V54P.js → chunk-ERT7XDQW.js} +1 -1
  24. package/dist/{chunk-WK5QEYFA.js → chunk-EXHXTMVR.js} +3 -3
  25. package/dist/{chunk-YXXIRM4C.js → chunk-FWVE373X.js} +2 -2
  26. package/dist/{chunk-EQWC76GQ.js → chunk-GWQRTA5W.js} +2 -2
  27. package/dist/{chunk-GJXMG4S3.js → chunk-HHVIE45A.js} +1 -1
  28. package/dist/{chunk-4FT5KQ7H.js → chunk-IGJEKO2P.js} +1 -1
  29. package/dist/{chunk-KRU2LCIP.js → chunk-IHN6WDEY.js} +1 -1
  30. package/dist/{chunk-QT3KDDXK.js → chunk-IN7XI6NO.js} +0 -7
  31. package/dist/{chunk-NMK7KJZZ.js → chunk-IQN2NGEU.js} +4 -4
  32. package/dist/{chunk-M6ZQAFPD.js → chunk-IY62DXT2.js} +1 -1
  33. package/dist/{chunk-4WQX55VX.js → chunk-IZHGT5HD.js} +31 -5
  34. package/dist/{chunk-CYDM2XII.js → chunk-JJ7RGTAU.js} +56 -7
  35. package/dist/{chunk-NJJCTEBM.js → chunk-KLBTJEIK.js} +1 -1
  36. package/dist/{chunk-KHL652SX.js → chunk-KSZB7TIY.js} +1 -1
  37. package/dist/{chunk-KPSSNGAE.js → chunk-L5S32VZJ.js} +4 -4
  38. package/dist/{chunk-472EOHVW.js → chunk-LAXMUSGW.js} +31 -5
  39. package/dist/{chunk-M4NV5PPU.js → chunk-LJGE43SG.js} +1 -1
  40. package/dist/{chunk-VSOZZYLK.js → chunk-NERQSSYD.js} +20 -9
  41. package/dist/{chunk-UG7AQQNR.js → chunk-OSSTOSXU.js} +2 -2
  42. package/dist/{chunk-YDZIVDVR.js → chunk-P5XA627W.js} +7 -7
  43. package/dist/{chunk-DRQSB72S.js → chunk-PGBTUGDB.js} +2 -2
  44. package/dist/{chunk-65GPEV5V.js → chunk-QKPOIJBT.js} +2 -2
  45. package/dist/{chunk-QJOVZ4TC.js → chunk-QPQWY5RU.js} +1 -1
  46. package/dist/{chunk-P7TRFL4P.js → chunk-R46N5KR4.js} +2 -0
  47. package/dist/{chunk-LNVB75QU.js → chunk-RBVFNUAL.js} +1 -1
  48. package/dist/{chunk-DAHQL57W.js → chunk-RITTLIDJ.js} +1 -1
  49. package/dist/{chunk-2TFXRBCD.js → chunk-RQTDUZUH.js} +3 -3
  50. package/dist/{chunk-Q7Y6JQ3R.js → chunk-S4SJ4LLY.js} +1 -1
  51. package/dist/{chunk-LUDUDBO6.js → chunk-S5Y3OO3V.js} +2 -2
  52. package/dist/{chunk-3GCASUWA.js → chunk-TASRGDYP.js} +1 -1
  53. package/dist/{chunk-5HAYT43L.js → chunk-U6VS3T2M.js} +19 -3
  54. package/dist/{chunk-42UJ23H3.js → chunk-UIEKW4SG.js} +1 -0
  55. package/dist/{chunk-IESUM4N5.js → chunk-USE6HIOZ.js} +95 -62
  56. package/dist/{chunk-FIYW7JW4.js → chunk-USZLHYEQ.js} +1 -1
  57. package/dist/{chunk-U7U64UUN.js → chunk-V5D6GDNK.js} +4 -4
  58. package/dist/{chunk-ADVGV3P7.js → chunk-VB4VMB2I.js} +7 -5
  59. package/dist/{chunk-CQYFZOUC.js → chunk-VBMRZCMQ.js} +1 -1
  60. package/dist/{chunk-USAGHYRD.js → chunk-VF7IKIRS.js} +2 -2
  61. package/dist/{chunk-EJS3K44P.js → chunk-VGAMBOOC.js} +5 -3
  62. package/dist/{chunk-P5FUWXPW.js → chunk-VTESGA5F.js} +7 -5
  63. package/dist/chunk-WTTIODDV.js +9 -0
  64. package/dist/{chunk-5CBX66KB.js → chunk-XJQ6Z3FO.js} +2 -2
  65. package/dist/{chunk-KPGPK4SK.js → chunk-XOMIYMQ3.js} +6 -6
  66. package/dist/{chunk-KCHQVED5.js → chunk-YQMIKX54.js} +43 -7
  67. package/dist/completion-registry.js +3 -0
  68. package/dist/copy-image.d.ts +34 -0
  69. package/dist/copy-image.js +96 -0
  70. package/dist/countdown.js +1 -1
  71. package/dist/{dgmo-router-CZN36TR3.js → dgmo-router-6YLKM6WU.js} +13 -13
  72. package/dist/{dimensions-7HHKO5BS.js → dimensions-DS6FWLRY.js} +2 -2
  73. package/dist/{flowchart-parser-4MZPWYK6.js → flowchart-parser-J3VWIFWB.js} +5 -5
  74. package/dist/{flowchart-renderer-5XDN575E.js → flowchart-renderer-FECH5KK5.js} +14 -12
  75. package/dist/index.js +19 -19
  76. package/dist/layout-5SZ5A64I.js +24 -0
  77. package/dist/{layout-5GHV7HNM.js → layout-EWXHEXNS.js} +11 -10
  78. package/dist/{layout-QXGPY7KA.js → layout-TIBRMWHL.js} +7 -6
  79. package/dist/layout-VDCJOZSH.js +11 -0
  80. package/dist/layout-YBMT74MG.js +24 -0
  81. package/dist/{layout-search-EMTCDC3C.js → layout-search-AWPJWBKT.js} +9 -8
  82. package/dist/{parser-R3LPEQIT.js → parser-AR2GON37.js} +2 -2
  83. package/dist/{parser-YX72VLDZ.js → parser-BTSTKY5G.js} +5 -5
  84. package/dist/{parser-OGF2CDA6.js → parser-MA7L3XND.js} +5 -5
  85. package/dist/{parser-VKYUAT4Y.js → parser-ZRIZFDZY.js} +5 -5
  86. package/dist/{redraw-T324XAF3.js → redraw-AHW7EUUF.js} +2 -2
  87. package/dist/{redraw-MSXU4ZD2.js → redraw-STZ4WJAI.js} +3 -3
  88. package/dist/{renderer-HYGTMBHT.js → renderer-2LYX6NHN.js} +3 -3
  89. package/dist/{renderer-XJMVG2WJ.js → renderer-2QPHDBZY.js} +5 -5
  90. package/dist/{renderer-GPAVVUET.js → renderer-3NLDX7DQ.js} +3 -3
  91. package/dist/{renderer-IHCWBFPI.js → renderer-4VGO27EE.js} +14 -13
  92. package/dist/{renderer-JJ4QW3SK.js → renderer-6BDK47V6.js} +1 -1
  93. package/dist/{renderer-FL7EOSBU.js → renderer-7OGGV327.js} +3 -3
  94. package/dist/{renderer-5ITLW7MX.js → renderer-ACQQ2JXA.js} +6 -4
  95. package/dist/{renderer-37PLQHVB.js → renderer-BXD5KVSR.js} +2 -2
  96. package/dist/{renderer-TSCSZ6CL.js → renderer-HX6ICPDX.js} +2 -2
  97. package/dist/{renderer-BO73LSVT.js → renderer-IGSHD3OT.js} +4 -4
  98. package/dist/{renderer-DD6T3C4J.js → renderer-ISQJ2ELA.js} +2 -2
  99. package/dist/{renderer-CNRQFIEI.js → renderer-IVHD7ENY.js} +4 -4
  100. package/dist/{renderer-POBGKIUT.js → renderer-IXBOT6DU.js} +3 -3
  101. package/dist/{renderer-GFALLIYT.js → renderer-JYHA6R2D.js} +3 -3
  102. package/dist/{renderer-GOXAP2IE.js → renderer-KJ3V5BYP.js} +2 -2
  103. package/dist/{renderer-GFGFHYWY.js → renderer-MWZC7TMD.js} +2 -2
  104. package/dist/{renderer-3F47TPZ2.js → renderer-O6RP52CQ.js} +2 -2
  105. package/dist/{renderer-PBKTAWQV.js → renderer-P3WR7TKD.js} +14 -13
  106. package/dist/{renderer-VDBNC7A6.js → renderer-QTPWRRJ7.js} +2 -2
  107. package/dist/{renderer-J3QWK6IM.js → renderer-RUSQJFFC.js} +3 -3
  108. package/dist/{renderer-7Y3LR4R2.js → renderer-TINHO2IO.js} +2 -2
  109. package/dist/{renderer-J6H4Q3RM.js → renderer-UGW4N2W5.js} +4 -3
  110. package/dist/{renderer-EVKWGUGT.js → renderer-UTEEJDGB.js} +4 -3
  111. package/dist/{renderer-ISDKO3DI.js → renderer-WPN2SXGT.js} +2 -2
  112. package/dist/{renderer-6GJWADLO.js → renderer-XCLARXCK.js} +2 -2
  113. package/dist/{renderer-RDI2RYUP.js → renderer-XDX6S7OV.js} +3 -3
  114. package/dist/{renderer-VI34SD5V.js → renderer-Y47EM337.js} +6 -6
  115. package/dist/{renderer-HJ54YXT3.js → renderer-ZV6KCLCL.js} +14 -14
  116. package/dist/{state-parser-NPYTMRXP.js → state-parser-PMNHLHLE.js} +5 -5
  117. package/dist/{state-renderer-44K2KDX7.js → state-renderer-JQ5DS66J.js} +14 -13
  118. package/docs/language-reference.md +2 -2
  119. package/package.json +5 -1
  120. package/dist/layout-33FHGDEV.js +0 -23
  121. package/dist/layout-FTOGDNUL.js +0 -23
  122. package/dist/layout-J3AGFZZ7.js +0 -10
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  renderNodeCard
3
3
  } from "./chunk-R2K5L4UA.js";
4
+ import {
5
+ placeEdgeLabels
6
+ } from "./chunk-IN7XI6NO.js";
4
7
  import {
5
8
  serializeSvg
6
9
  } from "./chunk-CYRB2JTN.js";
@@ -9,7 +12,7 @@ import {
9
12
  } from "./chunk-24YPR5EH.js";
10
13
  import {
11
14
  layoutInlineHeader
12
- } from "./chunk-42UJ23H3.js";
15
+ } from "./chunk-UIEKW4SG.js";
13
16
  import {
14
17
  TITLE_FONT_SIZE,
15
18
  TITLE_FONT_WEIGHT
@@ -45,7 +48,7 @@ import {
45
48
  } from "./chunk-IYULMRBE.js";
46
49
  import {
47
50
  renderInlineText
48
- } from "./chunk-65GPEV5V.js";
51
+ } from "./chunk-QKPOIJBT.js";
49
52
  import {
50
53
  FONT_FAMILY
51
54
  } from "./chunk-ICLB27PZ.js";
@@ -101,6 +104,51 @@ function containerStroke(palette, nodeColor) {
101
104
  }
102
105
  var lineGenerator = d3Shape.line().x((d) => d.x).y((d) => d.y).curve(d3Shape.curveBasis);
103
106
  var lineGeneratorLinear = d3Shape.line().x((d) => d.x).y((d) => d.y).curve(d3Shape.curveLinear);
107
+ function placeSitemapEdgeLabels(layout, fontSize) {
108
+ const nodes = [
109
+ ...layout.nodes.map((n) => ({
110
+ label: n.id,
111
+ x: n.x,
112
+ y: n.y + n.height / 2,
113
+ width: n.width,
114
+ height: n.height
115
+ })),
116
+ ...layout.containers.map((c) => ({
117
+ label: c.nodeId,
118
+ x: c.x + c.width / 2,
119
+ y: c.y + c.labelHeight / 2,
120
+ width: c.width,
121
+ height: c.labelHeight
122
+ }))
123
+ ];
124
+ const adapted = {
125
+ nodes,
126
+ groups: [],
127
+ width: layout.width,
128
+ height: layout.height,
129
+ edges: layout.edges.map((e) => ({
130
+ source: e.sourceId,
131
+ target: e.targetId,
132
+ ...e.label !== void 0 && { label: e.label },
133
+ bidirectional: false,
134
+ lineNumber: e.lineNumber,
135
+ points: e.points,
136
+ yOffset: 0,
137
+ parallelCount: 1,
138
+ metadata: {}
139
+ }))
140
+ };
141
+ const placed = placeEdgeLabels(adapted, {
142
+ fontSize,
143
+ maxWidth: Number.POSITIVE_INFINITY
144
+ });
145
+ const out = /* @__PURE__ */ new Map();
146
+ placed.layout.edges.forEach((e, idx) => {
147
+ if (e.labelX !== void 0 && e.labelY !== void 0)
148
+ out.set(idx, { x: e.labelX, y: e.labelY });
149
+ });
150
+ return out;
151
+ }
104
152
  function renderSitemap(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, hiddenAttributes, exportMode) {
105
153
  d3Selection.select(container).selectAll(":not([data-d3-tooltip])").remove();
106
154
  const width = exportDims?.width ?? container.clientWidth;
@@ -232,7 +280,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
232
280
  for (const c of layout.containers) {
233
281
  const cG = contentG.append("g").attr("transform", `translate(${c.x}, ${c.y})`).attr("class", "sitemap-container").attr("data-line-number", String(c.lineNumber));
234
282
  if (c.hasChildren) {
235
- cG.attr("data-node-toggle", c.nodeId).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!c.hiddenCount)).attr("aria-label", c.label);
283
+ cG.attr("data-node-toggle", c.nodeId).attr("role", "button").attr("aria-expanded", String(!c.hiddenCount)).attr("aria-label", c.label);
236
284
  }
237
285
  if (onClickItem) {
238
286
  cG.style("cursor", "pointer").on(
@@ -277,7 +325,8 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
277
325
  cG.append("rect").attr("y", c.height - sCollapseBarHeight).attr("width", c.width).attr("height", sCollapseBarHeight).attr("fill", stroke).attr("clip-path", `url(#${clipId})`).attr("class", "sitemap-collapse-bar");
278
326
  }
279
327
  }
280
- for (const edge of layout.edges) {
328
+ const labelCentres = placeSitemapEdgeLabels(layout, sEdgeLabelFontSize);
329
+ for (const [edgeIdx, edge] of layout.edges.entries()) {
281
330
  if (edge.points.length < 2) continue;
282
331
  const edgeG = contentG.append("g").attr("class", "sitemap-edge-group").attr("data-line-number", String(edge.lineNumber)).attr("data-from", edge.sourceId).attr("data-to", edge.targetId);
283
332
  const edgeColor = palette.textMuted;
@@ -287,8 +336,8 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
287
336
  if (pathD) {
288
337
  edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor).attr("stroke-width", sEdgeStrokeWidth).attr("marker-end", `url(#${markerId})`).attr("class", "sitemap-edge");
289
338
  }
290
- if (edge.label && edge.points.length >= 2) {
291
- const mid = edge.points[Math.floor(edge.points.length / 2)];
339
+ const mid = labelCentres.get(edgeIdx);
340
+ if (edge.label && mid) {
292
341
  const labelW = measureText(edge.label, sEdgeLabelFontSize) + 10;
293
342
  const labelH = sEdgeLabelFontSize + 6;
294
343
  edgeG.append("rect").attr("x", mid.x - labelW / 2).attr("y", mid.y - labelH / 2 - 1).attr("width", labelW).attr("height", labelH).attr("rx", 3).attr("fill", palette.bg).attr("opacity", EDGE_LABEL_KNOCKOUT_OPACITY).attr("class", "sitemap-edge-label-bg");
@@ -298,7 +347,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
298
347
  for (const node of layout.nodes) {
299
348
  const nodeG = contentG.append("g").attr("transform", `translate(${node.x - node.width / 2}, ${node.y})`).attr("class", "sitemap-node").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
300
349
  if (node.hasChildren) {
301
- nodeG.attr("data-node-toggle", node.id).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!node.hiddenCount));
350
+ nodeG.attr("data-node-toggle", node.id).attr("role", "button").attr("aria-expanded", String(!node.hiddenCount));
302
351
  }
303
352
  if (onClickItem) {
304
353
  nodeG.style("cursor", "pointer").on("click", () => onClickItem(node.lineNumber));
@@ -5,7 +5,7 @@ import {
5
5
  NOTE_GAP,
6
6
  noteBoxSize,
7
7
  noteConnectorPoints
8
- } from "./chunk-D6PVMUCX.js";
8
+ } from "./chunk-67N26CER.js";
9
9
  import {
10
10
  extractColor,
11
11
  measureIndent
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  INLINE_HEADER_PAD,
16
16
  layoutInlineHeader
17
- } from "./chunk-42UJ23H3.js";
17
+ } from "./chunk-UIEKW4SG.js";
18
18
  import {
19
19
  CAPTION_BOX_PADDING_X,
20
20
  CAPTION_BOX_PADDING_Y,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  layoutClassDiagram
3
- } from "./chunk-J43OCO22.js";
3
+ } from "./chunk-BCV2VJTM.js";
4
4
  import {
5
5
  extractExportSvg,
6
6
  runInExportContainer
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-24YPR5EH.js";
11
11
  import {
12
12
  layoutInlineHeader
13
- } from "./chunk-42UJ23H3.js";
13
+ } from "./chunk-UIEKW4SG.js";
14
14
  import {
15
15
  TITLE_FONT_SIZE,
16
16
  TITLE_FONT_WEIGHT,
@@ -32,14 +32,14 @@ import {
32
32
  } from "./chunk-JILEYZ2V.js";
33
33
  import {
34
34
  parseClassDiagram
35
- } from "./chunk-KCMGIYPO.js";
35
+ } from "./chunk-5XBYLYYI.js";
36
36
  import {
37
37
  NOTE_BADGE_RADIUS,
38
38
  noteConnectorPoints,
39
39
  renderNoteBadge,
40
40
  renderNoteBox,
41
41
  renderNoteConnector
42
- } from "./chunk-D6PVMUCX.js";
42
+ } from "./chunk-67N26CER.js";
43
43
  import {
44
44
  FONT_FAMILY
45
45
  } from "./chunk-ICLB27PZ.js";
@@ -5,7 +5,7 @@ import {
5
5
  NODE_LABEL_LINE_HEIGHT,
6
6
  layoutGraph,
7
7
  wrapNodeLabel
8
- } from "./chunk-WK5QEYFA.js";
8
+ } from "./chunk-EXHXTMVR.js";
9
9
  import {
10
10
  appendArrowheadMarkers
11
11
  } from "./chunk-XBJJP2HN.js";
@@ -18,6 +18,11 @@ import {
18
18
  import {
19
19
  ScaleContext
20
20
  } from "./chunk-24YPR5EH.js";
21
+ import {
22
+ INLINE_HEADER_PAD,
23
+ layoutInlineHeader,
24
+ measureTitleWidth
25
+ } from "./chunk-UIEKW4SG.js";
21
26
  import {
22
27
  TITLE_FONT_SIZE,
23
28
  TITLE_FONT_WEIGHT,
@@ -32,14 +37,14 @@ import {
32
37
  } from "./chunk-XCKNFFKM.js";
33
38
  import {
34
39
  parseFlowchart
35
- } from "./chunk-M6ZQAFPD.js";
40
+ } from "./chunk-IY62DXT2.js";
36
41
  import {
37
42
  NOTE_BADGE_RADIUS,
38
43
  noteConnectorPoints,
39
44
  renderNoteBadge,
40
45
  renderNoteBox,
41
46
  renderNoteConnector
42
- } from "./chunk-D6PVMUCX.js";
47
+ } from "./chunk-67N26CER.js";
43
48
  import {
44
49
  FONT_FAMILY
45
50
  } from "./chunk-ICLB27PZ.js";
@@ -331,7 +336,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
331
336
  const titleHeight = showTitle ? 40 : 0;
332
337
  const diagramW = layout.width;
333
338
  const diagramH = layout.height;
334
- const { scale, offsetX, offsetY, canvasHeight, canvasWidth } = fitDiagramToCanvas({
339
+ const fit = fitDiagramToCanvas({
335
340
  width,
336
341
  height,
337
342
  diagramW,
@@ -341,6 +346,27 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
341
346
  maxScale: MAX_SCALE,
342
347
  exportMode: !!exportDims
343
348
  });
349
+ const { scale, offsetY, canvasHeight } = fit;
350
+ let { offsetX, canvasWidth } = fit;
351
+ if (showTitle && exportDims) {
352
+ const titleW = Math.ceil(
353
+ measureTitleWidth(graph.title, sTitleFontSize) + INLINE_HEADER_PAD * 2
354
+ );
355
+ if (titleW > canvasWidth) {
356
+ offsetX += (titleW - canvasWidth) / 2;
357
+ canvasWidth = titleW;
358
+ }
359
+ }
360
+ const header = layoutInlineHeader({
361
+ requested: false,
362
+ title: graph.title ?? "",
363
+ hasLegend: false,
364
+ legendWidth: 0,
365
+ legendHeight: 0,
366
+ containerWidth: canvasWidth,
367
+ titleBandHeight: titleHeight,
368
+ legendReserve: 0
369
+ });
344
370
  const svg = d3Selection.select(container).append("svg").attr("width", canvasWidth).attr("height", canvasHeight).attr("viewBox", `0 0 ${canvasWidth} ${canvasHeight}`).attr("preserveAspectRatio", "xMidYMin meet").style("font-family", FONT_FAMILY);
345
371
  if (ctx.isBelowFloor) {
346
372
  svg.attr("width", "100%");
@@ -355,7 +381,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
355
381
  colors: edgeColors
356
382
  });
357
383
  if (showTitle) {
358
- const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", sTitleY).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", sTitleFontSize).attr("font-weight", TITLE_FONT_WEIGHT).style(
384
+ const titleEl = svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", sTitleY).attr("text-anchor", header.titleAnchor).attr("fill", palette.text).attr("font-size", sTitleFontSize).attr("font-weight", TITLE_FONT_WEIGHT).style(
359
385
  "cursor",
360
386
  onClickItem && graph.titleLineNumber ? "pointer" : "default"
361
387
  ).text(graph.title);
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  resolveNotes,
6
6
  tryCollectNote
7
- } from "./chunk-NJJCTEBM.js";
7
+ } from "./chunk-KLBTJEIK.js";
8
8
  import {
9
9
  displayName,
10
10
  normalizeName
@@ -38,10 +38,21 @@ function fractionalYearToDate(frac) {
38
38
  function dateToFractionalYear(d) {
39
39
  return d.getFullYear() + d.getMonth() / 12 + (d.getDate() - 1) / 365 + d.getHours() / 8760 + d.getMinutes() / 525600 + d.getSeconds() / 31536e3;
40
40
  }
41
+ var APPROXIMATE_CONVERTERS = {
42
+ toFractionalYear: dateToFractionalYear,
43
+ fromFractionalYear: fractionalYearToDate
44
+ };
45
+ function calendarDay(year, month0, day) {
46
+ const d = new Date(2e3, month0, day);
47
+ d.setFullYear(year);
48
+ return d;
49
+ }
41
50
  function formatYearTick(y) {
42
51
  return y < 0 ? `${-y} BCE` : String(y);
43
52
  }
44
- function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEnd, boundaryStartLabel, boundaryEndLabel, labelFit = { fontSize: 10 }) {
53
+ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEnd, boundaryStartLabel, boundaryEndLabel, labelFit = { fontSize: 10 }, converters) {
54
+ const { toFractionalYear, fromFractionalYear } = converters ?? APPROXIMATE_CONVERTERS;
55
+ const dayValue = (y, month0, day) => converters ? toFractionalYear(calendarDay(y, month0, day)) : y + month0 / 12 + (day - 1) / 365;
45
56
  const minYear = Math.floor(domainMin);
46
57
  const maxYear = Math.floor(domainMax);
47
58
  const span = domainMax - domainMin;
@@ -70,7 +81,7 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
70
81
  const crossesYear = maxYear > minYear;
71
82
  for (let y = minYear; y <= maxYear + 1; y++) {
72
83
  for (let m = 1; m <= 12; m++) {
73
- const val = y + (m - 1) / 12;
84
+ const val = dayValue(y, m - 1, 1);
74
85
  if (val > domainMax) break;
75
86
  if (val >= domainMin) {
76
87
  const abbr = MONTH_ABBR[m - 1];
@@ -89,13 +100,13 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
89
100
  if (spanSec > 180) stepSec = 30;
90
101
  else if (spanSec > 60) stepSec = 15;
91
102
  else if (spanSec > 30) stepSec = 10;
92
- const startDate = fractionalYearToDate(domainMin);
103
+ const startDate = fromFractionalYear(domainMin);
93
104
  startDate.setSeconds(
94
105
  Math.floor(startDate.getSeconds() / stepSec) * stepSec,
95
106
  0
96
107
  );
97
108
  while (true) {
98
- const val = dateToFractionalYear(startDate);
109
+ const val = toFractionalYear(startDate);
99
110
  if (val > domainMax) break;
100
111
  if (val >= domainMin) {
101
112
  const hh = String(startDate.getHours()).padStart(2, "0");
@@ -115,14 +126,14 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
115
126
  if (spanHours > 3) stepMin = 30;
116
127
  else if (spanHours > 1) stepMin = 15;
117
128
  else if (spanHours > 0.5) stepMin = 10;
118
- const startDate = fractionalYearToDate(domainMin);
129
+ const startDate = fromFractionalYear(domainMin);
119
130
  startDate.setMinutes(
120
131
  Math.floor(startDate.getMinutes() / stepMin) * stepMin,
121
132
  0,
122
133
  0
123
134
  );
124
135
  while (true) {
125
- const val = dateToFractionalYear(startDate);
136
+ const val = toFractionalYear(startDate);
126
137
  if (val > domainMax) break;
127
138
  if (val >= domainMin) {
128
139
  const hh = String(startDate.getHours()).padStart(2, "0");
@@ -142,7 +153,7 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
142
153
  else if (spanHours > 24) stepHour = 3;
143
154
  else if (spanHours > 12) stepHour = 2;
144
155
  const singleDay = spanHours <= 24;
145
- const startDate = fractionalYearToDate(domainMin);
156
+ const startDate = fromFractionalYear(domainMin);
146
157
  startDate.setHours(
147
158
  Math.floor(startDate.getHours() / stepHour) * stepHour,
148
159
  0,
@@ -150,7 +161,7 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
150
161
  0
151
162
  );
152
163
  while (true) {
153
- const val = dateToFractionalYear(startDate);
164
+ const val = toFractionalYear(startDate);
154
165
  if (val > domainMax) break;
155
166
  if (val >= domainMin) {
156
167
  const hh = String(startDate.getHours()).padStart(2, "0");
@@ -177,7 +188,7 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
177
188
  for (let y = minYear; y <= maxYear + 1; y++) {
178
189
  for (let m = 1; m <= 12; m++) {
179
190
  for (const d of [1, 8, 15, 22]) {
180
- const val = y + (m - 1) / 12 + (d - 1) / 365;
191
+ const val = dayValue(y, m - 1, d);
181
192
  if (val > domainMax) break;
182
193
  if (val >= domainMin) {
183
194
  ticks.push({
@@ -15,10 +15,10 @@ import {
15
15
  } from "./chunk-NMS5XSLX.js";
16
16
  import {
17
17
  wrapDescriptionLines
18
- } from "./chunk-MB2SQF7N.js";
18
+ } from "./chunk-7WEYXYLC.js";
19
19
  import {
20
20
  renderInlineText
21
- } from "./chunk-65GPEV5V.js";
21
+ } from "./chunk-QKPOIJBT.js";
22
22
  import {
23
23
  FONT_FAMILY
24
24
  } from "./chunk-ICLB27PZ.js";
@@ -36,7 +36,7 @@ import {
36
36
  import {
37
37
  WHITEBOARD_DIAGNOSTICS,
38
38
  parseWhiteboard
39
- } from "./chunk-5HAYT43L.js";
39
+ } from "./chunk-U6VS3T2M.js";
40
40
  import {
41
41
  SWIMLANE_DIAGNOSTICS,
42
42
  parseSwimlane
@@ -97,10 +97,10 @@ import {
97
97
  } from "./chunk-JXGSTBW6.js";
98
98
  import {
99
99
  parseBoxesAndLines
100
- } from "./chunk-A5WIAMCT.js";
100
+ } from "./chunk-4UVCTLRH.js";
101
101
  import {
102
102
  parseDgmoChartType
103
- } from "./chunk-UVX3IYXF.js";
103
+ } from "./chunk-BTP2BMWN.js";
104
104
  import {
105
105
  parseRaci
106
106
  } from "./chunk-KRPLP5LP.js";
@@ -123,13 +123,13 @@ import {
123
123
  } from "./chunk-CDM6XMOT.js";
124
124
  import {
125
125
  parseFlowchart
126
- } from "./chunk-M6ZQAFPD.js";
126
+ } from "./chunk-IY62DXT2.js";
127
127
  import {
128
128
  GRAPH_DIAGNOSTICS
129
129
  } from "./chunk-TIVMAITN.js";
130
130
  import {
131
131
  parseState
132
- } from "./chunk-M4NV5PPU.js";
132
+ } from "./chunk-LJGE43SG.js";
133
133
  import {
134
134
  makeYearContext,
135
135
  parseDateToken,
@@ -141,10 +141,10 @@ import {
141
141
  } from "./chunk-CYTFO2LF.js";
142
142
  import {
143
143
  parseERDiagram
144
- } from "./chunk-Q7Y6JQ3R.js";
144
+ } from "./chunk-S4SJ4LLY.js";
145
145
  import {
146
146
  parseClassDiagram
147
- } from "./chunk-KCMGIYPO.js";
147
+ } from "./chunk-5XBYLYYI.js";
148
148
  import {
149
149
  ARROW_DIAGNOSTIC_CODES
150
150
  } from "./chunk-N7VMGZCU.js";
@@ -205,7 +205,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
205
205
  }
206
206
  }
207
207
  if (c.hasChildren) {
208
- cG.attr("data-node-toggle", c.nodeId).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!c.hiddenCount)).attr("aria-label", c.label);
208
+ cG.attr("data-node-toggle", c.nodeId).attr("role", "button").attr("aria-expanded", String(!c.hiddenCount)).attr("aria-label", c.label);
209
209
  }
210
210
  if (onClickItem) {
211
211
  cG.style("cursor", "pointer").on("click", () => {
@@ -287,7 +287,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
287
287
  }
288
288
  }
289
289
  if (node.hasChildren) {
290
- nodeG.attr("data-node-toggle", node.id).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!node.hiddenCount)).attr("aria-label", node.label);
290
+ nodeG.attr("data-node-toggle", node.id).attr("role", "button").attr("aria-expanded", String(!node.hiddenCount)).attr("aria-label", node.label);
291
291
  }
292
292
  if (onClickItem) {
293
293
  nodeG.style("cursor", "pointer").on("click", () => {
@@ -25,7 +25,7 @@ function safeHref(url) {
25
25
  // src/utils/inline-markdown.ts
26
26
  function parseInlineMarkdown(text) {
27
27
  const spans = [];
28
- const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)|(https?:\/\/[^\s)>\]]+|www\.[^\s)>\]]+)|([^*_`[]+?(?=https?:\/\/|www\.|$)|[^*_`[]+)/g;
28
+ const regex = /\*\*(.+?)\*\*|__(.+?)__|\*(.+?)\*|_(.+?)_|`(.+?)`|\[([^[\]\n\r]+)\]\(((?:[^()\n\r]|\([^()\n\r]*\))+)\)|(https?:\/\/[^\s)>\]]+|www\.[^\s)>\]]+)|([^*_`[]+?(?=https?:\/\/|www\.|$)|[^*_`[]+|\[)/g;
29
29
  let match;
30
30
  while ((match = regex.exec(text)) !== null) {
31
31
  if (match[1])
@@ -58,7 +58,7 @@ function truncateBareUrl(url) {
58
58
  return stripped.slice(0, BARE_URL_MAX_DISPLAY - 1) + "\u2026";
59
59
  }
60
60
  function stripInlineMarkdown(text) {
61
- return text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1").replace(
61
+ return text.replace(/\[([^[\]\n\r]+)\]\((?:[^()\n\r]|\([^()\n\r]*\))+\)/g, "$1").replace(
62
62
  /https?:\/\/[^\s)>\]]+|www\.[^\s)>\]]+/g,
63
63
  (u) => truncateBareUrl(u)
64
64
  ).replace(/\*\*|__|[*_`]/g, "");
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-XSVWUOUZ.js";
4
4
  import {
5
5
  layoutInlineHeader
6
- } from "./chunk-42UJ23H3.js";
6
+ } from "./chunk-UIEKW4SG.js";
7
7
  import {
8
8
  TITLE_FONT_SIZE,
9
9
  TITLE_FONT_WEIGHT,
@@ -28,6 +28,7 @@ var WHITEBOARD_ELEMENT_KEYWORDS = [
28
28
  ];
29
29
  var WHITEBOARD_STROKE_STYLES = ["solid", "dashed"];
30
30
  var WHITEBOARD_FILLS = ["tint", "solid", "outline"];
31
+ var WHITEBOARD_LABEL_POSITIONS = ["top", "middle"];
31
32
  var WHITEBOARD_HEADS = ["end", "both"];
32
33
  var WHITEBOARD_NOTE_WIDTH = 160;
33
34
  var WHITEBOARD_NOTE_HEIGHT = 99;
@@ -45,6 +46,7 @@ export {
45
46
  WHITEBOARD_ELEMENT_KEYWORDS,
46
47
  WHITEBOARD_STROKE_STYLES,
47
48
  WHITEBOARD_FILLS,
49
+ WHITEBOARD_LABEL_POSITIONS,
48
50
  WHITEBOARD_HEADS,
49
51
  WHITEBOARD_NOTE_WIDTH,
50
52
  WHITEBOARD_NOTE_HEIGHT,
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  parseInlineMarkdown,
15
15
  safeHref
16
- } from "./chunk-65GPEV5V.js";
16
+ } from "./chunk-QKPOIJBT.js";
17
17
  import {
18
18
  FONT_FAMILY
19
19
  } from "./chunk-ICLB27PZ.js";
@@ -24,7 +24,7 @@ import {
24
24
  } from "./chunk-JILEYZ2V.js";
25
25
  import {
26
26
  renderInlineText
27
- } from "./chunk-65GPEV5V.js";
27
+ } from "./chunk-QKPOIJBT.js";
28
28
  import {
29
29
  FONT_FAMILY
30
30
  } from "./chunk-ICLB27PZ.js";
@@ -19,7 +19,7 @@ import {
19
19
  } from "./chunk-24YPR5EH.js";
20
20
  import {
21
21
  layoutInlineHeader
22
- } from "./chunk-42UJ23H3.js";
22
+ } from "./chunk-UIEKW4SG.js";
23
23
  import {
24
24
  TITLE_FONT_SIZE,
25
25
  TITLE_FONT_WEIGHT
@@ -43,7 +43,7 @@ import {
43
43
  } from "./chunk-IYULMRBE.js";
44
44
  import {
45
45
  renderInlineText
46
- } from "./chunk-65GPEV5V.js";
46
+ } from "./chunk-QKPOIJBT.js";
47
47
  import {
48
48
  FONT_FAMILY
49
49
  } from "./chunk-ICLB27PZ.js";
@@ -318,7 +318,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
318
318
  }
319
319
  }
320
320
  if (node.hasChildren) {
321
- nodeG.attr("data-node-toggle", node.id).attr("tabindex", "0").attr("role", "button").attr(
321
+ nodeG.attr("data-node-toggle", node.id).attr("role", "button").attr(
322
322
  "aria-expanded",
323
323
  node.hiddenCount != null && node.hiddenCount > 0 ? "false" : "true"
324
324
  ).attr("aria-label", node.label);
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  resolveNotes,
6
6
  tryCollectNote
7
- } from "./chunk-NJJCTEBM.js";
7
+ } from "./chunk-KLBTJEIK.js";
8
8
  import {
9
9
  displayName,
10
10
  normalizeName
@@ -18,11 +18,11 @@ import {
18
18
  } from "./chunk-3DPOIW3W.js";
19
19
  import {
20
20
  wrapDescriptionLines
21
- } from "./chunk-MB2SQF7N.js";
21
+ } from "./chunk-7WEYXYLC.js";
22
22
  import {
23
23
  renderInlineText,
24
24
  stripInlineMarkdown
25
- } from "./chunk-65GPEV5V.js";
25
+ } from "./chunk-QKPOIJBT.js";
26
26
  import {
27
27
  FONT_FAMILY
28
28
  } from "./chunk-ICLB27PZ.js";
@@ -9,7 +9,7 @@ import {
9
9
  capLabelColumn,
10
10
  computeTimeTicks,
11
11
  showFullOnHover
12
- } from "./chunk-VSOZZYLK.js";
12
+ } from "./chunk-NERQSSYD.js";
13
13
  import {
14
14
  parseTimelineDate
15
15
  } from "./chunk-BQO24BDM.js";
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  WHITEBOARD_COLORS,
3
3
  WHITEBOARD_ELEMENT_KEYWORDS,
4
+ WHITEBOARD_LABEL_POSITIONS,
4
5
  WHITEBOARD_NOTE_COLOR,
5
6
  WHITEBOARD_NOTE_HEIGHT,
6
7
  WHITEBOARD_NOTE_WIDTH,
7
8
  isWhiteboardColor,
8
9
  isWhiteboardShapeKind
9
- } from "./chunk-P7TRFL4P.js";
10
+ } from "./chunk-R46N5KR4.js";
10
11
  import {
11
12
  extractPaletteDirective
12
13
  } from "./chunk-CYTFO2LF.js";
@@ -100,7 +101,7 @@ var WHITEBOARD_DIAGNOSTICS = [
100
101
  chartType: "whiteboard",
101
102
  title: "Unknown whiteboard value",
102
103
  message: (p) => `Unknown ${s(p.key)}: "${s(p.value)}" \u2014 ${s(p.fallback)} used instead (valid: ${s(p.valid)})${p.hint ? `. ${s(p.hint)}` : ""}`,
103
- hint: "Shapes take `fill: solid` or `fill: outline`; arrows take `heads: both`; arrows and lines take `bend:` as a whole number.",
104
+ hint: "Shapes take `fill: solid` or `fill: outline`, and `label: top` or `label: middle`; arrows take `heads: both`; arrows and lines take `bend:` as a whole number.",
104
105
  example: "whiteboard\nrectangle at: 0 0, size: 100 60, fill: hatched"
105
106
  },
106
107
  {
@@ -353,8 +354,9 @@ var INK_WIDTH_RE = /^\d+(\.\d+)?$/;
353
354
  var INK_WIDTH_MAX = 200;
354
355
  var WRITTEN_STYLES = ["dashed"];
355
356
  var WRITTEN_FILLS = ["solid", "outline"];
357
+ var labelPart = (p) => p ? { labelPosition: p } : {};
356
358
  var KEYS_BY_KIND = {
357
- shape: ["at", "size", "color", "fill"],
359
+ shape: ["at", "size", "color", "fill", "label"],
358
360
  note: ["at", "size", "color"],
359
361
  arrow: ["from", "to", "color", "style", "heads", "bend"],
360
362
  line: ["from", "to", "color", "style", "bend"],
@@ -480,6 +482,19 @@ function parseWhiteboard(content, _palette) {
480
482
  });
481
483
  return "tint";
482
484
  };
485
+ const readLabelPosition = (raw, line) => {
486
+ if (raw === void 0) return void 0;
487
+ const v = raw.trim().toLowerCase();
488
+ if (v === "top" || v === "middle") return v;
489
+ warn(line, WHITEBOARD_DIAGNOSTIC_CODES.BAD_VALUE, {
490
+ key: "label",
491
+ value: raw,
492
+ fallback: "automatic",
493
+ valid: WHITEBOARD_LABEL_POSITIONS.join(", "),
494
+ hint: suggest(v, WHITEBOARD_LABEL_POSITIONS) ?? ""
495
+ });
496
+ return void 0;
497
+ };
483
498
  const readHeads = (raw, line) => {
484
499
  if (raw === void 0) return "end";
485
500
  const v = raw.trim().toLowerCase();
@@ -684,6 +699,7 @@ function parseWhiteboard(content, _palette) {
684
699
  label: joinLabel(name, body),
685
700
  color: readColor(meta.get("color"), lineNumber),
686
701
  fill: readFill(meta.get("fill"), lineNumber),
702
+ ...labelPart(readLabelPosition(meta.get("label"), lineNumber)),
687
703
  lineNumber
688
704
  });
689
705
  continue;
@@ -81,5 +81,6 @@ function layoutInlineHeader(input) {
81
81
  export {
82
82
  legendInlineSupported,
83
83
  INLINE_HEADER_PAD,
84
+ measureTitleWidth,
84
85
  layoutInlineHeader
85
86
  };