@diagrammo/dgmo 0.92.1 → 0.94.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 (174) hide show
  1. package/dist/advanced.d.ts +103 -38
  2. package/dist/advanced.js +457 -423
  3. package/dist/block.d.ts +2 -2
  4. package/dist/block.js +75 -70
  5. package/dist/{chart-meta-BBqLnv5q.d.ts → chart-meta-BbjsRY7o.d.ts} +2 -2
  6. package/dist/chart-meta.d.ts +3 -3
  7. package/dist/chart-meta.js +25 -19
  8. package/dist/{chart-types-CbXlZFLd.d.ts → chart-types-Cppnp31G.d.ts} +173 -4
  9. package/dist/{charts-d3-QUUDVETP.js → charts-d3-SZV2SFTM.js} +7 -6
  10. package/dist/{chunk-ADNIO3XY.js → chunk-2FDQEQID.js} +5 -5
  11. package/dist/{chunk-QUGC7GWB.js → chunk-2HSHWPTO.js} +15 -15
  12. package/dist/{chunk-L5NW3PVL.js → chunk-2I4UQG7W.js} +1 -1
  13. package/dist/{chunk-2YAFDND3.js → chunk-2MS623GW.js} +4 -6
  14. package/dist/{chunk-73EYNV4O.js → chunk-2XMTZ5JR.js} +4 -6
  15. package/dist/{chunk-ZJAK6C7Y.js → chunk-3PP746YM.js} +6 -1
  16. package/dist/{chunk-MDVJYRJT.js → chunk-3TWBMU7K.js} +22 -22
  17. package/dist/{chunk-FTUMRSGT.js → chunk-3ZP3QC47.js} +8 -288
  18. package/dist/{chunk-J2E7EUER.js → chunk-4EX4OKGZ.js} +86 -23
  19. package/dist/{chunk-Y2V5AEVG.js → chunk-4SP6OUO7.js} +1952 -1824
  20. package/dist/{chunk-HIWHIYLD.js → chunk-4TEPDQHJ.js} +19 -19
  21. package/dist/{chunk-DEFBUZWV.js → chunk-5HAYT43L.js} +70 -54
  22. package/dist/{chunk-6WVX4KNP.js → chunk-5ZUZZDW5.js} +97 -297
  23. package/dist/{chunk-X5BUX2GK.js → chunk-6JCTW74W.js} +7 -5
  24. package/dist/{chunk-Q6W2K33N.js → chunk-6XLMTAEX.js} +1 -1
  25. package/dist/{chunk-ONYO5WJW.js → chunk-7IOZ6JE4.js} +21 -21
  26. package/dist/chunk-7SXV7NUS.js +416 -0
  27. package/dist/{chunk-NPWVOFB3.js → chunk-7WEYXYLC.js} +1 -1
  28. package/dist/{chunk-GE7ICBX6.js → chunk-AM42TLSZ.js} +102 -97
  29. package/dist/{chunk-WLLO3PZ3.js → chunk-AYUSD4Z6.js} +45 -19
  30. package/dist/{chunk-45QUTYPD.js → chunk-B25IWGDH.js} +69 -20
  31. package/dist/{chunk-JKST4RTT.js → chunk-BH2SF4TT.js} +6 -6
  32. package/dist/{chunk-6OIMUSDX.js → chunk-C6G36F5S.js} +9 -9
  33. package/dist/{chunk-DRFGIOZ6.js → chunk-CIHHTS5B.js} +4 -6
  34. package/dist/chunk-CYTFO2LF.js +209 -0
  35. package/dist/{chunk-Q2UFOKPB.js → chunk-DDIOWNHS.js} +22 -22
  36. package/dist/{chunk-Q6ZQX2HX.js → chunk-DLJJOCIT.js} +4 -6
  37. package/dist/{chunk-26BBJUBW.js → chunk-DNM3XZCK.js} +4 -6
  38. package/dist/{chunk-AUS7V54P.js → chunk-ERT7XDQW.js} +1 -1
  39. package/dist/{chunk-7ENDOHAA.js → chunk-FMAVHTYB.js} +919 -927
  40. package/dist/{chunk-URQIWIKX.js → chunk-FWVE373X.js} +4 -4
  41. package/dist/{chunk-VOR32OHN.js → chunk-G3HZ4PGE.js} +13 -15
  42. package/dist/{chunk-RBFJT23E.js → chunk-GWQRTA5W.js} +6 -6
  43. package/dist/chunk-GXCDD6NG.js +24 -0
  44. package/dist/{chunk-3PFMGNOM.js → chunk-HHVIE45A.js} +26 -11
  45. package/dist/{chunk-MXAP37W6.js → chunk-HI6R27YA.js} +16 -7
  46. package/dist/{chunk-QQPNCXAO.js → chunk-I37S3EZE.js} +18 -18
  47. package/dist/{chunk-YITHYQCL.js → chunk-IGJEKO2P.js} +8 -8
  48. package/dist/{chunk-BZX7QCXJ.js → chunk-IHN6WDEY.js} +15 -15
  49. package/dist/{chunk-QT3KDDXK.js → chunk-IN7XI6NO.js} +0 -7
  50. package/dist/{chunk-4QLGGQNO.js → chunk-IZHGT5HD.js} +44 -18
  51. package/dist/{chunk-5SSTVFPX.js → chunk-JT2BG7LM.js} +5 -7
  52. package/dist/{chunk-2BJW7FSF.js → chunk-KBEWVCK3.js} +1 -1
  53. package/dist/{chunk-DUPZ2BBY.js → chunk-KBHT5XEY.js} +143 -6
  54. package/dist/{chunk-V4D2ZQBE.js → chunk-KRPLP5LP.js} +6 -1
  55. package/dist/{chunk-QKY6W4NA.js → chunk-KSZB7TIY.js} +25 -25
  56. package/dist/{chunk-6ZL2XYM7.js → chunk-MLY5ALOV.js} +6 -6
  57. package/dist/{chunk-VSOZZYLK.js → chunk-NERQSSYD.js} +20 -9
  58. package/dist/{chunk-OQW4ETJX.js → chunk-NM5V5EKY.js} +6 -1
  59. package/dist/{chunk-EBSFSOJC.js → chunk-NOQB4KMV.js} +22 -22
  60. package/dist/{chunk-6BNNLVAR.js → chunk-NPDVWFAQ.js} +6 -1
  61. package/dist/{chunk-FSJ3ZA6N.js → chunk-OSSTOSXU.js} +12 -12
  62. package/dist/chunk-P7TRFL4P.js +54 -0
  63. package/dist/{chunk-A4PNWAUW.js → chunk-PGSGJLUR.js} +6 -1
  64. package/dist/{chunk-S7W75MIM.js → chunk-QKPOIJBT.js} +23 -5
  65. package/dist/{chunk-YO6AQU4A.js → chunk-QPQWY5RU.js} +12 -12
  66. package/dist/{chunk-NREU4JFE.js → chunk-RBVFNUAL.js} +6 -8
  67. package/dist/{chunk-5EBYPETE.js → chunk-RESEJSCV.js} +3 -5
  68. package/dist/{chunk-BRSM6Z34.js → chunk-RITTLIDJ.js} +14 -14
  69. package/dist/{chunk-MX4SZLSV.js → chunk-S5Y3OO3V.js} +16 -8
  70. package/dist/{chunk-O5WUZGPV.js → chunk-TASRGDYP.js} +18 -18
  71. package/dist/{chunk-HXULJZA2.js → chunk-TDAGJJPZ.js} +6 -1
  72. package/dist/chunk-UCHZJJIT.js +421 -0
  73. package/dist/{chunk-42UJ23H3.js → chunk-UIEKW4SG.js} +1 -0
  74. package/dist/{chunk-WFA6IULY.js → chunk-URRAWU5D.js} +5 -0
  75. package/dist/{chunk-IGKFOHBG.js → chunk-VBMRZCMQ.js} +13 -13
  76. package/dist/{chunk-JRWUHLRP.js → chunk-VDY2GR6U.js} +51 -8
  77. package/dist/{chunk-EJS3K44P.js → chunk-VGAMBOOC.js} +5 -3
  78. package/dist/{chunk-B5PEKSRH.js → chunk-VSAKEMDD.js} +6 -1
  79. package/dist/chunk-WTTIODDV.js +9 -0
  80. package/dist/{chunk-JLU52ZDT.js → chunk-XJQ6Z3FO.js} +10 -10
  81. package/dist/{chunk-KTGZDMDX.js → chunk-XKCRKD2B.js} +140 -53
  82. package/dist/{chunk-LRP5FXST.js → chunk-YQMIKX54.js} +61 -24
  83. package/dist/{chunk-H5UEVW6Q.js → chunk-ZD3QCNB7.js} +1 -1
  84. package/dist/clock.js +168 -0
  85. package/dist/completion-registry.js +3 -1
  86. package/dist/countdown.js +36 -395
  87. package/dist/{dgmo-router-4UAPPIKN.js → dgmo-router-E5O7RJSW.js} +50 -43
  88. package/dist/{dimensions-SCNVYLRF.js → dimensions-DS6FWLRY.js} +3 -3
  89. package/dist/{d3-BThYBTQk.d.ts → export-context-Ceh3wr0E.d.ts} +2 -8
  90. package/dist/{flowchart-parser-NA75YQ77.js → flowchart-parser-NZXASOZG.js} +8 -3
  91. package/dist/{flowchart-renderer-6MGGX4RC.js → flowchart-renderer-PTCRIANF.js} +17 -19
  92. package/dist/index.d.ts +8 -7
  93. package/dist/index.js +80 -74
  94. package/dist/{layout-MBVBAMPA.js → layout-3TSVAGWH.js} +2 -2
  95. package/dist/layout-ISSBWBH7.js +24 -0
  96. package/dist/layout-IT4ZTV6C.js +24 -0
  97. package/dist/{layout-BNLFQHSB.js → layout-U3AH6M7J.js} +9 -10
  98. package/dist/layout-VC3MXRB4.js +29 -0
  99. package/dist/layout-VDCJOZSH.js +11 -0
  100. package/dist/{layout-search-PMYL3VWS.js → layout-search-BBX2BMEF.js} +11 -12
  101. package/dist/{palettes-IN7ZFRJM.js → palettes-4Y7CL2QL.js} +4 -2
  102. package/dist/{parser-QYISOAGR.js → parser-4RFY7D52.js} +8 -3
  103. package/dist/{parser-3MK56JZC.js → parser-4Y6PODW6.js} +2 -2
  104. package/dist/{parser-GX5YLRIP.js → parser-7QKQ4P4P.js} +8 -3
  105. package/dist/{parser-2NWH5JUS.js → parser-A3AN76RQ.js} +2 -1
  106. package/dist/{parser-LCJ76UXS.js → parser-BT4NI6JY.js} +5 -1
  107. package/dist/{parser-FXDS4JDK.js → parser-F7NDRPMA.js} +2 -2
  108. package/dist/{parser-BES6LV3G.js → parser-GDLKUBTO.js} +5 -1
  109. package/dist/{parser-SEUTXN6U.js → parser-KJPPUN4D.js} +2 -2
  110. package/dist/{parser-SIKL4PLF.js → parser-KMKVFET2.js} +5 -1
  111. package/dist/{parser-5LW5JDYG.js → parser-NL73FSFI.js} +5 -1
  112. package/dist/{parser-VA7ZQQTA.js → parser-NUU3DVW4.js} +5 -1
  113. package/dist/{parser-XZUKNZPB.js → parser-R3LPEQIT.js} +7 -1
  114. package/dist/{parser-X23GRTQJ.js → parser-RCIEKN7Y.js} +5 -1
  115. package/dist/{parser-L6RWDXQN.js → parser-TAYRTCPR.js} +8 -3
  116. package/dist/redraw-AHW7EUUF.js +1698 -0
  117. package/dist/redraw-STZ4WJAI.js +73 -0
  118. package/dist/{renderer-LM4ICK6I.js → renderer-2LYX6NHN.js} +4 -5
  119. package/dist/{renderer-NHTR7IRR.js → renderer-3NLDX7DQ.js} +4 -5
  120. package/dist/{renderer-TO2NVJP3.js → renderer-4SE7R22T.js} +50 -45
  121. package/dist/{renderer-3IHQI4A4.js → renderer-53B523PM.js} +11 -10
  122. package/dist/{renderer-3JY6JAQJ.js → renderer-7OGGV327.js} +5 -6
  123. package/dist/{renderer-2FVUPBGV.js → renderer-AM7P4LN7.js} +1 -1
  124. package/dist/{renderer-5VKPB4LL.js → renderer-BXD5KVSR.js} +5 -5
  125. package/dist/{renderer-OAR5VPH4.js → renderer-DAZWHNLI.js} +2 -2
  126. package/dist/{renderer-WIU5BJUK.js → renderer-DDWDCM2K.js} +2 -2
  127. package/dist/{renderer-3QAFDXEY.js → renderer-FMTLSOCX.js} +16 -12
  128. package/dist/{renderer-JEJT3YET.js → renderer-HX6ICPDX.js} +2 -3
  129. package/dist/{renderer-NDA2FFYB.js → renderer-ISQJ2ELA.js} +5 -5
  130. package/dist/{renderer-XGG2UNXT.js → renderer-IXBOT6DU.js} +3 -4
  131. package/dist/{renderer-S3YCLJKL.js → renderer-J3GPDK73.js} +20 -22
  132. package/dist/{renderer-DVNMCYHZ.js → renderer-J7ZSTJUE.js} +15 -15
  133. package/dist/{renderer-ALWVK3EJ.js → renderer-JJ4QW3SK.js} +6 -6
  134. package/dist/{renderer-RUSFL7WU.js → renderer-JYHA6R2D.js} +8 -7
  135. package/dist/{renderer-5TZVFQ7K.js → renderer-KJ3V5BYP.js} +7 -8
  136. package/dist/{renderer-RSK6QFWN.js → renderer-LNP23NSM.js} +7 -9
  137. package/dist/{renderer-ZHGHTSNG.js → renderer-M5DUMITP.js} +13 -12
  138. package/dist/{renderer-O6DY46AV.js → renderer-MWZC7TMD.js} +7 -7
  139. package/dist/{renderer-DC7C5Q3G.js → renderer-NOYLNVTI.js} +2 -2
  140. package/dist/{renderer-ISSDGK54.js → renderer-O6RP52CQ.js} +3 -3
  141. package/dist/{renderer-ZGY7P4BM.js → renderer-OUDHH5MV.js} +19 -22
  142. package/dist/{renderer-QGIHLZOJ.js → renderer-PHLCYVSN.js} +9 -10
  143. package/dist/{renderer-VPIELEE5.js → renderer-QTPWRRJ7.js} +8 -9
  144. package/dist/{renderer-LQP3AGEJ.js → renderer-RUSQJFFC.js} +3 -4
  145. package/dist/{renderer-MM27BSBO.js → renderer-TINHO2IO.js} +3 -4
  146. package/dist/{renderer-7ZZG5HR3.js → renderer-UTEEJDGB.js} +9 -9
  147. package/dist/{renderer-J5FKF423.js → renderer-W4MUMXJE.js} +7 -4
  148. package/dist/{renderer-XO57LTU4.js → renderer-WPN2SXGT.js} +5 -5
  149. package/dist/{renderer-ZZ6MWVB7.js → renderer-XCLARXCK.js} +4 -4
  150. package/dist/{renderer-J666LZXJ.js → renderer-XOWDERU2.js} +8 -8
  151. package/dist/{state-parser-TIR2ORJY.js → state-parser-KPVW5CRI.js} +8 -3
  152. package/dist/{state-renderer-G6SUXU4J.js → state-renderer-ZVEI265C.js} +18 -21
  153. package/dist/{tag-groups-DsoVpAY-.d.ts → tag-groups-DydewK3D.d.ts} +2 -173
  154. package/dist/{themes-DRNjxX7Q.d.ts → themes-DzIH3Hjv.d.ts} +3 -2
  155. package/docs/ai-integration.md +1 -1
  156. package/docs/language-reference.md +23 -2
  157. package/gallery/fixtures/whiteboard.dgmo +3 -0
  158. package/package.json +2 -6
  159. package/dist/chunk-3Y63RFJL.js +0 -75
  160. package/dist/chunk-5DH3KYFH.js +0 -20
  161. package/dist/chunk-O753JUEZ.js +0 -67
  162. package/dist/chunk-RJNZHFNG.js +0 -51
  163. package/dist/chunk-Z6DXWULM.js +0 -23
  164. package/dist/layout-5USEVQBY.js +0 -25
  165. package/dist/layout-J3AGFZZ7.js +0 -10
  166. package/dist/layout-S3RLVPH4.js +0 -25
  167. package/dist/layout-WRG4APSJ.js +0 -32
  168. package/dist/{chunk-DGUGE67L.js → chunk-CDYV46JE.js} +3 -3
  169. package/dist/{chunk-TKAB3FTK.js → chunk-DRQSB72S.js} +11 -11
  170. package/dist/{chunk-ZKP77MB3.js → chunk-FVTYJUXR.js} +5 -5
  171. package/dist/{chunk-MA42PIGJ.js → chunk-H5NVCOEJ.js} +4 -4
  172. package/dist/{chunk-BEA4D7OS.js → chunk-IXHWS2HI.js} +3 -3
  173. package/dist/{chunk-SOHZDW6N.js → chunk-UXNA2H2V.js} +3 -3
  174. package/dist/{chunk-NO3UX6AP.js → chunk-V2NQV7VL.js} +4 -4
