@diagrammo/dgmo 0.57.0 → 0.59.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 (198) hide show
  1. package/dist/advanced.d.ts +57 -7
  2. package/dist/advanced.js +128 -118
  3. package/dist/auto.css +38 -2
  4. package/dist/auto.js +162 -125
  5. package/dist/auto.mjs +1954 -1456
  6. package/dist/block.css +38 -2
  7. package/dist/block.js +94 -52
  8. package/dist/{calculator-BBKAAQGD.js → calculator-ORAKSL5D.js} +4 -2
  9. package/dist/{chart-meta-CPNVUZ5J.d.ts → chart-meta-C6UaqhTP.d.ts} +1 -1
  10. package/dist/chart-meta.d.ts +2 -2
  11. package/dist/chart-meta.js +44 -42
  12. package/dist/{charts-d3-Z6FOKUAL.js → charts-d3-JBNDV6TY.js} +5 -5
  13. package/dist/{chunk-5J2RQGFG.js → chunk-2NSR6INI.js} +3 -3
  14. package/dist/chunk-2SUUYIFC.js +65 -0
  15. package/dist/{chunk-CQJ5SE5T.js → chunk-3T2PKOTK.js} +4 -4
  16. package/dist/{chunk-5XMDSXZT.js → chunk-4IFPX4J6.js} +2 -2
  17. package/dist/{chunk-KRKU6WRS.js → chunk-4KRYJGBY.js} +4 -4
  18. package/dist/{chunk-6HSRT6WI.js → chunk-4YQI7ELC.js} +3 -3
  19. package/dist/{chunk-ORZQVUGW.js → chunk-5XV3Z3UJ.js} +32 -12
  20. package/dist/{chunk-SADYIA5Q.js → chunk-65AMRH2N.js} +3 -3
  21. package/dist/{chunk-MXDT446P.js → chunk-6F74K4JL.js} +51 -14
  22. package/dist/{chunk-ADKDIWCW.js → chunk-6KWE5553.js} +30 -17
  23. package/dist/{chunk-QMOX5I3G.js → chunk-6M3QPUHL.js} +5 -5
  24. package/dist/{chunk-VSFAJUEF.js → chunk-6XWZKCVS.js} +3 -3
  25. package/dist/{chunk-X32RDWT5.js → chunk-6YY56KU2.js} +7 -5
  26. package/dist/{chunk-G3L4GWLA.js → chunk-75LW3IUQ.js} +3 -3
  27. package/dist/{chunk-INU6ANOH.js → chunk-7XTJGMH6.js} +2 -2
  28. package/dist/{chunk-44GBBTMU.js → chunk-A6L6W43V.js} +2 -2
  29. package/dist/{chunk-OFEUXZPI.js → chunk-AFBQEBKL.js} +3 -3
  30. package/dist/{chunk-K2GDF2ZR.js → chunk-BFAU3OPW.js} +4 -4
  31. package/dist/{chunk-USFZQPJ2.js → chunk-BG23Y7JD.js} +3 -3
  32. package/dist/{chunk-ES3MUYRX.js → chunk-BGBGWFUI.js} +3 -3
  33. package/dist/{chunk-6PRLPGJB.js → chunk-BGT6SAR2.js} +3 -3
  34. package/dist/{chunk-FZECLCCU.js → chunk-BVPRRSMX.js} +3 -3
  35. package/dist/{chunk-3M6MKHIQ.js → chunk-CC6XIQDE.js} +2 -2
  36. package/dist/{chunk-U3DGAE7L.js → chunk-CRE3BAKN.js} +3 -3
  37. package/dist/chunk-D3K4U3ZM.js +232 -0
  38. package/dist/{chunk-T2VMOWAM.js → chunk-DD6EA4DU.js} +3 -3
  39. package/dist/{chunk-NFAHDPCG.js → chunk-DDQ47BMP.js} +3 -3
  40. package/dist/{chunk-KH74OWHU.js → chunk-DH3NCG4B.js} +3 -3
  41. package/dist/{chunk-DUI5SMFX.js → chunk-DKG2ADEN.js} +8 -5
  42. package/dist/{chunk-J6V3SMR3.js → chunk-E6QWV2G4.js} +7 -7
  43. package/dist/{chunk-FMPYKUKI.js → chunk-EIRNPTLH.js} +3 -3
  44. package/dist/{chunk-4MJOBVY7.js → chunk-EKKS325Q.js} +2 -2
  45. package/dist/{chunk-KF575IXC.js → chunk-EQGLGTU2.js} +3 -3
  46. package/dist/{chunk-4MB4UOT5.js → chunk-EYP34TFP.js} +2 -2
  47. package/dist/{chunk-LV5BFA24.js → chunk-GCZQAT4Z.js} +3 -3
  48. package/dist/{chunk-MGLJA5TK.js → chunk-GSVHOF3J.js} +2 -2
  49. package/dist/{chunk-ULR3BVNH.js → chunk-HQI7S72D.js} +4 -4
  50. package/dist/{chunk-TZ72UBOA.js → chunk-HSVVQZLC.js} +2 -2
  51. package/dist/{chunk-SQWWYGPT.js → chunk-I24URUTV.js} +5 -5
  52. package/dist/{chunk-FERE46TP.js → chunk-I53E3L5M.js} +9 -7
  53. package/dist/{chunk-NHZAYL2X.js → chunk-IH3GHOHU.js} +7 -6
  54. package/dist/{chunk-57RE4N22.js → chunk-IMEWQLRD.js} +2 -2
  55. package/dist/{chunk-3KOPPSUQ.js → chunk-IXY2IPOW.js} +30 -4
  56. package/dist/chunk-KJ3FIMPA.js +181 -0
  57. package/dist/{chunk-5VLUAAAE.js → chunk-KZFAEMQQ.js} +3 -3
  58. package/dist/{chunk-3ZONSZOX.js → chunk-LBEZKYAR.js} +2 -2
  59. package/dist/{chunk-D5FANMSG.js → chunk-LLA5C2TM.js} +14 -3
  60. package/dist/{chunk-CY5KE2P5.js → chunk-MM4Z32EH.js} +2 -2
  61. package/dist/{chunk-6DR2GMDM.js → chunk-NCW6NQPD.js} +158 -135
  62. package/dist/{chunk-VS7DGDT3.js → chunk-O66TS32B.js} +5 -5
  63. package/dist/{chunk-3G7BCZ4J.js → chunk-OANGI4EI.js} +5 -5
  64. package/dist/{chunk-OYCIVSL3.js → chunk-OBWIIXSZ.js} +6 -6
  65. package/dist/{chunk-X3ON4M5S.js → chunk-OIL6MTVH.js} +4 -4
  66. package/dist/{chunk-RB4HOOKP.js → chunk-OJD4FU6H.js} +2 -2
  67. package/dist/chunk-ON4MEUC4.js +50 -0
  68. package/dist/{chunk-RQGNELB3.js → chunk-OSXJY6SY.js} +3 -3
  69. package/dist/{chunk-U4FSWAOJ.js → chunk-PH36NIGK.js} +4 -4
  70. package/dist/{chunk-M65UOFJA.js → chunk-PNCACNE5.js} +3 -3
  71. package/dist/{chunk-VYEQPPS6.js → chunk-PSWWCLLI.js} +3 -3
  72. package/dist/{chunk-D76B4DMV.js → chunk-QG3RU7YT.js} +2 -2
  73. package/dist/{chunk-Q772PVKH.js → chunk-QTJZRAXM.js} +2 -2
  74. package/dist/{chunk-XBTJJLAU.js → chunk-R53THUTP.js} +4 -4
  75. package/dist/{chunk-PKFW6GJD.js → chunk-RVCBPDCK.js} +3 -3
  76. package/dist/{chunk-D64FRGKU.js → chunk-S5OQWV54.js} +2 -2
  77. package/dist/{chunk-UG4MWUXE.js → chunk-SEPM6JZV.js} +5 -5
  78. package/dist/{chunk-ST3ZNEUQ.js → chunk-SJT4W23S.js} +2 -2
  79. package/dist/{chunk-YNAHUNMA.js → chunk-SLGHGT76.js} +2 -2
  80. package/dist/{chunk-APD52YJV.js → chunk-SQLVM3G7.js} +4 -4
  81. package/dist/{chunk-BQLJAYVB.js → chunk-TDZRLG7I.js} +2 -2
  82. package/dist/{chunk-WOMXS5R7.js → chunk-TJV3J74Y.js} +3 -3
  83. package/dist/{chunk-RV2N7COG.js → chunk-TL6WZWSZ.js} +2 -2
  84. package/dist/{chunk-LZX3RLRP.js → chunk-TLJPI6WL.js} +6 -6
  85. package/dist/{chunk-SFVG4AIG.js → chunk-TR7WNZFJ.js} +3 -3
  86. package/dist/{chunk-7SXTD7L6.js → chunk-U5UKFXHB.js} +2 -2
  87. package/dist/{chunk-7Q35X3AL.js → chunk-UF7WAYBH.js} +9 -233
  88. package/dist/{chunk-7YPSFQFA.js → chunk-UWJNAEMY.js} +6 -6
  89. package/dist/{chunk-EEKGMS63.js → chunk-UYY7MVJK.js} +3 -3
  90. package/dist/{chunk-CXI6X54X.js → chunk-V5PHEH2M.js} +2 -2
  91. package/dist/{chunk-NIUE5VWY.js → chunk-VGFUVFJA.js} +17 -12
  92. package/dist/{chunk-M3IYDSI7.js → chunk-VIFFJOOR.js} +5 -5
  93. package/dist/{chunk-DIKIHU52.js → chunk-W2Z4KS72.js} +6 -4
  94. package/dist/{chunk-A6XELFU6.js → chunk-WBALHD3K.js} +8 -8
  95. package/dist/{chunk-5LBCOFA5.js → chunk-WCSVZW2W.js} +2 -2
  96. package/dist/{chunk-QWUYFUNO.js → chunk-XS7CL7NX.js} +2 -2
  97. package/dist/{chunk-3NSOKT7C.js → chunk-XVOGT46C.js} +2 -2
  98. package/dist/{chunk-3D6LDLIH.js → chunk-Y7KHN3MQ.js} +2 -2
  99. package/dist/{chunk-PRKPFRC2.js → chunk-YOK3BMEW.js} +4 -4
  100. package/dist/{chunk-PUGUOFM6.js → chunk-YPEMNAC7.js} +3 -3
  101. package/dist/{chunk-VYCV5WKH.js → chunk-YURNIF7Q.js} +60 -44
  102. package/dist/{chunk-OHBIN74X.js → chunk-ZBOSGLES.js} +8 -7
  103. package/dist/{chunk-HBRGNLF5.js → chunk-ZED4URQK.js} +6 -6
  104. package/dist/{chunk-TGOMHUOV.js → chunk-ZEIYC7XO.js} +12 -1
  105. package/dist/{chunk-PFG3EVRD.js → chunk-ZTSBP3AH.js} +8 -5
  106. package/dist/cli.cjs +149 -148
  107. package/dist/cloud-reference.d.ts +15 -8
  108. package/dist/cloud-reference.js +8 -39
  109. package/dist/completion-registry.js +24 -5
  110. package/dist/dgmo-router-I2LJOEAQ.js +90 -0
  111. package/dist/{dimensions-XRWIPAFO.js → dimensions-3IMJDSTT.js} +5 -5
  112. package/dist/editor.js +11 -2
  113. package/dist/element.js +163 -126
  114. package/dist/element.mjs +1954 -1456
  115. package/dist/{flowchart-parser-DA3V2SLH.js → flowchart-parser-PZQY2UC4.js} +4 -4
  116. package/dist/{flowchart-renderer-JGLZB5P5.js → flowchart-renderer-CKUW63MB.js} +5 -5
  117. package/dist/highlight.js +11 -2
  118. package/dist/index.d.ts +13 -4
  119. package/dist/index.js +55 -49
  120. package/dist/{layout-AQXLQVAJ.js → layout-2NWRELPU.js} +4 -4
  121. package/dist/{layout-WHOOLGPO.js → layout-47LIQXNX.js} +4 -4
  122. package/dist/{layout-NU5LQ4UP.js → layout-DH6GSKAH.js} +2 -2
  123. package/dist/{layout-AO3TPZUS.js → layout-IXNU33JR.js} +4 -4
  124. package/dist/{layout-5CX27X7I.js → layout-LH6LNIUV.js} +3 -3
  125. package/dist/{layout-TZKPVXKJ.js → layout-MAMV4RZF.js} +3 -3
  126. package/dist/{layout-EQTOVNEE.js → layout-NHNIMAHX.js} +4 -4
  127. package/dist/{layout-search-6CVR2MTZ.js → layout-search-N6NQI5OQ.js} +5 -5
  128. package/dist/{parser-HMQZPPOK.js → parser-2OJSWKXO.js} +4 -4
  129. package/dist/{parser-O5XCVGZG.js → parser-3QHLZK6F.js} +3 -3
  130. package/dist/{parser-SJ7ECFAP.js → parser-453DEZ4P.js} +4 -4
  131. package/dist/{parser-Q3KNFXQR.js → parser-4QYDFXV2.js} +4 -4
  132. package/dist/{parser-XQNM7BGD.js → parser-55CSWK3N.js} +4 -4
  133. package/dist/{parser-PQXN6SBB.js → parser-56HMQG5C.js} +5 -5
  134. package/dist/{parser-QL2LBPFE.js → parser-5BHZMV3O.js} +4 -4
  135. package/dist/{parser-QEWSTNEJ.js → parser-5I7W54EA.js} +4 -4
  136. package/dist/parser-5KOJWHOR.js +12 -0
  137. package/dist/{parser-DTXM5ROT.js → parser-63LK7YBR.js} +5 -5
  138. package/dist/{parser-5UZWYSIV.js → parser-6HT34DZ3.js} +4 -4
  139. package/dist/{parser-CCAUZLYI.js → parser-6S65S3DX.js} +4 -4
  140. package/dist/{parser-MH62NYKM.js → parser-7C5GZCAU.js} +4 -4
  141. package/dist/{parser-5WMH55UA.js → parser-7W7DPIGR.js} +4 -4
  142. package/dist/{parser-4TX6U4ZU.js → parser-AD5OAVX6.js} +3 -3
  143. package/dist/{parser-A6M25MLK.js → parser-AWO3N6YH.js} +3 -3
  144. package/dist/{parser-OPOGIKFR.js → parser-BLCDJB7N.js} +4 -4
  145. package/dist/{parser-KTVDCWHG.js → parser-BNGLB2VS.js} +4 -4
  146. package/dist/{parser-WT3DSNPQ.js → parser-BVC642CN.js} +4 -4
  147. package/dist/{parser-73YUU35J.js → parser-CXLR6MAY.js} +3 -3
  148. package/dist/{parser-6CM27UPA.js → parser-DROHJTBZ.js} +4 -4
  149. package/dist/{parser-AYZTKZC3.js → parser-G7KP6LZH.js} +3 -3
  150. package/dist/{parser-RBNOWHGM.js → parser-IWQQY5VU.js} +4 -4
  151. package/dist/{parser-Q62VR2UJ.js → parser-NJGZF5MK.js} +5 -5
  152. package/dist/{parser-DQ2DGDYO.js → parser-QCSDU4FU.js} +3 -3
  153. package/dist/{parser-LMNFVTIV.js → parser-QCYEJOLZ.js} +4 -4
  154. package/dist/{parser-PEBXIOPX.js → parser-QJ7XK7AB.js} +4 -4
  155. package/dist/{parser-4ZIJDGPG.js → parser-RMUGOZO3.js} +4 -4
  156. package/dist/{parser-IQLLBMBQ.js → parser-TABGTEHH.js} +3 -3
  157. package/dist/{parser-IPBEW2DG.js → parser-TPCKCQ4Z.js} +4 -4
  158. package/dist/{parser-XWNSCDY6.js → parser-UB6XGLTC.js} +4 -4
  159. package/dist/{parser-QN3GJJ3J.js → parser-WI2B7IL3.js} +3 -3
  160. package/dist/{parser-D7YZX3CH.js → parser-WXZU47Z4.js} +3 -3
  161. package/dist/{registry-CaSw0PSH.d.ts → registry-C0HvobTb.d.ts} +17 -0
  162. package/dist/{renderer-6OFPEBHG.js → renderer-2OQMYNQD.js} +5 -5
  163. package/dist/{renderer-IAJMS5U5.js → renderer-4S5LOABJ.js} +7 -7
  164. package/dist/{renderer-FQLFE3TQ.js → renderer-6NQZLBMX.js} +5 -5
  165. package/dist/{renderer-2TEGR3RX.js → renderer-73L6XERY.js} +5 -5
  166. package/dist/{renderer-3WYLLPQL.js → renderer-7EAS7J35.js} +6 -6
  167. package/dist/{renderer-W5GF5USI.js → renderer-A2APCS6I.js} +5 -5
  168. package/dist/{renderer-HDLM6OY6.js → renderer-AWFHCLXQ.js} +7 -7
  169. package/dist/{renderer-XSZ5MUIF.js → renderer-CQBLODU3.js} +5 -5
  170. package/dist/{renderer-AK2X3VRY.js → renderer-F5YIKPAC.js} +7 -7
  171. package/dist/{renderer-LU4R3BP2.js → renderer-G24W6J6H.js} +4 -4
  172. package/dist/{renderer-KXMKAXPQ.js → renderer-I3WY546K.js} +4 -4
  173. package/dist/{renderer-VWBNIZV3.js → renderer-KYWN5KRD.js} +6 -6
  174. package/dist/{renderer-PLRNQ6T3.js → renderer-LDSHG26O.js} +7 -7
  175. package/dist/{renderer-LRQ3OPNJ.js → renderer-LOTDM5WH.js} +7 -7
  176. package/dist/{renderer-5BFS4NBL.js → renderer-M225GOP2.js} +5 -5
  177. package/dist/{renderer-LMLSA457.js → renderer-NTKY64DL.js} +5 -5
  178. package/dist/{renderer-ND7YIUHD.js → renderer-PQXPBXKE.js} +3 -3
  179. package/dist/{renderer-I2P5FTZ2.js → renderer-QFWLXG6G.js} +7 -7
  180. package/dist/{renderer-W3JK5YVD.js → renderer-QGZBFYMZ.js} +5 -5
  181. package/dist/{renderer-BNEO5W3E.js → renderer-QMOSWMHK.js} +6 -6
  182. package/dist/{renderer-EJ3FETD2.js → renderer-R7JEM7R7.js} +5 -5
  183. package/dist/{renderer-JHYUK5TN.js → renderer-RB3DGCF4.js} +3 -3
  184. package/dist/{renderer-XKMG3SYD.js → renderer-RNTCDM5N.js} +6 -6
  185. package/dist/{renderer-TIIHLRMM.js → renderer-RRIXAQSF.js} +5 -5
  186. package/dist/renderer-T3JBQLLW.js +77 -0
  187. package/dist/{renderer-N4V7XVC3.js → renderer-VHYLVS2K.js} +7 -7
  188. package/dist/{renderer-BZZKS7KQ.js → renderer-VN3RCFHI.js} +7 -7
  189. package/dist/{renderer-B6XOO6EE.js → renderer-WAXZMPYS.js} +3 -3
  190. package/dist/{renderer-LNOBG226.js → renderer-X75XWLQS.js} +7 -7
  191. package/dist/{renderer-Q6TJ52B4.js → renderer-ZHGAY3Y6.js} +5 -5
  192. package/dist/{renderer-radial-LZAPQVM5.js → renderer-radial-C67KGADM.js} +6 -6
  193. package/dist/{state-parser-NQGVYSM3.js → state-parser-PNC2IHIA.js} +5 -5
  194. package/dist/{state-renderer-KSAKMFQ2.js → state-renderer-U4QW5YMY.js} +7 -7
  195. package/dist/{themes-tbBkIVsn.d.ts → themes-l406Vj2z.d.ts} +1 -1
  196. package/docs/language-reference.md +29 -0
  197. package/package.json +1 -1
  198. package/dist/dgmo-router-PMEKTIJ7.js +0 -88