@@ -1,17 +1,27 @@
1
1
  import {
2
2
  drawCylinderCard,
3
3
  drawQueueCard
4
- } from "./chunk-BZX7QCXJ.js";
4
+ } from "./chunk-IHN6WDEY.js";
5
5
  import {
6
6
  CYLINDER_RY,
7
7
  QUEUE_CAP
8
8
  } from "./chunk-5KKZXA44.js";
9
+ import {
10
+ WHITEBOARD_COLORS,
11
+ WHITEBOARD_NOTE_COLOR
12
+ } from "./chunk-P7TRFL4P.js";
9
13
  import {
10
14
  renderChartTitle
11
- } from "./chunk-Q6W2K33N.js";
15
+ } from "./chunk-6XLMTAEX.js";
12
16
  import {
13
17
  TITLE_FONT_SIZE
14
18
  } from "./chunk-VLC6WNRD.js";
19
+ import {
20
+ renderIntegratedLegend
21
+ } from "./chunk-NMS5XSLX.js";
22
+ import {
23
+ getMaxLegendReservedHeight
24
+ } from "./chunk-JILEYZ2V.js";
15
25
  import {
16
26
  FONT_FAMILY
17
27
  } from "./chunk-ICLB27PZ.js";
@@ -420,6 +430,33 @@ function visibleWhiteboardElements(parsed, options = {}) {
420
430
  }
421
431
  var WHITEBOARD_MARGIN = 24;
422
432
  var TITLE_BAND = 40;
433
+ var LEGEND_GAP = 8;
434
+ var LEGEND_FAINT_OPACITY = 0.4;
435
+ var LEGEND_DEFAULT_GROUP = "Meaning";
436
+ function whiteboardLegend(parsed, elements, colorOf) {
437
+ const used = /* @__PURE__ */ new Set();
438
+ for (const el of elements) {
439
+ const c = legendColor(el);
440
+ if (c) used.add(c);
441
+ }
442
+ if (used.size < 2) return null;
443
+ const tags = parsed.tagGroups[0];
444
+ const nameOf = (c) => tags?.entries.find((e) => e.color === c)?.value ?? "";
445
+ const entries = WHITEBOARD_COLORS.filter((c) => used.has(c)).map((c) => ({
446
+ value: nameOf(c),
447
+ color: colorOf(c)
448
+ }));
449
+ return {
450
+ group: { name: tags?.name ?? LEGEND_DEFAULT_GROUP, entries },
451
+ named: entries.some((e) => e.value !== ""),
452
+ entryOf: new Map([...used].map((c) => [c, nameOf(c)]))
453
+ };
454
+ }
455
+ function legendColor(el) {
456
+ if (!("color" in el) || el.color === "ink") return null;
457
+ if (el.kind === "note" && el.color === WHITEBOARD_NOTE_COLOR) return null;
458
+ return el.color;
459
+ }
423
460
  var SHAPE_STROKE = 2;