package/dist/element.mjs CHANGED
@@ -811,7 +811,14 @@ var init_directives_registry = __esm({
811
811
  { token: "no-rounds", category: "modifier" },
812
812
  { token: "single-elim", category: "modifier" },
813
813
  { token: "double-elim", category: "modifier" },
814
- { token: "seeded", category: "modifier" }
814
+ { token: "seeded", category: "modifier" },
815
+ // ── Live link (§38) ──────────────────────────────────────
816
+ // The pointer type's one directive. Registered so it highlights and
817
+ // autocompletes like `palette` does — §38 justifies the shape by calling it
818
+ // "the ordinary DGMO directive shape", and an unregistered `url` would make
819
+ // that sentence false in the editor: `editor/tokens.ts` specializes only
820
+ // against the keyword registries, so it would render as plain identifier text.
821
+ { token: "url", category: "directive" }
815
822
  ];
816
823
  ALL_REGISTRY_TOKENS = tokensWhere(() => true);
817
824
  INFRA_TOP_LEVEL_OPTION_SET = tokensWhere(
@@ -854,7 +861,12 @@ function staticRegistry(keys) {
854
861
  return { keys: new Set(keys), tagAliases: /* @__PURE__ */ new Set() };
855
862
  }
856
863
  function withTagAliases(base, aliases) {
857
- return { keys: base.keys, tagAliases: aliases };
864
+ const withSlugs = new Set(aliases);
865
+ for (const alias of aliases) withSlugs.add(tagSlug(alias));
866
+ return { keys: base.keys, tagAliases: withSlugs };
867
+ }
868
+ function tagSlug(name) {
869
+ return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
858
870
  }
859
871
  function isReservedKey(registry, key) {
860
872
  return registry.keys.has(key) || registry.tagAliases.has(key);
@@ -1149,6 +1161,17 @@ function stripQuotes(token) {
1149
1161
  }
1150
1162
  return token;
1151
1163
  }
1164
+ function peelQuotedName(name) {
1165
+ const trimmed = name.trim();
1166
+ if (trimmed.length < 2) return name;
1167
+ const first = trimmed[0];
1168
+ const last = trimmed[trimmed.length - 1];
1169
+ if ((first !== '"' || last !== '"') && (first !== "'" || last !== "'"))
1170
+ return name;
1171
+ const inner = trimmed.slice(1, -1);
1172
+ if (inner.length === 0 || inner.includes(first)) return name;
1173
+ return inner;
1174
+ }
1152
1175
  function tokenizeQuoteAware(input) {
1153
1176
  const tokens = [];
1154
1177
  let i = 0;
@@ -1528,7 +1551,9 @@ var init_parsing = __esm({
1528
1551
  "raci",
1529
1552
  "map",
1530
1553
  "family",
1531
- "bracket"
1554
+ "bracket",
1555
+ // pointer, not a drawing — internal (see ChartTypeMeta.internal)
1556
+ "live-link"
1532
1557
  ]);
1533
1558
  OPTION_NOCOLON_RE = /^([a-z][a-z0-9-]*)\s+(.+)$/i;
1534
1559
  GLOBAL_BOOLEANS = /* @__PURE__ */ new Set([
@@ -1591,7 +1616,17 @@ function assignAutoTagColors(group, palette) {
1591
1616
  }
1592
1617
  }
1593
1618
  function finalizeAutoTagColors(groups, palette) {
1594
- for (const g of groups) assignAutoTagColors(g, palette);
1619
+ for (const g of groups) {
1620
+ for (let i = 0; i < g.entries.length; i++) {
1621
+ const entry = g.entries[i];
1622
+ const peeled = peelQuotedName(entry.value);
1623
+ if (peeled !== entry.value) g.entries[i] = { ...entry, value: peeled };
1624
+ }
1625
+ if (g.defaultValue !== void 0) {
1626
+ g.defaultValue = peelQuotedName(g.defaultValue);
1627
+ }
1628
+ assignAutoTagColors(g, palette);
1629
+ }
1595
1630
  }
1596
1631
  function isAliasToken(token) {
1597
1632
  return /^[A-Za-z][A-Za-z0-9_]{0,11}$/.test(token);
@@ -8450,7 +8485,7 @@ function parseNoteLine(trimmed, participants, participantIds, sortedParticipants
8450
8485
  if (!lastMsgFrom) return { kind: "skip" };
8451
8486
  participantId = lastMsgFrom;
8452
8487
  }
8453
- const lookupKey = normalizeName(participantId);
8488
+ const lookupKey = normalizeName(peelQuotedName(participantId));
8454
8489
  if (participantIds.has(lookupKey)) {
8455
8490
  const found = participants.find((p) => normalizeName(p.id) === lookupKey);
8456
8491
  return {
@@ -8614,8 +8649,9 @@ function parseSequenceDgmo(content, palette) {
8614
8649
  const participantIds = /* @__PURE__ */ new Set();
8615
8650
  const idByKey = /* @__PURE__ */ new Map();
8616
8651
  const addParticipant = (name, lineNumber, extras) => {
8617
- const key = normalizeName(name);
8618
- const trimmed = name.trim();
8652
+ const peeled = peelQuotedName(name);
8653
+ const key = normalizeName(peeled);
8654
+ const trimmed = peeled.trim();
8619
8655
  const incomingLabel = extras?.label ?? trimmed;
8620
8656
  if (participantIds.has(key)) {
8621
8657
  const existing = result.participants.find(
@@ -8647,7 +8683,7 @@ function parseSequenceDgmo(content, palette) {
8647
8683
  result.participants.push({
8648
8684
  id: trimmed,
8649
8685
  label: incomingLabel,
8650
- type: extras?.type ?? inferParticipantType(name),
8686
+ type: extras?.type ?? inferParticipantType(peeled),
8651
8687
  lineNumber,
8652
8688
  ...extras?.position !== void 0 ? { position: extras.position } : {},
8653
8689
  // takePosition() may have emptied the metadata record (position was
@@ -12303,6 +12339,7 @@ function parseOrg(content, palette) {
12303
12339
  const containerMatch = trimmed.match(CONTAINER_RE);
12304
12340
  const metadataMatch = (() => {
12305
12341
  if (trimmed.includes("|")) return null;
12342
+ if (trimmed.startsWith('"') || trimmed.startsWith("'")) return null;
12306
12343
  const m = trimmed.match(METADATA_RE);
12307
12344
  if (!m) return null;
12308
12345
  const keyRegion = m[1].trim();
@@ -12314,7 +12351,7 @@ function parseOrg(content, palette) {
12314
12351
  const asMatch = rawLabel.match(
12315
12352
  /^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/
12316
12353
  );
12317
- const label = asMatch ? asMatch[1].trim() : rawLabel;
12354
+ const label = peelQuotedName(asMatch ? asMatch[1].trim() : rawLabel);
12318
12355
  containerCounter++;
12319
12356
  const containerId = `container-${containerCounter}`;
12320
12357
  if (asMatch) nameAliasMap.set(asMatch[2], containerId);
@@ -12412,7 +12449,8 @@ function parseNodeLabel(trimmed, _indent, lineNumber, _palette, counter, metaAli
12412
12449
  (msg) => diagnostics?.push(makeDgmoError(lineNumber, msg, "warning")),
12413
12450
  split.name
12414
12451
  );
12415
- const label = split.color !== void 0 ? `${split.name} ${split.color}` : split.name;
12452
+ const peeled = peelQuotedName(split.name);
12453
+ const label = split.color !== void 0 ? `${peeled} ${split.color}` : peeled;
12416
12454
  if (split.alias) {
12417
12455
  nameAliasMap?.set(normalizeName(split.alias), id);
12418
12456
  }
@@ -12519,7 +12557,7 @@ function parseArrowLine(trimmed, _palette, _lineNumber, _diagnostics) {
12519
12557
  const rawTarget = bareMatch[1].trim();
12520
12558
  const groupMatch = rawTarget.match(/^\[(.+)\]$/);
12521
12559
  return {
12522
- target: groupMatch ? groupMatch[1].trim() : rawTarget,
12560
+ target: peelQuotedName(groupMatch ? groupMatch[1].trim() : rawTarget),
12523
12561
  targetIsGroup: !!groupMatch
12524
12562
  };
12525
12563
  }
@@ -12530,7 +12568,7 @@ function parseArrowLine(trimmed, _palette, _lineNumber, _diagnostics) {
12530
12568
  const groupMatch = rawTarget.match(/^\[(.+)\]$/);
12531
12569
  return {
12532
12570
  ...label !== void 0 && { label },
12533
- target: groupMatch ? groupMatch[1].trim() : rawTarget,
12571
+ target: peelQuotedName(groupMatch ? groupMatch[1].trim() : rawTarget),
12534
12572
  targetIsGroup: !!groupMatch
12535
12573
  };
12536
12574
  }
@@ -12731,7 +12769,7 @@ function parseSitemap(content, palette) {
12731
12769
  const asMatch = rawLabel.match(
12732
12770
  /^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/
12733
12771
  );
12734
- const label = asMatch ? asMatch[1].trim() : rawLabel;
12772
+ const label = peelQuotedName(asMatch ? asMatch[1].trim() : rawLabel);
12735
12773
  const tail = (containerMatch[2] ?? "").trim();
12736
12774
  const containerMetadata = {};
12737
12775
  if (tail.length > 0) {
@@ -12912,7 +12950,7 @@ function parseNodeLabel2(trimmed, lineNumber, _palette, counter, metaAliasMap =
12912
12950
  split.name
12913
12951
  );
12914
12952
  }
12915
- const label = split.name;
12953
+ const label = peelQuotedName(split.name);
12916
12954
  if (split.alias) nameAliasMap?.set(normalizeName(split.alias), id);
12917
12955
  const metadata = { ...split.meta };
12918
12956
  if (split.color !== void 0) metadata["color"] = split.color;
@@ -13498,6 +13536,7 @@ function tokenizeActivityLine(line11, diagnostics, lineNumber, metaAliasMap) {
13498
13536
  name = rawTokens.slice(0, firstNumIdx).join(" ").trim();
13499
13537
  durationTokens = rawTokens.slice(firstNumIdx);
13500
13538
  }
13539
+ name = peelQuotedName(name);
13501
13540
  return {
13502
13541
  name,
13503
13542
  durationTokens,
@@ -13725,7 +13764,7 @@ function parsePert(content, parseOpts = {}) {
13725
13764
  if (groupMatch) {
13726
13765
  contentStarted = true;
13727
13766
  currentTagGroup = null;
13728
- const name = groupMatch[1].trim();
13767
+ const name = peelQuotedName(groupMatch[1].trim());
13729
13768
  let tail = (groupMatch[2] ?? "").trim();
13730
13769
  let bareCollapsed = false;
13731
13770
  const barePeel = peelTrailingCollapsedFlag(tail);
@@ -14747,6 +14786,17 @@ var init_chart_types = __esm({
14747
14786
  id: "boxes-and-lines",
14748
14787
  description: "General-purpose node-edge diagrams with groups and tags",
14749
14788
  fallback: true
14789
+ },
14790
+ // ── Not a tier — a pointer, not a drawing ─────────────────
14791
+ // `live-link` holds no diagram of its own; it names one published to
14792
+ // Diagrammo Cloud. Internal (see `internal` above): it arrives by being saved
14793
+ // from a shared link, never by being picked from a list. Kept LAST because
14794
+ // `chartTypes.slice(0, 8)` is a live window feeding language-reference checks
14795
+ // and the generated AI core — any insertion above position 8 shifts it.
14796
+ {
14797
+ id: "live-link",
14798
+ description: "A pointer to a diagram published at Diagrammo Cloud",
14799
+ internal: true
14750
14800
  }
14751
14801
  ];
14752
14802
  }
@@ -17307,7 +17357,7 @@ function parseKanban(content, palette) {
17307
17357
  }
17308
17358
  currentCard = null;
17309
17359
  columnCounter++;
17310
- const colName = columnMatch[1].trim();
17360
+ const colName = peelQuotedName(columnMatch[1].trim());
17311
17361
  let tail = (columnMatch[2] ?? "").trim();
17312
17362
  let colCollapsed = false;
17313
17363
  const barePeel = peelTrailingCollapsedFlag(tail);
@@ -17486,7 +17536,8 @@ function parseCardLine(trimmed, lineNumber, counter, metaAliasMap, _palette, dia
17486
17536
  (msg) => diagnostics?.push(makeDgmoError(lineNumber, msg, "warning")),
17487
17537
  split.name
17488
17538
  );
17489
- const title = split.color !== void 0 ? `${split.name} ${split.color}` : split.name;
17539
+ const name = peelQuotedName(split.name);
17540
+ const title = split.color !== void 0 ? `${name} ${split.color}` : name;
17490
17541
  const tags = { ...split.meta };
17491
17542
  return {
17492
17543
  id: `card-${counter}`,
@@ -17619,7 +17670,8 @@ function parseC4(content, palette) {
17619
17670
  const metaAliasMap = /* @__PURE__ */ new Map();
17620
17671
  const nameAliasMap = /* @__PURE__ */ new Map();
17621
17672
  function resolveNameRef(rawName) {
17622
- return nameAliasMap.get(rawName.trim()) ?? rawName;
17673
+ const trimmed = rawName.trim();
17674
+ return nameAliasMap.get(trimmed) ?? peelQuotedName(trimmed);
17623
17675
  }
17624
17676
  const knownNames = /* @__PURE__ */ new Map();
17625
17677
  const elementMetadata = /* @__PURE__ */ new WeakMap();
@@ -17746,7 +17798,7 @@ function parseC4(content, palette) {
17746
17798
  } else {
17747
17799
  const refMatch = trimmed.match(CONTAINER_REF_RE);
17748
17800
  if (refMatch) {
17749
- const refName = refMatch[1].trim();
17801
+ const refName = peelQuotedName(refMatch[1].trim());
17750
17802
  if (deployStack.length > 0) {
17751
17803
  deployStack[deployStack.length - 1].node.containerRefs.push(
17752
17804
  refName
@@ -17759,10 +17811,9 @@ function parseC4(content, palette) {
17759
17811
  }
17760
17812
  continue;
17761
17813
  }
17762
- const { name: nodeName, metadata } = parseC4NameAndMeta(
17763
- trimmed,
17764
- metaAliasMap
17765
- );
17814
+ const parsedNode = parseC4NameAndMeta(trimmed, metaAliasMap);
17815
+ const nodeName = peelQuotedName(parsedNode.name);
17816
+ const metadata = parsedNode.metadata;
17766
17817
  warnUnknownMetaKeys(
17767
17818
  metadata,
17768
17819
  withTagAliases(C4_REGISTRY, new Set(metaAliasMap.keys())),
@@ -17944,11 +17995,12 @@ function parseC4(content, palette) {
17944
17995
  let namePart = isATypeMatch[1].trim();
17945
17996
  const rawType = isATypeMatch[2].toLowerCase();
17946
17997
  let remainder = isATypeMatch[3];
17998
+ let declaredAlias;
17947
17999
  const asPostfix = remainder.match(
17948
18000
  /^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*(\|.*)?$/
17949
18001
  );
17950
18002
  if (asPostfix) {
17951
- nameAliasMap.set(asPostfix[2], namePart);
18003
+ declaredAlias = asPostfix[2];
17952
18004
  remainder = (asPostfix[1] + (asPostfix[3] ?? "")).trim();
17953
18005
  } else {
17954
18006
  const asInName = namePart.match(
@@ -17956,9 +18008,12 @@ function parseC4(content, palette) {
17956
18008
  );
17957
18009
  if (asInName) {
17958
18010
  namePart = asInName[1].trim();
17959
- nameAliasMap.set(asInName[2], namePart);
18011
+ declaredAlias = asInName[2];
17960
18012
  }
17961
18013
  }
18014
+ namePart = peelQuotedName(namePart);
18015
+ if (declaredAlias !== void 0)
18016
+ nameAliasMap.set(declaredAlias, namePart);
17962
18017
  let elementType;
17963
18018
  let explicitShape = null;
17964
18019
  if (rawType === "external") {
@@ -18053,7 +18108,7 @@ function parseC4(content, palette) {
18053
18108
  (msg) => pushError(lineNumber, msg, "warning"),
18054
18109
  parsed.name
18055
18110
  );
18056
- let namePart = parsed.name;
18111
+ let namePart = peelQuotedName(parsed.name);
18057
18112
  const metadata = parsed.metadata;
18058
18113
  let explicitShape = null;
18059
18114
  const isAMatch = namePart.match(IS_A_RE);
@@ -18347,6 +18402,23 @@ __export(parser_exports11, {
18347
18402
  extractSymbols: () => extractSymbols4,
18348
18403
  parseInfra: () => parseInfra
18349
18404
  });
18405
+ function assignAutoTagColorNames(groups) {
18406
+ for (const group of groups) {
18407
+ const explicit = new Set(
18408
+ group.values.filter((v) => v.color !== void 0).map((v) => v.color.toLowerCase())
18409
+ );
18410
+ let cursor = 0;
18411
+ for (const value of group.values) {
18412
+ if (value.color !== void 0) continue;
18413
+ while (cursor < autoTagColorCycle.length && explicit.has(autoTagColorCycle[cursor].toLowerCase())) {
18414
+ cursor++;
18415
+ }
18416
+ const name = autoTagColorCycle[cursor % autoTagColorCycle.length];
18417
+ cursor++;
18418
+ value.color = name;
18419
+ }
18420
+ }
18421
+ }
18350
18422
  function nodeId2(name) {
18351
18423
  return normalizeName(name);
18352
18424
  }
@@ -18448,6 +18520,16 @@ function parseInfra(content) {
18448
18520
  ...peeled.alias !== void 0 && { alias: peeled.alias }
18449
18521
  };
18450
18522
  }
18523
+ function warnMisplacedProperties(tags, label, lineNumber) {
18524
+ for (const key of Object.keys(tags)) {
18525
+ if (!INFRA_BEHAVIOR_KEYS.has(key) && !EDGE_ONLY_KEYS.has(key)) continue;
18526
+ warn(
18527
+ lineNumber,
18528
+ `'${key}' is a node property \u2014 indent it under '${label}' as '${key}: ${tags[key]}', not on the declaration line.`
18529
+ );
18530
+ delete tags[key];
18531
+ }
18532
+ }
18451
18533
  function resolveTargetId(rawName) {
18452
18534
  const aliasResolved = nameAliasMap.get(rawName.trim());
18453
18535
  if (aliasResolved !== void 0) return aliasResolved;
@@ -18623,13 +18705,14 @@ function parseInfra(content) {
18623
18705
  if (compMatch) {
18624
18706
  finishCurrentNode();
18625
18707
  finishCurrentTagGroup();
18626
- const { qname, uname, alias: asAlias, meta } = compMatch.groups;
18627
- const rawName = (qname ?? uname ?? "").trim();
18708
+ const { qname, uname, isa, alias: asAlias, meta } = compMatch.groups;
18709
+ const rawName = ((qname ?? uname ?? "") + (isa ?? "")).trim();
18628
18710
  const peeled = peelInfraDecorations(rawName, lineNumber);
18629
18711
  const name = peeled.label;
18630
18712
  const alias = asAlias ?? peeled.alias;
18631
18713
  const rest = meta ?? "";
18632
18714
  const { tags } = extractPipeMetadata(rest);
18715
+ warnMisplacedProperties(tags, name, lineNumber);
18633
18716
  warnUnknownMetaKeys(
18634
18717
  tags,
18635
18718
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
@@ -18665,8 +18748,11 @@ function parseInfra(content) {
18665
18748
  valueName = cleanEntry.substring(0, lastSpaceIdx).trimEnd();
18666
18749
  }
18667
18750
  }
18751
+ const peeledValue = peelQuotedName(valueName);
18752
+ const wasQuoted = peeledValue !== valueName;
18753
+ valueName = peeledValue;
18668
18754
  const tvMatch = valueName.match(TAG_VALUE_RE);
18669
- if (tvMatch || /^\w+$/.test(valueName)) {
18755
+ if (wasQuoted || tvMatch || /^\w+$/.test(valueName)) {
18670
18756
  currentTagGroup.values.push({
18671
18757
  name: valueName,
18672
18758
  ...rawColor !== void 0 && { color: rawColor }
@@ -18726,13 +18812,14 @@ function parseInfra(content) {
18726
18812
  const compMatch = trimmed.match(COMPONENT_RE);
18727
18813
  if (compMatch) {
18728
18814
  finishCurrentTagGroup();
18729
- const { qname, uname, alias: asAlias, meta } = compMatch.groups;
18730
- const rawName = (qname ?? uname ?? "").trim();
18815
+ const { qname, uname, isa, alias: asAlias, meta } = compMatch.groups;
18816
+ const rawName = ((qname ?? uname ?? "") + (isa ?? "")).trim();
18731
18817
  const peeled = peelInfraDecorations(rawName, lineNumber);
18732
18818
  const name = peeled.label;
18733
18819
  const alias = asAlias ?? peeled.alias;
18734
18820
  const rest = meta ?? "";
18735
18821
  const { tags: nodeTags } = extractPipeMetadata(rest);
18822
+ warnMisplacedProperties(nodeTags, name, lineNumber);
18736
18823
  warnUnknownMetaKeys(
18737
18824
  nodeTags,
18738
18825
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
@@ -18979,13 +19066,14 @@ function parseInfra(content) {
18979
19066
  finishCurrentNode();
18980
19067
  const compMatch = trimmed.match(COMPONENT_RE);
18981
19068
  if (compMatch) {
18982
- const { qname, uname, alias: asAlias, meta } = compMatch.groups;
18983
- const rawName = (qname ?? uname ?? "").trim();
19069
+ const { qname, uname, isa, alias: asAlias, meta } = compMatch.groups;
19070
+ const rawName = ((qname ?? uname ?? "") + (isa ?? "")).trim();
18984
19071
  const peeled = peelInfraDecorations(rawName, lineNumber);
18985
19072
  const name = peeled.label;
18986
19073
  const alias = asAlias ?? peeled.alias;
18987
19074
  const rest = meta ?? "";
18988
19075
  const { tags: nodeTags } = extractPipeMetadata(rest);
19076
+ warnMisplacedProperties(nodeTags, name, lineNumber);
18989
19077
  warnUnknownMetaKeys(
18990
19078
  nodeTags,
18991
19079
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
@@ -19014,13 +19102,14 @@ function parseInfra(content) {
19014
19102
  finishCurrentNode();
19015
19103
  finishCurrentTagGroup();
19016
19104
  currentGroup = null;
19017
- const { qname, uname, alias: asAlias, meta } = compMatch.groups;
19018
- const rawName = (qname ?? uname ?? "").trim();
19105
+ const { qname, uname, isa, alias: asAlias, meta } = compMatch.groups;
19106
+ const rawName = ((qname ?? uname ?? "") + (isa ?? "")).trim();
19019
19107
  const peeled = peelInfraDecorations(rawName, lineNumber);
19020
19108
  const name = peeled.label;
19021
19109
  const alias = asAlias ?? peeled.alias;
19022
19110
  const rest = meta ?? "";
19023
19111
  const { tags } = extractPipeMetadata(rest);
19112
+ warnMisplacedProperties(tags, name, lineNumber);
19024
19113
  warnUnknownMetaKeys(
19025
19114
  tags,
19026
19115
  withTagAliases(INFRA_REGISTRY, tagAliasSet),
@@ -19081,6 +19170,7 @@ function parseInfra(content) {
19081
19170
  }
19082
19171
  }
19083
19172
  }
19173
+ assignAutoTagColorNames(result.tagGroups);
19084
19174
  validateTagGroupNames(result.tagGroups, warn, setError);
19085
19175
  checkReachability(result);
19086
19176
  checkSplitSums(result);
@@ -19245,9 +19335,9 @@ var init_parser17 = __esm({
19245
19335
  DEPRECATED_FANOUT_RE = /\bx(\d+)\s*$/;
19246
19336
  GROUP_RE = /^\[([^\]]+)\]\s*(?:as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*)?(?:(collapsed)(?!\s*:)\s*)?((?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
19247
19337
  TAG_VALUE_RE = /^(\w[\w\s]+?)\s*$/;
19248
- COMPONENT_RE = /^(?:"(?<qname>[^"]+)"|(?<uname>[a-zA-Z_][\w -]*?))(?:\s+as\s+(?<alias>[A-Za-z][A-Za-z0-9_]{0,11}))?\s*(?<meta>(?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
19338
+ COMPONENT_RE = /^(?:"(?<qname>[^"]+)"|(?<uname>[a-zA-Z_][\w -]*?))(?<isa>\s+is\s+an?\s+[A-Za-z][\w-]*)?(?:\s+as\s+(?<alias>[A-Za-z][A-Za-z0-9_]{0,11}))?\s*(?<meta>(?:\|.*)|(?:[a-zA-Z_][\w-]*\s*:.*))?$/;
19249
19339
  PIPE_META_RE = /[|,]\s*(\w+)\s*:\s*([^|,]+)/g;
19250
- SAMELINE_META_RE = /(?:^|[\s,])(\w+)\s*:\s*([^,]+?)(?=\s*,|\s*$)/g;
19340
+ SAMELINE_META_RE = /(?:^|[\s,])([\w-]+)\s*:\s*([^,]+?)(?=\s*,|\s*$)/g;
19251
19341
  PROPERTY_RE = /^([\w-]+):\s*(.+)$/;
19252
19342
  PERCENT_RE = /^([\d.]+)%$/;
19253
19343
  RANGE_RE = /^(\d+)-(\d+)$/;
@@ -19518,7 +19608,9 @@ function parseGantt(content, palette) {
19518
19608
  result.eras.push({
19519
19609
  startDate: eraEntryMatch.start,
19520
19610
  endDate: eraEntryMatch.end,
19521
- label: eraExtracted.label,
19611
+ // Peel after extractColor — the quotes are what keep a trailing
19612
+ // color word inside the label (§2.2).
19613
+ label: peelQuotedName(eraExtracted.label),
19522
19614
  color: eraExtracted.color || null,
19523
19615
  lineNumber
19524
19616
  });
@@ -19547,7 +19639,9 @@ function parseGantt(content, palette) {
19547
19639
  );
19548
19640
  result.markers.push({
19549
19641
  date: markerEntryMatch.iso,
19550
- label: markerExtracted.label,
19642
+ // Peel after extractColor — the quotes are what keep a trailing
19643
+ // color word inside the label (§2.2).
19644
+ label: peelQuotedName(markerExtracted.label),
19551
19645
  color: markerExtracted.color || null,
19552
19646
  lineNumber
19553
19647
  });
@@ -19631,10 +19725,11 @@ function parseGantt(content, palette) {
19631
19725
  content2.explicitStart,
19632
19726
  content2.preExtracted
19633
19727
  );
19728
+ if (content2.alias) nameAliasMap.set(content2.alias, task.label);
19634
19729
  const taskNode = { kind: "task", ...task };
19635
19730
  if (lastTaskNode) {
19636
19731
  lastTaskNode.dependencies.push({
19637
- targetName: content2.name,
19732
+ targetName: task.label,
19638
19733
  ...arrowResult.label !== void 0 && {
19639
19734
  label: arrowResult.label
19640
19735
  },
@@ -19675,7 +19770,9 @@ function parseGantt(content, palette) {
19675
19770
  targetSegment = split.name;
19676
19771
  meta = split.meta;
19677
19772
  }
19678
- const targetName = resolveAliasTarget(targetSegment);
19773
+ const targetName = resolveAliasTarget(
19774
+ peelQuotedName(targetSegment)
19775
+ );
19679
19776
  let offset = arrowResult.lag;
19680
19777
  if (meta["lag"] || meta["lead"]) {
19681
19778
  const key = meta["lag"] ? "lag" : "lead";
@@ -19768,7 +19865,7 @@ function parseGantt(content, palette) {
19768
19865
  result.eras.push({
19769
19866
  startDate: "",
19770
19867
  endDate: "",
19771
- label: eraExtracted.label,
19868
+ label: peelQuotedName(eraExtracted.label),
19772
19869
  color: eraExtracted.color || null,
19773
19870
  lineNumber,
19774
19871
  ...startOff && { offsetStart: startOff },
@@ -19788,7 +19885,7 @@ function parseGantt(content, palette) {
19788
19885
  );
19789
19886
  result.markers.push({
19790
19887
  date: "",
19791
- label: markerExtracted.label,
19888
+ label: peelQuotedName(markerExtracted.label),
19792
19889
  color: markerExtracted.color || null,
19793
19890
  lineNumber,
19794
19891
  ...dateOff && { offsetDate: dateOff }
@@ -19871,7 +19968,7 @@ function parseGantt(content, palette) {
19871
19968
  result.eras.push({
19872
19969
  startDate: eraMatch.start,
19873
19970
  endDate: eraMatch.end,
19874
- label: eraExtracted.label,
19971
+ label: peelQuotedName(eraExtracted.label),
19875
19972
  color: eraExtracted.color || null,
19876
19973
  lineNumber
19877
19974
  });
@@ -19896,7 +19993,7 @@ function parseGantt(content, palette) {
19896
19993
  );
19897
19994
  result.markers.push({
19898
19995
  date: markerMatch.iso,
19899
- label: markerExtracted.label,
19996
+ label: peelQuotedName(markerExtracted.label),
19900
19997
  color: markerExtracted.color || null,
19901
19998
  lineNumber
19902
19999
  });
@@ -19957,7 +20054,6 @@ function parseGantt(content, palette) {
19957
20054
  softError(lineNumber, `Task name cannot be empty.`);
19958
20055
  continue;
19959
20056
  }
19960
- if (split.alias) nameAliasMap.set(split.alias, taskName);
19961
20057
  const preExtracted = { ...split.meta };
19962
20058
  delete preExtracted["duration"];
19963
20059
  delete preExtracted["start"];
@@ -19970,6 +20066,7 @@ function parseGantt(content, palette) {
19970
20066
  explicitStart,
19971
20067
  preExtracted
19972
20068
  );
20069
+ if (split.alias) nameAliasMap.set(split.alias, task.label);
19973
20070
  const taskNode = { kind: "task", ...task };
19974
20071
  currentContainer().push(taskNode);
19975
20072
  const writableTaskN = taskNode;
@@ -20195,10 +20292,10 @@ function parseGantt(content, palette) {
20195
20292
  delete metadata["collapsed"];
20196
20293
  }
20197
20294
  const groupPeeled = peelAlias2(gm[1]);
20198
- if (groupPeeled.alias)
20199
- nameAliasMap.set(groupPeeled.alias, groupPeeled.label);
20295
+ const groupName = peelQuotedName(groupPeeled.label);
20296
+ if (groupPeeled.alias) nameAliasMap.set(groupPeeled.alias, groupName);
20200
20297
  const group = {
20201
- name: groupPeeled.label,
20298
+ name: groupName,
20202
20299
  color: null,
20203
20300
  metadata,
20204
20301
  ...lineOffset && { offset: lineOffset },
@@ -20234,6 +20331,7 @@ function parseGantt(content, palette) {
20234
20331
  content2.explicitStart,
20235
20332
  content2.preExtracted
20236
20333
  );
20334
+ if (content2.alias) nameAliasMap.set(content2.alias, task.label);
20237
20335
  if (lineOffset) {
20238
20336
  task.offset = lineOffset;
20239
20337
  }
@@ -20260,6 +20358,7 @@ function parseGantt(content, palette) {
20260
20358
  if (currentTagGroup) {
20261
20359
  result.tagGroups.push(currentTagGroup);
20262
20360
  }
20361
+ finalizeAutoTagColors(result.tagGroups, palette);
20263
20362
  if (result.options.sort === "tag" && result.tagGroups.length === 0) {
20264
20363
  warn(0, "sort tag has no effect \u2014 no tag groups defined.");
20265
20364
  result.options.sort = "default";
@@ -20381,7 +20480,8 @@ function parseGantt(content, palette) {
20381
20480
  duration,
20382
20481
  uncertain,
20383
20482
  explicitStart,
20384
- preExtracted
20483
+ preExtracted,
20484
+ alias: split.alias
20385
20485
  };
20386
20486
  }
20387
20487
  function findOwningTask(stack, metaIndent) {
@@ -20396,7 +20496,6 @@ function parseGantt(content, palette) {
20396
20496
  function makeTask(labelRaw, duration, uncertain, ln, explicitStart, preExtractedMeta) {
20397
20497
  const peeled = peelAlias2(labelRaw);
20398
20498
  let label = peeled.label;
20399
- if (peeled.alias) nameAliasMap.set(peeled.alias, label);
20400
20499
  if (label.toLowerCase() === "parallel") {
20401
20500
  softError(
20402
20501
  ln,
@@ -20428,6 +20527,8 @@ function parseGantt(content, palette) {
20428
20527
  Object.assign(metadata, split.meta);
20429
20528
  }
20430
20529
  }
20530
+ label = peelQuotedName(label);
20531
+ if (peeled.alias) nameAliasMap.set(peeled.alias, label);
20431
20532
  if (preExtractedMeta) {
20432
20533
  Object.assign(metadata, preExtractedMeta);
20433
20534
  }
@@ -21794,7 +21895,7 @@ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap
21794
21895
  (msg) => diagnostics.push(makeDgmoError(lineNum, msg, "warning")),
21795
21896
  split.name
21796
21897
  );
21797
- let label = split.name;
21898
+ let label = peelQuotedName(split.name);
21798
21899
  const metadata = { ...split.meta };
21799
21900
  let description;
21800
21901
  if (split.color !== void 0) {
@@ -21848,7 +21949,7 @@ function resolveEndpoint(name, nameAliasMap) {
21848
21949
  const aliased = nameAliasMap.get(name.trim());
21849
21950
  if (aliased !== void 0) return aliased;
21850
21951
  }
21851
- return name;
21952
+ return peelQuotedName(name);
21852
21953
  }
21853
21954
  function parseEdgeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap) {
21854
21955
  const edgeRegistry = withTagAliases(
@@ -33131,6 +33232,221 @@ var init_parser38 = __esm({
33131
33232
  }
33132
33233
  });
33133
33234
 
33235
+ // src/cloud-reference.ts
33236
+ function parseCloudReference(text) {
33237
+ const fence = FENCE_RE.exec(text) ?? EMBED_RE.exec(text);
33238
+ if (fence) return reference(fence[1]);
33239
+ return parseCloudReferenceUrl(text);
33240
+ }
33241
+ function parseCloudReferenceUrl(text) {
33242
+ let url;
33243
+ try {
33244
+ url = new URL(text.trim());
33245
+ } catch {
33246
+ return null;
33247
+ }
33248
+ if (url.protocol !== "https:" && url.protocol !== "http:") return null;
33249
+ const match = URL_PATH_RE.exec(url.pathname);
33250
+ if (!match) return null;
33251
+ if (url.searchParams.has("at")) return null;
33252
+ return reference(match[1] ?? match[2] ?? match[3]);
33253
+ }
33254
+ function reference(id) {
33255
+ return id ? { id } : null;
33256
+ }
33257
+ var ID, FENCE_RE, EMBED_RE, URL_PATH_RE;
33258
+ var init_cloud_reference = __esm({
33259
+ "src/cloud-reference.ts"() {
33260
+ "use strict";
33261
+ ID = String.raw`[A-Za-z0-9_-]{3,64}`;
33262
+ FENCE_RE = new RegExp(`^\\s*live-link\\s+(${ID})\\s*$`);
33263
+ EMBED_RE = new RegExp(
33264
+ `^\\s*!\\[\\[\\s*live-link:\\s*(${ID})\\s*\\]\\]\\s*$`
33265
+ );
33266
+ URL_PATH_RE = new RegExp(
33267
+ `^/(?:public/diagrams/(${ID})/source|d/(${ID})|view/(${ID}))/?$`
33268
+ );
33269
+ }
33270
+ });
33271
+
33272
+ // src/live-link/parser.ts
33273
+ var parser_exports33 = {};
33274
+ __export(parser_exports33, {
33275
+ parseLiveLink: () => parseLiveLink
33276
+ });
33277
+ function resolveTarget(value) {
33278
+ const trimmed = value.trim();
33279
+ const asUrl = parseCloudReferenceUrl(trimmed)?.id;
33280
+ if (asUrl) return asUrl;
33281
+ if (!/^[^\s[\]]+$/.test(trimmed)) return null;
33282
+ return parseCloudReference(`live-link ${trimmed}`)?.id ?? null;
33283
+ }
33284
+ function pinnedRevision(value) {
33285
+ const trimmed = value.trim();
33286
+ if (resolveTarget(trimmed) !== null) return null;
33287
+ try {
33288
+ const url = new URL(trimmed);
33289
+ const at2 = url.searchParams.get("at");
33290
+ if (at2 !== null) {
33291
+ url.searchParams.delete("at");
33292
+ if (resolveTarget(url.toString()) !== null) return `?at=${at2}`;
33293
+ }
33294
+ } catch {
33295
+ }
33296
+ const at = trimmed.indexOf("@");
33297
+ if (at > 0) {
33298
+ const pin = trimmed.slice(at);
33299
+ if (resolveTarget(trimmed.slice(0, at)) !== null) return pin;
33300
+ }
33301
+ return null;
33302
+ }
33303
+ function parseLiveLink(content) {
33304
+ const diagnostics = [];
33305
+ let error = null;
33306
+ const fail = (line11, message) => {
33307
+ const diag = makeDgmoError(line11, message);
33308
+ diagnostics.push(diag);
33309
+ error ??= formatDgmoError(diag);
33310
+ };
33311
+ const warn = (line11, message) => {
33312
+ diagnostics.push(makeDgmoError(line11, message, "warning"));
33313
+ };
33314
+ const lines = content.split("\n");
33315
+ const isSkippable = (line11) => !line11 || line11.startsWith("//");
33316
+ let titleSlot = null;
33317
+ let titleLineNumber = 1;
33318
+ let bodyStart = lines.length;
33319
+ for (let i = 0; i < lines.length; i++) {
33320
+ const trimmed = lines[i].trim();
33321
+ if (isSkippable(trimmed)) continue;
33322
+ const first = parseFirstLine(trimmed);
33323
+ titleLineNumber = i + 1;
33324
+ titleSlot = first?.title ?? null;
33325
+ bodyStart = first ? i + 1 : i;
33326
+ break;
33327
+ }
33328
+ let sawUrlLine = false;
33329
+ const urls = [];
33330
+ for (let i = bodyStart; i < lines.length; i++) {
33331
+ const trimmed = lines[i].trim();
33332
+ if (isSkippable(trimmed)) continue;
33333
+ const spaceIdx = trimmed.search(/\s/);
33334
+ const key = (spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx)).toLowerCase();
33335
+ const value = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1).trim();
33336
+ if (key === "url") {
33337
+ sawUrlLine = true;
33338
+ if (!value) {
33339
+ fail(
33340
+ i + 1,
33341
+ `"url" needs a diagram \u2014 a link like ${EXAMPLE_URL}, or a bare diagram id.`
33342
+ );
33343
+ continue;
33344
+ }
33345
+ urls.push({ value, line: i + 1 });
33346
+ continue;
33347
+ }
33348
+ if (GLOBAL_DIRECTIVES.has(key)) continue;
33349
+ warn(
33350
+ i + 1,
33351
+ `Unrecognized directive "${key}" \u2014 a live link takes only "url".`
33352
+ );
33353
+ }
33354
+ const titleIsPhrase = titleSlot !== null && /\s/.test(titleSlot);
33355
+ const done = (title, id2) => ({
33356
+ type: "live-link",
33357
+ title,
33358
+ titleLineNumber,
33359
+ id: id2,
33360
+ diagnostics,
33361
+ error
33362
+ });
33363
+ if (!sawUrlLine && titleSlot === null) {
33364
+ fail(
33365
+ titleLineNumber,
33366
+ "A live link needs a diagram \u2014 add `url <link>`, or write `live-link <id>`."
33367
+ );
33368
+ return done(null, null);
33369
+ }
33370
+ if (sawUrlLine && urls.length === 0) {
33371
+ return done(titleIsPhrase ? titleSlot : null, null);
33372
+ }
33373
+ if (urls.length > 1) {
33374
+ const [a, b] = [urls[0], urls[1]];
33375
+ fail(
33376
+ b.line,
33377
+ `Two targets: "${a.value}" on line ${a.line} and "${b.value}" on line ${b.line}. A live link points at one diagram \u2014 delete one.`
33378
+ );
33379
+ return done(titleIsPhrase ? titleSlot : null, null);
33380
+ }
33381
+ const url = urls[0];
33382
+ if (url && titleSlot !== null && !titleIsPhrase) {
33383
+ fail(
33384
+ titleLineNumber,
33385
+ `Two targets: "${titleSlot}" on line ${titleLineNumber} and "${url.value}" on line ${url.line}. A live link points at one diagram \u2014 keep the \`url\` line and give line ${titleLineNumber} a title, or delete the \`url\` line.`
33386
+ );
33387
+ return done(null, null);
33388
+ }
33389
+ if (url) {
33390
+ const pin = pinnedRevision(url.value);
33391
+ if (pin !== null) {
33392
+ fail(
33393
+ url.line,
33394
+ `A pinned revision cannot be served \u2014 a live link always shows the publisher's current version. Remove the "${pin}" from the link.`
33395
+ );
33396
+ return done(titleSlot, null);
33397
+ }
33398
+ const id2 = resolveTarget(url.value);
33399
+ if (id2 === null) {
33400
+ fail(
33401
+ url.line,
33402
+ `"${url.value}" is not a Diagrammo diagram \u2014 use a link like ${EXAMPLE_URL}, or a bare diagram id.`
33403
+ );
33404
+ return done(titleSlot, null);
33405
+ }
33406
+ return done(titleSlot, id2);
33407
+ }
33408
+ if (titleIsPhrase) {
33409
+ fail(
33410
+ titleLineNumber,
33411
+ `"${titleSlot}" is a title, not a diagram id \u2014 add a \`url <link>\` line naming the diagram this points at.`
33412
+ );
33413
+ return done(titleSlot, null);
33414
+ }
33415
+ const shorthandPin = pinnedRevision(titleSlot);
33416
+ if (shorthandPin !== null) {
33417
+ fail(
33418
+ titleLineNumber,
33419
+ `A pinned revision cannot be served \u2014 a live link always shows the publisher's current version. Remove the "${shorthandPin}" from the id.`
33420
+ );
33421
+ return done(null, null);
33422
+ }
33423
+ const id = resolveTarget(titleSlot);
33424
+ if (id === null) {
33425
+ fail(
33426
+ titleLineNumber,
33427
+ `"${titleSlot}" is not a diagram id \u2014 use a bare id, or add a \`url <link>\` line.`
33428
+ );
33429
+ return done(null, null);
33430
+ }
33431
+ return done(null, id);
33432
+ }
33433
+ var GLOBAL_DIRECTIVES, EXAMPLE_URL;
33434
+ var init_parser39 = __esm({
33435
+ "src/live-link/parser.ts"() {
33436
+ "use strict";
33437
+ init_diagnostics();
33438
+ init_cloud_reference();
33439
+ init_parsing();
33440
+ GLOBAL_DIRECTIVES = /* @__PURE__ */ new Set([
33441
+ "palette",
33442
+ "theme",
33443
+ "no-title",
33444
+ "legend-inline"
33445
+ ]);
33446
+ EXAMPLE_URL = "https://online.diagrammo.app/d/dgm_7f2a91";
33447
+ }
33448
+ });
33449
+
33134
33450
  // src/chart-type-registry.ts
33135
33451
  function measureSequence(content) {
33136
33452
  const parsed = parseSequenceDgmo(content);
@@ -33395,6 +33711,7 @@ var init_chart_type_registry = __esm({
33395
33711
  init_parser36();
33396
33712
  init_parser37();
33397
33713
  init_parser38();
33714
+ init_parser39();
33398
33715
  CHART_TYPE_REGISTRY = [
33399
33716
  // ── Structured diagrams ───────────────────────────────────
33400
33717
  {
@@ -33583,7 +33900,12 @@ var init_chart_type_registry = __esm({
33583
33900
  // no measure/minDims — it sizes to content and scales to fit its rectangle.
33584
33901
  { id: "bracket", category: "diagram", parse: parseBracket },
33585
33902
  // ── Geographic map (own parser → resolver → layout → renderer) ──
33586
- { id: "map", category: "visualization", parse: parseMap }
33903
+ { id: "map", category: "visualization", parse: parseMap },
33904
+ // Live link: a pointer to a diagram published at Diagrammo Cloud, rendered
33905
+ // as a reference card. `diagram` like every other card-shaped type, so the
33906
+ // export-handler cross-check covers it rather than being relaxed for it. No
33907
+ // measure/minDims — the card sizes to its own text and scales to fit.
33908
+ { id: "live-link", category: "diagram", parse: parseLiveLink }
33587
33909
  ];
33588
33910
  REGISTRY_BY_ID = new Map(
33589
33911
  CHART_TYPE_REGISTRY.map((d) => [d.id, d])
@@ -33682,13 +34004,19 @@ function parseDgmoUndeduped(content) {
33682
34004
  if (parser2) {
33683
34005
  const result2 = parser2(content);
33684
34006
  return {
33685
- diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
34007
+ diagnostics: [
34008
+ ...result2.diagnostics,
34009
+ ...detectEmptyContent(content, chartType)
34010
+ ],
33686
34011
  chartType
33687
34012
  };
33688
34013
  }
33689
34014
  const result = parseVisualization(content);
33690
34015
  return {
33691
- diagnostics: [...result.diagnostics, ...detectEmptyContent(content)],
34016
+ diagnostics: [
34017
+ ...result.diagnostics,
34018
+ ...detectEmptyContent(content, chartType)
34019
+ ],
33692
34020
  chartType
33693
34021
  };
33694
34022
  }
@@ -33720,7 +34048,8 @@ function detectColonChartType(content) {
33720
34048
  }
33721
34049
  return null;
33722
34050
  }
33723
- function detectEmptyContent(content) {
34051
+ function detectEmptyContent(content, chartType) {
34052
+ if (chartType && EMPTY_CONTENT_EXEMPT.has(chartType)) return [];
33724
34053
  const lines = content.split("\n");
33725
34054
  const nonEmpty = lines.filter(
33726
34055
  (l) => l.trim() && !l.trim().startsWith("#") && !l.trim().startsWith("//")
@@ -33732,7 +34061,7 @@ function detectEmptyContent(content) {
33732
34061
  }
33733
34062
  return [];
33734
34063
  }
33735
- var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, CHART_TYPE_DESCRIPTIONS, chartTypeParsers, knownChartTypeIds, PARSER_BY_ID, ALL_KNOWN_TYPES;
34064
+ var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, CHART_TYPE_DESCRIPTIONS, chartTypeParsers, knownChartTypeIds, PARSER_BY_ID, ALL_KNOWN_TYPES, EMPTY_CONTENT_EXEMPT;
33736
34065
  var init_dgmo_router = __esm({
33737
34066
  "src/dgmo-router.ts"() {
33738
34067
  "use strict";
@@ -33759,6 +34088,7 @@ var init_dgmo_router = __esm({
33759
34088
  );
33760
34089
  PARSER_BY_ID = new Map(chartTypeParsers);
33761
34090
  ALL_KNOWN_TYPES = new Set(knownChartTypeIds);
34091
+ EMPTY_CONTENT_EXEMPT = /* @__PURE__ */ new Set(["live-link"]);
33762
34092
  }
33763
34093
  });
33764
34094
 
@@ -37690,14 +38020,14 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
37690
38020
  const exportMode = !!exportDims;
37691
38021
  const paneW = exportMode ? 0 : container.clientWidth || 0;
37692
38022
  const paneH = exportMode ? 0 : container.clientHeight || 0;
37693
- const W3 = Math.round(Math.max(baseW, paneW));
38023
+ const W4 = Math.round(Math.max(baseW, paneW));
37694
38024
  const H2 = Math.round(Math.max(baseH, paneH));
37695
- const vw = exportMode ? W3 : paneW || W3;
38025
+ const vw = exportMode ? W4 : paneW || W4;
37696
38026
  const vh = exportMode ? H2 : paneH || H2;
37697
- const svg = d3Selection8.select(container).append("svg").attr("width", vw).attr("height", vh).attr("viewBox", `0 0 ${W3} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
37698
- svg.append("rect").attr("width", W3).attr("height", H2).attr("fill", palette.bg);
38027
+ const svg = d3Selection8.select(container).append("svg").attr("width", vw).attr("height", vh).attr("viewBox", `0 0 ${W4} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
38028
+ svg.append("rect").attr("width", W4).attr("height", H2).attr("fill", palette.bg);
37699
38029
  if (showTitle) {
37700
- const t = svg.append("text").attr("class", "chart-title").attr("x", W3 / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("data-line-number", parsed.titleLineNumber ?? 1).text(parsed.title);
38030
+ const t = svg.append("text").attr("class", "chart-title").attr("x", W4 / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("data-line-number", parsed.titleLineNumber ?? 1).text(parsed.title);
37701
38031
  if (onClickItem && parsed.titleLineNumber && !exportMode) {
37702
38032
  const ln = parsed.titleLineNumber;
37703
38033
  t.style("cursor", "pointer").on("click", () => onClickItem(ln));
@@ -44555,25 +44885,45 @@ function splitCamelCase(word) {
44555
44885
  parts.push(word.slice(start));
44556
44886
  return parts.length > 1 ? parts : [word];
44557
44887
  }
44888
+ function splitLabelChunks(label) {
44889
+ const chunks = [];
44890
+ const words = label.split(/\s+/).filter((w) => w.length > 0);
44891
+ for (let wi = 0; wi < words.length; wi++) {
44892
+ const word = words[wi];
44893
+ const hyphenParts = [];
44894
+ let start = 0;
44895
+ for (let i = 0; i < word.length; i++) {
44896
+ if (word[i] === "-") {
44897
+ hyphenParts.push(word.slice(start, i + 1));
44898
+ start = i + 1;
44899
+ }
44900
+ }
44901
+ if (start < word.length) hyphenParts.push(word.slice(start));
44902
+ let firstOfWord = true;
44903
+ for (const part of hyphenParts) {
44904
+ for (const camel of splitCamelCase(part)) {
44905
+ chunks.push({ text: camel, spaceBefore: wi > 0 && firstOfWord });
44906
+ firstOfWord = false;
44907
+ }
44908
+ }
44909
+ }
44910
+ return chunks;
44911
+ }
44558
44912
  function fitLabelToHeader(label, nodeWidth, maxLines) {
44559
44913
  const maxTextWidth = nodeWidth - NODE_TEXT_PADDING * 2;
44560
- const rawParts = label.split(/(\s+|-)/);
44561
- const words = [];
44562
- for (const part of rawParts) {
44563
- if (!part || /^\s+$/.test(part) || part === "-") continue;
44564
- words.push(...splitCamelCase(part));
44565
- }
44914
+ const words = splitLabelChunks(label);
44566
44915
  for (let fontSize = NODE_FONT_SIZE; fontSize >= MIN_NODE_FONT_SIZE; fontSize--) {
44567
44916
  if (maxTextWidth < measureText("MM", fontSize)) continue;
44568
44917
  const lines = [];
44569
44918
  let current = "";
44570
44919
  for (const word of words) {
44571
- const test = current ? `${current} ${word}` : word;
44920
+ const joiner = current && word.spaceBefore ? " " : "";
44921
+ const test = current ? `${current}${joiner}${word.text}` : word.text;
44572
44922
  if (measureText(test, fontSize) <= maxTextWidth) {
44573
44923
  current = test;
44574
44924
  } else {
44575
44925
  if (current) lines.push(current);
44576
- current = word;
44926
+ current = word.text;
44577
44927
  }
44578
44928
  }
44579
44929
  if (current) lines.push(current);
@@ -45422,7 +45772,7 @@ function findClearPosition(w, h, points, obstacles) {
45422
45772
  }
45423
45773
  function resolveLabelOverlaps(boxes) {
45424
45774
  const MAX_PASSES = 8;
45425
- const PAD3 = 4;
45775
+ const PAD4 = 4;
45426
45776
  for (let pass = 0; pass < MAX_PASSES; pass++) {
45427
45777
  let moved = false;
45428
45778
  for (let i = 0; i < boxes.length; i++) {
@@ -45431,8 +45781,8 @@ function resolveLabelOverlaps(boxes) {
45431
45781
  const b = boxes[j];
45432
45782
  const dx = Math.abs(a.cx - b.cx);
45433
45783
  const dy = Math.abs(a.cy - b.cy);
45434
- const overlapX = (a.w + b.w) / 2 + PAD3 - dx;
45435
- const overlapY = (a.h + b.h) / 2 + PAD3 - dy;
45784
+ const overlapX = (a.w + b.w) / 2 + PAD4 - dx;
45785
+ const overlapY = (a.h + b.h) / 2 + PAD4 - dy;
45436
45786
  if (overlapX > 0 && overlapY > 0) {
45437
45787
  const shift = overlapY / 2 + 1;
45438
45788
  if (a.cy < b.cy) {
@@ -49667,7 +50017,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49667
50017
  const fillMode = fillModeFromOptions(parsed.options);
49668
50018
  const noDaggers = parsed.options["no-daggers"] === "true";
49669
50019
  const baseBg = themeBaseBg(palette, isDark);
49670
- const PAD3 = 20;
50020
+ const PAD4 = 20;
49671
50021
  const MAX_SCALE8 = 1.5;
49672
50022
  const titleReserve = parsed.title ? TITLE_RESERVE : 0;
49673
50023
  const legendGroups = parsed.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({
@@ -49683,8 +50033,8 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49683
50033
  };
49684
50034
  const contentW = layout.width;
49685
50035
  const contentH = layout.height;
49686
- const W3 = opts.fit?.width ?? opts.exportDims?.width ?? contentW + PAD3 * 2;
49687
- const legendReserve = hasLegend ? getMaxLegendReservedHeight(legendConfig, W3) + LEGEND_GROUP_GAP : 0;
50036
+ const W4 = opts.fit?.width ?? opts.exportDims?.width ?? contentW + PAD4 * 2;
50037
+ const legendReserve = hasLegend ? getMaxLegendReservedHeight(legendConfig, W4) + LEGEND_GROUP_GAP : 0;
49688
50038
  const inlineRequested = legendInlineRequested(parsed.options);
49689
50039
  const legendExtent = inlineRequested && hasLegend ? getLegendExtent(
49690
50040
  {
@@ -49697,7 +50047,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49697
50047
  showInactivePills: true
49698
50048
  },
49699
50049
  { activeGroup: activeTagGroup },
49700
- W3
50050
+ W4
49701
50051
  ) : { width: 0, height: 0 };
49702
50052
  const header = layoutInlineHeader({
49703
50053
  requested: inlineRequested,
@@ -49705,7 +50055,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49705
50055
  hasLegend,
49706
50056
  legendWidth: legendExtent.width,
49707
50057
  legendHeight: legendExtent.height,
49708
- containerWidth: W3,
50058
+ containerWidth: W4,
49709
50059
  titleBandHeight: titleReserve,
49710
50060
  legendReserve,
49711
50061
  titleBaselineY: TITLE_Y,
@@ -49716,14 +50066,14 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49716
50066
  let H2;
49717
50067
  if (opts.fit) {
49718
50068
  H2 = opts.fit.height;
49719
- const availW = Math.max(1, W3 - PAD3 * 2);
49720
- const availH = Math.max(1, H2 - chrome - PAD3 * 2);
50069
+ const availW = Math.max(1, W4 - PAD4 * 2);
50070
+ const availH = Math.max(1, H2 - chrome - PAD4 * 2);
49721
50071
  scale = Math.min(MAX_SCALE8, availW / contentW, availH / contentH);
49722
50072
  if (!Number.isFinite(scale) || scale <= 0) scale = 1;
49723
50073
  } else {
49724
- H2 = contentH + chrome + PAD3 * 2;
50074
+ H2 = contentH + chrome + PAD4 * 2;
49725
50075
  }
49726
- const svg = d3Selection16.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr("width", W3).attr("height", H2).attr("viewBox", `0 0 ${W3} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("data-fit-scale", scale.toFixed(3)).style("font-family", FONT_FAMILY);
50076
+ const svg = d3Selection16.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr("width", W4).attr("height", H2).attr("viewBox", `0 0 ${W4} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("data-fit-scale", scale.toFixed(3)).style("font-family", FONT_FAMILY);
49727
50077
  svg.append("style").text(
49728
50078
  ".family-focus-icon{opacity:0;transition:opacity .15s ease;pointer-events:none}.family-card:hover .family-focus-icon{opacity:.6;pointer-events:all}.family-focus-icon:hover{opacity:1}"
49729
50079
  );
@@ -49745,15 +50095,15 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49745
50095
  },
49746
50096
  palette,
49747
50097
  isDark,
49748
- width: W3,
50098
+ width: W4,
49749
50099
  activeGroup: activeTagGroup
49750
50100
  });
49751
50101
  legendParent.selectAll("[data-legend-group]").classed("family-legend-group", true);
49752
50102
  }
49753
- const contentX = (W3 - contentW * scale) / 2;
50103
+ const contentX = (W4 - contentW * scale) / 2;
49754
50104
  const root = svg.append("g").attr(
49755
50105
  "transform",
49756
- `translate(${contentX}, ${chrome + PAD3}) scale(${scale})`
50106
+ `translate(${contentX}, ${chrome + PAD4}) scale(${scale})`
49757
50107
  );
49758
50108
  if (parsed.options["generations"] === "true" && layout.rows.length > 0) {
49759
50109
  const bandG = root.append("g").attr("class", "family-generation-bands");
@@ -57030,7 +57380,7 @@ function nodeMapWithGroups(nodes, groups) {
57030
57380
  function computePortPts(edges, nodeMap, direction) {
57031
57381
  const srcPts = /* @__PURE__ */ new Map();
57032
57382
  const tgtPts = /* @__PURE__ */ new Map();
57033
- const PAD3 = 0.1;
57383
+ const PAD4 = 0.1;
57034
57384
  const activeEdges = edges.filter((e) => e.points.length > 0);
57035
57385
  const bySource = /* @__PURE__ */ new Map();
57036
57386
  for (const e of activeEdges) {
@@ -57046,7 +57396,7 @@ function computePortPts(edges, nodeMap, direction) {
57046
57396
  ).sort((a, b) => direction === "LR" ? a.t.y - b.t.y : a.t.x - b.t.x);
57047
57397
  const n = sorted.length;
57048
57398
  for (let i = 0; i < n; i++) {
57049
- const frac = n === 1 ? 0.5 : PAD3 + (1 - 2 * PAD3) * i / (n - 1);
57399
+ const frac = n === 1 ? 0.5 : PAD4 + (1 - 2 * PAD4) * i / (n - 1);
57050
57400
  const { e, t } = sorted[i];
57051
57401
  const isBackward = direction === "LR" ? t.x < source.x : t.y < source.y;
57052
57402
  if (direction === "LR") {
@@ -57076,7 +57426,7 @@ function computePortPts(edges, nodeMap, direction) {
57076
57426
  ).sort((a, b) => direction === "LR" ? a.s.y - b.s.y : a.s.x - b.s.x);
57077
57427
  const n = sorted.length;
57078
57428
  for (let i = 0; i < n; i++) {
57079
- const frac = n === 1 ? 0.5 : PAD3 + (1 - 2 * PAD3) * i / (n - 1);
57429
+ const frac = n === 1 ? 0.5 : PAD4 + (1 - 2 * PAD4) * i / (n - 1);
57080
57430
  const { e, s } = sorted[i];
57081
57431
  const isBackward = direction === "LR" ? target.x < s.x : target.y < s.y;
57082
57432
  if (direction === "LR") {
@@ -61972,10 +62322,10 @@ function ambiguousTaskMessage(trimmed, suggestions) {
61972
62322
  return `Multiple tasks match "${trimmed}". Did you mean ${suggestions.map((s) => `\`${s}\``).join(" or ")}?`;
61973
62323
  }
61974
62324
  function resolveTaskName(name, allTasks2) {
61975
- let trimmed = name.trim();
62325
+ let trimmed = peelQuotedName(name.trim()).trim();
61976
62326
  const bracketMatch = trimmed.match(BRACKET_GROUP_RE);
61977
62327
  if (bracketMatch) {
61978
- trimmed = `${bracketMatch[1]}.${bracketMatch[2]}`;
62328
+ trimmed = `${peelQuotedName(bracketMatch[1])}.${bracketMatch[2]}`;
61979
62329
  }
61980
62330
  const normTrimmed = normalizeName(trimmed);
61981
62331
  const exactMatches = allTasks2.filter(
@@ -61995,8 +62345,8 @@ function resolveTaskName(name, allTasks2) {
61995
62345
  }
61996
62346
  const lastDotIdx = trimmed.lastIndexOf(".");
61997
62347
  if (lastDotIdx > 0) {
61998
- const groupPrefix = trimmed.substring(0, lastDotIdx);
61999
- const taskLabel = trimmed.substring(lastDotIdx + 1);
62348
+ const groupPrefix = peelQuotedName(trimmed.substring(0, lastDotIdx));
62349
+ const taskLabel = peelQuotedName(trimmed.substring(lastDotIdx + 1));
62000
62350
  const normTaskLabel = normalizeName(taskLabel);
62001
62351
  const matches = allTasks2.filter((t) => {
62002
62352
  if (normalizeName(t.label) !== normTaskLabel) return false;
@@ -62033,6 +62383,7 @@ var init_resolver = __esm({
62033
62383
  "src/gantt/resolver.ts"() {
62034
62384
  "use strict";
62035
62385
  init_name_normalize();
62386
+ init_parsing();
62036
62387
  BRACKET_GROUP_RE = /^\[(.+?)\]\.(.+)$/;
62037
62388
  }
62038
62389
  });
@@ -71275,7 +71626,7 @@ function layoutMap(resolvedIn, data, size, opts) {
71275
71626
  const akRef = resolved.regions.some((r) => r.iso === "US-AK") || resolved.pois.some((p) => inAlaska(p.lon, p.lat));
71276
71627
  const hiRef = resolved.regions.some((r) => r.iso === "US-HI") || resolved.pois.some((p) => inHawaii(p.lon, p.lat));
71277
71628
  if (resolved.projection === "albers-usa" && usLayer && (akRef || hiRef)) {
71278
- const PAD3 = 8;
71629
+ const PAD4 = 8;
71279
71630
  const GAP = 12;
71280
71631
  const yB = height - FIT_PAD;
71281
71632
  const BW = 8;
@@ -71318,22 +71669,22 @@ function layoutMap(resolvedIn, data, size, opts) {
71318
71669
  const f = usLayer.get(iso);
71319
71670
  if (!f) return boxX;
71320
71671
  const x0 = boxX;
71321
- const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD3);
71672
+ const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD4);
71322
71673
  if (iw < 24) return boxX;
71323
- const xr = x0 + iw + 2 * PAD3;
71674
+ const xr = x0 + iw + 2 * PAD4;
71324
71675
  const floor = coastFloor(x0, xr);
71325
71676
  const topGuess = floor > -Infinity ? floor + GAP : yB - height * 0.42;
71326
71677
  proj.fitWidth(iw, f);
71327
71678
  const bb = geoPath(proj).bounds(f);
71328
71679
  const sh = Number.isFinite(bb[0][0]) ? bb[1][1] - bb[0][1] : iw;
71329
- const needH = sh + 2 * PAD3;
71680
+ const needH = sh + 2 * PAD4;
71330
71681
  let topFit = topGuess;
71331
71682
  const bottom2 = Math.min(topFit + needH, yB);
71332
71683
  if (bottom2 - topFit < needH) topFit = bottom2 - needH;
71333
71684
  proj.fitExtent(
71334
71685
  [
71335
- [x0 + PAD3, topFit + PAD3],
71336
- [xr - PAD3, bottom2 - PAD3]
71686
+ [x0 + PAD4, topFit + PAD4],
71687
+ [xr - PAD4, bottom2 - PAD4]
71337
71688
  ],
71338
71689
  f
71339
71690
  );
@@ -72971,15 +73322,15 @@ function layoutMap(resolvedIn, data, size, opts) {
72971
73322
  }
72972
73323
  }
72973
73324
  if (regionLabelGuards.length > 0) {
72974
- const PAD3 = 2;
73325
+ const PAD4 = 2;
72975
73326
  const poiRects = labels.filter((l) => l.poiId !== void 0 && l.hidden !== true).map((l) => {
72976
73327
  const w = measureLegendText(l.text, FONT2);
72977
73328
  const x = l.anchor === "start" ? l.x : l.anchor === "end" ? l.x - w : l.x - w / 2;
72978
73329
  return {
72979
- x: x - PAD3,
73330
+ x: x - PAD4,
72980
73331
  y: l.y - FONT2,
72981
- w: w + 2 * PAD3,
72982
- h: FONT2 * 1.4 + 2 * PAD3
73332
+ w: w + 2 * PAD4,
73333
+ h: FONT2 * 1.4 + 2 * PAD4
72983
73334
  };
72984
73335
  });
72985
73336
  for (const g of regionLabelGuards) {
@@ -73592,7 +73943,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
73592
73943
  if (poiLabels.length) {
73593
73944
  const patchBlurId = nid("dgmo-map-label-patch-blur");
73594
73945
  defs.append("filter").attr("id", patchBlurId).attr("x", "-50%").attr("y", "-50%").attr("width", "200%").attr("height", "200%").append("feGaussianBlur").attr("in", "SourceGraphic").attr("stdDeviation", 2.5);
73595
- const PAD3 = 8;
73946
+ const PAD4 = 8;
73596
73947
  const buildPatch = (labels, maskId, decoCluster) => {
73597
73948
  if (!labels.length) return;
73598
73949
  const patchMask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
@@ -73608,10 +73959,10 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
73608
73959
  const h = th + 6;
73609
73960
  blobs.append("rect").attr("x", cx - w / 2).attr("y", cy - h / 2).attr("width", w).attr("height", h).attr("rx", h / 2).attr("fill", "white");
73610
73961
  blobRects.push({
73611
- x0: cx - w / 2 - PAD3,
73612
- y0: cy - h / 2 - PAD3,
73613
- x1: cx + w / 2 + PAD3,
73614
- y1: cy + h / 2 + PAD3
73962
+ x0: cx - w / 2 - PAD4,
73963
+ y0: cy - h / 2 - PAD4,
73964
+ x1: cx + w / 2 + PAD4,
73965
+ y1: cy + h / 2 + PAD4
73615
73966
  });
73616
73967
  }
73617
73968
  const gPatch = svg.append("g").attr("class", "dgmo-map-label-patch").attr("mask", `url(#${maskId})`).style("pointer-events", "none");
@@ -74738,16 +75089,16 @@ function renderRing(container, parsed, palette, isDark, onClickItem, exportDims)
74738
75089
  }
74739
75090
  }
74740
75091
  function drawRingCurvedLabel(labelG, defs, pathId, text, cx, cy, rMid, labelFont, textColor, palette) {
74741
- const PAD3 = 1.18;
75092
+ const PAD4 = 1.18;
74742
75093
  let fs = labelFont;
74743
75094
  let rPath = rMid - fs * 0.32;
74744
75095
  const maxLen = MAX_LABEL_ARC * rPath;
74745
- const wPadded = measureText(text, labelFont) * PAD3;
75096
+ const wPadded = measureText(text, labelFont) * PAD4;
74746
75097
  if (wPadded > maxLen) {
74747
75098
  fs = Math.max(LABEL_FONT_MIN2, Math.floor(labelFont * maxLen / wPadded));
74748
75099
  rPath = rMid - fs * 0.32;
74749
75100
  }
74750
- const arcLen = measureText(text, fs) * PAD3;
75101
+ const arcLen = measureText(text, fs) * PAD4;
74751
75102
  const halfAngle = Math.min(arcLen / (2 * rPath), MAX_LABEL_ARC / 2);
74752
75103
  const largeArc = halfAngle * 2 > Math.PI ? 1 : 0;
74753
75104
  const p0x = cx - Math.sin(halfAngle) * rPath;
@@ -75699,13 +76050,13 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75699
76050
  g.append("text").attr("class", "dgmo-treemap-header-value").attr("x", w - ICON_RESERVE - 4).attr("y", 13).attr("text-anchor", "end").attr("font-size", 10.5).attr("fill", ink).attr("opacity", 0.75).text(valStr);
75700
76051
  }
75701
76052
  }
75702
- const PAD3 = Math.max(4, Math.min(14, Math.floor(Math.min(w, h) / 5)));
76053
+ const PAD4 = Math.max(4, Math.min(14, Math.floor(Math.min(w, h) / 5)));
75703
76054
  const MIN_FS = 7;
75704
- if (!cell.isContainer && w >= 2 * PAD3 + 8 && h >= 2 * PAD3 + 8) {
75705
- const maxW = w - 2 * PAD3;
76055
+ if (!cell.isContainer && w >= 2 * PAD4 + 8 && h >= 2 * PAD4 + 8) {
76056
+ const maxW = w - 2 * PAD4;
75706
76057
  const horizMinW = measureText(cell.label, MIN_FS) * 1.06;
75707
- if (horizMinW > maxW && h > w * 1.25 && h - 2 * PAD3 > maxW) {
75708
- drawVerticalLabel(g, cell.label, w, h, PAD3, ink);
76058
+ if (horizMinW > maxW && h > w * 1.25 && h - 2 * PAD4 > maxW) {
76059
+ drawVerticalLabel(g, cell.label, w, h, PAD4, ink);
75709
76060
  if (drillable && w > 30 && h > 22) drawFocusIcon(g, w, ink, 9);
75710
76061
  continue;
75711
76062
  }
@@ -75716,8 +76067,8 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75716
76067
  const nameOpacity = 0.95 - tg * 0.5;
75717
76068
  const vfs = clamp4(Math.round(fs * 0.42), 11, 28);
75718
76069
  const valOpacity = Math.max(0.45, nameOpacity - 0.1);
75719
- let y = PAD3 + Math.round(fs * 0.78);
75720
- g.append("text").attr("class", "dgmo-treemap-label").attr("x", PAD3).attr("y", y).attr("font-size", fs).attr("font-weight", 600).attr("fill", ink).attr("opacity", nameOpacity).text(clipLabel(cell.label, maxW, fs));
76070
+ let y = PAD4 + Math.round(fs * 0.78);
76071
+ g.append("text").attr("class", "dgmo-treemap-label").attr("x", PAD4).attr("y", y).attr("font-size", fs).attr("font-weight", 600).attr("fill", ink).attr("opacity", nameOpacity).text(clipLabel(cell.label, maxW, fs));
75721
76072
  const valParts = [
75722
76073
  opts.noValues ? "" : compactNumber2(cell.value),
75723
76074
  opts.noPercent ? "" : formatPct(cell.pctOfRoot)
@@ -75725,12 +76076,12 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75725
76076
  const combined = valParts.join(" \xB7 ");
75726
76077
  const nameBaseY = y;
75727
76078
  const addLineAt = (text, yy, size, opacity) => {
75728
- g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD3).attr("y", yy).attr("font-size", size).attr("fill", ink).attr("opacity", opacity).text(text);
76079
+ g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD4).attr("y", yy).attr("font-size", size).attr("fill", ink).attr("opacity", opacity).text(text);
75729
76080
  };
75730
76081
  if (combined) {
75731
76082
  const fitsW = measureText(combined, vfs) <= maxW;
75732
76083
  const valY = y + lineDrop(fs, vfs);
75733
- const roomBelow = valY + descent(vfs) <= h - PAD3;
76084
+ const roomBelow = valY + descent(vfs) <= h - PAD4;
75734
76085
  if (fitsW && roomBelow) {
75735
76086
  addLineAt(combined, valY, vfs, valOpacity);
75736
76087
  } else if (fitsW) {
@@ -75738,24 +76089,24 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75738
76089
  const rendered = clipLabel(cell.label, maxW, fs);
75739
76090
  const nW = measureText(rendered, fs) * 1.12;
75740
76091
  const gap = Math.max(12, Math.round(fs * 0.25));
75741
- if (PAD3 + nW + gap + measureText(combined, ivfs) <= w - PAD3) {
75742
- g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD3 + nW + gap).attr("y", nameBaseY).attr("font-size", ivfs).attr("fill", ink).attr("opacity", valOpacity).text(combined);
76092
+ if (PAD4 + nW + gap + measureText(combined, ivfs) <= w - PAD4) {
76093
+ g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD4 + nW + gap).attr("y", nameBaseY).attr("font-size", ivfs).attr("fill", ink).attr("opacity", valOpacity).text(combined);
75743
76094
  }
75744
76095
  } else if (valParts.length === 2) {
75745
76096
  const d1 = lineDrop(fs, vfs);
75746
- if (y + d1 + descent(vfs) <= h - PAD3) {
76097
+ if (y + d1 + descent(vfs) <= h - PAD4) {
75747
76098
  y += d1;
75748
76099
  addLineAt(valParts[0], y, vfs, valOpacity);
75749
76100
  }
75750
76101
  const pfs = Math.max(10, Math.round(vfs * 0.9));
75751
76102
  const d2 = lineDrop(vfs, pfs);
75752
- if (y + d2 + descent(pfs) <= h - PAD3) {
76103
+ if (y + d2 + descent(pfs) <= h - PAD4) {
75753
76104
  y += d2;
75754
76105
  addLineAt(valParts[1], y, pfs, valOpacity);
75755
76106
  }
75756
76107
  } else {
75757
76108
  const onlyY = y + lineDrop(fs, vfs);
75758
- if (onlyY + descent(vfs) <= h - PAD3) {
76109
+ if (onlyY + descent(vfs) <= h - PAD4) {
75759
76110
  addLineAt(combined, onlyY, vfs, valOpacity);
75760
76111
  }
75761
76112
  }
@@ -75871,382 +76222,971 @@ var init_renderer26 = __esm({
75871
76222
  }
75872
76223
  });
75873
76224
 
75874
- // src/block/layout.ts
75875
- function layoutBlock(grid, opts = {}) {
75876
- const collapsed = opts.collapsed ?? /* @__PURE__ */ new Set();
75877
- const node = layoutGrid(grid, 0, 0, null, collapsed);
75878
- return { width: node.w, height: node.h, items: node.items };
75879
- }
75880
- function maxSpanSum(g) {
75881
- return Math.max(
75882
- 1,
75883
- ...g.rows.map((r) => r.reduce((s, c) => s + (c.span || 1), 0))
75884
- );
75885
- }
75886
- function leafW(node) {
75887
- return Math.max(
75888
- MIN_COL,
75889
- Math.min(MAX_COL, measureText(node.label, LABEL_FS) + 2 * BLOCK_PAD + 14)
75890
- );
75891
- }
75892
- function gridColW(g) {
75893
- let m = MIN_COL;
75894
- for (const row of g.rows)
75895
- for (const c of row) {
75896
- if (!isBlockNode(c)) continue;
75897
- const iw = c.grid ? intrinsicGridW(c.grid) + 2 * BLOCK_PAD : leafW(c);
75898
- m = Math.max(m, iw / (c.span || 1));
75899
- }
75900
- return m;
75901
- }
75902
- function intrinsicGridW(g) {
75903
- const cols = g.cols ?? maxSpanSum(g);
75904
- return cols * gridColW(g) + (cols + 1) * BLOCK_GAP;
75905
- }
75906
- function layoutGrid(g, ox, oy, forceColW, collapsed) {
75907
- const cols = g.cols ?? maxSpanSum(g);
75908
- const colW = forceColW ?? gridColW(g);
75909
- const gridW = cols * colW + (cols + 1) * BLOCK_GAP;
75910
- let cy = oy + BLOCK_GAP;
75911
- const items = [];
75912
- let maxRight = ox + BLOCK_GAP;
75913
- for (const row of g.rows) {
75914
- let cx = ox + BLOCK_GAP;
75915
- let rowH = BLOCK_LEAF_H;
75916
- const rowItems = [];
75917
- for (const cell of row) {
75918
- const span = cell.span || 1;
75919
- const cw = span * colW + (span - 1) * BLOCK_GAP;
75920
- if (!isBlockNode(cell)) {
75921
- rowItems.push({ type: "empty", x: cx, y: cy, w: cw, h: BLOCK_LEAF_H });
75922
- cx += cw + BLOCK_GAP;
75923
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75924
- continue;
75925
- }
75926
- if (cell.grid && collapsed.has(cell.id)) {
75927
- const item = {
75928
- type: "collapsed",
75929
- x: cx,
75930
- y: cy,
75931
- w: cw,
75932
- h: BLOCK_COLLAPSED_H,
75933
- label: cell.label,
75934
- node: cell,
75935
- lineNumber: cell.lineNumber
75936
- };
75937
- rowItems.push(item);
75938
- rowH = Math.max(rowH, BLOCK_COLLAPSED_H);
75939
- cx += cw + BLOCK_GAP;
75940
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75941
- continue;
75942
- }
75943
- if (cell.grid) {
75944
- const innerCols = cell.grid.cols ?? maxSpanSum(cell.grid);
75945
- const innerColW = Math.max(
75946
- MIN_COL * 0.66,
75947
- (cw - 2 * BLOCK_PAD - (innerCols + 1) * BLOCK_GAP) / innerCols
75948
- );
75949
- const inner = layoutGrid(
75950
- cell.grid,
75951
- cx + BLOCK_PAD,
75952
- cy + BLOCK_HEADER_H,
75953
- innerColW,
75954
- collapsed
75955
- );
75956
- const h = BLOCK_HEADER_H + inner.h + BLOCK_PAD;
75957
- rowItems.push({
75958
- type: "container",
75959
- x: cx,
75960
- y: cy,
75961
- w: cw,
75962
- h,
75963
- label: cell.label,
75964
- node: cell,
75965
- lineNumber: cell.lineNumber,
75966
- inner: inner.items
75967
- });
75968
- rowH = Math.max(rowH, h);
75969
- cx += cw + BLOCK_GAP;
75970
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75971
- continue;
75972
- }
75973
- rowItems.push({
75974
- type: "leaf",
75975
- x: cx,
75976
- y: cy,
75977
- w: cw,
75978
- h: BLOCK_LEAF_H,
75979
- label: cell.label,
75980
- node: cell,
75981
- lineNumber: cell.lineNumber
75982
- });
75983
- cx += cw + BLOCK_GAP;
75984
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75985
- }
75986
- items.push(...rowItems);
75987
- cy += rowH + BLOCK_GAP;
75988
- }
75989
- const fitW = Math.max(gridW, maxRight - ox + BLOCK_GAP);
75990
- return { x: ox, y: oy, w: fitW, h: cy - oy, items };
75991
- }
75992
- var BLOCK_GAP, BLOCK_PAD, BLOCK_LEAF_H, BLOCK_HEADER_H, BLOCK_COLLAPSED_H, BLOCK_BAR_H, MIN_COL, MAX_COL, LABEL_FS;
75993
- var init_layout20 = __esm({
75994
- "src/block/layout.ts"() {
76225
+ // node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
76226
+ var require_lz_string = __commonJS({
76227
+ "node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
75995
76228
  "use strict";
75996
- init_text_measure();
75997
- init_types4();
75998
- BLOCK_GAP = 12;
75999
- BLOCK_PAD = 10;
76000
- BLOCK_LEAF_H = 46;
76001
- BLOCK_HEADER_H = 28;
76002
- BLOCK_COLLAPSED_H = 46;
76003
- BLOCK_BAR_H = 6;
76004
- MIN_COL = 104;
76005
- MAX_COL = 250;
76006
- LABEL_FS = 13;
76007
- }
76008
- });
76009
-
76010
- // src/block/renderer.ts
76011
- var renderer_exports26 = {};
76012
- __export(renderer_exports26, {
76013
- authoredCollapsedIds: () => authoredCollapsedIds,
76014
- renderBlock: () => renderBlock,
76015
- renderBlockForExport: () => renderBlockForExport
76016
- });
76017
- import * as d3Selection33 from "d3-selection";
76018
- function renderBlockForExport(container, parsed, palette, isDark, exportDims, options) {
76019
- renderBlock(container, parsed, palette, isDark, exportDims, {
76020
- exportMode: true,
76021
- ...options
76022
- });
76023
- }
76024
- function renderBlock(container, parsed, palette, isDark, exportDims, options = {}) {
76025
- if (parsed.error || parsed.top.rows.length === 0) return;
76026
- d3Selection33.select(container).selectAll(":not([data-d3-tooltip])").remove();
76027
- const opts = parsed.options;
76028
- const showTitle = !!parsed.title;
76029
- const titleH = showTitle ? TITLE_BAND2 : 0;
76030
- const collapsed = options.collapsed ?? authoredCollapsedIds(parsed);
76031
- const layout = layoutBlock(parsed.top, { collapsed });
76032
- const legend = !opts.noLegend ? buildBlockLegend(parsed) : null;
76033
- let width;
76034
- let height;
76035
- if (options.exportMode) {
76036
- width = Math.max(layout.width, MIN_EXPORT_WIDTH) + PADDING5 * 2;
76037
- } else {
76038
- width = exportDims?.width ?? container.clientWidth;
76039
- }
76040
- const legendReserve = legend ? getMaxLegendReservedHeight(
76041
- { groups: legend.groups, position: LEGEND_POSITION3, mode: "preview" },
76042
- width
76043
- ) + LEGEND_GROUP_GAP : 0;
76044
- const inlineRequested = opts.legendInline === true;
76045
- const legendExtent = inlineRequested && legend ? getLegendExtent(
76046
- {
76047
- groups: legend.groups,
76048
- position: {
76049
- placement: "top-center",
76050
- titleRelation: "inline-with-title"
76051
- },
76052
- mode: options.exportMode ? "export" : "preview"
76053
- },
76054
- { activeGroup: legend.activeGroup ?? null },
76055
- width
76056
- ) : { width: 0, height: 0 };
76057
- const header = layoutInlineHeader({
76058
- requested: inlineRequested,
76059
- title: parsed.title ?? "",
76060
- hasLegend: !!legend,
76061
- legendWidth: legendExtent.width,
76062
- legendHeight: legendExtent.height,
76063
- containerWidth: width,
76064
- titleBandHeight: titleH,
76065
- legendReserve,
76066
- titleBaselineY: TITLE_Y,
76067
- titleFontSize: TITLE_FONT_SIZE
76068
- });
76069
- const areaY = (header.inline ? titleH : titleH + legendReserve) + PADDING5;
76070
- if (options.exportMode) {
76071
- height = areaY + layout.height + PADDING5;
76072
- } else {
76073
- height = exportDims?.height ?? container.clientHeight;
76074
- }
76075
- if (width <= 0 || height <= 0) return;
76076
- const areaX = PADDING5;
76077
- const areaW = Math.max(1, width - PADDING5 * 2);
76078
- const areaH = Math.max(1, height - areaY - PADDING5);
76079
- const scale = Math.min(1, areaW / layout.width, areaH / layout.height);
76080
- const offsetX = areaX + (areaW - layout.width * scale) / 2;
76081
- const offsetY = areaY;
76082
- const svg = d3Selection33.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").attr("class", "dgmo-block").style("font-family", FONT_FAMILY);
76083
- if (showTitle) {
76084
- const title = svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", TITLE_Y).attr("text-anchor", header.titleAnchor).attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).text(parsed.title);
76085
- if (parsed.titleLineNumber !== null) {
76086
- title.attr("data-line-number", parsed.titleLineNumber);
76087
- }
76088
- }
76089
- const activeGroup = parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null;
76090
- const neutral = mix(palette.text, palette.bg, 22);
76091
- const root = svg.append("g").attr("class", "dgmo-block-cells").attr("transform", `translate(${offsetX},${offsetY}) scale(${scale})`);
76092
- drawItems(root, layout.items, {
76093
- palette,
76094
- tagGroups: parsed.tagGroups,
76095
- activeGroup,
76096
- activeKey: activeGroup ? tagAttrKey(activeGroup) : null,
76097
- neutral,
76098
- fillMode: opts.fillMode,
76099
- isDark,
76100
- onToggle: options.onToggle
76101
- });
76102
- if (legend) {
76103
- const legendG = svg.append("g").attr("class", "dgmo-block-legend").attr(
76104
- "transform",
76105
- header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0, ${titleH})`
76106
- );
76107
- renderIntegratedLegend(legendG, {
76108
- groups: legend.groups,
76109
- palette: {
76110
- bg: palette.bg,
76111
- surface: palette.surface,
76112
- text: palette.text,
76113
- textMuted: palette.textMuted,
76114
- primary: palette.primary
76115
- },
76116
- isDark,
76117
- width,
76118
- mode: options.exportMode ? "export" : "preview",
76119
- position: {
76120
- placement: "top-center",
76121
- titleRelation: header.inline ? "inline-with-title" : "below-title"
76122
- },
76123
- activeGroup: legend.activeGroup
76124
- });
76125
- }
76126
- }
76127
- function colorOf(node, ctx) {
76128
- if (!node || !ctx.activeGroup) return null;
76129
- return resolveTagColor(node.metadata, ctx.tagGroups, ctx.activeGroup) ?? null;
76130
- }
76131
- function clipLabel2(s, maxWidth, fs) {
76132
- if (measureText(s, fs) <= maxWidth) return s;
76133
- let lo = 0;
76134
- let hi = s.length;
76135
- while (lo < hi) {
76136
- const mid = Math.ceil((lo + hi) / 2);
76137
- if (measureText(s.slice(0, mid) + "\u2026", fs) <= maxWidth) lo = mid;
76138
- else hi = mid - 1;
76139
- }
76140
- return lo <= 0 ? "" : s.slice(0, lo) + "\u2026";
76141
- }
76142
- function drawItems(g, items, ctx, path = []) {
76143
- const { palette, fillMode } = ctx;
76144
- for (const it of items) {
76145
- if (it.type === "empty") {
76146
- g.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 7).attr("fill", "none").attr("stroke", ctx.neutral).attr("stroke-width", 1).attr("stroke-dasharray", "3 4").attr("opacity", 0.7);
76147
- continue;
76148
- }
76149
- const node = it.node;
76150
- const itemPath = [...path, node.id];
76151
- const color = colorOf(node, ctx);
76152
- const stroke2 = color ?? ctx.neutral;
76153
- const cell = g.append("g").attr("class", "dgmo-block-cell").attr("data-block-id", node.id).attr("data-block-path", itemPath.join(" / "));
76154
- if (it.lineNumber !== void 0)
76155
- cell.attr("data-line-number", it.lineNumber);
76156
- if (ctx.activeKey) {
76157
- const v = node.metadata[ctx.activeKey];
76158
- if (v) cell.attr(`data-tag-${ctx.activeKey}`, v);
76159
- }
76160
- if (it.type === "collapsed") {
76161
- const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 12) : palette.surface;
76162
- const cid = `dgmo-block-clip-${clipCounter++}`;
76163
- cell.append("clipPath").attr("id", cid).append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10);
76164
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
76165
- cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 4).attr("text-anchor", "middle").attr("font-size", 12.5).attr("font-weight", 700).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 24, 12.5));
76166
- cell.append("rect").attr("x", it.x).attr("y", it.y + it.h - BLOCK_BAR_H).attr("width", it.w).attr("height", BLOCK_BAR_H).attr("fill", fillMode === "solid" && color ? palette.text : stroke2).attr("clip-path", `url(#${cid})`);
76167
- bindToggle(cell, it, ctx, it.h);
76168
- continue;
76169
- }
76170
- if (it.type === "container") {
76171
- const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 7) : palette.surface;
76172
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
76173
- const sizeMetric = Math.min(it.w, it.h * 2.5);
76174
- const headerFs = Math.max(
76175
- 13,
76176
- Math.min(20, Math.round(13 + (sizeMetric - 220) / 70))
76177
- );
76178
- const grow = (headerFs - 13) / (20 - 13);
76179
- const headerOpacity = 0.92 - grow * 0.3;
76180
- const headerY = it.y + Math.round(headerFs * 0.7) + 7;
76181
- cell.append("text").attr("x", it.x + it.w / 2).attr("y", headerY).attr("text-anchor", "middle").attr("font-size", headerFs).attr("font-weight", 700).attr("fill", palette.text).attr("opacity", headerOpacity).text(clipLabel2(it.label ?? "", it.w - 24, headerFs));
76182
- bindToggle(cell, it, ctx, BLOCK_HEADER_H);
76183
- if (it.inner) drawItems(g, it.inner, ctx, itemPath);
76184
- continue;
76185
- }
76186
- const fill2 = color ? fillMode === "solid" ? mix(color, palette.bg, 80) : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 14) : palette.bg;
76187
- cell.attr("data-leaf", "true");
76188
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 8).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.25);
76189
- cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 5).attr("text-anchor", "middle").attr("font-size", 13).attr("font-weight", 600).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 16, 13));
76190
- }
76191
- }
76192
- function bindToggle(cell, it, ctx, hitH) {
76193
- if (!ctx.onToggle || !it.node || it.lineNumber === void 0) return;
76194
- const id = it.node.id;
76195
- const ln = it.lineNumber;
76196
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", hitH).attr("rx", 10).attr("fill", "transparent").style("cursor", "pointer").on("click", () => ctx.onToggle(id, ln));
76197
- }
76198
- function authoredCollapsedIds(parsed) {
76199
- const into = /* @__PURE__ */ new Set();
76200
- collectCollapsed(parsed, into);
76201
- return into;
76202
- }
76203
- function collectCollapsed(parsed, into) {
76204
- const walk = (grid) => {
76205
- for (const row of grid.rows)
76206
- for (const c of row)
76207
- if (isBlockNode(c)) {
76208
- if (c.collapsed && c.grid) into.add(c.id);
76209
- if (c.grid) walk(c.grid);
76210
- }
76211
- };
76212
- walk(parsed.top);
76213
- }
76214
- function buildBlockLegend(parsed) {
76215
- if (parsed.tagGroups.length === 0) return null;
76216
- const tg = parsed.tagGroups[0];
76217
- const key = tagAttrKey(tg.name);
76218
- const used = /* @__PURE__ */ new Set();
76219
- const walk = (grid) => {
76220
- for (const row of grid.rows)
76221
- for (const c of row)
76222
- if (isBlockNode(c)) {
76223
- const v = c.metadata[key];
76224
- if (v) used.add(v.toLowerCase());
76225
- if (c.grid) walk(c.grid);
76229
+ var LZString = (function() {
76230
+ var f = String.fromCharCode;
76231
+ var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
76232
+ var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
76233
+ var baseReverseDic = {};
76234
+ function getBaseValue(alphabet, character) {
76235
+ if (!baseReverseDic[alphabet]) {
76236
+ baseReverseDic[alphabet] = {};
76237
+ for (var i = 0; i < alphabet.length; i++) {
76238
+ baseReverseDic[alphabet][alphabet.charAt(i)] = i;
76239
+ }
76226
76240
  }
76227
- };
76228
- walk(parsed.top);
76229
- const entries = tg.entries.filter((e) => used.has(e.value.toLowerCase())).map((e) => ({ value: e.value, color: e.color }));
76230
- if (entries.length === 0) return null;
76231
- return { groups: [{ name: tg.name, entries }], activeGroup: tg.name };
76232
- }
76233
- var PADDING5, TITLE_BAND2, MIN_EXPORT_WIDTH, LEGEND_POSITION3, clipCounter;
76234
- var init_renderer27 = __esm({
76235
- "src/block/renderer.ts"() {
76236
- "use strict";
76237
- init_fonts();
76238
- init_color_utils();
76239
- init_tag_groups();
76240
- init_inline_header();
76241
- init_legend_integration();
76242
- init_legend_layout();
76243
- init_legend_constants();
76244
- init_title_constants();
76245
- init_text_measure();
76246
- init_types4();
76247
- init_layout20();
76248
- PADDING5 = 12;
76249
- TITLE_BAND2 = 36;
76241
+ return baseReverseDic[alphabet][character];
76242
+ }
76243
+ var LZString2 = {
76244
+ compressToBase64: function(input) {
76245
+ if (input == null) return "";
76246
+ var res = LZString2._compress(input, 6, function(a) {
76247
+ return keyStrBase64.charAt(a);
76248
+ });
76249
+ switch (res.length % 4) {
76250
+ // To produce valid Base64
76251
+ default:
76252
+ // When could this happen ?
76253
+ case 0:
76254
+ return res;
76255
+ case 1:
76256
+ return res + "===";
76257
+ case 2:
76258
+ return res + "==";
76259
+ case 3:
76260
+ return res + "=";
76261
+ }
76262
+ },
76263
+ decompressFromBase64: function(input) {
76264
+ if (input == null) return "";
76265
+ if (input == "") return null;
76266
+ return LZString2._decompress(input.length, 32, function(index) {
76267
+ return getBaseValue(keyStrBase64, input.charAt(index));
76268
+ });
76269
+ },
76270
+ compressToUTF16: function(input) {
76271
+ if (input == null) return "";
76272
+ return LZString2._compress(input, 15, function(a) {
76273
+ return f(a + 32);
76274
+ }) + " ";
76275
+ },
76276
+ decompressFromUTF16: function(compressed) {
76277
+ if (compressed == null) return "";
76278
+ if (compressed == "") return null;
76279
+ return LZString2._decompress(compressed.length, 16384, function(index) {
76280
+ return compressed.charCodeAt(index) - 32;
76281
+ });
76282
+ },
76283
+ //compress into uint8array (UCS-2 big endian format)
76284
+ compressToUint8Array: function(uncompressed) {
76285
+ var compressed = LZString2.compress(uncompressed);
76286
+ var buf = new Uint8Array(compressed.length * 2);
76287
+ for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
76288
+ var current_value = compressed.charCodeAt(i);
76289
+ buf[i * 2] = current_value >>> 8;
76290
+ buf[i * 2 + 1] = current_value % 256;
76291
+ }
76292
+ return buf;
76293
+ },
76294
+ //decompress from uint8array (UCS-2 big endian format)
76295
+ decompressFromUint8Array: function(compressed) {
76296
+ if (compressed === null || compressed === void 0) {
76297
+ return LZString2.decompress(compressed);
76298
+ } else {
76299
+ var buf = new Array(compressed.length / 2);
76300
+ for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
76301
+ buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
76302
+ }
76303
+ var result = [];
76304
+ buf.forEach(function(c) {
76305
+ result.push(f(c));
76306
+ });
76307
+ return LZString2.decompress(result.join(""));
76308
+ }
76309
+ },
76310
+ //compress into a string that is already URI encoded
76311
+ compressToEncodedURIComponent: function(input) {
76312
+ if (input == null) return "";
76313
+ return LZString2._compress(input, 6, function(a) {
76314
+ return keyStrUriSafe.charAt(a);
76315
+ });
76316
+ },
76317
+ //decompress from an output of compressToEncodedURIComponent
76318
+ decompressFromEncodedURIComponent: function(input) {
76319
+ if (input == null) return "";
76320
+ if (input == "") return null;
76321
+ input = input.replace(/ /g, "+");
76322
+ return LZString2._decompress(input.length, 32, function(index) {
76323
+ return getBaseValue(keyStrUriSafe, input.charAt(index));
76324
+ });
76325
+ },
76326
+ compress: function(uncompressed) {
76327
+ return LZString2._compress(uncompressed, 16, function(a) {
76328
+ return f(a);
76329
+ });
76330
+ },
76331
+ _compress: function(uncompressed, bitsPerChar, getCharFromInt) {
76332
+ if (uncompressed == null) return "";
76333
+ var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
76334
+ for (ii = 0; ii < uncompressed.length; ii += 1) {
76335
+ context_c = uncompressed.charAt(ii);
76336
+ if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
76337
+ context_dictionary[context_c] = context_dictSize++;
76338
+ context_dictionaryToCreate[context_c] = true;
76339
+ }
76340
+ context_wc = context_w + context_c;
76341
+ if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
76342
+ context_w = context_wc;
76343
+ } else {
76344
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
76345
+ if (context_w.charCodeAt(0) < 256) {
76346
+ for (i = 0; i < context_numBits; i++) {
76347
+ context_data_val = context_data_val << 1;
76348
+ if (context_data_position == bitsPerChar - 1) {
76349
+ context_data_position = 0;
76350
+ context_data.push(getCharFromInt(context_data_val));
76351
+ context_data_val = 0;
76352
+ } else {
76353
+ context_data_position++;
76354
+ }
76355
+ }
76356
+ value = context_w.charCodeAt(0);
76357
+ for (i = 0; i < 8; i++) {
76358
+ context_data_val = context_data_val << 1 | value & 1;
76359
+ if (context_data_position == bitsPerChar - 1) {
76360
+ context_data_position = 0;
76361
+ context_data.push(getCharFromInt(context_data_val));
76362
+ context_data_val = 0;
76363
+ } else {
76364
+ context_data_position++;
76365
+ }
76366
+ value = value >> 1;
76367
+ }
76368
+ } else {
76369
+ value = 1;
76370
+ for (i = 0; i < context_numBits; i++) {
76371
+ context_data_val = context_data_val << 1 | value;
76372
+ if (context_data_position == bitsPerChar - 1) {
76373
+ context_data_position = 0;
76374
+ context_data.push(getCharFromInt(context_data_val));
76375
+ context_data_val = 0;
76376
+ } else {
76377
+ context_data_position++;
76378
+ }
76379
+ value = 0;
76380
+ }
76381
+ value = context_w.charCodeAt(0);
76382
+ for (i = 0; i < 16; i++) {
76383
+ context_data_val = context_data_val << 1 | value & 1;
76384
+ if (context_data_position == bitsPerChar - 1) {
76385
+ context_data_position = 0;
76386
+ context_data.push(getCharFromInt(context_data_val));
76387
+ context_data_val = 0;
76388
+ } else {
76389
+ context_data_position++;
76390
+ }
76391
+ value = value >> 1;
76392
+ }
76393
+ }
76394
+ context_enlargeIn--;
76395
+ if (context_enlargeIn == 0) {
76396
+ context_enlargeIn = Math.pow(2, context_numBits);
76397
+ context_numBits++;
76398
+ }
76399
+ delete context_dictionaryToCreate[context_w];
76400
+ } else {
76401
+ value = context_dictionary[context_w];
76402
+ for (i = 0; i < context_numBits; i++) {
76403
+ context_data_val = context_data_val << 1 | value & 1;
76404
+ if (context_data_position == bitsPerChar - 1) {
76405
+ context_data_position = 0;
76406
+ context_data.push(getCharFromInt(context_data_val));
76407
+ context_data_val = 0;
76408
+ } else {
76409
+ context_data_position++;
76410
+ }
76411
+ value = value >> 1;
76412
+ }
76413
+ }
76414
+ context_enlargeIn--;
76415
+ if (context_enlargeIn == 0) {
76416
+ context_enlargeIn = Math.pow(2, context_numBits);
76417
+ context_numBits++;
76418
+ }
76419
+ context_dictionary[context_wc] = context_dictSize++;
76420
+ context_w = String(context_c);
76421
+ }
76422
+ }
76423
+ if (context_w !== "") {
76424
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
76425
+ if (context_w.charCodeAt(0) < 256) {
76426
+ for (i = 0; i < context_numBits; i++) {
76427
+ context_data_val = context_data_val << 1;
76428
+ if (context_data_position == bitsPerChar - 1) {
76429
+ context_data_position = 0;
76430
+ context_data.push(getCharFromInt(context_data_val));
76431
+ context_data_val = 0;
76432
+ } else {
76433
+ context_data_position++;
76434
+ }
76435
+ }
76436
+ value = context_w.charCodeAt(0);
76437
+ for (i = 0; i < 8; i++) {
76438
+ context_data_val = context_data_val << 1 | value & 1;
76439
+ if (context_data_position == bitsPerChar - 1) {
76440
+ context_data_position = 0;
76441
+ context_data.push(getCharFromInt(context_data_val));
76442
+ context_data_val = 0;
76443
+ } else {
76444
+ context_data_position++;
76445
+ }
76446
+ value = value >> 1;
76447
+ }
76448
+ } else {
76449
+ value = 1;
76450
+ for (i = 0; i < context_numBits; i++) {
76451
+ context_data_val = context_data_val << 1 | value;
76452
+ if (context_data_position == bitsPerChar - 1) {
76453
+ context_data_position = 0;
76454
+ context_data.push(getCharFromInt(context_data_val));
76455
+ context_data_val = 0;
76456
+ } else {
76457
+ context_data_position++;
76458
+ }
76459
+ value = 0;
76460
+ }
76461
+ value = context_w.charCodeAt(0);
76462
+ for (i = 0; i < 16; i++) {
76463
+ context_data_val = context_data_val << 1 | value & 1;
76464
+ if (context_data_position == bitsPerChar - 1) {
76465
+ context_data_position = 0;
76466
+ context_data.push(getCharFromInt(context_data_val));
76467
+ context_data_val = 0;
76468
+ } else {
76469
+ context_data_position++;
76470
+ }
76471
+ value = value >> 1;
76472
+ }
76473
+ }
76474
+ context_enlargeIn--;
76475
+ if (context_enlargeIn == 0) {
76476
+ context_enlargeIn = Math.pow(2, context_numBits);
76477
+ context_numBits++;
76478
+ }
76479
+ delete context_dictionaryToCreate[context_w];
76480
+ } else {
76481
+ value = context_dictionary[context_w];
76482
+ for (i = 0; i < context_numBits; i++) {
76483
+ context_data_val = context_data_val << 1 | value & 1;
76484
+ if (context_data_position == bitsPerChar - 1) {
76485
+ context_data_position = 0;
76486
+ context_data.push(getCharFromInt(context_data_val));
76487
+ context_data_val = 0;
76488
+ } else {
76489
+ context_data_position++;
76490
+ }
76491
+ value = value >> 1;
76492
+ }
76493
+ }
76494
+ context_enlargeIn--;
76495
+ if (context_enlargeIn == 0) {
76496
+ context_enlargeIn = Math.pow(2, context_numBits);
76497
+ context_numBits++;
76498
+ }
76499
+ }
76500
+ value = 2;
76501
+ for (i = 0; i < context_numBits; i++) {
76502
+ context_data_val = context_data_val << 1 | value & 1;
76503
+ if (context_data_position == bitsPerChar - 1) {
76504
+ context_data_position = 0;
76505
+ context_data.push(getCharFromInt(context_data_val));
76506
+ context_data_val = 0;
76507
+ } else {
76508
+ context_data_position++;
76509
+ }
76510
+ value = value >> 1;
76511
+ }
76512
+ while (true) {
76513
+ context_data_val = context_data_val << 1;
76514
+ if (context_data_position == bitsPerChar - 1) {
76515
+ context_data.push(getCharFromInt(context_data_val));
76516
+ break;
76517
+ } else context_data_position++;
76518
+ }
76519
+ return context_data.join("");
76520
+ },
76521
+ decompress: function(compressed) {
76522
+ if (compressed == null) return "";
76523
+ if (compressed == "") return null;
76524
+ return LZString2._decompress(compressed.length, 32768, function(index) {
76525
+ return compressed.charCodeAt(index);
76526
+ });
76527
+ },
76528
+ _decompress: function(length, resetValue, getNextValue) {
76529
+ var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
76530
+ for (i = 0; i < 3; i += 1) {
76531
+ dictionary[i] = i;
76532
+ }
76533
+ bits = 0;
76534
+ maxpower = Math.pow(2, 2);
76535
+ power = 1;
76536
+ while (power != maxpower) {
76537
+ resb = data.val & data.position;
76538
+ data.position >>= 1;
76539
+ if (data.position == 0) {
76540
+ data.position = resetValue;
76541
+ data.val = getNextValue(data.index++);
76542
+ }
76543
+ bits |= (resb > 0 ? 1 : 0) * power;
76544
+ power <<= 1;
76545
+ }
76546
+ switch (next = bits) {
76547
+ case 0:
76548
+ bits = 0;
76549
+ maxpower = Math.pow(2, 8);
76550
+ power = 1;
76551
+ while (power != maxpower) {
76552
+ resb = data.val & data.position;
76553
+ data.position >>= 1;
76554
+ if (data.position == 0) {
76555
+ data.position = resetValue;
76556
+ data.val = getNextValue(data.index++);
76557
+ }
76558
+ bits |= (resb > 0 ? 1 : 0) * power;
76559
+ power <<= 1;
76560
+ }
76561
+ c = f(bits);
76562
+ break;
76563
+ case 1:
76564
+ bits = 0;
76565
+ maxpower = Math.pow(2, 16);
76566
+ power = 1;
76567
+ while (power != maxpower) {
76568
+ resb = data.val & data.position;
76569
+ data.position >>= 1;
76570
+ if (data.position == 0) {
76571
+ data.position = resetValue;
76572
+ data.val = getNextValue(data.index++);
76573
+ }
76574
+ bits |= (resb > 0 ? 1 : 0) * power;
76575
+ power <<= 1;
76576
+ }
76577
+ c = f(bits);
76578
+ break;
76579
+ case 2:
76580
+ return "";
76581
+ }
76582
+ dictionary[3] = c;
76583
+ w = c;
76584
+ result.push(c);
76585
+ while (true) {
76586
+ if (data.index > length) {
76587
+ return "";
76588
+ }
76589
+ bits = 0;
76590
+ maxpower = Math.pow(2, numBits);
76591
+ power = 1;
76592
+ while (power != maxpower) {
76593
+ resb = data.val & data.position;
76594
+ data.position >>= 1;
76595
+ if (data.position == 0) {
76596
+ data.position = resetValue;
76597
+ data.val = getNextValue(data.index++);
76598
+ }
76599
+ bits |= (resb > 0 ? 1 : 0) * power;
76600
+ power <<= 1;
76601
+ }
76602
+ switch (c = bits) {
76603
+ case 0:
76604
+ bits = 0;
76605
+ maxpower = Math.pow(2, 8);
76606
+ power = 1;
76607
+ while (power != maxpower) {
76608
+ resb = data.val & data.position;
76609
+ data.position >>= 1;
76610
+ if (data.position == 0) {
76611
+ data.position = resetValue;
76612
+ data.val = getNextValue(data.index++);
76613
+ }
76614
+ bits |= (resb > 0 ? 1 : 0) * power;
76615
+ power <<= 1;
76616
+ }
76617
+ dictionary[dictSize++] = f(bits);
76618
+ c = dictSize - 1;
76619
+ enlargeIn--;
76620
+ break;
76621
+ case 1:
76622
+ bits = 0;
76623
+ maxpower = Math.pow(2, 16);
76624
+ power = 1;
76625
+ while (power != maxpower) {
76626
+ resb = data.val & data.position;
76627
+ data.position >>= 1;
76628
+ if (data.position == 0) {
76629
+ data.position = resetValue;
76630
+ data.val = getNextValue(data.index++);
76631
+ }
76632
+ bits |= (resb > 0 ? 1 : 0) * power;
76633
+ power <<= 1;
76634
+ }
76635
+ dictionary[dictSize++] = f(bits);
76636
+ c = dictSize - 1;
76637
+ enlargeIn--;
76638
+ break;
76639
+ case 2:
76640
+ return result.join("");
76641
+ }
76642
+ if (enlargeIn == 0) {
76643
+ enlargeIn = Math.pow(2, numBits);
76644
+ numBits++;
76645
+ }
76646
+ if (dictionary[c]) {
76647
+ entry = dictionary[c];
76648
+ } else {
76649
+ if (c === dictSize) {
76650
+ entry = w + w.charAt(0);
76651
+ } else {
76652
+ return null;
76653
+ }
76654
+ }
76655
+ result.push(entry);
76656
+ dictionary[dictSize++] = w + entry.charAt(0);
76657
+ enlargeIn--;
76658
+ w = entry;
76659
+ if (enlargeIn == 0) {
76660
+ enlargeIn = Math.pow(2, numBits);
76661
+ numBits++;
76662
+ }
76663
+ }
76664
+ }
76665
+ };
76666
+ return LZString2;
76667
+ })();
76668
+ if (typeof define === "function" && define.amd) {
76669
+ define(function() {
76670
+ return LZString;
76671
+ });
76672
+ } else if (typeof module !== "undefined" && module != null) {
76673
+ module.exports = LZString;
76674
+ } else if (typeof angular !== "undefined" && angular != null) {
76675
+ angular.module("LZString", []).factory("LZString", function() {
76676
+ return LZString;
76677
+ });
76678
+ }
76679
+ }
76680
+ });
76681
+
76682
+ // src/sharing.ts
76683
+ function encodeViewState(state) {
76684
+ const keys = Object.keys(state);
76685
+ if (keys.length === 0) return "";
76686
+ return (0, import_lz_string.compressToEncodedURIComponent)(JSON.stringify(state));
76687
+ }
76688
+ function encodeDiagramUrl(dsl, options) {
76689
+ const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
76690
+ const compressed = (0, import_lz_string.compressToEncodedURIComponent)(dsl);
76691
+ const byteSize = new TextEncoder().encode(compressed).byteLength;
76692
+ if (byteSize > COMPRESSED_SIZE_LIMIT) {
76693
+ return {
76694
+ error: "too-large",
76695
+ compressedSize: byteSize,
76696
+ limit: COMPRESSED_SIZE_LIMIT
76697
+ };
76698
+ }
76699
+ let hash = `dgmo=${compressed}`;
76700
+ if (options?.viewState) {
76701
+ const vsEncoded = encodeViewState(options.viewState);
76702
+ if (vsEncoded) {
76703
+ hash += `&vs=${vsEncoded}`;
76704
+ }
76705
+ }
76706
+ if (options?.palette && options.palette !== "nord") {
76707
+ hash += `&pal=${encodeURIComponent(options.palette)}`;
76708
+ }
76709
+ if (options?.theme && options.theme !== "dark") {
76710
+ hash += `&th=${encodeURIComponent(options.theme)}`;
76711
+ }
76712
+ if (options?.filename) {
76713
+ hash += `&fn=${encodeURIComponent(options.filename)}`;
76714
+ }
76715
+ return { url: `${baseUrl}?${hash}#${hash}` };
76716
+ }
76717
+ var import_lz_string, DEFAULT_BASE_URL, COMPRESSED_SIZE_LIMIT;
76718
+ var init_sharing = __esm({
76719
+ "src/sharing.ts"() {
76720
+ "use strict";
76721
+ import_lz_string = __toESM(require_lz_string(), 1);
76722
+ DEFAULT_BASE_URL = "https://online.diagrammo.app";
76723
+ COMPRESSED_SIZE_LIMIT = 8192;
76724
+ }
76725
+ });
76726
+
76727
+ // src/error-card.ts
76728
+ function docsLink(source) {
76729
+ const chartType = parseDgmoChartType(source);
76730
+ const hasGuide = chartType !== null && !chartTypes.some((c) => c.id === chartType && c.internal);
76731
+ return hasGuide ? {
76732
+ url: `${DOCS_BASE}/chart-${chartType}/`,
76733
+ label: `Read the ${chartType} guide \u2197`
76734
+ } : { url: `${DOCS_BASE}/`, label: "Browse the DGMO docs \u2197" };
76735
+ }
76736
+ var DOCS_BASE, MONO_FAMILY, W, PAD2, CONTENT_W;
76737
+ var init_error_card = __esm({
76738
+ "src/error-card.ts"() {
76739
+ "use strict";
76740
+ init_dgmo_router();
76741
+ init_chart_types();
76742
+ DOCS_BASE = "https://diagrammo.app/docs";
76743
+ MONO_FAMILY = "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace";
76744
+ W = 660;
76745
+ PAD2 = 24;
76746
+ CONTENT_W = W - PAD2 * 2;
76747
+ }
76748
+ });
76749
+
76750
+ // src/live-link/renderer.ts
76751
+ var renderer_exports26 = {};
76752
+ __export(renderer_exports26, {
76753
+ renderLiveLinkCard: () => renderLiveLinkCard
76754
+ });
76755
+ function renderLiveLinkCard(parsed, palette, theme) {
76756
+ const isTransparent = theme === "transparent";
76757
+ const parts = [];
76758
+ let y = PAD3 + 18;
76759
+ parts.push(cloudGlyph(PAD3, y - 14, 24, palette.textMuted));
76760
+ const headline = parsed.title ?? parsed.id ?? "Unresolved live link";
76761
+ const headlineMono = parsed.title === null && parsed.id !== null;
76762
+ parts.push(
76763
+ `<text x="${CONTENT_X}" y="${y}" fill="${palette.text}" font-family="${headlineMono ? MONO_FAMILY : FONT_FAMILY}" font-size="${HEADLINE_FS}" font-weight="${headlineMono ? 500 : 700}">${escapeXml(truncateText(headline, HEADLINE_FS, CONTENT_W2))}</text>`
76764
+ );
76765
+ y += 30;
76766
+ parts.push(
76767
+ `<text x="${CONTENT_X}" y="${y}" fill="${palette.textMuted}" font-family="${FONT_FAMILY}" font-size="${SUBTITLE_FS}">${escapeXml(SUBTITLE)}</text>`
76768
+ );
76769
+ y += 22;
76770
+ if (parsed.title !== null && parsed.id !== null) {
76771
+ parts.push(
76772
+ `<text x="${CONTENT_X}" y="${y}" fill="${palette.textMuted}" font-family="${MONO_FAMILY}" font-size="${ID_FS}">${escapeXml(
76773
+ truncateText(parsed.id, ID_FS, CONTENT_W2)
76774
+ )}</text>`
76775
+ );
76776
+ y += 22;
76777
+ }
76778
+ const height = Math.round(y + PAD3 - 12);
76779
+ const pageBg = isTransparent ? "" : `<rect width="100%" height="100%" fill="${palette.bg}"/>`;
76780
+ return [
76781
+ `<svg xmlns="http://www.w3.org/2000/svg" width="${W2}" height="${height}" viewBox="0 0 ${W2} ${height}" preserveAspectRatio="xMidYMid meet" font-family="${FONT_FAMILY}">`,
76782
+ pageBg,
76783
+ `<rect x="0.5" y="0.5" width="${W2 - 1}" height="${height - 1}" rx="10" fill="${palette.surface}" stroke="${palette.border}" stroke-width="1"/>`,
76784
+ parts.join(""),
76785
+ `</svg>`
76786
+ ].join("");
76787
+ }
76788
+ function cloudGlyph(x, y, size, color) {
76789
+ const s = size / 24;
76790
+ const d = "M6.5 19a4.5 4.5 0 0 1-.6-8.96A6 6 0 0 1 17.6 8.7 4.15 4.15 0 0 1 17.5 19Z";
76791
+ return `<path transform="translate(${x},${y}) scale(${s})" d="${d}" fill="none" stroke="${color}" stroke-width="1.6" stroke-linejoin="round"/>`;
76792
+ }
76793
+ function escapeXml(s) {
76794
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
76795
+ }
76796
+ var W2, PAD3, CONTENT_X, CONTENT_W2, HEADLINE_FS, SUBTITLE_FS, ID_FS, SUBTITLE;
76797
+ var init_renderer27 = __esm({
76798
+ "src/live-link/renderer.ts"() {
76799
+ "use strict";
76800
+ init_text_measure();
76801
+ init_fonts();
76802
+ init_error_card();
76803
+ W2 = 560;
76804
+ PAD3 = 28;
76805
+ CONTENT_X = PAD3 + 40;
76806
+ CONTENT_W2 = W2 - CONTENT_X - PAD3;
76807
+ HEADLINE_FS = 18;
76808
+ SUBTITLE_FS = 13;
76809
+ ID_FS = 13;
76810
+ SUBTITLE = "Live link published at Diagrammo Cloud";
76811
+ }
76812
+ });
76813
+
76814
+ // src/block/layout.ts
76815
+ function layoutBlock(grid, opts = {}) {
76816
+ const collapsed = opts.collapsed ?? /* @__PURE__ */ new Set();
76817
+ const node = layoutGrid(grid, 0, 0, null, collapsed);
76818
+ return { width: node.w, height: node.h, items: node.items };
76819
+ }
76820
+ function maxSpanSum(g) {
76821
+ return Math.max(
76822
+ 1,
76823
+ ...g.rows.map((r) => r.reduce((s, c) => s + (c.span || 1), 0))
76824
+ );
76825
+ }
76826
+ function leafW(node) {
76827
+ return Math.max(
76828
+ MIN_COL,
76829
+ Math.min(MAX_COL, measureText(node.label, LABEL_FS) + 2 * BLOCK_PAD + 14)
76830
+ );
76831
+ }
76832
+ function gridColW(g) {
76833
+ let m = MIN_COL;
76834
+ for (const row of g.rows)
76835
+ for (const c of row) {
76836
+ if (!isBlockNode(c)) continue;
76837
+ const iw = c.grid ? intrinsicGridW(c.grid) + 2 * BLOCK_PAD : leafW(c);
76838
+ m = Math.max(m, iw / (c.span || 1));
76839
+ }
76840
+ return m;
76841
+ }
76842
+ function intrinsicGridW(g) {
76843
+ const cols = g.cols ?? maxSpanSum(g);
76844
+ return cols * gridColW(g) + (cols + 1) * BLOCK_GAP;
76845
+ }
76846
+ function layoutGrid(g, ox, oy, forceColW, collapsed) {
76847
+ const cols = g.cols ?? maxSpanSum(g);
76848
+ const colW = forceColW ?? gridColW(g);
76849
+ const gridW = cols * colW + (cols + 1) * BLOCK_GAP;
76850
+ let cy = oy + BLOCK_GAP;
76851
+ const items = [];
76852
+ let maxRight = ox + BLOCK_GAP;
76853
+ for (const row of g.rows) {
76854
+ let cx = ox + BLOCK_GAP;
76855
+ let rowH = BLOCK_LEAF_H;
76856
+ const rowItems = [];
76857
+ for (const cell of row) {
76858
+ const span = cell.span || 1;
76859
+ const cw = span * colW + (span - 1) * BLOCK_GAP;
76860
+ if (!isBlockNode(cell)) {
76861
+ rowItems.push({ type: "empty", x: cx, y: cy, w: cw, h: BLOCK_LEAF_H });
76862
+ cx += cw + BLOCK_GAP;
76863
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76864
+ continue;
76865
+ }
76866
+ if (cell.grid && collapsed.has(cell.id)) {
76867
+ const item = {
76868
+ type: "collapsed",
76869
+ x: cx,
76870
+ y: cy,
76871
+ w: cw,
76872
+ h: BLOCK_COLLAPSED_H,
76873
+ label: cell.label,
76874
+ node: cell,
76875
+ lineNumber: cell.lineNumber
76876
+ };
76877
+ rowItems.push(item);
76878
+ rowH = Math.max(rowH, BLOCK_COLLAPSED_H);
76879
+ cx += cw + BLOCK_GAP;
76880
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76881
+ continue;
76882
+ }
76883
+ if (cell.grid) {
76884
+ const innerCols = cell.grid.cols ?? maxSpanSum(cell.grid);
76885
+ const innerColW = Math.max(
76886
+ MIN_COL * 0.66,
76887
+ (cw - 2 * BLOCK_PAD - (innerCols + 1) * BLOCK_GAP) / innerCols
76888
+ );
76889
+ const inner = layoutGrid(
76890
+ cell.grid,
76891
+ cx + BLOCK_PAD,
76892
+ cy + BLOCK_HEADER_H,
76893
+ innerColW,
76894
+ collapsed
76895
+ );
76896
+ const h = BLOCK_HEADER_H + inner.h + BLOCK_PAD;
76897
+ rowItems.push({
76898
+ type: "container",
76899
+ x: cx,
76900
+ y: cy,
76901
+ w: cw,
76902
+ h,
76903
+ label: cell.label,
76904
+ node: cell,
76905
+ lineNumber: cell.lineNumber,
76906
+ inner: inner.items
76907
+ });
76908
+ rowH = Math.max(rowH, h);
76909
+ cx += cw + BLOCK_GAP;
76910
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76911
+ continue;
76912
+ }
76913
+ rowItems.push({
76914
+ type: "leaf",
76915
+ x: cx,
76916
+ y: cy,
76917
+ w: cw,
76918
+ h: BLOCK_LEAF_H,
76919
+ label: cell.label,
76920
+ node: cell,
76921
+ lineNumber: cell.lineNumber
76922
+ });
76923
+ cx += cw + BLOCK_GAP;
76924
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76925
+ }
76926
+ items.push(...rowItems);
76927
+ cy += rowH + BLOCK_GAP;
76928
+ }
76929
+ const fitW = Math.max(gridW, maxRight - ox + BLOCK_GAP);
76930
+ return { x: ox, y: oy, w: fitW, h: cy - oy, items };
76931
+ }
76932
+ var BLOCK_GAP, BLOCK_PAD, BLOCK_LEAF_H, BLOCK_HEADER_H, BLOCK_COLLAPSED_H, BLOCK_BAR_H, MIN_COL, MAX_COL, LABEL_FS;
76933
+ var init_layout20 = __esm({
76934
+ "src/block/layout.ts"() {
76935
+ "use strict";
76936
+ init_text_measure();
76937
+ init_types4();
76938
+ BLOCK_GAP = 12;
76939
+ BLOCK_PAD = 10;
76940
+ BLOCK_LEAF_H = 46;
76941
+ BLOCK_HEADER_H = 28;
76942
+ BLOCK_COLLAPSED_H = 46;
76943
+ BLOCK_BAR_H = 6;
76944
+ MIN_COL = 104;
76945
+ MAX_COL = 250;
76946
+ LABEL_FS = 13;
76947
+ }
76948
+ });
76949
+
76950
+ // src/block/renderer.ts
76951
+ var renderer_exports27 = {};
76952
+ __export(renderer_exports27, {
76953
+ authoredCollapsedIds: () => authoredCollapsedIds,
76954
+ renderBlock: () => renderBlock,
76955
+ renderBlockForExport: () => renderBlockForExport
76956
+ });
76957
+ import * as d3Selection33 from "d3-selection";
76958
+ function renderBlockForExport(container, parsed, palette, isDark, exportDims, options) {
76959
+ renderBlock(container, parsed, palette, isDark, exportDims, {
76960
+ exportMode: true,
76961
+ ...options
76962
+ });
76963
+ }
76964
+ function renderBlock(container, parsed, palette, isDark, exportDims, options = {}) {
76965
+ if (parsed.error || parsed.top.rows.length === 0) return;
76966
+ d3Selection33.select(container).selectAll(":not([data-d3-tooltip])").remove();
76967
+ const opts = parsed.options;
76968
+ const showTitle = !!parsed.title;
76969
+ const titleH = showTitle ? TITLE_BAND2 : 0;
76970
+ const collapsed = options.collapsed ?? authoredCollapsedIds(parsed);
76971
+ const layout = layoutBlock(parsed.top, { collapsed });
76972
+ const legend = !opts.noLegend ? buildBlockLegend(parsed) : null;
76973
+ let width;
76974
+ let height;
76975
+ if (options.exportMode) {
76976
+ width = Math.max(layout.width, MIN_EXPORT_WIDTH) + PADDING5 * 2;
76977
+ } else {
76978
+ width = exportDims?.width ?? container.clientWidth;
76979
+ }
76980
+ const legendReserve = legend ? getMaxLegendReservedHeight(
76981
+ { groups: legend.groups, position: LEGEND_POSITION3, mode: "preview" },
76982
+ width
76983
+ ) + LEGEND_GROUP_GAP : 0;
76984
+ const inlineRequested = opts.legendInline === true;
76985
+ const legendExtent = inlineRequested && legend ? getLegendExtent(
76986
+ {
76987
+ groups: legend.groups,
76988
+ position: {
76989
+ placement: "top-center",
76990
+ titleRelation: "inline-with-title"
76991
+ },
76992
+ mode: options.exportMode ? "export" : "preview"
76993
+ },
76994
+ { activeGroup: legend.activeGroup ?? null },
76995
+ width
76996
+ ) : { width: 0, height: 0 };
76997
+ const header = layoutInlineHeader({
76998
+ requested: inlineRequested,
76999
+ title: parsed.title ?? "",
77000
+ hasLegend: !!legend,
77001
+ legendWidth: legendExtent.width,
77002
+ legendHeight: legendExtent.height,
77003
+ containerWidth: width,
77004
+ titleBandHeight: titleH,
77005
+ legendReserve,
77006
+ titleBaselineY: TITLE_Y,
77007
+ titleFontSize: TITLE_FONT_SIZE
77008
+ });
77009
+ const areaY = (header.inline ? titleH : titleH + legendReserve) + PADDING5;
77010
+ if (options.exportMode) {
77011
+ height = areaY + layout.height + PADDING5;
77012
+ } else {
77013
+ height = exportDims?.height ?? container.clientHeight;
77014
+ }
77015
+ if (width <= 0 || height <= 0) return;
77016
+ const areaX = PADDING5;
77017
+ const areaW = Math.max(1, width - PADDING5 * 2);
77018
+ const areaH = Math.max(1, height - areaY - PADDING5);
77019
+ const scale = Math.min(1, areaW / layout.width, areaH / layout.height);
77020
+ const offsetX = areaX + (areaW - layout.width * scale) / 2;
77021
+ const offsetY = areaY;
77022
+ const svg = d3Selection33.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").attr("class", "dgmo-block").style("font-family", FONT_FAMILY);
77023
+ if (showTitle) {
77024
+ const title = svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", TITLE_Y).attr("text-anchor", header.titleAnchor).attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).text(parsed.title);
77025
+ if (parsed.titleLineNumber !== null) {
77026
+ title.attr("data-line-number", parsed.titleLineNumber);
77027
+ }
77028
+ }
77029
+ const activeGroup = parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null;
77030
+ const neutral = mix(palette.text, palette.bg, 22);
77031
+ const root = svg.append("g").attr("class", "dgmo-block-cells").attr("transform", `translate(${offsetX},${offsetY}) scale(${scale})`);
77032
+ drawItems(root, layout.items, {
77033
+ palette,
77034
+ tagGroups: parsed.tagGroups,
77035
+ activeGroup,
77036
+ activeKey: activeGroup ? tagAttrKey(activeGroup) : null,
77037
+ neutral,
77038
+ fillMode: opts.fillMode,
77039
+ isDark,
77040
+ onToggle: options.onToggle
77041
+ });
77042
+ if (legend) {
77043
+ const legendG = svg.append("g").attr("class", "dgmo-block-legend").attr(
77044
+ "transform",
77045
+ header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0, ${titleH})`
77046
+ );
77047
+ renderIntegratedLegend(legendG, {
77048
+ groups: legend.groups,
77049
+ palette: {
77050
+ bg: palette.bg,
77051
+ surface: palette.surface,
77052
+ text: palette.text,
77053
+ textMuted: palette.textMuted,
77054
+ primary: palette.primary
77055
+ },
77056
+ isDark,
77057
+ width,
77058
+ mode: options.exportMode ? "export" : "preview",
77059
+ position: {
77060
+ placement: "top-center",
77061
+ titleRelation: header.inline ? "inline-with-title" : "below-title"
77062
+ },
77063
+ activeGroup: legend.activeGroup
77064
+ });
77065
+ }
77066
+ }
77067
+ function colorOf(node, ctx) {
77068
+ if (!node || !ctx.activeGroup) return null;
77069
+ return resolveTagColor(node.metadata, ctx.tagGroups, ctx.activeGroup) ?? null;
77070
+ }
77071
+ function clipLabel2(s, maxWidth, fs) {
77072
+ if (measureText(s, fs) <= maxWidth) return s;
77073
+ let lo = 0;
77074
+ let hi = s.length;
77075
+ while (lo < hi) {
77076
+ const mid = Math.ceil((lo + hi) / 2);
77077
+ if (measureText(s.slice(0, mid) + "\u2026", fs) <= maxWidth) lo = mid;
77078
+ else hi = mid - 1;
77079
+ }
77080
+ return lo <= 0 ? "" : s.slice(0, lo) + "\u2026";
77081
+ }
77082
+ function drawItems(g, items, ctx, path = []) {
77083
+ const { palette, fillMode } = ctx;
77084
+ for (const it of items) {
77085
+ if (it.type === "empty") {
77086
+ g.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 7).attr("fill", "none").attr("stroke", ctx.neutral).attr("stroke-width", 1).attr("stroke-dasharray", "3 4").attr("opacity", 0.7);
77087
+ continue;
77088
+ }
77089
+ const node = it.node;
77090
+ const itemPath = [...path, node.id];
77091
+ const color = colorOf(node, ctx);
77092
+ const stroke2 = color ?? ctx.neutral;
77093
+ const cell = g.append("g").attr("class", "dgmo-block-cell").attr("data-block-id", node.id).attr("data-block-path", itemPath.join(" / "));
77094
+ if (it.lineNumber !== void 0)
77095
+ cell.attr("data-line-number", it.lineNumber);
77096
+ if (ctx.activeKey) {
77097
+ const v = node.metadata[ctx.activeKey];
77098
+ if (v) cell.attr(`data-tag-${ctx.activeKey}`, v);
77099
+ }
77100
+ if (it.type === "collapsed") {
77101
+ const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 12) : palette.surface;
77102
+ const cid = `dgmo-block-clip-${clipCounter++}`;
77103
+ cell.append("clipPath").attr("id", cid).append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10);
77104
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
77105
+ cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 4).attr("text-anchor", "middle").attr("font-size", 12.5).attr("font-weight", 700).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 24, 12.5));
77106
+ cell.append("rect").attr("x", it.x).attr("y", it.y + it.h - BLOCK_BAR_H).attr("width", it.w).attr("height", BLOCK_BAR_H).attr("fill", fillMode === "solid" && color ? palette.text : stroke2).attr("clip-path", `url(#${cid})`);
77107
+ bindToggle(cell, it, ctx, it.h);
77108
+ continue;
77109
+ }
77110
+ if (it.type === "container") {
77111
+ const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 7) : palette.surface;
77112
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
77113
+ const sizeMetric = Math.min(it.w, it.h * 2.5);
77114
+ const headerFs = Math.max(
77115
+ 13,
77116
+ Math.min(20, Math.round(13 + (sizeMetric - 220) / 70))
77117
+ );
77118
+ const grow = (headerFs - 13) / (20 - 13);
77119
+ const headerOpacity = 0.92 - grow * 0.3;
77120
+ const headerY = it.y + Math.round(headerFs * 0.7) + 7;
77121
+ cell.append("text").attr("x", it.x + it.w / 2).attr("y", headerY).attr("text-anchor", "middle").attr("font-size", headerFs).attr("font-weight", 700).attr("fill", palette.text).attr("opacity", headerOpacity).text(clipLabel2(it.label ?? "", it.w - 24, headerFs));
77122
+ bindToggle(cell, it, ctx, BLOCK_HEADER_H);
77123
+ if (it.inner) drawItems(g, it.inner, ctx, itemPath);
77124
+ continue;
77125
+ }
77126
+ const fill2 = color ? fillMode === "solid" ? mix(color, palette.bg, 80) : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 14) : palette.bg;
77127
+ cell.attr("data-leaf", "true");
77128
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 8).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.25);
77129
+ cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 5).attr("text-anchor", "middle").attr("font-size", 13).attr("font-weight", 600).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 16, 13));
77130
+ }
77131
+ }
77132
+ function bindToggle(cell, it, ctx, hitH) {
77133
+ if (!ctx.onToggle || !it.node || it.lineNumber === void 0) return;
77134
+ const id = it.node.id;
77135
+ const ln = it.lineNumber;
77136
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", hitH).attr("rx", 10).attr("fill", "transparent").style("cursor", "pointer").on("click", () => ctx.onToggle(id, ln));
77137
+ }
77138
+ function authoredCollapsedIds(parsed) {
77139
+ const into = /* @__PURE__ */ new Set();
77140
+ collectCollapsed(parsed, into);
77141
+ return into;
77142
+ }
77143
+ function collectCollapsed(parsed, into) {
77144
+ const walk = (grid) => {
77145
+ for (const row of grid.rows)
77146
+ for (const c of row)
77147
+ if (isBlockNode(c)) {
77148
+ if (c.collapsed && c.grid) into.add(c.id);
77149
+ if (c.grid) walk(c.grid);
77150
+ }
77151
+ };
77152
+ walk(parsed.top);
77153
+ }
77154
+ function buildBlockLegend(parsed) {
77155
+ if (parsed.tagGroups.length === 0) return null;
77156
+ const tg = parsed.tagGroups[0];
77157
+ const key = tagAttrKey(tg.name);
77158
+ const used = /* @__PURE__ */ new Set();
77159
+ const walk = (grid) => {
77160
+ for (const row of grid.rows)
77161
+ for (const c of row)
77162
+ if (isBlockNode(c)) {
77163
+ const v = c.metadata[key];
77164
+ if (v) used.add(v.toLowerCase());
77165
+ if (c.grid) walk(c.grid);
77166
+ }
77167
+ };
77168
+ walk(parsed.top);
77169
+ const entries = tg.entries.filter((e) => used.has(e.value.toLowerCase())).map((e) => ({ value: e.value, color: e.color }));
77170
+ if (entries.length === 0) return null;
77171
+ return { groups: [{ name: tg.name, entries }], activeGroup: tg.name };
77172
+ }
77173
+ var PADDING5, TITLE_BAND2, MIN_EXPORT_WIDTH, LEGEND_POSITION3, clipCounter;
77174
+ var init_renderer28 = __esm({
77175
+ "src/block/renderer.ts"() {
77176
+ "use strict";
77177
+ init_fonts();
77178
+ init_color_utils();
77179
+ init_tag_groups();
77180
+ init_inline_header();
77181
+ init_legend_integration();
77182
+ init_legend_layout();
77183
+ init_legend_constants();
77184
+ init_title_constants();
77185
+ init_text_measure();
77186
+ init_types4();
77187
+ init_layout20();
77188
+ PADDING5 = 12;
77189
+ TITLE_BAND2 = 36;
76250
77190
  MIN_EXPORT_WIDTH = 220;
76251
77191
  LEGEND_POSITION3 = {
76252
77192
  placement: "top-center",
@@ -76257,8 +77197,8 @@ var init_renderer27 = __esm({
76257
77197
  });
76258
77198
 
76259
77199
  // src/goal/renderer.ts
76260
- var renderer_exports27 = {};
76261
- __export(renderer_exports27, {
77200
+ var renderer_exports28 = {};
77201
+ __export(renderer_exports28, {
76262
77202
  renderGoal: () => renderGoal,
76263
77203
  renderGoalForExport: () => renderGoalForExport
76264
77204
  });
@@ -76597,7 +77537,7 @@ function renderGauge(svg, parsed, metrics, paint) {
76597
77537
  };
76598
77538
  }
76599
77539
  var GOAL_TITLE_SIZE;
76600
- var init_renderer28 = __esm({
77540
+ var init_renderer29 = __esm({
76601
77541
  "src/goal/renderer.ts"() {
76602
77542
  "use strict";
76603
77543
  init_fonts();
@@ -76611,8 +77551,8 @@ var init_renderer28 = __esm({
76611
77551
  });
76612
77552
 
76613
77553
  // src/countdown/renderer.ts
76614
- var renderer_exports28 = {};
76615
- __export(renderer_exports28, {
77554
+ var renderer_exports29 = {};
77555
+ __export(renderer_exports29, {
76616
77556
  renderCountdown: () => renderCountdown,
76617
77557
  renderCountdownForExport: () => renderCountdownForExport
76618
77558
  });
@@ -77583,7 +78523,7 @@ function renderCountdownForExport(container, parsed, palette, isDark, exportDims
77583
78523
  renderCountdown(container, parsed, palette, isDark, exportDims);
77584
78524
  }
77585
78525
  var MON_ABBR, WD_ABBR, DAY_START, dayDelta2, keyOf, REPEAT_ICON_PATH, MONTH_TARGET_PX;
77586
- var init_renderer29 = __esm({
78526
+ var init_renderer30 = __esm({
77587
78527
  "src/countdown/renderer.ts"() {
77588
78528
  "use strict";
77589
78529
  init_fonts();
@@ -77622,8 +78562,8 @@ var init_renderer29 = __esm({
77622
78562
  });
77623
78563
 
77624
78564
  // src/clock/renderer.ts
77625
- var renderer_exports29 = {};
77626
- __export(renderer_exports29, {
78565
+ var renderer_exports30 = {};
78566
+ __export(renderer_exports30, {
77627
78567
  renderClock: () => renderClock,
77628
78568
  renderClockForExport: () => renderClockForExport
77629
78569
  });
@@ -78146,7 +79086,7 @@ function renderClockForExport(container, parsed, palette, isDark, exportDims) {
78146
79086
  renderClock(container, parsed, palette, isDark, exportDims);
78147
79087
  }
78148
79088
  var PLACE_ACCENTS, clipSeq, WEEKDAY_ABBR4;
78149
- var init_renderer30 = __esm({
79089
+ var init_renderer31 = __esm({
78150
79090
  "src/clock/renderer.ts"() {
78151
79091
  "use strict";
78152
79092
  init_fonts();
@@ -78744,8 +79684,8 @@ var init_layout21 = __esm({
78744
79684
  });
78745
79685
 
78746
79686
  // src/bracket/renderer.ts
78747
- var renderer_exports30 = {};
78748
- __export(renderer_exports30, {
79687
+ var renderer_exports31 = {};
79688
+ __export(renderer_exports31, {
78749
79689
  bracketExportDimensions: () => bracketExportDimensions,
78750
79690
  renderBracket: () => renderBracket,
78751
79691
  renderBracketForExport: () => renderBracketForExport
@@ -79117,7 +80057,7 @@ function renderBracketForExport(container, parsed, palette, isDark, exportDims)
79117
80057
  renderBracket(container, parsed, palette, isDark, exportDims);
79118
80058
  }
79119
80059
  var PADDING6, TITLE_BAND3, HALF_SPAN2, COMMENT_LH, LEGEND_POSITION4;
79120
- var init_renderer31 = __esm({
80060
+ var init_renderer32 = __esm({
79121
80061
  "src/bracket/renderer.ts"() {
79122
80062
  "use strict";
79123
80063
  init_fonts();
@@ -79144,8 +80084,8 @@ var init_renderer31 = __esm({
79144
80084
  });
79145
80085
 
79146
80086
  // src/raci/renderer.ts
79147
- var renderer_exports31 = {};
79148
- __export(renderer_exports31, {
80087
+ var renderer_exports32 = {};
80088
+ __export(renderer_exports32, {
79149
80089
  MARKER_LABELS: () => MARKER_LABELS,
79150
80090
  renderRaci: () => renderRaci,
79151
80091
  renderRaciForExport: () => renderRaciForExport
@@ -79845,7 +80785,7 @@ function parseQuotedSegments(message) {
79845
80785
  return out;
79846
80786
  }
79847
80787
  var MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN2, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT5, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT2, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT5, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
79848
- var init_renderer32 = __esm({
80788
+ var init_renderer33 = __esm({
79849
80789
  "src/raci/renderer.ts"() {
79850
80790
  "use strict";
79851
80791
  init_parsing();
@@ -80109,8 +81049,8 @@ var init_tag_resolution = __esm({
80109
81049
  });
80110
81050
 
80111
81051
  // src/sequence/renderer.ts
80112
- var renderer_exports32 = {};
80113
- __export(renderer_exports32, {
81052
+ var renderer_exports33 = {};
81053
+ __export(renderer_exports33, {
80114
81054
  applyGroupOrdering: () => applyGroupOrdering,
80115
81055
  applyPositionOverrides: () => applyPositionOverrides,
80116
81056
  buildNoteMessageMap: () => buildNoteMessageMap,
@@ -80160,7 +81100,7 @@ function wrapLabelWords(words, maxWidth, fontSize) {
80160
81100
  if (current) lines.push(current);
80161
81101
  return lines;
80162
81102
  }
80163
- function renderRectParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81103
+ function renderRectParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80164
81104
  g.append("rect").attr("x", -w / 2).attr("y", 0).attr("width", w).attr("height", h).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, fillMode)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
80165
81105
  }
80166
81106
  function renderActorParticipant(g, palette, color, h = H) {
@@ -80182,7 +81122,7 @@ function renderActorParticipant(g, palette, color, h = H) {
80182
81122
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx - legSpan).attr("y2", legY).attr("stroke", s).attr("stroke-width", actorSW);
80183
81123
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx + legSpan).attr("y2", legY).attr("stroke", s).attr("stroke-width", actorSW);
80184
81124
  }
80185
- function renderDatabaseParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81125
+ function renderDatabaseParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80186
81126
  const ry = 7;
80187
81127
  const topY = ry;
80188
81128
  const bodyH = h - ry * 2;
@@ -80194,7 +81134,7 @@ function renderDatabaseParticipant(g, palette, isDark, color, fillMode, w = W, h
80194
81134
  g.append("line").attr("x1", w / 2).attr("y1", topY).attr("x2", w / 2).attr("y2", topY + bodyH).attr("stroke", s).attr("stroke-width", SW);
80195
81135
  g.append("ellipse").attr("cx", 0).attr("cy", topY).attr("rx", w / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
80196
81136
  }
80197
- function renderQueueParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81137
+ function renderQueueParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80198
81138
  const rx = 10;
80199
81139
  const leftX = -w / 2 + rx;
80200
81140
  const bodyW = w - rx * 2;
@@ -80206,7 +81146,7 @@ function renderQueueParticipant(g, palette, isDark, color, fillMode, w = W, h =
80206
81146
  g.append("line").attr("x1", leftX).attr("y1", h).attr("x2", leftX + bodyW).attr("y2", h).attr("stroke", s).attr("stroke-width", SW);
80207
81147
  g.append("ellipse").attr("cx", leftX).attr("cy", h / 2).attr("rx", rx).attr("ry", h / 2).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
80208
81148
  }
80209
- function renderCacheParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81149
+ function renderCacheParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80210
81150
  const ry = 7;
80211
81151
  const topY = ry;
80212
81152
  const bodyH = h - ry * 2;
@@ -81421,846 +82361,389 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
81421
82361
  renderBlockFrames(el.children, depth + 1);
81422
82362
  if (el.elseIfBranches) {
81423
82363
  for (const branch of el.elseIfBranches) {
81424
- renderBlockFrames(branch.children, depth + 1);
81425
- }
81426
- }
81427
- renderBlockFrames(el.elseChildren, depth + 1);
81428
- }
81429
- };
81430
- if (elements && elements.length > 0) {
81431
- renderBlockFrames(elements, 0);
81432
- }
81433
- const ACTIVATION_NEST_OFFSET = ctx.structural(6);
81434
- activations.forEach((act) => {
81435
- const px = participantX.get(act.participantId);
81436
- if (px === void 0) return;
81437
- const x = px - sActivationWidth / 2 + act.depth * ACTIVATION_NEST_OFFSET;
81438
- const y1 = stepY(act.startStep);
81439
- const y2 = stepY(act.endStep);
81440
- const coveredLines = [];
81441
- for (let si = act.startStep; si <= act.endStep; si++) {
81442
- const step = renderSteps[si];
81443
- if (!step) continue;
81444
- const msg = messages[step.messageIndex];
81445
- if (msg) coveredLines.push(msg.lineNumber);
81446
- }
81447
- const triggerStep = renderSteps[act.startStep];
81448
- const triggerMsg = triggerStep !== void 0 ? messages[triggerStep.messageIndex] : void 0;
81449
- const actTagValue = triggerMsg ? tagMap?.messages.get(triggerMsg.lineNumber) : void 0;
81450
- const actTagColor = getTagColor(actTagValue);
81451
- const actBaseColor = actTagColor || palette.primary;
81452
- svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", themeBaseBg(palette, isDark));
81453
- const actFill = shapeFill(palette, actBaseColor, isDark, {
81454
- mode: fillMode
81455
- });
81456
- const actRect = svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", actFill).attr("stroke", actBaseColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("data-participant-id", act.participantId).attr("data-msg-lines", coveredLines.join(",")).attr("data-line-number", coveredLines[0] ?? "").attr("class", "activation");
81457
- if (tagKey && actTagValue) {
81458
- actRect.attr(`data-tag-${tagKey}`, actTagValue.toLowerCase());
81459
- }
81460
- });
81461
- for (const ln of deferredLines) {
81462
- const line11 = svg.append("line").attr("x1", ln.x1).attr("y1", ln.y1).attr("x2", ln.x2).attr("y2", ln.y2).attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-dasharray", "2 3").attr("class", "block-divider");
81463
- if (ln.blockLine !== void 0)
81464
- line11.attr("data-block-line", String(ln.blockLine));
81465
- }
81466
- for (const lbl of deferredLabels) {
81467
- const t = svg.append("text").attr("x", lbl.x).attr("y", lbl.y).attr("fill", palette.text).attr("font-size", 11).attr("class", "block-label").text(lbl.text);
81468
- if (lbl.bold) t.attr("font-weight", "bold");
81469
- if (lbl.italic) t.attr("font-style", "italic");
81470
- if (lbl.blockLine !== void 0)
81471
- t.attr("data-block-line", String(lbl.blockLine));
81472
- }
81473
- const activeDepthAt = (pid, stepIdx) => {
81474
- let maxDepth = -1;
81475
- for (const act of activations) {
81476
- if (act.participantId === pid && act.startStep <= stepIdx && stepIdx <= act.endStep && act.depth > maxDepth) {
81477
- maxDepth = act.depth;
81478
- }
81479
- }
81480
- return maxDepth;
81481
- };
81482
- const arrowEdgeX = (pid, stepIdx, side) => {
81483
- const px = participantX.get(pid);
81484
- const depth = activeDepthAt(pid, stepIdx);
81485
- if (depth < 0) return px;
81486
- const offset = depth * ACTIVATION_NEST_OFFSET;
81487
- return side === "right" ? px + sActivationWidth / 2 + offset : px - sActivationWidth / 2 + offset;
81488
- };
81489
- const leftmostX = Math.min(...Array.from(participantX.values()));
81490
- const rightmostX = frameRightmostX;
81491
- const sectionLineX1 = leftmostX - sBoxW / 2 - 10;
81492
- const sectionLineX2 = rightmostX + sBoxW / 2 + 10;
81493
- for (const region of sectionRegions) {
81494
- const sec = region.section;
81495
- const secY = sectionYPositions.get(sec.lineNumber);
81496
- if (secY === void 0) continue;
81497
- const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;
81498
- const lineColor = palette.textMuted;
81499
- const sectionG = svg.append("g").attr("data-section-toggle", "").attr("data-line-number", String(sec.lineNumber)).attr("data-section", "").attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!isCollapsed));
81500
- const BAND_HEIGHT = 22;
81501
- const bandX = sectionLineX1 - 10;
81502
- const bandWidth = sectionLineX2 - sectionLineX1 + 20;
81503
- const bandOpacity = isCollapsed ? isDark ? 0.35 : 0.25 : isDark ? 0.1 : 0.08;
81504
- sectionG.append("rect").attr("x", bandX).attr("y", secY - BAND_HEIGHT / 2).attr("width", bandWidth).attr("height", BAND_HEIGHT).attr("fill", lineColor).attr("opacity", bandOpacity).attr("rx", 2).attr("pointer-events", "none").attr("class", "section-divider");
81505
- const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;
81506
- const labelText = isCollapsed ? `${sec.label} (${msgCount} ${msgCount === 1 ? "message" : "messages"})` : sec.label;
81507
- const labelX = (sectionLineX1 + sectionLineX2) / 2;
81508
- const labelHitW = Math.max(80, measureText(labelText, 11) + 24);
81509
- sectionG.append("rect").attr("x", labelX - labelHitW / 2).attr("y", secY - BAND_HEIGHT / 2).attr("width", labelHitW).attr("height", BAND_HEIGHT).attr("fill", "transparent").attr("class", "section-label-hit");
81510
- sectionG.append("text").attr("x", labelX).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", lineColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
81511
- }
81512
- renderSteps.forEach((step, i) => {
81513
- const fromX = participantX.get(step.from);
81514
- const toX = participantX.get(step.to);
81515
- if (fromX === void 0 || toX === void 0) return;
81516
- const y = stepY(i);
81517
- const HIT_H = 20;
81518
- const msg = messages[step.messageIndex];
81519
- const msgTagValue = msg ? tagMap?.messages.get(msg.lineNumber) : void 0;
81520
- const msgTagColor = getTagColor(msgTagValue);
81521
- if (step.type === "call") {
81522
- const arrowColor = msgTagColor || palette.text;
81523
- if (step.from === step.to) {
81524
- const x = arrowEdgeX(step.from, i, "right");
81525
- const loopX = x + sSelfCallWidth;
81526
- const hitX = x;
81527
- svg.append("rect").attr("x", hitX).attr("y", y - 5).attr("width", sSelfCallWidth).attr("height", sSelfCallHeight + 10).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81528
- const selfCallEl = svg.append("path").attr("d", `M ${x} ${y} H ${loopX} V ${y + sSelfCallHeight} H ${x}`).attr("fill", "none").attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", coloredMarker("call", msgTagColor)).attr("class", "message-arrow self-call").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
81529
- if (tagKey && msgTagValue) {
81530
- selfCallEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81531
- }
81532
- if (step.label) {
81533
- const labelEl = svg.append("text").attr("x", loopX + 5).attr("y", y + sSelfCallHeight / 2 + 4).attr("text-anchor", "start").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81534
- if (tagKey && msgTagValue) {
81535
- labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81536
- }
81537
- labelEl.text(step.label);
81538
- }
81539
- } else {
81540
- const goingRight = fromX < toX;
81541
- const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
81542
- const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
81543
- svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81544
- const markerRef = step.async ? coloredMarker("async", msgTagColor) : coloredMarker("call", msgTagColor);
81545
- const arrowEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", markerRef).attr("class", "message-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
81546
- if (tagKey && msgTagValue) {
81547
- arrowEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81548
- }
81549
- if (step.label) {
81550
- const midX = (x1 + x2) / 2;
81551
- const labelEl = svg.append("text").attr("x", midX).attr("y", y - 8).attr("text-anchor", "middle").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81552
- if (tagKey && msgTagValue) {
81553
- labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81554
- }
81555
- labelEl.text(step.label);
81556
- }
81557
- }
81558
- } else {
81559
- if (step.from === step.to) {
81560
- return;
81561
- }
81562
- const goingRight = fromX < toX;
81563
- const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
81564
- const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
81565
- const returnColor = msgTagColor || palette.textMuted;
81566
- svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81567
- const returnEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", returnColor).attr("stroke-width", 1).attr("stroke-dasharray", "6 4").attr("marker-end", coloredMarker("return", msgTagColor)).attr("class", "return-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
81568
- if (tagKey && msgTagValue) {
81569
- returnEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81570
- }
81571
- if (step.label) {
81572
- const midX = (x1 + x2) / 2;
81573
- const labelEl = svg.append("text").attr("x", midX).attr("y", y - 6).attr("text-anchor", "middle").attr("fill", returnColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 11).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81574
- if (tagKey && msgTagValue) {
81575
- labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81576
- }
81577
- labelEl.text(step.label);
81578
- }
81579
- }
81580
- });
81581
- const noteFill = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.bg, palette.surface, 15);
81582
- const renderNoteElements = (els) => {
81583
- for (const el of els) {
81584
- if (isSequenceNote(el)) {
81585
- const px = participantX.get(el.participantId);
81586
- if (px === void 0) continue;
81587
- const noteTopY = noteYMap.get(el);
81588
- if (noteTopY === void 0) continue;
81589
- const position = effectiveNotePosition(el);
81590
- const isRight = position === "right";
81591
- const afterSelfCall = isNoteAfterSelfCall(el);
81592
- const maxW = noteEffectiveMaxW(
81593
- el.participantId,
81594
- position,
81595
- afterSelfCall
81596
- );
81597
- const textWidth = noteTextWidth(maxW);
81598
- const wrappedLines = wrapTextLines(el.text, textWidth, sNoteFontSize);
81599
- const noteH = wrappedLines.length * sNoteLineH + sNotePadV * 2;
81600
- const maxLineW = Math.max(
81601
- ...wrappedLines.map((l) => measureText(l.text, sNoteFontSize))
81602
- );
81603
- const noteW = Math.min(
81604
- maxW,
81605
- Math.max(80, maxLineW + sNotePadH * 2 + sNoteFold)
81606
- );
81607
- const rightOffset = afterSelfCall && isRight ? sActivationWidth / 2 + sSelfCallWidth + sNoteGap : sActivationWidth + sNoteGap;
81608
- const noteX = isRight ? px + rightOffset : px - sActivationWidth - sNoteGap - noteW;
81609
- const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
81610
- noteG.append("path").attr(
81611
- "d",
81612
- [
81613
- `M ${noteX} ${noteTopY}`,
81614
- `L ${noteX + noteW - sNoteFold} ${noteTopY}`,
81615
- `L ${noteX + noteW} ${noteTopY + sNoteFold}`,
81616
- `L ${noteX + noteW} ${noteTopY + noteH}`,
81617
- `L ${noteX} ${noteTopY + noteH}`,
81618
- "Z"
81619
- ].join(" ")
81620
- ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
81621
- noteG.append("path").attr(
81622
- "d",
81623
- [
81624
- `M ${noteX + noteW - sNoteFold} ${noteTopY}`,
81625
- `L ${noteX + noteW - sNoteFold} ${noteTopY + sNoteFold}`,
81626
- `L ${noteX + noteW} ${noteTopY + sNoteFold}`
81627
- ].join(" ")
81628
- ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
81629
- const BULLET_BODY_INDENT3 = 10;
81630
- wrappedLines.forEach((line11, li) => {
81631
- const textY = noteTopY + sNotePadV + (li + 1) * sNoteLineH - 3;
81632
- const indent = line11.kind === "plain" ? 0 : BULLET_BODY_INDENT3;
81633
- if (line11.kind === "bullet-first") {
81634
- noteG.append("text").attr("x", noteX + sNotePadH).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).text("\u2022");
81635
- }
81636
- const textEl = noteG.append("text").attr("x", noteX + sNotePadH + indent).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).attr("class", "note-text");
81637
- renderInlineText(textEl, line11.text, palette, sNoteFontSize);
81638
- });
81639
- } else if (isSequenceBlock(el)) {
81640
- renderNoteElements(el.children);
81641
- if (el.elseIfBranches) {
81642
- for (const branch of el.elseIfBranches) {
81643
- renderNoteElements(branch.children);
81644
- }
82364
+ renderBlockFrames(branch.children, depth + 1);
81645
82365
  }
81646
- renderNoteElements(el.elseChildren);
81647
82366
  }
82367
+ renderBlockFrames(el.elseChildren, depth + 1);
81648
82368
  }
81649
82369
  };
81650
82370
  if (elements && elements.length > 0) {
81651
- renderNoteElements(elements);
81652
- }
81653
- if (hasTagGroups) {
81654
- const legendY = sTopMargin + titleOffset;
81655
- const legendCallbacks = {};
81656
- const legendG = svg.append("g").attr("class", "sequence-legend").attr(
81657
- "transform",
81658
- header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0,${legendY})`
81659
- );
81660
- renderIntegratedLegend(legendG, {
81661
- ...legendConfig,
81662
- // Inline → left-origin so the wrapper's right-flush translate lands the
81663
- // legend at the header's right edge; stacked → centered below the title
81664
- // (identical to legendConfig.position, so the stacked path is unchanged).
81665
- position: {
81666
- placement: "top-center",
81667
- titleRelation: header.inline ? "inline-with-title" : "below-title"
81668
- },
81669
- palette,
81670
- isDark,
81671
- width: svgWidth,
81672
- activeGroup: activeTagGroup ?? null,
81673
- controlsExpanded: false,
81674
- callbacks: legendCallbacks
81675
- });
82371
+ renderBlockFrames(elements, 0);
81676
82372
  }
81677
- }
81678
- function buildNoteMessageMap(elements) {
81679
- const map = /* @__PURE__ */ new Map();
81680
- let lastMessageLine = -1;
81681
- const walk = (els) => {
81682
- for (const el of els) {
81683
- if (isSequenceNote(el)) {
81684
- if (lastMessageLine >= 0) {
81685
- map.set(el.lineNumber, lastMessageLine);
81686
- }
81687
- } else if (isSequenceBlock(el)) {
81688
- walk(el.children);
81689
- if (el.elseIfBranches) {
81690
- for (const branch of el.elseIfBranches) {
81691
- walk(branch.children);
81692
- }
81693
- }
81694
- walk(el.elseChildren);
81695
- } else if (!isSequenceSection(el)) {
81696
- lastMessageLine = el.lineNumber;
81697
- }
82373
+ const ACTIVATION_NEST_OFFSET = ctx.structural(6);
82374
+ activations.forEach((act) => {
82375
+ const px = participantX.get(act.participantId);
82376
+ if (px === void 0) return;
82377
+ const x = px - sActivationWidth / 2 + act.depth * ACTIVATION_NEST_OFFSET;
82378
+ const y1 = stepY(act.startStep);
82379
+ const y2 = stepY(act.endStep);
82380
+ const coveredLines = [];
82381
+ for (let si = act.startStep; si <= act.endStep; si++) {
82382
+ const step = renderSteps[si];
82383
+ if (!step) continue;
82384
+ const msg = messages[step.messageIndex];
82385
+ if (msg) coveredLines.push(msg.lineNumber);
81698
82386
  }
81699
- };
81700
- walk(elements);
81701
- return map;
81702
- }
81703
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, fillMode, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
81704
- const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
81705
- if (tagAttr) {
81706
- g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
81707
- }
81708
- switch (participant.type) {
81709
- case "actor":
81710
- renderActorParticipant(g, palette, color, boxH);
81711
- break;
81712
- case "database":
81713
- renderDatabaseParticipant(
81714
- g,
81715
- palette,
81716
- isDark,
81717
- color,
81718
- fillMode,
81719
- boxW,
81720
- boxH
81721
- );
81722
- break;
81723
- case "queue":
81724
- renderQueueParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
81725
- break;
81726
- case "cache":
81727
- renderCacheParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
81728
- break;
81729
- default:
81730
- renderRectParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
81731
- break;
81732
- }
81733
- const isActor = participant.type === "actor";
81734
- const labelLines = splitParticipantLabel(
81735
- participant.label,
81736
- labelTextW,
81737
- labelFontSize2
81738
- );
81739
- const fontSize = labelFontSize2;
81740
- const lineHeight = fontSize + 2;
81741
- const labelFill = isActor ? palette.text : contrastText(
81742
- fill(palette, isDark, color, fillMode),
81743
- palette.textOnFillLight,
81744
- palette.textOnFillDark
81745
- );
81746
- const textEl = g.append("text").attr("x", 0).attr("text-anchor", "middle").attr("fill", labelFill).attr("font-size", fontSize).attr("font-weight", 500);
81747
- const maxLabelW = labelTextWidth(boxW);
81748
- const truncLine = (text) => truncateText(text, fontSize, maxLabelW);
81749
- if (labelLines.length === 1) {
81750
- textEl.attr("y", isActor ? boxH + 14 : boxH / 2 + 5).text(truncLine(participant.label));
81751
- } else {
81752
- const totalHeight = labelLines.length * lineHeight;
81753
- const baseY = isActor ? boxH + 14 - (labelLines.length - 1) * lineHeight / 2 : boxH / 2 + 5 - (totalHeight - lineHeight) / 2;
81754
- labelLines.forEach((line11, i) => {
81755
- textEl.append("tspan").attr("x", 0).attr("dy", i === 0 ? `${baseY}px` : `${lineHeight}px`).text(truncLine(line11));
82387
+ const triggerStep = renderSteps[act.startStep];
82388
+ const triggerMsg = triggerStep !== void 0 ? messages[triggerStep.messageIndex] : void 0;
82389
+ const actTagValue = triggerMsg ? tagMap?.messages.get(triggerMsg.lineNumber) : void 0;
82390
+ const actTagColor = getTagColor(actTagValue);
82391
+ const actBaseColor = actTagColor || palette.primary;
82392
+ svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", themeBaseBg(palette, isDark));
82393
+ const actFill = shapeFill(palette, actBaseColor, isDark, {
82394
+ mode: fillMode
81756
82395
  });
82396
+ const actRect = svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", actFill).attr("stroke", actBaseColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("data-participant-id", act.participantId).attr("data-msg-lines", coveredLines.join(",")).attr("data-line-number", coveredLines[0] ?? "").attr("class", "activation");
82397
+ if (tagKey && actTagValue) {
82398
+ actRect.attr(`data-tag-${tagKey}`, actTagValue.toLowerCase());
82399
+ }
82400
+ });
82401
+ for (const ln of deferredLines) {
82402
+ const line11 = svg.append("line").attr("x1", ln.x1).attr("y1", ln.y1).attr("x2", ln.x2).attr("y2", ln.y2).attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-dasharray", "2 3").attr("class", "block-divider");
82403
+ if (ln.blockLine !== void 0)
82404
+ line11.attr("data-block-line", String(ln.blockLine));
81757
82405
  }
81758
- }
81759
- var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE3, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
81760
- var init_renderer33 = __esm({
81761
- "src/sequence/renderer.ts"() {
81762
- "use strict";
81763
- init_tag_groups();
81764
- init_parsing();
81765
- init_color_utils();
81766
- init_inline_markdown();
81767
- init_fonts();
81768
- init_parser7();
81769
- init_collapse5();
81770
- init_wrapped_desc();
81771
- init_text_measure();
81772
- init_tag_resolution();
81773
- init_tag_groups();
81774
- init_legend_layout();
81775
- init_parsing();
81776
- init_inline_header();
81777
- init_legend_integration();
81778
- init_title_constants();
81779
- init_scaling();
81780
- PARTICIPANT_GAP = 160;
81781
- PARTICIPANT_BOX_WIDTH = 120;
81782
- PARTICIPANT_BOX_HEIGHT = 50;
81783
- LABEL_FONT_SIZE5 = 13;
81784
- TOP_MARGIN = 20;
81785
- TITLE_HEIGHT8 = 30;
81786
- PARTICIPANT_Y_OFFSET = 10;
81787
- MESSAGE_START_OFFSET = 50;
81788
- LIFELINE_TAIL = 30;
81789
- ARROWHEAD_SIZE = 8;
81790
- NOTE_MAX_W2 = 200;
81791
- NOTE_FOLD2 = 10;
81792
- NOTE_PAD_H2 = 8;
81793
- NOTE_PAD_V2 = 6;
81794
- NOTE_FONT_SIZE3 = 10;
81795
- NOTE_LINE_H2 = 14;
81796
- NOTE_GAP2 = 15;
81797
- ACTIVATION_WIDTH = 10;
81798
- SELF_CALL_HEIGHT = 25;
81799
- SELF_CALL_WIDTH = 30;
81800
- ACTOR_LABEL_CLEARANCE = 22;
81801
- labelTextWidth = (boxW) => boxW - 10;
81802
- fill = (palette, isDark, color, fillMode) => color ? shapeFill(palette, color, isDark, { mode: fillMode }) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
81803
- stroke = (palette, color) => color || palette.border;
81804
- SW = 1.5;
81805
- W = PARTICIPANT_BOX_WIDTH;
81806
- H = PARTICIPANT_BOX_HEIGHT;
82406
+ for (const lbl of deferredLabels) {
82407
+ const t = svg.append("text").attr("x", lbl.x).attr("y", lbl.y).attr("fill", palette.text).attr("font-size", 11).attr("class", "block-label").text(lbl.text);
82408
+ if (lbl.bold) t.attr("font-weight", "bold");
82409
+ if (lbl.italic) t.attr("font-style", "italic");
82410
+ if (lbl.blockLine !== void 0)
82411
+ t.attr("data-block-line", String(lbl.blockLine));
81807
82412
  }
81808
- });
81809
-
81810
- // node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
81811
- var require_lz_string = __commonJS({
81812
- "node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
81813
- "use strict";
81814
- var LZString = (function() {
81815
- var f = String.fromCharCode;
81816
- var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
81817
- var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
81818
- var baseReverseDic = {};
81819
- function getBaseValue(alphabet, character) {
81820
- if (!baseReverseDic[alphabet]) {
81821
- baseReverseDic[alphabet] = {};
81822
- for (var i = 0; i < alphabet.length; i++) {
81823
- baseReverseDic[alphabet][alphabet.charAt(i)] = i;
81824
- }
81825
- }
81826
- return baseReverseDic[alphabet][character];
82413
+ const activeDepthAt = (pid, stepIdx) => {
82414
+ let maxDepth = -1;
82415
+ for (const act of activations) {
82416
+ if (act.participantId === pid && act.startStep <= stepIdx && stepIdx <= act.endStep && act.depth > maxDepth) {
82417
+ maxDepth = act.depth;
81827
82418
  }
81828
- var LZString2 = {
81829
- compressToBase64: function(input) {
81830
- if (input == null) return "";
81831
- var res = LZString2._compress(input, 6, function(a) {
81832
- return keyStrBase64.charAt(a);
81833
- });
81834
- switch (res.length % 4) {
81835
- // To produce valid Base64
81836
- default:
81837
- // When could this happen ?
81838
- case 0:
81839
- return res;
81840
- case 1:
81841
- return res + "===";
81842
- case 2:
81843
- return res + "==";
81844
- case 3:
81845
- return res + "=";
81846
- }
81847
- },
81848
- decompressFromBase64: function(input) {
81849
- if (input == null) return "";
81850
- if (input == "") return null;
81851
- return LZString2._decompress(input.length, 32, function(index) {
81852
- return getBaseValue(keyStrBase64, input.charAt(index));
81853
- });
81854
- },
81855
- compressToUTF16: function(input) {
81856
- if (input == null) return "";
81857
- return LZString2._compress(input, 15, function(a) {
81858
- return f(a + 32);
81859
- }) + " ";
81860
- },
81861
- decompressFromUTF16: function(compressed) {
81862
- if (compressed == null) return "";
81863
- if (compressed == "") return null;
81864
- return LZString2._decompress(compressed.length, 16384, function(index) {
81865
- return compressed.charCodeAt(index) - 32;
81866
- });
81867
- },
81868
- //compress into uint8array (UCS-2 big endian format)
81869
- compressToUint8Array: function(uncompressed) {
81870
- var compressed = LZString2.compress(uncompressed);
81871
- var buf = new Uint8Array(compressed.length * 2);
81872
- for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
81873
- var current_value = compressed.charCodeAt(i);
81874
- buf[i * 2] = current_value >>> 8;
81875
- buf[i * 2 + 1] = current_value % 256;
81876
- }
81877
- return buf;
81878
- },
81879
- //decompress from uint8array (UCS-2 big endian format)
81880
- decompressFromUint8Array: function(compressed) {
81881
- if (compressed === null || compressed === void 0) {
81882
- return LZString2.decompress(compressed);
81883
- } else {
81884
- var buf = new Array(compressed.length / 2);
81885
- for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
81886
- buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
81887
- }
81888
- var result = [];
81889
- buf.forEach(function(c) {
81890
- result.push(f(c));
81891
- });
81892
- return LZString2.decompress(result.join(""));
81893
- }
81894
- },
81895
- //compress into a string that is already URI encoded
81896
- compressToEncodedURIComponent: function(input) {
81897
- if (input == null) return "";
81898
- return LZString2._compress(input, 6, function(a) {
81899
- return keyStrUriSafe.charAt(a);
81900
- });
81901
- },
81902
- //decompress from an output of compressToEncodedURIComponent
81903
- decompressFromEncodedURIComponent: function(input) {
81904
- if (input == null) return "";
81905
- if (input == "") return null;
81906
- input = input.replace(/ /g, "+");
81907
- return LZString2._decompress(input.length, 32, function(index) {
81908
- return getBaseValue(keyStrUriSafe, input.charAt(index));
81909
- });
81910
- },
81911
- compress: function(uncompressed) {
81912
- return LZString2._compress(uncompressed, 16, function(a) {
81913
- return f(a);
81914
- });
81915
- },
81916
- _compress: function(uncompressed, bitsPerChar, getCharFromInt) {
81917
- if (uncompressed == null) return "";
81918
- var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
81919
- for (ii = 0; ii < uncompressed.length; ii += 1) {
81920
- context_c = uncompressed.charAt(ii);
81921
- if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
81922
- context_dictionary[context_c] = context_dictSize++;
81923
- context_dictionaryToCreate[context_c] = true;
81924
- }
81925
- context_wc = context_w + context_c;
81926
- if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
81927
- context_w = context_wc;
81928
- } else {
81929
- if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
81930
- if (context_w.charCodeAt(0) < 256) {
81931
- for (i = 0; i < context_numBits; i++) {
81932
- context_data_val = context_data_val << 1;
81933
- if (context_data_position == bitsPerChar - 1) {
81934
- context_data_position = 0;
81935
- context_data.push(getCharFromInt(context_data_val));
81936
- context_data_val = 0;
81937
- } else {
81938
- context_data_position++;
81939
- }
81940
- }
81941
- value = context_w.charCodeAt(0);
81942
- for (i = 0; i < 8; i++) {
81943
- context_data_val = context_data_val << 1 | value & 1;
81944
- if (context_data_position == bitsPerChar - 1) {
81945
- context_data_position = 0;
81946
- context_data.push(getCharFromInt(context_data_val));
81947
- context_data_val = 0;
81948
- } else {
81949
- context_data_position++;
81950
- }
81951
- value = value >> 1;
81952
- }
81953
- } else {
81954
- value = 1;
81955
- for (i = 0; i < context_numBits; i++) {
81956
- context_data_val = context_data_val << 1 | value;
81957
- if (context_data_position == bitsPerChar - 1) {
81958
- context_data_position = 0;
81959
- context_data.push(getCharFromInt(context_data_val));
81960
- context_data_val = 0;
81961
- } else {
81962
- context_data_position++;
81963
- }
81964
- value = 0;
81965
- }
81966
- value = context_w.charCodeAt(0);
81967
- for (i = 0; i < 16; i++) {
81968
- context_data_val = context_data_val << 1 | value & 1;
81969
- if (context_data_position == bitsPerChar - 1) {
81970
- context_data_position = 0;
81971
- context_data.push(getCharFromInt(context_data_val));
81972
- context_data_val = 0;
81973
- } else {
81974
- context_data_position++;
81975
- }
81976
- value = value >> 1;
81977
- }
81978
- }
81979
- context_enlargeIn--;
81980
- if (context_enlargeIn == 0) {
81981
- context_enlargeIn = Math.pow(2, context_numBits);
81982
- context_numBits++;
81983
- }
81984
- delete context_dictionaryToCreate[context_w];
81985
- } else {
81986
- value = context_dictionary[context_w];
81987
- for (i = 0; i < context_numBits; i++) {
81988
- context_data_val = context_data_val << 1 | value & 1;
81989
- if (context_data_position == bitsPerChar - 1) {
81990
- context_data_position = 0;
81991
- context_data.push(getCharFromInt(context_data_val));
81992
- context_data_val = 0;
81993
- } else {
81994
- context_data_position++;
81995
- }
81996
- value = value >> 1;
81997
- }
81998
- }
81999
- context_enlargeIn--;
82000
- if (context_enlargeIn == 0) {
82001
- context_enlargeIn = Math.pow(2, context_numBits);
82002
- context_numBits++;
82003
- }
82004
- context_dictionary[context_wc] = context_dictSize++;
82005
- context_w = String(context_c);
82006
- }
82007
- }
82008
- if (context_w !== "") {
82009
- if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
82010
- if (context_w.charCodeAt(0) < 256) {
82011
- for (i = 0; i < context_numBits; i++) {
82012
- context_data_val = context_data_val << 1;
82013
- if (context_data_position == bitsPerChar - 1) {
82014
- context_data_position = 0;
82015
- context_data.push(getCharFromInt(context_data_val));
82016
- context_data_val = 0;
82017
- } else {
82018
- context_data_position++;
82019
- }
82020
- }
82021
- value = context_w.charCodeAt(0);
82022
- for (i = 0; i < 8; i++) {
82023
- context_data_val = context_data_val << 1 | value & 1;
82024
- if (context_data_position == bitsPerChar - 1) {
82025
- context_data_position = 0;
82026
- context_data.push(getCharFromInt(context_data_val));
82027
- context_data_val = 0;
82028
- } else {
82029
- context_data_position++;
82030
- }
82031
- value = value >> 1;
82032
- }
82033
- } else {
82034
- value = 1;
82035
- for (i = 0; i < context_numBits; i++) {
82036
- context_data_val = context_data_val << 1 | value;
82037
- if (context_data_position == bitsPerChar - 1) {
82038
- context_data_position = 0;
82039
- context_data.push(getCharFromInt(context_data_val));
82040
- context_data_val = 0;
82041
- } else {
82042
- context_data_position++;
82043
- }
82044
- value = 0;
82045
- }
82046
- value = context_w.charCodeAt(0);
82047
- for (i = 0; i < 16; i++) {
82048
- context_data_val = context_data_val << 1 | value & 1;
82049
- if (context_data_position == bitsPerChar - 1) {
82050
- context_data_position = 0;
82051
- context_data.push(getCharFromInt(context_data_val));
82052
- context_data_val = 0;
82053
- } else {
82054
- context_data_position++;
82055
- }
82056
- value = value >> 1;
82057
- }
82058
- }
82059
- context_enlargeIn--;
82060
- if (context_enlargeIn == 0) {
82061
- context_enlargeIn = Math.pow(2, context_numBits);
82062
- context_numBits++;
82063
- }
82064
- delete context_dictionaryToCreate[context_w];
82065
- } else {
82066
- value = context_dictionary[context_w];
82067
- for (i = 0; i < context_numBits; i++) {
82068
- context_data_val = context_data_val << 1 | value & 1;
82069
- if (context_data_position == bitsPerChar - 1) {
82070
- context_data_position = 0;
82071
- context_data.push(getCharFromInt(context_data_val));
82072
- context_data_val = 0;
82073
- } else {
82074
- context_data_position++;
82075
- }
82076
- value = value >> 1;
82077
- }
82078
- }
82079
- context_enlargeIn--;
82080
- if (context_enlargeIn == 0) {
82081
- context_enlargeIn = Math.pow(2, context_numBits);
82082
- context_numBits++;
82083
- }
82084
- }
82085
- value = 2;
82086
- for (i = 0; i < context_numBits; i++) {
82087
- context_data_val = context_data_val << 1 | value & 1;
82088
- if (context_data_position == bitsPerChar - 1) {
82089
- context_data_position = 0;
82090
- context_data.push(getCharFromInt(context_data_val));
82091
- context_data_val = 0;
82092
- } else {
82093
- context_data_position++;
82094
- }
82095
- value = value >> 1;
82096
- }
82097
- while (true) {
82098
- context_data_val = context_data_val << 1;
82099
- if (context_data_position == bitsPerChar - 1) {
82100
- context_data.push(getCharFromInt(context_data_val));
82101
- break;
82102
- } else context_data_position++;
82419
+ }
82420
+ return maxDepth;
82421
+ };
82422
+ const arrowEdgeX = (pid, stepIdx, side) => {
82423
+ const px = participantX.get(pid);
82424
+ const depth = activeDepthAt(pid, stepIdx);
82425
+ if (depth < 0) return px;
82426
+ const offset = depth * ACTIVATION_NEST_OFFSET;
82427
+ return side === "right" ? px + sActivationWidth / 2 + offset : px - sActivationWidth / 2 + offset;
82428
+ };
82429
+ const leftmostX = Math.min(...Array.from(participantX.values()));
82430
+ const rightmostX = frameRightmostX;
82431
+ const sectionLineX1 = leftmostX - sBoxW / 2 - 10;
82432
+ const sectionLineX2 = rightmostX + sBoxW / 2 + 10;
82433
+ for (const region of sectionRegions) {
82434
+ const sec = region.section;
82435
+ const secY = sectionYPositions.get(sec.lineNumber);
82436
+ if (secY === void 0) continue;
82437
+ const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;
82438
+ const lineColor = palette.textMuted;
82439
+ const sectionG = svg.append("g").attr("data-section-toggle", "").attr("data-line-number", String(sec.lineNumber)).attr("data-section", "").attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!isCollapsed));
82440
+ const BAND_HEIGHT = 22;
82441
+ const bandX = sectionLineX1 - 10;
82442
+ const bandWidth = sectionLineX2 - sectionLineX1 + 20;
82443
+ const bandOpacity = isCollapsed ? isDark ? 0.35 : 0.25 : isDark ? 0.1 : 0.08;
82444
+ sectionG.append("rect").attr("x", bandX).attr("y", secY - BAND_HEIGHT / 2).attr("width", bandWidth).attr("height", BAND_HEIGHT).attr("fill", lineColor).attr("opacity", bandOpacity).attr("rx", 2).attr("pointer-events", "none").attr("class", "section-divider");
82445
+ const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;
82446
+ const labelText = isCollapsed ? `${sec.label} (${msgCount} ${msgCount === 1 ? "message" : "messages"})` : sec.label;
82447
+ const labelX = (sectionLineX1 + sectionLineX2) / 2;
82448
+ const labelHitW = Math.max(80, measureText(labelText, 11) + 24);
82449
+ sectionG.append("rect").attr("x", labelX - labelHitW / 2).attr("y", secY - BAND_HEIGHT / 2).attr("width", labelHitW).attr("height", BAND_HEIGHT).attr("fill", "transparent").attr("class", "section-label-hit");
82450
+ sectionG.append("text").attr("x", labelX).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", lineColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
82451
+ }
82452
+ renderSteps.forEach((step, i) => {
82453
+ const fromX = participantX.get(step.from);
82454
+ const toX = participantX.get(step.to);
82455
+ if (fromX === void 0 || toX === void 0) return;
82456
+ const y = stepY(i);
82457
+ const HIT_H = 20;
82458
+ const msg = messages[step.messageIndex];
82459
+ const msgTagValue = msg ? tagMap?.messages.get(msg.lineNumber) : void 0;
82460
+ const msgTagColor = getTagColor(msgTagValue);
82461
+ if (step.type === "call") {
82462
+ const arrowColor = msgTagColor || palette.text;
82463
+ if (step.from === step.to) {
82464
+ const x = arrowEdgeX(step.from, i, "right");
82465
+ const loopX = x + sSelfCallWidth;
82466
+ const hitX = x;
82467
+ svg.append("rect").attr("x", hitX).attr("y", y - 5).attr("width", sSelfCallWidth).attr("height", sSelfCallHeight + 10).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82468
+ const selfCallEl = svg.append("path").attr("d", `M ${x} ${y} H ${loopX} V ${y + sSelfCallHeight} H ${x}`).attr("fill", "none").attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", coloredMarker("call", msgTagColor)).attr("class", "message-arrow self-call").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
82469
+ if (tagKey && msgTagValue) {
82470
+ selfCallEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82471
+ }
82472
+ if (step.label) {
82473
+ const labelEl = svg.append("text").attr("x", loopX + 5).attr("y", y + sSelfCallHeight / 2 + 4).attr("text-anchor", "start").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82474
+ if (tagKey && msgTagValue) {
82475
+ labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82103
82476
  }
82104
- return context_data.join("");
82105
- },
82106
- decompress: function(compressed) {
82107
- if (compressed == null) return "";
82108
- if (compressed == "") return null;
82109
- return LZString2._decompress(compressed.length, 32768, function(index) {
82110
- return compressed.charCodeAt(index);
82111
- });
82112
- },
82113
- _decompress: function(length, resetValue, getNextValue) {
82114
- var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
82115
- for (i = 0; i < 3; i += 1) {
82116
- dictionary[i] = i;
82477
+ labelEl.text(step.label);
82478
+ }
82479
+ } else {
82480
+ const goingRight = fromX < toX;
82481
+ const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
82482
+ const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
82483
+ svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82484
+ const markerRef = step.async ? coloredMarker("async", msgTagColor) : coloredMarker("call", msgTagColor);
82485
+ const arrowEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", markerRef).attr("class", "message-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
82486
+ if (tagKey && msgTagValue) {
82487
+ arrowEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82488
+ }
82489
+ if (step.label) {
82490
+ const midX = (x1 + x2) / 2;
82491
+ const labelEl = svg.append("text").attr("x", midX).attr("y", y - 8).attr("text-anchor", "middle").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82492
+ if (tagKey && msgTagValue) {
82493
+ labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82117
82494
  }
82118
- bits = 0;
82119
- maxpower = Math.pow(2, 2);
82120
- power = 1;
82121
- while (power != maxpower) {
82122
- resb = data.val & data.position;
82123
- data.position >>= 1;
82124
- if (data.position == 0) {
82125
- data.position = resetValue;
82126
- data.val = getNextValue(data.index++);
82127
- }
82128
- bits |= (resb > 0 ? 1 : 0) * power;
82129
- power <<= 1;
82495
+ labelEl.text(step.label);
82496
+ }
82497
+ }
82498
+ } else {
82499
+ if (step.from === step.to) {
82500
+ return;
82501
+ }
82502
+ const goingRight = fromX < toX;
82503
+ const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
82504
+ const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
82505
+ const returnColor = msgTagColor || palette.textMuted;
82506
+ svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82507
+ const returnEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", returnColor).attr("stroke-width", 1).attr("stroke-dasharray", "6 4").attr("marker-end", coloredMarker("return", msgTagColor)).attr("class", "return-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
82508
+ if (tagKey && msgTagValue) {
82509
+ returnEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82510
+ }
82511
+ if (step.label) {
82512
+ const midX = (x1 + x2) / 2;
82513
+ const labelEl = svg.append("text").attr("x", midX).attr("y", y - 6).attr("text-anchor", "middle").attr("fill", returnColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 11).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82514
+ if (tagKey && msgTagValue) {
82515
+ labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82516
+ }
82517
+ labelEl.text(step.label);
82518
+ }
82519
+ }
82520
+ });
82521
+ const noteFill = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.bg, palette.surface, 15);
82522
+ const renderNoteElements = (els) => {
82523
+ for (const el of els) {
82524
+ if (isSequenceNote(el)) {
82525
+ const px = participantX.get(el.participantId);
82526
+ if (px === void 0) continue;
82527
+ const noteTopY = noteYMap.get(el);
82528
+ if (noteTopY === void 0) continue;
82529
+ const position = effectiveNotePosition(el);
82530
+ const isRight = position === "right";
82531
+ const afterSelfCall = isNoteAfterSelfCall(el);
82532
+ const maxW = noteEffectiveMaxW(
82533
+ el.participantId,
82534
+ position,
82535
+ afterSelfCall
82536
+ );
82537
+ const textWidth = noteTextWidth(maxW);
82538
+ const wrappedLines = wrapTextLines(el.text, textWidth, sNoteFontSize);
82539
+ const noteH = wrappedLines.length * sNoteLineH + sNotePadV * 2;
82540
+ const maxLineW = Math.max(
82541
+ ...wrappedLines.map((l) => measureText(l.text, sNoteFontSize))
82542
+ );
82543
+ const noteW = Math.min(
82544
+ maxW,
82545
+ Math.max(80, maxLineW + sNotePadH * 2 + sNoteFold)
82546
+ );
82547
+ const rightOffset = afterSelfCall && isRight ? sActivationWidth / 2 + sSelfCallWidth + sNoteGap : sActivationWidth + sNoteGap;
82548
+ const noteX = isRight ? px + rightOffset : px - sActivationWidth - sNoteGap - noteW;
82549
+ const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
82550
+ noteG.append("path").attr(
82551
+ "d",
82552
+ [
82553
+ `M ${noteX} ${noteTopY}`,
82554
+ `L ${noteX + noteW - sNoteFold} ${noteTopY}`,
82555
+ `L ${noteX + noteW} ${noteTopY + sNoteFold}`,
82556
+ `L ${noteX + noteW} ${noteTopY + noteH}`,
82557
+ `L ${noteX} ${noteTopY + noteH}`,
82558
+ "Z"
82559
+ ].join(" ")
82560
+ ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
82561
+ noteG.append("path").attr(
82562
+ "d",
82563
+ [
82564
+ `M ${noteX + noteW - sNoteFold} ${noteTopY}`,
82565
+ `L ${noteX + noteW - sNoteFold} ${noteTopY + sNoteFold}`,
82566
+ `L ${noteX + noteW} ${noteTopY + sNoteFold}`
82567
+ ].join(" ")
82568
+ ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
82569
+ const BULLET_BODY_INDENT3 = 10;
82570
+ wrappedLines.forEach((line11, li) => {
82571
+ const textY = noteTopY + sNotePadV + (li + 1) * sNoteLineH - 3;
82572
+ const indent = line11.kind === "plain" ? 0 : BULLET_BODY_INDENT3;
82573
+ if (line11.kind === "bullet-first") {
82574
+ noteG.append("text").attr("x", noteX + sNotePadH).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).text("\u2022");
82130
82575
  }
82131
- switch (next = bits) {
82132
- case 0:
82133
- bits = 0;
82134
- maxpower = Math.pow(2, 8);
82135
- power = 1;
82136
- while (power != maxpower) {
82137
- resb = data.val & data.position;
82138
- data.position >>= 1;
82139
- if (data.position == 0) {
82140
- data.position = resetValue;
82141
- data.val = getNextValue(data.index++);
82142
- }
82143
- bits |= (resb > 0 ? 1 : 0) * power;
82144
- power <<= 1;
82145
- }
82146
- c = f(bits);
82147
- break;
82148
- case 1:
82149
- bits = 0;
82150
- maxpower = Math.pow(2, 16);
82151
- power = 1;
82152
- while (power != maxpower) {
82153
- resb = data.val & data.position;
82154
- data.position >>= 1;
82155
- if (data.position == 0) {
82156
- data.position = resetValue;
82157
- data.val = getNextValue(data.index++);
82158
- }
82159
- bits |= (resb > 0 ? 1 : 0) * power;
82160
- power <<= 1;
82161
- }
82162
- c = f(bits);
82163
- break;
82164
- case 2:
82165
- return "";
82576
+ const textEl = noteG.append("text").attr("x", noteX + sNotePadH + indent).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).attr("class", "note-text");
82577
+ renderInlineText(textEl, line11.text, palette, sNoteFontSize);
82578
+ });
82579
+ } else if (isSequenceBlock(el)) {
82580
+ renderNoteElements(el.children);
82581
+ if (el.elseIfBranches) {
82582
+ for (const branch of el.elseIfBranches) {
82583
+ renderNoteElements(branch.children);
82166
82584
  }
82167
- dictionary[3] = c;
82168
- w = c;
82169
- result.push(c);
82170
- while (true) {
82171
- if (data.index > length) {
82172
- return "";
82173
- }
82174
- bits = 0;
82175
- maxpower = Math.pow(2, numBits);
82176
- power = 1;
82177
- while (power != maxpower) {
82178
- resb = data.val & data.position;
82179
- data.position >>= 1;
82180
- if (data.position == 0) {
82181
- data.position = resetValue;
82182
- data.val = getNextValue(data.index++);
82183
- }
82184
- bits |= (resb > 0 ? 1 : 0) * power;
82185
- power <<= 1;
82186
- }
82187
- switch (c = bits) {
82188
- case 0:
82189
- bits = 0;
82190
- maxpower = Math.pow(2, 8);
82191
- power = 1;
82192
- while (power != maxpower) {
82193
- resb = data.val & data.position;
82194
- data.position >>= 1;
82195
- if (data.position == 0) {
82196
- data.position = resetValue;
82197
- data.val = getNextValue(data.index++);
82198
- }
82199
- bits |= (resb > 0 ? 1 : 0) * power;
82200
- power <<= 1;
82201
- }
82202
- dictionary[dictSize++] = f(bits);
82203
- c = dictSize - 1;
82204
- enlargeIn--;
82205
- break;
82206
- case 1:
82207
- bits = 0;
82208
- maxpower = Math.pow(2, 16);
82209
- power = 1;
82210
- while (power != maxpower) {
82211
- resb = data.val & data.position;
82212
- data.position >>= 1;
82213
- if (data.position == 0) {
82214
- data.position = resetValue;
82215
- data.val = getNextValue(data.index++);
82216
- }
82217
- bits |= (resb > 0 ? 1 : 0) * power;
82218
- power <<= 1;
82219
- }
82220
- dictionary[dictSize++] = f(bits);
82221
- c = dictSize - 1;
82222
- enlargeIn--;
82223
- break;
82224
- case 2:
82225
- return result.join("");
82226
- }
82227
- if (enlargeIn == 0) {
82228
- enlargeIn = Math.pow(2, numBits);
82229
- numBits++;
82230
- }
82231
- if (dictionary[c]) {
82232
- entry = dictionary[c];
82233
- } else {
82234
- if (c === dictSize) {
82235
- entry = w + w.charAt(0);
82236
- } else {
82237
- return null;
82238
- }
82239
- }
82240
- result.push(entry);
82241
- dictionary[dictSize++] = w + entry.charAt(0);
82242
- enlargeIn--;
82243
- w = entry;
82244
- if (enlargeIn == 0) {
82245
- enlargeIn = Math.pow(2, numBits);
82246
- numBits++;
82247
- }
82585
+ }
82586
+ renderNoteElements(el.elseChildren);
82587
+ }
82588
+ }
82589
+ };
82590
+ if (elements && elements.length > 0) {
82591
+ renderNoteElements(elements);
82592
+ }
82593
+ if (hasTagGroups) {
82594
+ const legendY = sTopMargin + titleOffset;
82595
+ const legendCallbacks = {};
82596
+ const legendG = svg.append("g").attr("class", "sequence-legend").attr(
82597
+ "transform",
82598
+ header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0,${legendY})`
82599
+ );
82600
+ renderIntegratedLegend(legendG, {
82601
+ ...legendConfig,
82602
+ // Inline → left-origin so the wrapper's right-flush translate lands the
82603
+ // legend at the header's right edge; stacked → centered below the title
82604
+ // (identical to legendConfig.position, so the stacked path is unchanged).
82605
+ position: {
82606
+ placement: "top-center",
82607
+ titleRelation: header.inline ? "inline-with-title" : "below-title"
82608
+ },
82609
+ palette,
82610
+ isDark,
82611
+ width: svgWidth,
82612
+ activeGroup: activeTagGroup ?? null,
82613
+ controlsExpanded: false,
82614
+ callbacks: legendCallbacks
82615
+ });
82616
+ }
82617
+ }
82618
+ function buildNoteMessageMap(elements) {
82619
+ const map = /* @__PURE__ */ new Map();
82620
+ let lastMessageLine = -1;
82621
+ const walk = (els) => {
82622
+ for (const el of els) {
82623
+ if (isSequenceNote(el)) {
82624
+ if (lastMessageLine >= 0) {
82625
+ map.set(el.lineNumber, lastMessageLine);
82626
+ }
82627
+ } else if (isSequenceBlock(el)) {
82628
+ walk(el.children);
82629
+ if (el.elseIfBranches) {
82630
+ for (const branch of el.elseIfBranches) {
82631
+ walk(branch.children);
82248
82632
  }
82249
82633
  }
82250
- };
82251
- return LZString2;
82252
- })();
82253
- if (typeof define === "function" && define.amd) {
82254
- define(function() {
82255
- return LZString;
82256
- });
82257
- } else if (typeof module !== "undefined" && module != null) {
82258
- module.exports = LZString;
82259
- } else if (typeof angular !== "undefined" && angular != null) {
82260
- angular.module("LZString", []).factory("LZString", function() {
82261
- return LZString;
82262
- });
82634
+ walk(el.elseChildren);
82635
+ } else if (!isSequenceSection(el)) {
82636
+ lastMessageLine = el.lineNumber;
82637
+ }
82263
82638
  }
82639
+ };
82640
+ walk(elements);
82641
+ return map;
82642
+ }
82643
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, fillMode, boxW = W3, boxH = H, labelTextW = labelTextWidth(W3), labelFontSize2 = LABEL_FONT_SIZE5) {
82644
+ const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
82645
+ if (tagAttr) {
82646
+ g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
82647
+ }
82648
+ switch (participant.type) {
82649
+ case "actor":
82650
+ renderActorParticipant(g, palette, color, boxH);
82651
+ break;
82652
+ case "database":
82653
+ renderDatabaseParticipant(
82654
+ g,
82655
+ palette,
82656
+ isDark,
82657
+ color,
82658
+ fillMode,
82659
+ boxW,
82660
+ boxH
82661
+ );
82662
+ break;
82663
+ case "queue":
82664
+ renderQueueParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
82665
+ break;
82666
+ case "cache":
82667
+ renderCacheParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
82668
+ break;
82669
+ default:
82670
+ renderRectParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
82671
+ break;
82672
+ }
82673
+ const isActor = participant.type === "actor";
82674
+ const labelLines = splitParticipantLabel(
82675
+ participant.label,
82676
+ labelTextW,
82677
+ labelFontSize2
82678
+ );
82679
+ const fontSize = labelFontSize2;
82680
+ const lineHeight = fontSize + 2;
82681
+ const labelFill = isActor ? palette.text : contrastText(
82682
+ fill(palette, isDark, color, fillMode),
82683
+ palette.textOnFillLight,
82684
+ palette.textOnFillDark
82685
+ );
82686
+ const textEl = g.append("text").attr("x", 0).attr("text-anchor", "middle").attr("fill", labelFill).attr("font-size", fontSize).attr("font-weight", 500);
82687
+ const maxLabelW = labelTextWidth(boxW);
82688
+ const truncLine = (text) => truncateText(text, fontSize, maxLabelW);
82689
+ if (labelLines.length === 1) {
82690
+ textEl.attr("y", isActor ? boxH + 14 : boxH / 2 + 5).text(truncLine(participant.label));
82691
+ } else {
82692
+ const totalHeight = labelLines.length * lineHeight;
82693
+ const baseY = isActor ? boxH + 14 - (labelLines.length - 1) * lineHeight / 2 : boxH / 2 + 5 - (totalHeight - lineHeight) / 2;
82694
+ labelLines.forEach((line11, i) => {
82695
+ textEl.append("tspan").attr("x", 0).attr("dy", i === 0 ? `${baseY}px` : `${lineHeight}px`).text(truncLine(line11));
82696
+ });
82697
+ }
82698
+ }
82699
+ var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE3, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W3, H;
82700
+ var init_renderer34 = __esm({
82701
+ "src/sequence/renderer.ts"() {
82702
+ "use strict";
82703
+ init_tag_groups();
82704
+ init_parsing();
82705
+ init_color_utils();
82706
+ init_inline_markdown();
82707
+ init_fonts();
82708
+ init_parser7();
82709
+ init_collapse5();
82710
+ init_wrapped_desc();
82711
+ init_text_measure();
82712
+ init_tag_resolution();
82713
+ init_tag_groups();
82714
+ init_legend_layout();
82715
+ init_parsing();
82716
+ init_inline_header();
82717
+ init_legend_integration();
82718
+ init_title_constants();
82719
+ init_scaling();
82720
+ PARTICIPANT_GAP = 160;
82721
+ PARTICIPANT_BOX_WIDTH = 120;
82722
+ PARTICIPANT_BOX_HEIGHT = 50;
82723
+ LABEL_FONT_SIZE5 = 13;
82724
+ TOP_MARGIN = 20;
82725
+ TITLE_HEIGHT8 = 30;
82726
+ PARTICIPANT_Y_OFFSET = 10;
82727
+ MESSAGE_START_OFFSET = 50;
82728
+ LIFELINE_TAIL = 30;
82729
+ ARROWHEAD_SIZE = 8;
82730
+ NOTE_MAX_W2 = 200;
82731
+ NOTE_FOLD2 = 10;
82732
+ NOTE_PAD_H2 = 8;
82733
+ NOTE_PAD_V2 = 6;
82734
+ NOTE_FONT_SIZE3 = 10;
82735
+ NOTE_LINE_H2 = 14;
82736
+ NOTE_GAP2 = 15;
82737
+ ACTIVATION_WIDTH = 10;
82738
+ SELF_CALL_HEIGHT = 25;
82739
+ SELF_CALL_WIDTH = 30;
82740
+ ACTOR_LABEL_CLEARANCE = 22;
82741
+ labelTextWidth = (boxW) => boxW - 10;
82742
+ fill = (palette, isDark, color, fillMode) => color ? shapeFill(palette, color, isDark, { mode: fillMode }) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
82743
+ stroke = (palette, color) => color || palette.border;
82744
+ SW = 1.5;
82745
+ W3 = PARTICIPANT_BOX_WIDTH;
82746
+ H = PARTICIPANT_BOX_HEIGHT;
82264
82747
  }
82265
82748
  });
82266
82749
 
@@ -84085,6 +84568,7 @@ var DIAGRAM_EXPORT_HANDLERS = {
84085
84568
  bracket: exportBracket,
84086
84569
  raci: exportRaci,
84087
84570
  body: exportBody,
84571
+ "live-link": exportLiveLink,
84088
84572
  // D3 visualizations — own handler per type (Story 109.2). Only `sequence`
84089
84573
  // still falls through to exportVisualization (no chart-type of its own).
84090
84574
  slope: exportSlope,
@@ -84131,7 +84615,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
84131
84615
  viewState,
84132
84616
  options,
84133
84617
  exportMode,
84134
- isDark: theme === "dark"
84618
+ isDark: theme === "dark",
84619
+ width: options?.width && options.width > 0 ? Math.round(options.width) : EXPORT_WIDTH,
84620
+ height: options?.height && options.height > 0 ? Math.round(options.height) : EXPORT_HEIGHT
84135
84621
  };
84136
84622
  const handler = detectedType !== null ? DIAGRAM_EXPORT_HANDLERS[detectedType] : void 0;
84137
84623
  return (handler ?? exportVisualization)(ctx);
@@ -84146,13 +84632,13 @@ async function exportEventLine(ctx) {
84146
84632
  const effectivePalette = await resolveExportPalette(theme, palette);
84147
84633
  const parsed = parseEventLine2(content, effectivePalette);
84148
84634
  if (parsed.error || parsed.events.length === 0) return "";
84149
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84635
+ const container = createExportContainer(ctx.width, ctx.height);
84150
84636
  renderEventLineForExport2(
84151
84637
  container,
84152
84638
  parsed,
84153
84639
  effectivePalette,
84154
84640
  ctx.isDark,
84155
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
84641
+ { width: ctx.width, height: ctx.height },
84156
84642
  ctxTagOverride(ctx),
84157
84643
  /* @__PURE__ */ new Date()
84158
84644
  );
@@ -84165,13 +84651,13 @@ async function exportBody(ctx) {
84165
84651
  const effectivePalette = await resolveExportPalette(theme, palette);
84166
84652
  const parsed = parseBody2(content, effectivePalette);
84167
84653
  if (parsed.error) return "";
84168
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84654
+ const container = createExportContainer(ctx.width, ctx.height);
84169
84655
  renderBodyForExport2(
84170
84656
  container,
84171
84657
  parsed,
84172
84658
  effectivePalette,
84173
84659
  ctx.isDark,
84174
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
84660
+ { width: ctx.width, height: ctx.height },
84175
84661
  ctxTagOverride(ctx)
84176
84662
  );
84177
84663
  return finalizeSvgExport(container, theme, effectivePalette);
@@ -84183,15 +84669,15 @@ async function exportVersionControl(ctx) {
84183
84669
  const effectivePalette = await resolveExportPalette(theme, palette);
84184
84670
  const parsed = parseVersionControl2(content, effectivePalette);
84185
84671
  if (parsed.error || parsed.nodes.length === 0) return "";
84186
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84672
+ const container = createExportContainer(ctx.width, ctx.height);
84187
84673
  renderVersionControlForExport2(
84188
84674
  container,
84189
84675
  parsed,
84190
84676
  effectivePalette,
84191
84677
  ctx.isDark,
84192
84678
  {
84193
- width: EXPORT_WIDTH,
84194
- height: EXPORT_HEIGHT
84679
+ width: ctx.width,
84680
+ height: ctx.height
84195
84681
  }
84196
84682
  );
84197
84683
  return finalizeSvgExport(container, theme, effectivePalette);
@@ -84662,7 +85148,7 @@ async function exportFlowchart(ctx) {
84662
85148
  const fcParsed = parseFlowchart2(content, effectivePalette);
84663
85149
  if (fcParsed.error || fcParsed.nodes.length === 0) return "";
84664
85150
  const layout = layoutGraph2(fcParsed);
84665
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85151
+ const container = createExportContainer(ctx.width, ctx.height);
84666
85152
  renderFlowchart2(
84667
85153
  container,
84668
85154
  fcParsed,
@@ -84670,7 +85156,7 @@ async function exportFlowchart(ctx) {
84670
85156
  effectivePalette,
84671
85157
  ctx.isDark,
84672
85158
  void 0,
84673
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
85159
+ { width: ctx.width, height: ctx.height }
84674
85160
  );
84675
85161
  return finalizeSvgExport(container, theme, effectivePalette);
84676
85162
  }
@@ -84835,7 +85321,7 @@ async function exportState(ctx) {
84835
85321
  collapsedChildCounts,
84836
85322
  originalGroups
84837
85323
  });
84838
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85324
+ const container = createExportContainer(ctx.width, ctx.height);
84839
85325
  renderState2(
84840
85326
  container,
84841
85327
  effectiveParsed,
@@ -84843,7 +85329,7 @@ async function exportState(ctx) {
84843
85329
  effectivePalette,
84844
85330
  ctx.isDark,
84845
85331
  void 0,
84846
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
85332
+ { width: ctx.width, height: ctx.height }
84847
85333
  );
84848
85334
  return finalizeSvgExport(container, theme, effectivePalette);
84849
85335
  }
@@ -84897,13 +85383,13 @@ async function exportCycle(ctx) {
84897
85383
  const effectivePalette = await resolveExportPalette(theme, palette);
84898
85384
  const cycleParsed = parseCycle2(content);
84899
85385
  if (cycleParsed.error || cycleParsed.nodes.length === 0) return "";
84900
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85386
+ const container = createExportContainer(ctx.width, ctx.height);
84901
85387
  renderCycleForExport2(
84902
85388
  container,
84903
85389
  cycleParsed,
84904
85390
  effectivePalette,
84905
85391
  ctx.isDark,
84906
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
85392
+ { width: ctx.width, height: ctx.height },
84907
85393
  viewState,
84908
85394
  exportMode
84909
85395
  );
@@ -84931,7 +85417,7 @@ async function exportMap(ctx) {
84931
85417
  const dims = mapExportDimensions2(
84932
85418
  mapResolved,
84933
85419
  mapData,
84934
- EXPORT_WIDTH,
85420
+ ctx.width,
84935
85421
  options?.mapAspect
84936
85422
  );
84937
85423
  const container = createExportContainer(dims.width, dims.height);
@@ -84952,13 +85438,13 @@ async function exportPyramid(ctx) {
84952
85438
  const effectivePalette = await resolveExportPalette(theme, palette);
84953
85439
  const pyramidParsed = parsePyramid2(content);
84954
85440
  if (pyramidParsed.error || pyramidParsed.layers.length === 0) return "";
84955
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85441
+ const container = createExportContainer(ctx.width, ctx.height);
84956
85442
  renderPyramidForExport2(
84957
85443
  container,
84958
85444
  pyramidParsed,
84959
85445
  effectivePalette,
84960
85446
  ctx.isDark,
84961
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
85447
+ { width: ctx.width, height: ctx.height }
84962
85448
  );
84963
85449
  return finalizeSvgExport(container, theme, effectivePalette);
84964
85450
  }
@@ -84969,10 +85455,10 @@ async function exportRing(ctx) {
84969
85455
  const effectivePalette = await resolveExportPalette(theme, palette);
84970
85456
  const ringParsed = parseRing2(content);
84971
85457
  if (ringParsed.error || ringParsed.layers.length === 0) return "";
84972
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85458
+ const container = createExportContainer(ctx.width, ctx.height);
84973
85459
  renderRingForExport2(container, ringParsed, effectivePalette, ctx.isDark, {
84974
- width: EXPORT_WIDTH,
84975
- height: EXPORT_HEIGHT
85460
+ width: ctx.width,
85461
+ height: ctx.height
84976
85462
  });
84977
85463
  return finalizeSvgExport(container, theme, effectivePalette);
84978
85464
  }
@@ -84982,8 +85468,8 @@ async function exportTreemap(ctx) {
84982
85468
  const effectivePalette = await resolveExportPalette(theme, palette);
84983
85469
  const treemapParsed = parseTreemap2(content, effectivePalette);
84984
85470
  if (treemapParsed.error || treemapParsed.roots.length === 0) return "";
84985
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84986
- const dims = { width: EXPORT_WIDTH, height: EXPORT_HEIGHT };
85471
+ const container = createExportContainer(ctx.width, ctx.height);
85472
+ const dims = { width: ctx.width, height: ctx.height };
84987
85473
  if (treemapParsed.options.radial) {
84988
85474
  const { renderTreemapRadialForExport: renderTreemapRadialForExport2 } = await Promise.resolve().then(() => (init_renderer_radial(), renderer_radial_exports));
84989
85475
  renderTreemapRadialForExport2(
@@ -85005,66 +85491,73 @@ async function exportTreemap(ctx) {
85005
85491
  }
85006
85492
  return finalizeSvgExport(container, theme, effectivePalette);
85007
85493
  }
85494
+ async function exportLiveLink(ctx) {
85495
+ const { content, theme, palette } = ctx;
85496
+ const { parseLiveLink: parseLiveLink2 } = await Promise.resolve().then(() => (init_parser39(), parser_exports33));
85497
+ const { renderLiveLinkCard: renderLiveLinkCard2 } = await Promise.resolve().then(() => (init_renderer27(), renderer_exports26));
85498
+ const effectivePalette = await resolveExportPalette(theme, palette);
85499
+ return renderLiveLinkCard2(parseLiveLink2(content), effectivePalette, theme);
85500
+ }
85008
85501
  async function exportBlock(ctx) {
85009
85502
  const { content, theme, palette } = ctx;
85010
85503
  const { parseBlock: parseBlock2 } = await Promise.resolve().then(() => (init_parser32(), parser_exports26));
85011
- const { renderBlockForExport: renderBlockForExport2 } = await Promise.resolve().then(() => (init_renderer27(), renderer_exports26));
85504
+ const { renderBlockForExport: renderBlockForExport2 } = await Promise.resolve().then(() => (init_renderer28(), renderer_exports27));
85012
85505
  const effectivePalette = await resolveExportPalette(theme, palette);
85013
85506
  const blockParsed = parseBlock2(content, effectivePalette);
85014
85507
  if (blockParsed.error || blockParsed.top.rows.length === 0) return "";
85015
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85508
+ const container = createExportContainer(ctx.width, ctx.height);
85016
85509
  renderBlockForExport2(container, blockParsed, effectivePalette, ctx.isDark, {
85017
- width: EXPORT_WIDTH,
85018
- height: EXPORT_HEIGHT
85510
+ width: ctx.width,
85511
+ height: ctx.height
85019
85512
  });
85020
85513
  return finalizeSvgExport(container, theme, effectivePalette);
85021
85514
  }
85022
85515
  async function exportGoal(ctx) {
85023
85516
  const { content, theme, palette } = ctx;
85024
85517
  const { parseGoal: parseGoal2 } = await Promise.resolve().then(() => (init_parser33(), parser_exports27));
85025
- const { renderGoalForExport: renderGoalForExport2 } = await Promise.resolve().then(() => (init_renderer28(), renderer_exports27));
85518
+ const { renderGoalForExport: renderGoalForExport2 } = await Promise.resolve().then(() => (init_renderer29(), renderer_exports28));
85026
85519
  const effectivePalette = await resolveExportPalette(theme, palette);
85027
85520
  const parsed = parseGoal2(content, effectivePalette);
85028
85521
  if (parsed.error) return "";
85029
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85522
+ const container = createExportContainer(ctx.width, ctx.height);
85030
85523
  renderGoalForExport2(container, parsed, effectivePalette, ctx.isDark, {
85031
- width: EXPORT_WIDTH,
85032
- height: EXPORT_HEIGHT
85524
+ width: ctx.width,
85525
+ height: ctx.height
85033
85526
  });
85034
85527
  return finalizeSvgExport(container, theme, effectivePalette);
85035
85528
  }
85036
85529
  async function exportCountdown(ctx) {
85037
85530
  const { content, theme, palette } = ctx;
85038
85531
  const { parseCountdown: parseCountdown2 } = await Promise.resolve().then(() => (init_parser34(), parser_exports28));
85039
- const { renderCountdownForExport: renderCountdownForExport2 } = await Promise.resolve().then(() => (init_renderer29(), renderer_exports28));
85532
+ const { renderCountdownForExport: renderCountdownForExport2 } = await Promise.resolve().then(() => (init_renderer30(), renderer_exports29));
85040
85533
  const effectivePalette = await resolveExportPalette(theme, palette);
85041
85534
  const parsed = parseCountdown2(content, effectivePalette);
85042
85535
  if (parsed.error) return "";
85043
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85536
+ const container = createExportContainer(ctx.width, ctx.height);
85044
85537
  renderCountdownForExport2(container, parsed, effectivePalette, ctx.isDark, {
85045
- width: EXPORT_WIDTH,
85046
- height: EXPORT_HEIGHT
85538
+ width: ctx.width,
85539
+ height: ctx.height
85047
85540
  });
85048
85541
  return finalizeSvgExport(container, theme, effectivePalette);
85049
85542
  }
85050
85543
  async function exportClock(ctx) {
85051
85544
  const { content, theme, palette } = ctx;
85052
85545
  const { parseClock: parseClock2 } = await Promise.resolve().then(() => (init_parser35(), parser_exports29));
85053
- const { renderClockForExport: renderClockForExport2 } = await Promise.resolve().then(() => (init_renderer30(), renderer_exports29));
85546
+ const { renderClockForExport: renderClockForExport2 } = await Promise.resolve().then(() => (init_renderer31(), renderer_exports30));
85054
85547
  const effectivePalette = await resolveExportPalette(theme, palette);
85055
85548
  const parsed = parseClock2(content, effectivePalette);
85056
85549
  if (parsed.error) return "";
85057
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85550
+ const container = createExportContainer(ctx.width, ctx.height);
85058
85551
  renderClockForExport2(container, parsed, effectivePalette, ctx.isDark, {
85059
- width: EXPORT_WIDTH,
85060
- height: EXPORT_HEIGHT
85552
+ width: ctx.width,
85553
+ height: ctx.height
85061
85554
  });
85062
85555
  return finalizeSvgExport(container, theme, effectivePalette);
85063
85556
  }
85064
85557
  async function exportBracket(ctx) {
85065
85558
  const { content, theme, palette } = ctx;
85066
85559
  const { parseBracket: parseBracket2 } = await Promise.resolve().then(() => (init_parser36(), parser_exports30));
85067
- const { renderBracketForExport: renderBracketForExport2, bracketExportDimensions: bracketExportDimensions2 } = await Promise.resolve().then(() => (init_renderer31(), renderer_exports30));
85560
+ const { renderBracketForExport: renderBracketForExport2, bracketExportDimensions: bracketExportDimensions2 } = await Promise.resolve().then(() => (init_renderer32(), renderer_exports31));
85068
85561
  const effectivePalette = await resolveExportPalette(theme, palette);
85069
85562
  const parsed = parseBracket2(content, effectivePalette);
85070
85563
  if (parsed.error) return "";
@@ -85079,22 +85572,22 @@ async function exportBracket(ctx) {
85079
85572
  async function exportRaci(ctx) {
85080
85573
  const { content, theme, palette } = ctx;
85081
85574
  const { parseRaci: parseRaci2 } = await Promise.resolve().then(() => (init_parser37(), parser_exports31));
85082
- const { renderRaciForExport: renderRaciForExport2 } = await Promise.resolve().then(() => (init_renderer32(), renderer_exports31));
85575
+ const { renderRaciForExport: renderRaciForExport2 } = await Promise.resolve().then(() => (init_renderer33(), renderer_exports32));
85083
85576
  const effectivePalette = await resolveExportPalette(theme, palette);
85084
85577
  const raciParsed = parseRaci2(content, effectivePalette);
85085
85578
  if (raciParsed.error) return "";
85086
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85579
+ const container = createExportContainer(ctx.width, ctx.height);
85087
85580
  renderRaciForExport2(container, raciParsed, effectivePalette, ctx.isDark, {
85088
- width: EXPORT_WIDTH,
85089
- height: EXPORT_HEIGHT
85581
+ width: ctx.width,
85582
+ height: ctx.height
85090
85583
  });
85091
85584
  return finalizeSvgExport(container, theme, effectivePalette);
85092
85585
  }
85093
- function beginVizExport() {
85094
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85586
+ function beginVizExport(ctx) {
85587
+ const container = createExportContainer(ctx.width, ctx.height);
85095
85588
  const dims = {
85096
- width: EXPORT_WIDTH,
85097
- height: EXPORT_HEIGHT
85589
+ width: ctx.width,
85590
+ height: ctx.height
85098
85591
  };
85099
85592
  return { container, dims };
85100
85593
  }
@@ -85103,7 +85596,7 @@ async function exportSlope(ctx) {
85103
85596
  const parsed = parseSlope(content, palette);
85104
85597
  if (parsed.error || parsed.data.length === 0) return "";
85105
85598
  const effectivePalette = await resolveExportPalette(theme, palette);
85106
- const { container, dims } = beginVizExport();
85599
+ const { container, dims } = beginVizExport(ctx);
85107
85600
  renderSlopeChart(
85108
85601
  container,
85109
85602
  parsed,
@@ -85119,7 +85612,7 @@ async function exportArc(ctx) {
85119
85612
  const parsed = parseArc(content, palette);
85120
85613
  if (parsed.error || parsed.links.length === 0) return "";
85121
85614
  const effectivePalette = await resolveExportPalette(theme, palette);
85122
- const { container, dims } = beginVizExport();
85615
+ const { container, dims } = beginVizExport(ctx);
85123
85616
  renderArcDiagram(
85124
85617
  container,
85125
85618
  parsed,
@@ -85135,7 +85628,7 @@ async function exportTimeline(ctx) {
85135
85628
  const parsed = parseTimeline(content, palette);
85136
85629
  if (parsed.error || parsed.timelineEvents.length === 0) return "";
85137
85630
  const effectivePalette = await resolveExportPalette(theme, palette);
85138
- const { container, dims } = beginVizExport();
85631
+ const { container, dims } = beginVizExport(ctx);
85139
85632
  renderTimeline(
85140
85633
  container,
85141
85634
  parsed,
@@ -85162,7 +85655,7 @@ async function exportWordcloud(ctx) {
85162
85655
  const parsed = parseWordcloud(content, palette);
85163
85656
  if (parsed.error || parsed.words.length === 0) return "";
85164
85657
  const effectivePalette = await resolveExportPalette(theme, palette);
85165
- const { container, dims } = beginVizExport();
85658
+ const { container, dims } = beginVizExport(ctx);
85166
85659
  await renderWordCloudAsync(
85167
85660
  container,
85168
85661
  parsed,
@@ -85177,7 +85670,7 @@ async function exportVenn(ctx) {
85177
85670
  const parsed = parseVenn(content, palette);
85178
85671
  if (parsed.error || parsed.vennSets.length < 2) return "";
85179
85672
  const effectivePalette = await resolveExportPalette(theme, palette);
85180
- const { container, dims } = beginVizExport();
85673
+ const { container, dims } = beginVizExport(ctx);
85181
85674
  renderVenn(container, parsed, effectivePalette, ctx.isDark, void 0, dims);
85182
85675
  return finalizeSvgExport(container, theme, effectivePalette);
85183
85676
  }
@@ -85186,7 +85679,7 @@ async function exportQuadrant(ctx) {
85186
85679
  const parsed = parseQuadrant(content, palette);
85187
85680
  if (parsed.error || parsed.quadrantPoints.length === 0) return "";
85188
85681
  const effectivePalette = await resolveExportPalette(theme, palette);
85189
- const { container, dims } = beginVizExport();
85682
+ const { container, dims } = beginVizExport(ctx);
85190
85683
  renderQuadrant(
85191
85684
  container,
85192
85685
  parsed,
@@ -85210,9 +85703,9 @@ async function exportVisualization(ctx) {
85210
85703
  }
85211
85704
  const effectivePalette = await resolveExportPalette(theme, palette);
85212
85705
  const isDark = ctx.isDark;
85213
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85706
+ const container = createExportContainer(ctx.width, ctx.height);
85214
85707
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser7(), parser_exports));
85215
- const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer33(), renderer_exports32));
85708
+ const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer34(), renderer_exports33));
85216
85709
  const seqParsed = parseSequenceDgmo2(content, effectivePalette);
85217
85710
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
85218
85711
  const collapsedSections = viewState?.cs ? new Set(viewState.cs) : void 0;
@@ -85225,7 +85718,7 @@ async function exportVisualization(ctx) {
85225
85718
  isDark,
85226
85719
  void 0,
85227
85720
  {
85228
- exportWidth: EXPORT_WIDTH,
85721
+ exportWidth: ctx.width,
85229
85722
  ...seqActiveTagGroup !== void 0 && {
85230
85723
  activeTagGroup: seqActiveTagGroup
85231
85724
  },
@@ -85821,9 +86314,16 @@ async function render(content, options) {
85821
86314
  if (category === "data-chart") {
85822
86315
  await acquireDom();
85823
86316
  try {
85824
- const raw = await renderDataChartD3(renderContent, theme, paletteColors);
86317
+ const raw = await renderDataChartD3(renderContent, theme, paletteColors, {
86318
+ ...options?.width !== void 0 && { width: options.width },
86319
+ ...options?.height !== void 0 && { height: options.height }
86320
+ });
85825
86321
  const svg2 = injectHoverStyles(raw, chartType, { bakeHover });
85826
- return { svg: svg2, diagnostics: withLegendInlineWarning(diagnostics), chartType: chartType ?? void 0 };
86322
+ return {
86323
+ svg: svg2,
86324
+ diagnostics: withLegendInlineWarning(diagnostics),
86325
+ chartType: chartType ?? void 0
86326
+ };
85827
86327
  } finally {
85828
86328
  releaseDom();
85829
86329
  }
@@ -85845,6 +86345,8 @@ async function render(content, options) {
85845
86345
  },
85846
86346
  ...options?.tagGroup !== void 0 && { tagGroup: options.tagGroup },
85847
86347
  ...options?.mapData !== void 0 && { mapData: options.mapData },
86348
+ ...options?.width !== void 0 && { width: options.width },
86349
+ ...options?.height !== void 0 && { height: options.height },
85848
86350
  onMapResolverDiagnostics: (d) => {
85849
86351
  mapDiag.current = d;
85850
86352
  }
@@ -85857,7 +86359,11 @@ async function render(content, options) {
85857
86359
  if (chartType === "map" && mapDiag.current) {
85858
86360
  diagnostics = [...mapDiag.current];
85859
86361
  }
85860
- return { svg, diagnostics: withLegendInlineWarning(diagnostics), chartType: chartType ?? void 0 };
86362
+ return {
86363
+ svg,
86364
+ diagnostics: withLegendInlineWarning(diagnostics),
86365
+ chartType: chartType ?? void 0
86366
+ };
85861
86367
  }
85862
86368
 
85863
86369
  // src/countdown/ticker.ts
@@ -86202,46 +86708,11 @@ function startClocks(root = document) {
86202
86708
  init_dgmo_router();
86203
86709
  init_palettes();
86204
86710
 
86205
- // src/sharing.ts
86206
- var import_lz_string = __toESM(require_lz_string(), 1);
86207
- var DEFAULT_BASE_URL = "https://online.diagrammo.app";
86208
- var COMPRESSED_SIZE_LIMIT = 8192;
86209
- function encodeViewState(state) {
86210
- const keys = Object.keys(state);
86211
- if (keys.length === 0) return "";
86212
- return (0, import_lz_string.compressToEncodedURIComponent)(JSON.stringify(state));
86213
- }
86214
- function encodeDiagramUrl(dsl, options) {
86215
- const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
86216
- const compressed = (0, import_lz_string.compressToEncodedURIComponent)(dsl);
86217
- const byteSize = new TextEncoder().encode(compressed).byteLength;
86218
- if (byteSize > COMPRESSED_SIZE_LIMIT) {
86219
- return {
86220
- error: "too-large",
86221
- compressedSize: byteSize,
86222
- limit: COMPRESSED_SIZE_LIMIT
86223
- };
86224
- }
86225
- let hash = `dgmo=${compressed}`;
86226
- if (options?.viewState) {
86227
- const vsEncoded = encodeViewState(options.viewState);
86228
- if (vsEncoded) {
86229
- hash += `&vs=${vsEncoded}`;
86230
- }
86231
- }
86232
- if (options?.palette && options.palette !== "nord") {
86233
- hash += `&pal=${encodeURIComponent(options.palette)}`;
86234
- }
86235
- if (options?.theme && options.theme !== "dark") {
86236
- hash += `&th=${encodeURIComponent(options.theme)}`;
86237
- }
86238
- if (options?.filename) {
86239
- hash += `&fn=${encodeURIComponent(options.filename)}`;
86240
- }
86241
- return { url: `${baseUrl}?${hash}#${hash}` };
86242
- }
86711
+ // src/auto/shared.ts
86712
+ init_sharing();
86243
86713
 
86244
86714
  // src/embed/index.ts
86715
+ init_sharing();
86245
86716
  init_palettes();
86246
86717
 
86247
86718
  // src/editor/dgmo.grammar.js
@@ -86309,7 +86780,9 @@ var CHART_TYPES = /* @__PURE__ */ new Set([
86309
86780
  "venn",
86310
86781
  "quadrant",
86311
86782
  "map",
86312
- "body"
86783
+ "body",
86784
+ // Pointer type — internal, but it must still highlight when one is open
86785
+ "live-link"
86313
86786
  ]);
86314
86787
  var TAG_KEYWORD = "tag";
86315
86788
  var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([...REGISTRY_DIRECTIVE_TOKENS]);
@@ -86761,19 +87234,8 @@ function markTokensInRange(tokens, from, to, role) {
86761
87234
  }
86762
87235
  }
86763
87236
 
86764
- // src/error-card.ts
86765
- init_dgmo_router();
86766
- var DOCS_BASE = "https://diagrammo.app/docs";
86767
- function docsLink(source) {
86768
- const chartType = parseDgmoChartType(source);
86769
- return chartType ? {
86770
- url: `${DOCS_BASE}/chart-${chartType}/`,
86771
- label: `Read the ${chartType} guide \u2197`
86772
- } : { url: `${DOCS_BASE}/`, label: "Browse the DGMO docs \u2197" };
86773
- }
86774
- var W2 = 660;
86775
- var PAD2 = 24;
86776
- var CONTENT_W = W2 - PAD2 * 2;
87237
+ // src/embed/index.ts
87238
+ init_error_card();
86777
87239
 
86778
87240
  // src/embed/escape.ts
86779
87241
  var HTML_ENTITIES = {
@@ -87180,8 +87642,8 @@ var BLOCK_CSS = `
87180
87642
  font-style: italic;
87181
87643
  }
87182
87644
 
87183
- /* === Cloud references ===
87184
- * A withdrawn reference's placeholder, and the "this moved" affordance a host's
87645
+ /* === Live links ===
87646
+ * A withdrawn pointer's placeholder, and the "this moved" affordance a host's
87185
87647
  * client script falls back to when it can see a diagram has changed but cannot
87186
87648
  * safely swap it in. Both are deliberately quiet: a page peppered with badges
87187
87649
  * is worse than one that is a few days behind. */
@@ -87203,6 +87665,42 @@ var BLOCK_CSS = `
87203
87665
  opacity: 0.7;
87204
87666
  text-align: right;
87205
87667
  }
87668
+ /* The card a docs site shows when live links are switched OFF, plus its
87669
+ * hover-revealed way to turn them on. Hover-only on purpose: a READER never
87670
+ * meets it, and anyone mousing over a diagram-shaped thing on their own docs
87671
+ * site is almost certainly its author \u2014 which makes this the fix for a build
87672
+ * warning nobody reads. The markup is the WRAPPER's (only it knows the feature
87673
+ * is off); the styling is here because there is one stylesheet. */
87674
+ .dgmo-live-link-off {
87675
+ position: relative;
87676
+ }
87677
+ .dgmo-live-link-view {
87678
+ display: block;
87679
+ text-decoration: none;
87680
+ }
87681
+ /* pointer-events: none alongside the fade, or an invisible link sits over the
87682
+ * card's bottom-right corner and navigates a reader who clicks near it. Focus
87683
+ * still reveals it (:focus-within on the wrapper), so a keyboard user is not
87684
+ * shut out of something a mouse user can reach. */
87685
+ .dgmo-live-link-enable {
87686
+ bottom: 0.5rem;
87687
+ font-size: 0.8em;
87688
+ opacity: 0;
87689
+ pointer-events: none;
87690
+ position: absolute;
87691
+ right: 0.5rem;
87692
+ transition: opacity 0.15s ease-in-out;
87693
+ }
87694
+ .dgmo-live-link-off:hover .dgmo-live-link-enable,
87695
+ .dgmo-live-link-off:focus-within .dgmo-live-link-enable {
87696
+ opacity: 1;
87697
+ pointer-events: auto;
87698
+ }
87699
+ @media (prefers-reduced-motion: reduce) {
87700
+ .dgmo-live-link-enable {
87701
+ transition: none;
87702
+ }
87703
+ }
87206
87704
  `;
87207
87705
 
87208
87706
  // src/embed/index.ts
@@ -87327,7 +87825,7 @@ var CSS = AUTO_BASE_CSS + "\n" + BLOCK_CSS + "\n" + darkScopedBlockCss(BLOCK_CSS
87327
87825
 
87328
87826
  // src/auto/shared.ts
87329
87827
  init_safe_href();
87330
- var VERSION = "0.57.0";
87828
+ var VERSION = "0.59.0";
87331
87829
  var ARIA_LABEL_MAX = 200;
87332
87830
  var COPIED_INTERACTION_MS = 1500;
87333
87831
  var LOG_PREFIX = "[dgmo]";