424
461
  var ARROW_STROKE = 2;
425
462
  var ARROW_HEAD_LEN = 12;
@@ -461,6 +498,7 @@ function whiteboardBounds(parsed, options = {}) {
461
498
  maxY: -Infinity
462
499
  };
463
500
  const elements = visibleWhiteboardElements(parsed, options);
501
+ const labelAt = placeConnectorLabels(elements);
464
502
  for (const el of elements) {
465
503
  switch (el.kind) {
466
504
  case "shape":
@@ -490,7 +528,7 @@ function whiteboardBounds(parsed, options = {}) {
490
528
  }
491
529
  if (el.label) {
492
530
  const lines = labelLines(el.label);
493
- const { x: mx, y: my } = whiteboardSegmentMidpoint(s);
531
+ const { x: mx, y: my } = labelAt.get(el);
494
532
  const hw = widest(lines, WHITEBOARD_LABEL_FONT) / 2 + 4;
495
533
  const hh = WHITEBOARD_LABEL_FONT + (lines.length - 1) * WHITEBOARD_LABEL_FONT * WHITEBOARD_LABEL_LINE / 2;
496
534
  grow(b, mx - hw, my - hh, mx + hw, my + hh);
@@ -541,6 +579,79 @@ function curveTrim(s, end, len) {
541
579
  }
542
580
  return (near + far) / 2;
543
581
  }
582
+ var LABEL_SLIDE_STEP = 0.05;
583
+ var LABEL_SLIDE_TRIES = 8;
584
+ var LABEL_CLEAR = 5;
585
+ function boxesOverlap(a, b) {
586
+ return a.x0 < b.x1 && b.x0 < a.x1 && a.y0 < b.y1 && b.y0 < a.y1;
587
+ }
588
+ function connectorLabelBox(lines, x, y) {
589
+ const hw = widest(lines, WHITEBOARD_LABEL_FONT) / 2 + LABEL_CLEAR;
590
+ const hh = lines.length * WHITEBOARD_LABEL_FONT * WHITEBOARD_LABEL_LINE / 2 + LABEL_CLEAR;
591
+ return { x0: x - hw, y0: y - hh, x1: x + hw, y1: y + hh };
592
+ }
593
+ function authoredTextBoxes(elements) {
594
+ const boxes = [];
595
+ for (const el of elements) {
596
+ if (el.kind === "text") {
597
+ const lines = labelLines(el.text);
598
+ boxes.push({
599
+ x0: el.x,
600
+ y0: el.y,
601
+ x1: el.x + widest(lines, WHITEBOARD_TEXT_FONT),
602
+ y1: el.y + lines.length * WHITEBOARD_TEXT_FONT * WHITEBOARD_LABEL_LINE
603
+ });
604
+ } else if (el.kind === "note") {
605
+ boxes.push({
606
+ x0: el.x,
607
+ y0: el.y,
608
+ x1: el.x + el.width,
609
+ y1: el.y + Math.max(el.height, noteTextHeight(el))
610
+ });
611
+ } else if (el.kind === "shape" && el.label) {
612
+ const { lines, font } = fitWhiteboardLabel(el.label, el);
613
+ if (lines.length === 0) continue;
614
+ const cx = el.x + el.width / 2 + whiteboardLabelShift(el);
615
+ const cy = el.y + el.height / 2;
616
+ const hw = widest(lines, font) / 2;
617
+ const hh = lines.length * font * WHITEBOARD_LABEL_LINE / 2;
618
+ boxes.push({ x0: cx - hw, y0: cy - hh, x1: cx + hw, y1: cy + hh });
619
+ }
620
+ }
621
+ return boxes;
622
+ }
623
+ function placeConnectorLabels(elements) {
624
+ const placed = /* @__PURE__ */ new Map();
625
+ const taken = authoredTextBoxes(elements);
626
+ for (const el of elements) {
627
+ if (el.kind !== "arrow" && el.kind !== "line" || !el.label) continue;
628
+ const lines = labelLines(el.label);
629
+ const s = clipWhiteboardConnector(el, elements);
630
+ const mid = whiteboardSegmentMidpoint(s);
631
+ let at = mid;
632
+ const clears = (p) => {
633
+ const box = connectorLabelBox(lines, p.x, p.y);
634
+ return !taken.some((t) => boxesOverlap(box, t));
635
+ };
636
+ if (!clears(mid)) {
637
+ search: for (let k = 1; k <= LABEL_SLIDE_TRIES; k++) {
638
+ for (const t of [
639
+ 0.5 - k * LABEL_SLIDE_STEP,
640
+ 0.5 + k * LABEL_SLIDE_STEP
641
+ ]) {
642
+ const p = segmentPoint(s, t);
643
+ if (clears(p)) {
644
+ at = p;
645
+ break search;
646
+ }
647
+ }
648
+ }
649
+ }
650
+ placed.set(el, at);
651
+ taken.push(connectorLabelBox(lines, at.x, at.y));
652
+ }
653
+ return placed;
654
+ }
544
655
  function whiteboardConnectorPaint(s, heads) {
545
656
  const polygon = (tip, ux, uy, head) => {
546
657
  const bx = tip.x - ux * head;
@@ -628,13 +739,26 @@ function renderWhiteboard(container, parsed, palette, isDark, options = {}) {
628
739
  const titleOffset = showTitle ? TITLE_BAND : 0;
629
740
  const elements = visibleWhiteboardElements(parsed, options);
630
741
  const b = whiteboardBounds(parsed, options);
742
+ const labelAt = placeConnectorLabels(elements);
631
743
  const contentW = b.maxX - b.minX;
632
744
  const contentH = b.maxY - b.minY;
633
745
  const titleW = showTitle ? measureText(parsed.title, TITLE_FONT_SIZE, { bold: true }) : 0;
634
746
  const width = Math.ceil(Math.max(contentW, titleW) + 2 * WHITEBOARD_MARGIN);
635
- const height = Math.ceil(contentH + 2 * WHITEBOARD_MARGIN + titleOffset);
747
+ const legend = whiteboardLegend(parsed, elements, colorOf);
748
+ const legendConfig = legend && {
749
+ groups: [legend.group],
750
+ position: {
751
+ placement: "top-center",
752
+ titleRelation: "below-title"
753
+ },
754
+ mode: "export"
755
+ };
756
+ const legendOffset = legendConfig ? getMaxLegendReservedHeight(legendConfig, width) + LEGEND_GAP : 0;
757
+ const height = Math.ceil(
758
+ contentH + 2 * WHITEBOARD_MARGIN + titleOffset + legendOffset
759
+ );
636
760
  const tx = WHITEBOARD_MARGIN - b.minX + (width - 2 * WHITEBOARD_MARGIN - contentW) / 2;
637
- const ty = WHITEBOARD_MARGIN + titleOffset - b.minY;
761
+ const ty = WHITEBOARD_MARGIN + titleOffset + legendOffset - b.minY;
638
762
  d3.select(container).selectAll("*").remove();
639
763
  const svg = d3.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).style("font-family", FONT_FAMILY);
640
764
  if (showTitle) {
@@ -646,6 +770,17 @@ function renderWhiteboard(container, parsed, palette, isDark, options = {}) {
646
770
  palette.text
647
771
  );
648
772
  }
773
+ if (legend && legendConfig) {
774
+ const legendG = svg.append("g").attr("class", "whiteboard-legend").attr("transform", `translate(0,${titleOffset + WHITEBOARD_MARGIN / 2})`);
775
+ if (!legend.named) legendG.attr("opacity", LEGEND_FAINT_OPACITY);
776
+ renderIntegratedLegend(legendG, {
777
+ ...legendConfig,
778
+ activeGroup: legend.group.name,
779
+ palette,
780
+ isDark,
781
+ width
782
+ });
783
+ }
649
784
  const canvas = svg.append("g").attr("class", "whiteboard-canvas").attr("transform", `translate(${round2(tx)},${round2(ty)})`);
650
785
  const halo = palette.bg;
651
786
  const centredLabel = (g, { lines, font }, cx, cy, color, ground) => {
@@ -671,6 +806,8 @@ function renderWhiteboard(container, parsed, palette, isDark, options = {}) {
671
806
  };
672
807
  const drawElement = (el) => {
673
808
  const g = canvas.append("g").attr("class", `whiteboard-${el.kind === "shape" ? el.shape : el.kind}`).attr("data-line-number", el.lineNumber);
809
+ const lc = legend && legendColor(el);
810
+ if (lc) g.attr("data-wb-meaning", legend.entryOf.get(lc) ?? "");
674
811
  switch (el.kind) {
675
812
  case "shape": {
676
813
  const hue = colorOf(el.color);
@@ -752,7 +889,7 @@ function renderWhiteboard(container, parsed, palette, isDark, options = {}) {
752
889
  }
753
890
  if (el.label) {
754
891
  const lines = labelLines(el.label);
755
- const mid = whiteboardSegmentMidpoint(s);
892
+ const mid = labelAt.get(el);
756
893
  const mx = round2(mid.x);
757
894
  const lh = WHITEBOARD_LABEL_FONT * WHITEBOARD_LABEL_LINE;
758
895
  const firstY = mid.y + WHITEBOARD_LABEL_FONT * 0.35 - (lines.length - 1) * lh / 2;
@@ -1,3 +1,6 @@
1
+ import {
2
+ extractPaletteDirective
3
+ } from "./chunk-CYTFO2LF.js";
1
4
  import {
2
5
  displayName,
3
6
  normalizeName
@@ -95,7 +98,9 @@ function parseRaci(content, palette) {
95
98
  if (!content?.trim()) {
96
99
  return fail(0, "No content provided");
97
100
  }
98
- const lines = content.split("\n");
101
+ const directive = extractPaletteDirective(content);
102
+ result.diagnostics.push(...directive.diagnostics);
103
+ const lines = directive.content.split("\n");
99
104
  let i = 0;
100
105
  for (; i < lines.length; i++) {
101
106
  const trimmed = lines[i].trim();
@@ -1,16 +1,31 @@
1
- import {
2
- analyzePert
3
- } from "./chunk-FOTH2WWP.js";
4
1
  import {
5
2
  computeNodeSizing,
6
3
  layoutPert
7
4
  } from "./chunk-NBAAIRFP.js";
5
+ import {
6
+ analyzePert
7
+ } from "./chunk-FOTH2WWP.js";
8
+ import {
9
+ serializeSvg
10
+ } from "./chunk-CYRB2JTN.js";
8
11
  import {
9
12
  ScaleContext
10
13
  } from "./chunk-24YPR5EH.js";
11
14
  import {
12
- renderIntegratedLegend
13
- } from "./chunk-NMS5XSLX.js";
15
+ INLINE_HEADER_PAD,
16
+ layoutInlineHeader
17
+ } from "./chunk-UIEKW4SG.js";
18
+ import {
19
+ CAPTION_BOX_PADDING_X,
20
+ CAPTION_BOX_PADDING_Y,
21
+ CAPTION_FONT_SIZE,
22
+ CAPTION_FONT_WEIGHT,
23
+ CAPTION_LINE_HEIGHT,
24
+ CAPTION_TOP_GAP,
25
+ TITLE_FONT_SIZE,
26
+ TITLE_FONT_WEIGHT,
27
+ TITLE_Y
28
+ } from "./chunk-VLC6WNRD.js";
14
29
  import {
15
30
  ARROWHEAD_HEIGHT,
16
31
  ARROWHEAD_WIDTH,
@@ -27,29 +42,11 @@ import {
27
42
  NODE_STROKE_WIDTH
28
43
  } from "./chunk-XCKNFFKM.js";
29
44
  import {
30
- INLINE_HEADER_PAD,
31
- layoutInlineHeader
32
- } from "./chunk-42UJ23H3.js";
33
- import {
34
- serializeSvg
35
- } from "./chunk-CYRB2JTN.js";
45
+ renderIntegratedLegend
46
+ } from "./chunk-NMS5XSLX.js";
36
47
  import {
37
48
  getLegendExtent
38
49
  } from "./chunk-JILEYZ2V.js";
39
- import {
40
- CAPTION_BOX_PADDING_X,
41
- CAPTION_BOX_PADDING_Y,
42
- CAPTION_FONT_SIZE,
43
- CAPTION_FONT_WEIGHT,
44
- CAPTION_LINE_HEIGHT,
45
- CAPTION_TOP_GAP,
46
- TITLE_FONT_SIZE,
47
- TITLE_FONT_WEIGHT,
48
- TITLE_Y
49
- } from "./chunk-VLC6WNRD.js";
50
- import {
51
- FONT_FAMILY
52
- } from "./chunk-ICLB27PZ.js";
53
50
  import {
54
51
  parsePert
55
52
  } from "./chunk-CDM6XMOT.js";
@@ -60,6 +57,9 @@ import {
60
57
  formatSlackValue,
61
58
  formatSprintCell
62
59
  } from "./chunk-2SKMEL7V.js";
60
+ import {
61
+ FONT_FAMILY
62
+ } from "./chunk-ICLB27PZ.js";
63
63
  import {
64
64
  UNTAGGED_TAG_COLOR,
65
65
  resolveActiveTagGroup,
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  ScaleContext
3
3
  } from "./chunk-24YPR5EH.js";
4
- import {
5
- NODE_STROKE_WIDTH
6
- } from "./chunk-XCKNFFKM.js";
7
4
  import {
8
5
  TITLE_FONT_SIZE,
9
6
  TITLE_FONT_WEIGHT,
10
7
  TITLE_Y
11
8
  } from "./chunk-VLC6WNRD.js";
12
9
  import {
13
- FONT_FAMILY
14
- } from "./chunk-ICLB27PZ.js";
10
+ NODE_STROKE_WIDTH
11
+ } from "./chunk-XCKNFFKM.js";
15
12
  import {
16
13
  allTasks
17
- } from "./chunk-V4D2ZQBE.js";
14
+ } from "./chunk-KRPLP5LP.js";
15
+ import {
16
+ FONT_FAMILY
17
+ } from "./chunk-ICLB27PZ.js";
18
18
  import {
19
19
  VARIANTS
20
20
  } from "./chunk-4WW3SGMH.js";
@@ -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({
@@ -1,3 +1,6 @@
1
+ import {
2
+ extractPaletteDirective
3
+ } from "./chunk-CYTFO2LF.js";
1
4
  import {
2
5
  RING_REGISTRY,
3
6
  measureIndent,
@@ -30,7 +33,9 @@ function parseRing(content) {
30
33
  diagnostics: [],
31
34
  error: null
32
35
  };
33
- const lines = content.split("\n");
36
+ const directive = extractPaletteDirective(content);
37
+ result.diagnostics.push(...directive.diagnostics);
38
+ const lines = directive.content.split("\n");
34
39
  let headerParsed = false;
35
40
  let currentLayer = null;
36
41
  const fail = makeFail(result);
@@ -7,26 +7,17 @@ import {
7
7
  appendArrowheadMarkers,
8
8
  appendReverseArrowheadMarkers
9
9
  } from "./chunk-XBJJP2HN.js";
10
- import {
11
- NOTE_BADGE_RADIUS,
12
- noteConnectorPoints,
13
- renderNoteBadge,
14
- renderNoteBox,
15
- renderNoteConnector
16
- } from "./chunk-JRWUHLRP.js";
17
- import {
18
- wrapDescriptionLines
19
- } from "./chunk-NPWVOFB3.js";
20
- import {
21
- renderInlineText,
22
- stripInlineMarkdown
23
- } from "./chunk-S7W75MIM.js";
24
10
  import {
25
11
  ScaleContext
26
12
  } from "./chunk-24YPR5EH.js";
27
13
  import {
28
- renderIntegratedLegend
29
- } from "./chunk-NMS5XSLX.js";
14
+ layoutInlineHeader
15
+ } from "./chunk-UIEKW4SG.js";
16
+ import {
17
+ TITLE_FONT_SIZE,
18
+ TITLE_FONT_WEIGHT,
19
+ TITLE_Y
20
+ } from "./chunk-VLC6WNRD.js";
30
21
  import {
31
22
  ARROWHEAD_HEIGHT,
32
23
  ARROWHEAD_WIDTH,
@@ -38,17 +29,26 @@ import {
38
29
  NODE_STROKE_WIDTH
39
30
  } from "./chunk-XCKNFFKM.js";
40
31
  import {
41
- layoutInlineHeader
42
- } from "./chunk-42UJ23H3.js";
32
+ renderIntegratedLegend
33
+ } from "./chunk-NMS5XSLX.js";
43
34
  import {
44
35
  getLegendExtent,
45
36
  getMaxLegendReservedHeight
46
37
  } from "./chunk-JILEYZ2V.js";
47
38
  import {
48
- TITLE_FONT_SIZE,
49
- TITLE_FONT_WEIGHT,
50
- TITLE_Y
51
- } from "./chunk-VLC6WNRD.js";
39
+ NOTE_BADGE_RADIUS,
40
+ noteConnectorPoints,
41
+ renderNoteBadge,
42
+ renderNoteBox,
43
+ renderNoteConnector
44
+ } from "./chunk-VDY2GR6U.js";
45
+ import {
46
+ wrapDescriptionLines
47
+ } from "./chunk-7WEYXYLC.js";
48
+ import {
49
+ renderInlineText,
50
+ stripInlineMarkdown
51
+ } from "./chunk-QKPOIJBT.js";
52
52
  import {
53
53
  FONT_FAMILY
54
54
  } from "./chunk-ICLB27PZ.js";
@@ -1,3 +1,6 @@
1
+ import {
2
+ extractPaletteDirective
3
+ } from "./chunk-CYTFO2LF.js";
1
4
  import {
2
5
  CYCLE_REGISTRY,
3
6
  measureIndent,
@@ -27,7 +30,9 @@ function parseCycle(content) {
27
30
  diagnostics: [],
28
31
  error: null
29
32
  };
30
- const lines = content.split("\n");
33
+ const directive = extractPaletteDirective(content);
34
+ result.diagnostics.push(...directive.diagnostics);
35
+ const lines = directive.content.split("\n");
31
36
  let headerParsed = false;
32
37
  let state = "top";
33
38
  let currentNode = null;
@@ -1,24 +1,24 @@
1
- import {
2
- wrapDescriptionLines
3
- } from "./chunk-NPWVOFB3.js";
4
- import {
5
- renderInlineText
6
- } from "./chunk-S7W75MIM.js";
7
1
  import {
8
2
  ScaleContext
9
3
  } from "./chunk-24YPR5EH.js";
10
4
  import {
11
- renderIntegratedLegend
12
- } from "./chunk-NMS5XSLX.js";
5
+ TITLE_FONT_SIZE,
6
+ TITLE_FONT_WEIGHT,
7
+ TITLE_Y
8
+ } from "./chunk-VLC6WNRD.js";
13
9
  import {
14
10
  ARROWHEAD_HEIGHT,
15
11
  ARROWHEAD_WIDTH
16
12
  } from "./chunk-XCKNFFKM.js";
17
13
  import {
18
- TITLE_FONT_SIZE,
19
- TITLE_FONT_WEIGHT,
20
- TITLE_Y
21
- } from "./chunk-VLC6WNRD.js";
14
+ renderIntegratedLegend
15
+ } from "./chunk-NMS5XSLX.js";
16
+ import {
17
+ wrapDescriptionLines
18
+ } from "./chunk-7WEYXYLC.js";
19
+ import {
20
+ renderInlineText
21
+ } from "./chunk-QKPOIJBT.js";
22
22
  import {
23
23
  FONT_FAMILY
24
24
  } from "./chunk-ICLB27PZ.js";
@@ -0,0 +1,54 @@
1
+ // src/whiteboard/types.ts
2
+ var WHITEBOARD_COLORS = [
3
+ "ink",
4
+ "red",
5
+ "green",
6
+ "blue",
7
+ "teal",
8
+ "purple",
9
+ "orange",
10
+ "yellow",
11
+ "cyan",
12
+ "gray"
13
+ ];
14
+ var WHITEBOARD_SHAPE_KINDS = [
15
+ "rectangle",
16
+ "ellipse",
17
+ "database",
18
+ "queue"
19
+ ];
20
+ var WHITEBOARD_ELEMENT_KEYWORDS = [
21
+ ...WHITEBOARD_SHAPE_KINDS,
22
+ "note",
23
+ "arrow",
24
+ "line",
25
+ "text",
26
+ "image",
27
+ "ink"
28
+ ];
29
+ var WHITEBOARD_STROKE_STYLES = ["solid", "dashed"];
30
+ var WHITEBOARD_FILLS = ["tint", "solid", "outline"];
31
+ var WHITEBOARD_HEADS = ["end", "both"];
32
+ var WHITEBOARD_NOTE_WIDTH = 160;
33
+ var WHITEBOARD_NOTE_HEIGHT = 99;
34
+ var WHITEBOARD_NOTE_COLOR = "yellow";
35
+ function isWhiteboardColor(value) {
36
+ return WHITEBOARD_COLORS.includes(value);
37
+ }
38
+ function isWhiteboardShapeKind(value) {
39
+ return WHITEBOARD_SHAPE_KINDS.includes(value);
40
+ }
41
+
42
+ export {
43
+ WHITEBOARD_COLORS,
44
+ WHITEBOARD_SHAPE_KINDS,
45
+ WHITEBOARD_ELEMENT_KEYWORDS,
46
+ WHITEBOARD_STROKE_STYLES,
47
+ WHITEBOARD_FILLS,
48
+ WHITEBOARD_HEADS,
49
+ WHITEBOARD_NOTE_WIDTH,
50
+ WHITEBOARD_NOTE_HEIGHT,
51
+ WHITEBOARD_NOTE_COLOR,
52
+ isWhiteboardColor,
53
+ isWhiteboardShapeKind
54
+ };
@@ -1,3 +1,6 @@
1
+ import {
2
+ extractPaletteDirective
3
+ } from "./chunk-CYTFO2LF.js";
1
4
  import {
2
5
  tryStripDescriptionKeyword
3
6
  } from "./chunk-IYULMRBE.js";
@@ -61,7 +64,9 @@ function parseJourneyMap(content, palette) {
61
64
  if (!content?.trim()) {
62
65
  return fail(0, "No content provided");
63
66
  }
64
- const lines = content.split("\n");
67
+ const directive = extractPaletteDirective(content);
68
+ result.diagnostics.push(...directive.diagnostics);
69
+ const lines = directive.content.split("\n");
65
70
  let contentStarted = false;
66
71
  let activeTagOptionLine = 0;
67
72
  let currentTagGroup = null;